Непонятки с ___imp_RtlUnwind
Пока мыщъх'и оттягивались на конопляном поле в полный рос, находясь в блаженном кайфе, магический макрос споткнулся на функции "___imp_RtlUnwind" (он попросту не нашел ее в KERNEL32.LIB), все пошло кувырком и мыщъх'ей сразу попустило.
Что же это за противная функция такая?! Кстати, в KERNEL32.LIB ее действительно нет. Так что макрос тут не причем. Смотрим в demo_3.asm (не забывая убрать один из символов прочерка, вставленный транслятором). Контекстный поиск тут же находит RtlUnwind, представляющую собой классический переходник (thunk) к одноименной функции из KERNEL32.DLL:
RtlUnwind proc near
jmp ds:__imp_RtlUnwind
RtlUnwind endp
Листинг 8 переходник (thunk) к API-функции RtlUnwind из KERNEL32.DLL
Только вот по не совсем понятной причине, IDA Pro не нашла этой функции в KERNEL32.DLL (не знала о ней? или не захотела искать?!), но тот же HIEW отобразил thunk совершенно правильно!
Рисунок 5 HIEW правильно отображает имя API-функции RtlUnwind, а IDA Pro – нет
Собственно, багофича заключается в том, что IDA Pro дает API-функции неправильное имя. Ну какой же это "__imp_RtlUnwind"?! Правильный вариант включает в себя _два_ символа прочерка между "imp" и "RtlUnwind". Естественно, наш магический (но слегка туповатый) макрос не ожидал такой внезапной подлости! Приходится брать бразды правления на себя и либо править ассемблерный листинг, добавляя еще один символ прочерка, либо алиасить функцию как есть. Последний вариант более предпочтителен, поскольку он не требует вмешательства в исходный код. Включаемый файл нужно писать, так, чтобы он работал, а не исходить из того, что правильно/неправильно и не пытаться оправдаться "это же не наш баг? почему мы должны его учитывать?!". Положитесь на мой хвост парни! Мы должны! И правильный алисасинг выглядит так:
externdef imp__RtlUnwind@16:PTR pr4
__imp_RtlUnwind equ < _imp__RtlUnwind@16>
Листинг 9 алиасинг API-функции __imp_RtlUnwind