Охота на ведьм Николай «GorluM» Андреев Хакер, номер #078, стр. 078-104-2 1) перечисляем все модули нашей программы; 2) в каждом модуле ищем таблицу импорта; 3) с помощью GetProcAddress проверяем правильность каждого адреса функций в таблице; 4) если адрес, возвращенный GetProcAddress (или ее аналогом), и адрес, взятый из таблицы, не совпали — громко орем и выводим на экран всю возможную информацию (о лечении я пока молчу, ибо бесполезно лечить одну только нашу программу). Правда, есть небольшой нюанс. GetProcAddress, возвращающая адрес функции по ее имени и хэндлу модуля, тоже может быть перехвачена (даже не может, а обязана). А это значит, доверять ей нельзя и придется написать собственный аналог, который перехватывать никто не станет и не сможет. Что ж, с основной идеей разобрались, можно начинать кодить. [кодим помаленьку] Перечислить все модули определенного процесса (в данном случае нашего) можно тучей разных способов: тут и библиотека psapi сгодится, и даже сама NtQuerySystemInformation. Я, правда, привык пользоваться ToolHelp-функциями. Они удобные, если приноровиться их юзать. Сначала получаешь снимок нужной тебе системной информации с помощью CreateToolhelp32Snapshot, а затем бегаешь по нему с помощью Module32First\Module32Next или аналогов. К примеру, чтобы выполнить функцию Test для каждого хэндла модуля текущего процесса (нашего детектора), нужно написать вот такой несложный код: MODULEENTRY32 me = {sizeof(me)}; HANDLE m_Snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); if (m_Snap == INVALID_HANDLE_VALUE) return; if (!Module32First(m_Snap, &me)) return; do Test(me.hModule); while (Module32Next(m_Snap, &me)); CloseHandle(m_Snap); Функция Test — это второй, третий и четвертый шаги нашего алгоритма. В ней мы должны найти таблицу импорта и проверить подлинность каждой записи. Но, как ты понимаешь, для работы с таблицей надо знать ее формат. Он уже описывался всеми, кем только можно, и отыскать в Сети подробный мануал тебе труда не составит (wasm.ru, к примеру, располагает подобной информацией). Разобравшись с форматом таблицы импорта и вообще с PE (я не знаю, как можно программировать под windows без таких основ), можно приступить к кодингу нашей функции Test. Первое, что она должна сделать, — найти импорт в модуле, чей хэндл был передан ей в единственном параметре. Осуществить это можно двумя способами: 1) с помощью функции библиотеки imagehlp, сразу возвращающей нужный нам указатель на первую структуру таблицы: PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(hModule, 2) вручную, покопавшись в PE-заголовках модуля. Хэндл модуля — это указатель на первый байт образа библиотеки, загруженной в адресное пространство процесса. Мы без проблем можем найти все необходимые данные: |