Защита програмного обеспечения

При разработке модуля защиты (и нападения) часто возникает необходимость вызова функций 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).

А.В. БЫЧЕНКОВ,
eris-by@mail.ru

Версия для печатиВерсия для печати

Номер: 

21 за 1999 год

Рубрика: 

Азбука программирования
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!