nMaxwell Ну и для чего нужны все посты >64? Если исключительно для выяснения отношений с 737061, но на месте модераторов я бы забанил нахрен обоих.
согласен! Только еще тему надо была закрыть давно с причиной "вопрос исчерпан". Ведь 737061 не троллит в нормальных темах, ибо людям мешать это не хорошо.
Rel Я чувствовал что я особенный, но чтобы так просто вызывать кернел паник, это конечно неожиданная новость.
Что имеется ввиду под переходниками? Вызовы на JMP котрые ведут в IAT? И что имеется ввиду под экзотикой?
Думал, будет проще, а пришлось полдня убить. Но раз уж такой вопрос задают не впервые, а я не могу позволить себе упустить возможность в очередной раз доказать крутоту fasm, закончились полдня следующим: Код (Text): ... section '.edata' export data readable exportForwarded 'FORWEXP.DLL','C:\windows\system32\winmm.dll',\ mySndPlaySound,'sndPlaySoundA',\ mySecondFunction,2 Данный код полностью реконструирует в модуле forwexp.dll директорию экспорта идентичную экспорту модуля winmm.dll. Весь экспорт кроме указанных функций будет сквозным. Указанные функции будут соответственно заменять таковые из оригинального модуля. Первые два параметра (имя своей dll и путь к оригинальной dll) обязательны. Если дальше ничего не указывать, весь экспорт будет перенаправлен в оригинальную dll. Дальнейшие параметры идут попарно: 1-й параметр — имя метки (функции, перенаправляющей строки, переменной и т.п.) в исходнике. 2-й параметр — имя или ординал функции из оригинальной dll, которую нужно перехватить. Макрос полезен в том числе и тем, кто хочет перенаправлять вызовы функций оригинального модуля в dll, написанные не на fasm. Пусть, например, myCoolDll.dll написана на Delphi и экспортирует функцию myMegaFunction, которая должна получать управление вместо MessageBoxA из user32.dll. Следующая dll (user33.dll), скомпилированная fasm будет осуществлять желаемое: Код (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 invoke ExitProcess,0 section '.idata' import data readable writeable library kernel32,'kernel32.dll' import kernel32,\ ExitProcess,'ExitProcess' section '.edata' export data readable exportForwarded 'user33.dll','C:\windows\system32\user32.dll',\ myMegaFunction,'MessageBoxA' myMegaFunction db 'MYCOOLDLL.myMegaFunction',0 section '.reloc' fixups data discardable Все вызовы функций из user32.dll она будет перенаправлять в user32.dll за исключением вызова MessageBoxA. Вызов MessageBoxA будет перенаправлен в функцию myMegaFunction из модуля myCoolDll.dll. Макрос и простой пример использования приложены.
nMaxwell Пожалуйста. Но я всё таки хотел бы там пару строк подправить: улучшить проверку валидности параметров и ускорить раза в полтора-два. На днях пару свободных часов появится, исправлю. Поэтому лучше пока не закрывать.
Значит так. Изменения следующие: 1) Больше нельзя сделать так: Код (Text): exportForwarded 'FORWEXP.DLL','%WinDir%\system32\kernel32.dll',\ redir,'Beep',\ redir,'BeepX' , и чтобы при этом макрос сделал вид, что не заметил, что BeepX отсутствует в экспорте kernel32.dll. 2) После такого кода: Код (Text): exportForwarded 'FORWEXP.DLL','%WinDir%\system32\kernel32.dll',\ redir,'Beep',\ redir2,'Beep' макрос больше не думает, что Beep отсутствует в экспорте kernel32.dll. Теперь он уверенно сообщает о переопределении метки для одной и той же функции. 3) Больше нельзя отправить функцию по имени на одну метку и ту же самую функцию по ординалу на другую (или на ту же). Макрос это заметит и найдёт правильные выражения, чтобы об этом высказаться. 4) Скорость обработки увеличена в полтора-два раза. Кстати, родной GUI'шный компилятор fasm справляется почти вдвое дольше. Так что имеет смысл использовать альтернативные IDE, работающие с консольной версией fasm. Для сравнения время четырёхпроходной обработки kernel32.dll : Код (Text): версия макроса | старая | новая | версия fasm | | | ———————————————————————————+———————————+——————————| GUI | 27.7 с | 15.9 с | ———————————————————————————+———————————+——————————| консоль | 14.4 с | 8.3 с | ———————————————————————————+———————————+——————————| Из-за ускорения работы макроса возможна проблема в случае, если имена экспортируемых модулем функций подпёрты под самый конец образа (в старой версии эта проблема тоже возможна, но с меньшей вероятностью). В принципе, можно было бы и это улучшить. Реальные образы, где эта проблема может проявиться, если и существуют, то в очень небольших количествах.
Исправил пару достаточно критичных и довольно глупых багов. Старые версии оставляю исключительно для желающих сравнить.
Исправил баг, приводящий к зависанию в случае, если указанный путь к оригинальной dll не содержит слешей.
а если я хочу помимо подмены функции ещё и вызывать оригинальную? что-то типа аналога наследования в ООП - при переопределении метода родителя иметь возможность вызвать родительский код. как тогда поступить? я догадываюсь что можно перетянуть весь код оригинальной функции, но в некоторых случаях такое "перетягивание" повлечёт за собой неограниченное количество кода.