возможно ли сделать сквозной экспорт для библиотеки, расширение которой отлично от dll? (dll'ка с экспортом создается, но импортирует функции все равно из dll)
h0t При сквозном экспорте (forwarded export) внутри таблицы экспорта находятся строки вида NTDLL.RtlAllocateHeap, на которые указывают RVA соответствующих функций (в данном примере ф-ия HeapAlloc из kernel32.dll). Загрузчик при разрешении импорта такой функции (HeapAlloc) сразу кладёт в IAT адрес RtlAllocateHeap из ntdll.dll. Вопрос в том, можно ли этот же вид экспорта использовать, чтобы загрузчик искал адрес импортируемой функции в библиотеке somedll.plg, например, а не в somedll.dll.
О сквозном экспорте я знаю, просто не понял вопроса вначале. Знайте, наверное нет, так-как на сколько я помню загрузчику неоткуда взять полное имя файла... P.S. l_inc спасибо)
а зачем загрузчику полное имя файла? достаточно знать до расширения - NTDLL.RtlAllocateHeap somedll.plg -> SOMEDLL.SomeFunc Дельфевые bpl-то,наверное, работают... А вот что будет, если загрузить ntdll.dll и ntdll.bpl... вот надо поэкспериментировать...
l_inc если использовать dll, то придется ломать всю логику delphi, т.к. все пакеты там используют bpl. ладно, фиг с ним, с экспортом, как перехватить тогда не в ран-тайме пару функций у delphi32.exe ( у него в экспорте туева куча)
nMaxwell Ничего не надо ломать. Прокси dll нужно дать расширение bpl. А оригинальную переименовать в .dll. Т.о. все будут использовать прокси dll.
я, видимо, не вижу другого обьяснения тому, что кроме delphi32.exe никакие другие приложения и библиотеки наотрез отказываются работать, т.е. когда дельфя начинает загружать свои либы, они выкидывают ошибки (может функция rtl-инициализации запускается в нормальном режиме, а через прокси она теряется, следовательно вызов какой-то неинициализированной переменной приводит к ошибке)
nMaxwell Предположительно теряться ничего не должно. Я бы сам попробовал, но у меня нету delphi. Если хотите, выложите код прокси dll и тексты ошибок и опишите, где что лежит (приложение, основная dll, прокси dll) и под какими именами.
Код (Text): format PE GUI 4.0 DLL entry DllEntryPoint include 'win32a.inc' include 'forwardedexport.inc' section 'CODE' code readable executable proc DllEntryPoint hinstDLL,fdwReason,lpvReserved mov eax, TRUE ret endp proc ReadStr name invoke MessageBox,NULL,text,title,MB_OK ret endp title db 'Title',0 text db 'A call catched',0 section '.idata' import data readable writeable library user32,'USER32.DLL' import user32, MessageBox, 'MessageBoxA' section '.edata' export data readable exportForwarded 'rtl70.bpl','rtl70.bpl', ReadStr, '@Dateutils@IsPM$qqrx16System@TDateTime', DllEntryPoint, 5007 ; section '.reloc' fixups data discardable выкидывается Runtime error 216 at 40005CDE все находится в одной диръ имена соответственно 1)rtl70.dll (оригинал переименованный), rtls7.bpl (прокси, в exe поменял имя) и rtl70.bpl (для остальных библиотек) 2)rtl70.dll (оригинал переименованный), rtl70.bpl (прокси)
nMaxwell Во-первых, не забываете потом переименовать rtl70.bpl в rtl70.dll и наоборот? Во-вторых, Вот это ещё зачем? В-третьих, если я правильно помню, delphi использует fastcall, что у Вас, похоже, не учитывается. На таком коде всё нормально отрабатывает? Код (Text): format PE GUI 4.0 DLL entry DllEntryPoint include 'win32a.inc' include 'forwardedexport.inc' section '.text' code readable executable proc DllEntryPoint hinstDLL,fdwReason,lpvReserved mov eax, TRUE ret endp ReadStr: jmp [OriginalReadStr] title db 'Title',0 text db 'A call catched',0 section '.idata' import data readable writeable library user32,'USER32.DLL',\ rtl70bpl,'RTL70.DLL' import user32,\ MessageBox, 'MessageBoxA' import rtl70bpl,\ OriginalReadStr,'@Dateutils@IsPM$qqrx16System@TDateTime' section '.edata' export data readable exportForwarded 'rtl70.bpl','rtl70.bpl',\ ReadStr, '@Dateutils@IsPM$qqrx16System@TDateTime' section '.reloc' fixups data discardable P.S. Имя rtl70bpl было неправильное. Подправил.
l_inc тут дело не совсем в том, код получается одинаковый 1) @Dateutils@IsPM$qqrx16System@TDateTime - первая попавшаяся мне функция, не используемая дельфи при запуске, поэтому fastcall не причем тут. 2) rtl70.bpl при запуске использует функцию по ординалу равную 5007, поэтому я написал 'DllEntryPoint, 5007' главная задача, пока что, это запуск IDE без перехвата)
nMaxwell Ну так Вы взяли и заменили его функцию, которая, наверное, какие-то полезные действия выполняет, на пустую. Причём, вероятно 5007 — fastcall, а DllEntryPoint — stdcall, в результате чего ещё и стек портится. Так что fastcall очень даже причём.
l_inc EP rtl70.bpl делает джамп на 5007 и все, больше никаких действий он не выполняет, как утверждает ида. а если нет параметров, есть ли разница, как вызывать? просто call? или надо еще указывать ( как например в cdecl - cinvoke, в stdcall - invoke)
nMaxwell В данном случае нету, но его внутренний прыжок не имеет никакого значения. Важно, вызывают ли внешние модули 5007. Просто проверьте, работает ли код из #14. Если работает, значит никаких проблем с bpl/dll нету.
nMaxwell Тогда ХЗ, но маловероятно, что это как-то связано с расширениями. Возможно, delphi использует собственные процедуры разрешения импорта и не учитывает сквозной экспорт.