Ясен хуй че на debugapi далеко не улетишь, но похуй…
Тута идем в точку в хода
С помощью дебугг апи можно обрабатывать события там
исключения хуету всякую вобщем. Можно вот например показать рекламу в
месаджбоксе.
Со стороны выглядит так:
Подключаемся к процессу. Создаем событие. Получаем евошнюю
структуру через WaitForDebugEvent. Обрабатываем. Продолжаем ожидание события
через ContinueDebugEvent;
Ну а так по шагам:
Прочитать хидоры фэйлинга
hFile:=OpenFile(путь,OFS,OF_READ);
SetFilePointer(hFile,$3C,0,FILE_BEGIN);
ReadFile(hFile,tmp,4,tmpRW,0);
SetFilePointer(hFile,tmp,0,FILE_BEGIN);
ReadFile(hFile,IMAGENTHEADER,SizeOf(IMAGENTHEADER),tmpRW,0);
CloseHandle(hFile);
Создать процесс
ZeroMemory(@SI,sizeof(SI));ZeroMemory(@PI,SizeOf(PI));
CreateProcess(path, 0, 0, 0, FALSE,DEBUG_ONLY_THIS_PROCESS + DEBUG_PROCESS, 0,0, SI, PI);
Сделать событие вызывающее исключение на ентрипоинте
посредством int3:
ReadProcessMemory(PI.hProcess,Pointer(EntryPoint),@EPByte,1,tmpRW);
WriteProcessMemory(PI.hProcess,Pointer(EntryPoint),@int3,1,tmpRW);
Организовать стандартный дебугг луп
While true do
Begin
case DebugEvent.dwDebugEventCode of
EXCEPTION_DEBUG_EVENT
итд …
Кароче бля, вот чтоб перехватить функцию нужно поставить
брейкпойнт(в данном случае хардварный) на адрес функции. Хардварный занчит
через регистры DR. Все
как в дебуггере, ага. И с помощью GetThreadContext распарсерить аргументы
через ригистер esp, который
бля указывает на бля верх стэка, те по формуле esp+4*Arg n.Тута идем в точку в хода
EXCEPTION_DEBUG_EVENT:
if DebugEvent.Exception.ExceptionRecord.ExceptionCode = EXCEPTION_BREAKPOINT then begin
if CTX.Eip = EntryPoint+1 then begin
Dec(CTX.Eip);
WriteProcessMemory(PI.hProcess,Pointer(EntryPoint),@EPByte,1,tmpRW);
CTX.Dr0 := pProc;
CTX.Dr7 := $01;
SetThreadContext(PI.hThread,CTX);
ContinueDebugEvent(PI.dwProcessId, PI.dwThreadID,DBG_CONTINUE);
end;
Тута парсим аргументы
EXCEPTION_DEBUG_EVENT:
if CTX.Eip = pProc then begin
ZeroMemory(@argStr,Length(argStr));
ReadProcessMemory(PI.hProcess,Pointer(CTX.Esp),Pointer(@pRet),4,tmpRW);
ReadProcessMemory(PI.hProcess,Pointer(CTX.Esp+4*3),Pointer(@pArg),4,tmpRW);
ReadProcessMemory(PI.hProcess,Pointer(pArg),PChar(@argStr[0]),256,tmpRW);
WriteLn('Title:'+argStr);
ZeroMemory(@argStr,Length(argStr));
ReadProcessMemory(PI.hProcess,Pointer(CTX.Esp+4*2),Pointer(@pArg),4,tmpRW);
ReadProcessMemory(PI.hProcess,Pointer(pArg),PChar(@argStr[0]),256,tmpRW);
WriteLn('Text:'+argStr);
WriteLn('===============');
Подменить там ченить.
ADLen:=StrLen(argStr);
for i := 1 to Length(AD) do begin
argStr[ADLen-1+i]:=AnsiChar(AD[i]);
end;
ADLen:=Length(argStr);
pFakeText:=Cardinal(VirtualAllocEx(PI.hProcess,0,Length(argStr),MEM_COMMIT,PAGE_READWRITE));
WriteProcessMemory(PI.hProcess,Pointer(pFakeText),PChar(@argStr),Length(argStr),tmpRW);
WriteProcessMemory(PI.hProcess,Pointer(CTX.Esp+4*2),Pointer(@pFakeText),4,tmpRW);
CTX.Dr0 := pRet;
CTX.Dr7 := 1;
SetThreadContext(PI.hThread,CTX);
Потом поставить бряк на ret, те на то куда указывает esp+4*0, да. Заодно память
освободить. Во.
if CTX.Eip = pRet then begin
VirtualFreeEx(PI.hProcess,Pointer(pFakeText),ADLen,MEM_RELEASE);
CTX.Dr0 := pProc;
CTX.Dr7 := $01;
SetThreadContext(PI.hThread,CTX);
end;
Вот екземпл(>>Слить готовое<<):
uses
SysUtils,
Windows;
type TString = array [0..256] of ansichar;
var
hFile,tmpRW,tmp:DWORD;
EntryPoint:DWORD;
pArg,pProc,pRet,pFakeText:DWORD;
EPByte:BYTE;
int3:BYTE = $CC;
OFS:_OFSTRUCT;
INH:TIMAGENTHEADERS;
SI:TStartupInfo;
PI:TProcessInformation;
DebugEvent:TDEBUGEVENT;
CTX:CONTEXT;
argStr:TString;
i,ADLen:integer;
AD:ansistring = #13#10'visit:thehukker.blogspot.ru'#0;
const
path = 'test.exe';
procName = 'MessageBoxA';
libName = 'USER32.DLL';
function StrLen(var str:TString):integer;
var i:integer;
begin
for I := 0 to Length(str) do begin
if str[i]=Char(0) then break
end;
StrLen:=i;
end;
begin
pProc:=DWORD(GetProcAddress(GetModuleHandle(libName),procName));
hFile:=OpenFile(path,OFS,OF_READ);
SetFilePointer(hFile,$3C,0,FILE_BEGIN);
ReadFile(hFile,tmp,4,tmpRW,0);
SetFilePointer(hFile,tmp,0,FILE_BEGIN);
ReadFile(hFile,INH,SizeOf(INH),tmpRW,0);
CloseHandle(hFile);
EntryPoint:=INH.OptionalHeader.AddressOfEntryPoint+INH.OptionalHeader.ImageBase;
ZeroMemory(@SI,sizeof(SI));ZeroMemory(@PI,SizeOf(PI));
CreateProcess(path, 0, 0, 0, FALSE,DEBUG_ONLY_THIS_PROCESS + DEBUG_PROCESS, 0,0, SI, PI);
ResumeThread(PI.hThread);
ReadProcessMemory(PI.hProcess,Pointer(EntryPoint),@EPByte,1,tmpRW);
WriteProcessMemory(PI.hProcess,Pointer(EntryPoint),@int3,1,tmpRW);
ZeroMemory(@CTX,SizeOf(@CTX));
CTX.ContextFlags:=CONTEXT_FULL + CONTEXT_DEBUG_REGISTERS;
while True do begin
WaitForDebugEvent(DebugEvent,INFINITE);
GetThreadContext(PI.hThread,CTX);
case DebugEvent.dwDebugEventCode of
EXCEPTION_DEBUG_EVENT: begin
if DebugEvent.Exception.ExceptionRecord.ExceptionCode = EXCEPTION_BREAKPOINT then begin
if CTX.Eip = EntryPoint+1 then begin
Dec(CTX.Eip);
WriteProcessMemory(PI.hProcess,Pointer(EntryPoint),@EPByte,1,tmpRW);
CTX.Dr0 := pProc;
CTX.Dr7 := $01;
SetThreadContext(PI.hThread,CTX);
ContinueDebugEvent(PI.dwProcessId, PI.dwThreadID,DBG_CONTINUE);
end;
end;
if DebugEvent.Exception.ExceptionRecord.ExceptionCode = EXCEPTION_SINGLE_STEP then begin
if CTX.Eip = pProc then begin
ZeroMemory(@argStr,Length(argStr));
ReadProcessMemory(PI.hProcess,Pointer(CTX.Esp),Pointer(@pRet),4,tmpRW);
ReadProcessMemory(PI.hProcess,Pointer(CTX.Esp+4*3),Pointer(@pArg),4,tmpRW);
ReadProcessMemory(PI.hProcess,Pointer(pArg),PChar(@argStr[0]),256,tmpRW);
WriteLn('Title:'+argStr);
ZeroMemory(@argStr,Length(argStr));
ReadProcessMemory(PI.hProcess,Pointer(CTX.Esp+4*2),Pointer(@pArg),4,tmpRW);
ReadProcessMemory(PI.hProcess,Pointer(pArg),PChar(@argStr[0]),256,tmpRW);
WriteLn('Text:'+argStr);
WriteLn('===============');
ADLen:=StrLen(argStr);
for i := 1 to Length(AD) do begin
argStr[ADLen-1+i]:=AnsiChar(AD[i]);
end;
ADLen:=Length(argStr);
pFakeText:=Cardinal(VirtualAllocEx(PI.hProcess,0,Length(argStr),MEM_COMMIT,PAGE_READWRITE));
WriteProcessMemory(PI.hProcess,Pointer(pFakeText),PChar(@argStr),Length(argStr),tmpRW);
WriteProcessMemory(PI.hProcess,Pointer(CTX.Esp+4*2),Pointer(@pFakeText),4,tmpRW);
CTX.Dr0 := pRet;
CTX.Dr7 := 1;
SetThreadContext(PI.hThread,CTX);
end;
if CTX.Eip = pRet then begin
VirtualFreeEx(PI.hProcess,Pointer(pFakeText),ADLen,MEM_RELEASE);
CTX.Dr0 := pProc;
CTX.Dr7 := $01;
SetThreadContext(PI.hThread,CTX);
end;
end;
end;
EXIT_PROCESS_DEBUG_EVENT: begin
Break;
end;
end;
ContinueDebugEvent(PI.dwProcessId, PI.dwThreadID,DBG_CONTINUE);
end;
Halt;
end.
Комментариев нет:
Отправить комментарий