При разработке модуля защиты (и нападения) часто возникает необходимость вызова функций Win32 API, минуя таблицу импорта. Обычно приложения вызывают функции API, используя таблицу импорта, данные в которую заносятся при загрузке приложения. Поэтому вызовы API компилируются как код команды call + смещение в таблице импорта. При динамической генерации кода модуля защиты подобные вызовы применить нельзя, так как неизвестен адрес таблицы импорта и порядок следования её элементов. Идея, основанная на том факте, что ядро Windows располагается в памяти статически (всегда по одним и тем же адресам), неработоспособна, так как, хотя ядра Win95 и Win98 имеют одинаковые начальные адреса, но адреса точек входа функций различны (это связано с тем, что длина кода функций в Win95 и Win98 различна). Первоначальная задача может быть сведена к вызову одной функции - GetProcAddress, с помощью которой можно получить адреса точек входа всех необходимых функций. Сигнатура этой функции уникальна и одинакова в Win95 и в Win98, поэтому представляется возможным провести поиск точки входа в эту функцию по её сигнатуре, что и реализует приведённый ниже фрагмент кода:
mov edi,$0BFF70000 //Загрузка начального адреса //kernel32.dll mov eax,$2B226A57 //Сигнатура для поиска cld //Автоматическое увеличение EDI repne scasd //Поиск сигнатуры sub edi,4 //Коррекция адреса, теперь EDI //содержит адрес точки входа
После поиска можно вызывать GetProcAddress с помощью команды call edi, предварительно занеся параметры этой функции в стек. Этот способ был протестирован в Win95 и Win98 с положительным результатом. В качестве области применения этого метода можно назвать саморасшифровывающийся код в системах защиты, вирусоподобные (к примеру, пристыковочные модули) и им подобные программы. Как известно автору, подобный способ используют некоторые Win32 вирусы (к примеру, Win95.SGWW).
А.В. БЫЧЕНКОВ,
[email protected]
Горячие темы