Охота на ведьм Николай «GorluM» Андреев Хакер, номер #078, стр. 078-104-4 HMODULE ModuleFromAddressEx(PVOID pv) { MEMORY_BASIC_INFORMATION mbi; return((VirtualQuery( pv, &mbi, sizeof(mbi)) != 0) ? (HMODULE) mbi.AllocationBase : NULL); } Такая классная штука вернет хэндл модуля, в котором обитает функция-перехватчик, если скормить ей адрес поддельной функции из таблицы. А по хэндлу можно уже определить и имя модуля, а потом и вовсе удалить надоедливую программу-невидимку (это при условии, что перехватчик внедрялся в виде библиотеки). [глобальное лечение] Мы разобрались с тем, как засечь перехват; теперь надо понять, как его вылечить, чтобы увидеть все скрытые в системе записи. Сделать это в рамках одного-единственного нашего процесса очень просто: вместо вывода ошибки напиши pThunk->u1.Function = f, и найденный нами подлинный адрес функции запишется поверх поддельного в таблице. Вылечить же от перехвата не только наш процесс, но и всю систему будет уже посложнее. Тут надо либо внедрять код нашего детектора в каждый процесс и пусть он там наводит марафет, либо манипулировать функциями WriteProcessMemory и ReadProcessMemory, чтобы без внедрения кода получить таблицу импорта, проанализировать ее и вылечить. Но, честно тебе скажу, инжект работает на порядок быстрее. Постоянные межпроцессные обращения сильно грузят камень, и сканирование системы может затянуться на минуты! Так что, для того чтобы вылечить от перехвата API методом модифицирования таблицы импорта всю систему, надо всего лишь чуток подправить функцию Test и инжектировать ее уже описанным мною способом по все процессы. Как минимум половина руткитов сразу станет видной, ну а что делать с остальными? // получение DOS-заголовка модуля чужого процесса // …лучше так не делать IMAGE_DOS_HEADER rDosHeader; ReadProcessMemory(m_hProcess, hModule, (LPVOID)&rDosHeader, sizeof(IMAGE_DOS_HEADER), &dwBytes); [альтернативный перехват] Как ты, конечно, понимаешь, модифицирование импорта — хоть и популярный, но не единственный способ перехвата API. Реже, возможно, из-за сложности реализации, используют перехват подменой кода (есть отличное готовое решение — библиотека Detours от Microsoft). В этом методе таблицу импорта не трогают, а модифицируют только саму перехватываемую функцию, впатчивая ей в начало безусловный переход (jmp) на перехватчик, который запускает оригинал (либо копируя функцию целиком, либо восстанавливая первые байты, поверх которых был впатчен джамп) и фильтрует его вывод. Мне этот способ перехвата очень понравился, и я уже переделал свою невидимку под него, так что на диске можешь взять новую версию. Чем он так хорош? Ну хотя бы тем, что качество невидимости не будет страдать оттого, что таблица импорта основного модуля одной из обрабатываемых программ по каким-нибудь причинам попорчена — например, защита стоит. Его волнует только тот модуль, в котором лежит перехватываемая функция, и с ним обычно никаких проблем не возникает. |