![]() |
Доброго времени суток ув. форумчане.Покопавшись на форуме я понял что не хватает статей по перехвату АПИ,да и я давно ничего толком не писал.Так что сегодня пойдет речь,я думаю,об одном из самых перспективынх методов перехвата АПИ в ring 3- сплайсинге.
И так не много теории. Сплайсинг-метод перехвата API функций в режиме юзера (ring 3). Обычно изменяются первые 5 байт функции на длинный прыжок по адресу обработчика перехвата.В зависимости от ситуации может понадобится дизассемблер длин инструкций,однако M$ изменила пролог начиная с ХР SP2, позволяя при этом не анализировать длины.Длины в 5 байт будет достаточно(5байт- E9h- опкод прыжка jmp).Сплайсинг так же позволяет осуществлять глобальный перехват функций, тем самым охватывая все процессы в системе. Применение: Данный вид перехвата используется: 1)Десктопное ПО производящее операции с ОС (например мониторы) 2)Хуки 3)Малварь (руткиты и т.п.) Инструменты: 1)ЯП (в данном случае Delphi) 2)музычка (kmfdm или rammstein сойдет) 3)руки.голова И так начнем. Как вы поняли наш код будет размещаться в dll-ке которая будет загружаться во все процессы и творить там свои темные дела.Чтобы не парится я буду извращаться с мэссэджбоксом. код: Создаем две записи-структуры Код:
typeобъявим переменные структур Код:
varТеперь нам нужно описать функции на которые будет происходить прыжок. Их будет две.Почему так?Мурка заключается в том что существуют две категории АПИ ansi и Unicode которые имеют соответствующее окончание MessageBoxA или например MessageBoxW. Соль в том что анси является 8 битной кодировкой и может предоставлять только 256 уникальных символов, в то время как юникод обеспечивает 65535 уникальных символов,это было сделано с целью работы со всеми языками мира. начнем описание функций: Код:
function NMessageBoxExA(hWnd: HWND; lpText, lpCaption: PAnsiChar;дескриптор окна, текст сообщения,заголовок окна,стиль окна и язык. работаем с widechar выше разобрали почему(т.к. он поддерживает интернациональные символы). напрямую со string мы не работаем,а работаем с памятью. Получаем длину текста и длину заголовка.Выделяем кол-во динамической памяти= длине, получая данные в нужные переменные.Затем конвертируем строки и получаем готовые флаги ф-ии.вызываем ф-ю с нужными параметрами и освобождаем память. Следующей определяем оригинал Код:
function TrueMessageBoxExW(hWnd: HWND; lpText, lpCaption: PWideChar;Код:
function NMessageBoxExW(hWnd: HWND; lpText, lpCaption: PWideChar;вот они: Код:
Function AllocMem(Size: Integer): Pointer;эта функция выд-т область памяти,после чего мы применяем функцию конвертирования string строки в widechar Код:
function stringtopwide(str:string;var a:integer):pwidechar;Код:
procedure SetHook;получаем дескриптор системной dll-ки в которой хранятся наши функции. записываем их адреса в записи. сохраняем оригинальные начала. Формирование новых начал функций в структурах jmpmw и jmpma идет так: опкод 68h -push, затем ее аргумент – адрес нашей функции, которая заменит оригинальную, в конце идет опкод c3h-ret.И переписываются оригинальные начала на наши. когда надо подставить оригинал,возвращаем байты Код:
Procedure Unhook;Код:
Function Msg(code : integer; wParam : word;Код:
Procedure SetGlobalHookO;Код:
Procedure SetGlobalHook;Код:
procedure DLL(dwReason: DWord);Остается лишь написать лоадер. Код:
.386и так алгоритм работы в кратце (итог типо) 1) получаем дескриптор библиотеки , в которой содержатся функции которые необходимо перехватить. 2) в соответствующие переменные записываем оригинальные адреса функций 3) сохраняются оригинальные начала функций 4) Формирование новых начал функций в структурах jmpmw и jmpma. В начале идет опкод команды push, затем ее аргумент – адрес нашей функции, которая заменит оригинальную, в конце идет оператор ret. 5) переписываются начала оригинальных API-функции данными из структур Таким образом в начало оригинальных функций будут вставлены переходы на их функции-заменители. Рез-ат работы перехвата: http://4put.ru/pictures/max/236/726808.jpg ССЫЛАЛСЯ: На код перехвата createprocess ms-rema. Сильно не бейте!спасибо за внимание! |
ну,что скажете люди?
|
Круто )
|
Спасибо, познавательно. На дельфячем языке мне норм понятно.
+ |
То, что на ачате нету статей по перехвату API, это нехорошо, конечно. Но и здесь не описано ничего нового. Все это можно найти в инете. Тот же MS-REM описал все намного лучше.
Это также есть на самом деле нехорошо: Цитата:
Код оформлен плохо. Эти INVALID_HANDLE_VALUE немного сбивают с толку. Также нужно сказать, что здесь перезаписывается не 5, а 6 байт. Цитата:
|
Цитата:
|
Цитата:
0. С помощью дизассемблера длин выделяем столько целых первых команд перехватываемой функции, длина которых >= 5. Запоминаем эту длину в переменную len. 1. Запоминаем адрес следующей команды в переменную next_opcode. 2. Выделяем len + 5 байт памяти, адрес этой памяти записываем в переменную old_func. 3. В выделенный участок памяти копируем первые len байт из перехватываемой функции и дописываем команду jmp next_opcode (для нее мы выделели 5 дополнительных байт). 4. Перезаписываем первые 5 байт перехватываемой функции командой jmp . 5. Когда нужно вызвать старую функцию, делаем call old_func. |
Цитата:
|
Цитата:
|
Цитата:
|
| Время: 17:06 |