Аудит и дизассемблирование exploit'ов

         

процедура MyGetProcAddress, возвращающая адрес API-функции по хэш-сумме его имени


Зная базовый адрес загрузки KERNEL32.DLL (он передается функции через стек и лежит по смещению 24h байта от вершины — остальное пространство занимают регистры, сохраненные командой PUSHA), программа получает указатель на PE-заголовок, откуда извлекает указатель на таблицу экспорта, считывая общее количество экспортируемых имен (numberOfNamePointers) и RVA-указатель на массив с именами, который тут же преобразуется в эффективный виртуальный адрес путем сложения с базовым адресом загрузки KERNEL32.DLL.

А вот дальше… дальше начинается самое интересное! Для каждого из экспортируемых имен функция вычисляет хэш, сравнивая его с тем "загадочным" числом. Если они совпадают, искомая API-функция считается найденной и возвращается ее виртуальный адрес. Таким образом, данный код представляет собой аналог функции GetProcAddress, только с той разницей, что он принимает не ASCII-имя функции, а его 32-битный хэш. Условимся называть эту процедуру MyGetProcAddress.

Можно ли восстановить имя функции по ее хэшу? С математической точки зрения — навряд ли, но что мешает нам запустить shell-код под отладчиком (см. одноименную врезку) и "подсмотреть" возвращенный виртуальный адрес, по которому имя определяется без проблем!

Сказано сделано! Немного протрассировав программу до строки 82h, мы обнаруживаем в регистре EAX число 79450221h (зависит от версии системы на вашей машине наверняка будет иным). Нормальные отладчики (типа OllyDbg) тут же покажут имя функции LoadLibraryA. Как вариант, можно воспользоваться утилитой DUMPBIN из Platform SDK, запустив ее со следующими ключами: "dumpbin KERNEL32.DLL /EXPORTS >
 kernel32", только помните, что она показывает относительные RVA-адреса, поэтому необходимо либо добавить к ним базовый адрес загрузки KERNEL32.DLL, либо вычесть его из адреса искомой функции.

seg000:00000082 66 53                    push   bx            ; \

seg000:00000084 66 68 33 32       push   small 3233h   ;  + - "ws2_32"

seg000:00000088 68 77 73 32 5F    push   5F327377h     ; /

seg000:0000008D 54                push   esp           ; &"ws2_32"

seg000:0000008E FF D0                    call   eax           ; LoadLibraryA

seg000:00000090 68 CB ED FC 3B    push   3BFCEDCBh     ; WSAStartup

seg000:00000095 50                push   eax           ;

seg000:00000096 FF D6                    call   esi           ; MyGetProcAddress



Содержание раздела