В сотнях программ встречаю этот код (иногда, десятки раз, в нескольких секциях). Явных ссылок на него, обычно, нет. Код (Text): 00000EF4: 55 push ebp 00000EF5: 8BEC mov ebp,esp 00000EF7: 5D pop ebp 00000EF8: C3 retn В чем тут сермяжный смысл ?
MSVC/Delphi/BCPPB Гм. Десятки/сотни раз в секции? Ex: Код (Text): 15 00069152 .03069D52 5DEC8B55 EBP: Debugger Trap 16 00084529 .03085129 5DEC8B55 EBP: Debugger Trap 17 00084537 .03085137 5DEC8B55 EBP: Debugger Trap ..................................................................................................................... 127 0008FDB9 .030909B9 5DEC8B55 EBP: Debugger Trap 128 0008FDD8 .030909D8 5DEC8B55 EBP: Debugger Trap 129 0008FDF7 .030909F7 5DEC8B55 EBP: Debugger Trap
Обычно, для выравнивания, компилятор пишет стандартные заглушки, ничего общего с полноценными функциями не имеющие. IDA их распознает и помечает как alignment. Эта функция может (не) /присутствовать одновременно со стандартными заглушками. Эти 5 байт можно было бы залить и CC и еще чем-либо, так что предположительно, какой -то смысл в этом мог бы быть, поэтому и пытаюсь его найти
Просто программист на будущее написал что-то вроде : void MySuperFunc(){}; чтобы, когда у него будет время, дописать ее таки, а компилятор без оптимизации сделал код как ему подсунули в исходнике.
И так 150 раз ... причем написал это одновременно в нескольких компиляторах (все сгенерировали идентичный код) и в десятках системных DLL от M$.
gazlan Обычно такое встречается, если методы класса имеют вид method_name(...) { } а таких в упомянутых тобой компиляторах может быть достаточно много.
Может под перехват какой-нибудь место зарезервировано? В 5 байт аккурат инструкция 'jmp rel32' влезает. В итоге, если ф-ию перехватаят, то вызовается jmp, который в эти 5 байт записан, а если нет -- просто произойдет возврат.
gazlan Ты не мог бы привести пример такой системной DLL? AFAIK, релизный виндовс собирается с полной оптимизацией, а компилятор/линкер VC в этом режиме такого себе не позволяют.
Дома посмотрю. У меня там валялся архив с такими файлами. Гм. Не уверен. Мне как-то попадалась прога на Delphi - там такая функция висела почти на каждой форме. Кстати, IDA иногда ее именует (зависит от файла) - всякий раз по-разному :-\
Архив оказался разношерстным, поэтому для чистоты эксперимента натравил скэнер на директорию system32 (без поддиректорий). У меня в ней почти 2,000 файлов, из них исполняемых более 1,500. Полный отчет здесь (не нашел, где приаттачить): h**p://rapidshare.com/files/56472179/ebp_trick_report.rar.html После выбрасывания всех Debug и Unicode версий, а также всего, что не M$, осталось 16 файлов, которые будем считать "системными": Код (Text): atl.dll atl70.dll atl71.dll dbmsrpcn.dll dbmssocn.dll dbmsspxn.dll dxmasf.dll mfc70.dll mfc71.dll msjtes40.dll ntkrnlpa.exe ntoskrnl.exe rsvpmsg.dll snmpsnap.dll strmdll.dll sysedit.exe Кроме этого, еще вчетверо большее число файлов содержит JMP вместо RETN, но с тем же странным префиксом.
это называется инкрементальная линковка. В эти переходники пишется jmp на реальные функции, которые дописываются в конец файла. Для ускорения сборки используется.
gazlan в моём ntoskrnl.exe (XP32 SP2) посл. 55 8B EC 5D C3 не встречается ни разу... В atl71.dll есть парочка таких ф-ций. Если пустая ф-ция компилится без /Oy, к тому же запрещён неявный инлайн или берётся адрес такой ф-ции (например, если ф-ция виртуальная), то компилятор будет вынужден сгенерировать такой код. Такие ограничения оптимизации могут быть сделаны для облегчения отладки. Или по недосмотру.
Там может быть и RET x (x = 4, 8, 12, 16, 20). У меня в SSF-листинге точно указаны смещение в файле и возвращаемое значение. Все еще сомнительно. IMHO, простого RET x было бы достаточно - без имитации EBP-фрейма. Второе соображение: будь это в самом деле так, то встречалось бы чаще чем 1 файл к 100 (для данной выборки). И еще: в трех случаях из четырех (по выборке) после 55 8B EC 5D стоит JMP куда-то там ... Для меня это полная загадка.
Странно, в моём ntoskrnl.exe(5.1.2600.3093 (xpsp_sp2_gdr.070227-2254) ни разу нет ни '55 8B EC 5D C3' ни '55 8B EC 5D C2'. У тебя случайно не checked build виндовса? Если не выставлена опция /Oy, то компилятор обязан генерировать фрейм, даже для пустой ф-ции. Компиляция без /Oy встречается довольно часто, т.к. облегчает отладку - можно нормально смотреть локальные переменные и стек вызовов. Насчёт JMP. Компилятор может оптимизировать код ф-ции, разбивая его на несколько разнесённых кусков. Очень типичное явление. Из-за этого кстати, в IDA появилась возможность работать с chunked functions.