function SimpleExtractFilePath(f: String): String;
var
i: integer;
begin
for i := Length(f) downto 1 do
if f[i] = '\' then Break;
result := copy(f, 0, i);
end;
procedure CreateVictimProcess(Path: String);
var
DbgEvent: TDebugEvent;
DbgParam: DWORD;
NewPrt: DWORD;
DbgContext: TContext;
begin
ZeroMemory(@si, SizeOf(STARTUPINFO));
si.cb := SizeOf(STARTUPINFO);
if not CreateProcess(PChar(Path), nil, nil, nil, False, CREATE_DEFAULT_ERROR_MODE, nil,
PChar(SimpleExtractFilePath(Path)), si, pi) then
begin
MessageBox(0, 'CreateProcess failed! ', 'Error!', 0);
exit;
end;
if WaitForInputIdle(pi.hProcess, INFINITE) <> 0 then
begin
MessageBox(0, 'WaitForInputIdle failed! ', 'Error!', 0);
exit;
end;
if not DebugActiveProcess(pi.dwProcessId) then
//这里用DebugActiveProcess来附加到目标进程,如果用CreateProcess时加上DEBUG_ONLY_THIS_PROCESS
//方式调试,设置硬件断点方法参阅hume的文章。
begin
MessageBox(0, 'DebugActiveProcess failed! ', 'Error!', 0);
exit;
end;
DbgContext.ContextFlags := CONTEXT_ALL;
while WaitForDebugEvent(DbgEvent, INFINITE) do
begin
DbgParam := DBG_CONTINUE;
case DbgEvent.dwDebugEventCode of
CREATE_PROCESS_DEBUG_EVENT:
(*
对DebugActiveProcess附加debugee的情况,必须在CREATE_PROCESS_DEBUG_EVENT中,
不可在第一个EXCEPTION_BREAKPOINT处设置硬件断点。这是试验出的结论,不知道为什么。
没有试验deguber挂起debugee后设硬件断点情况。
*)
begin
GetThreadContext(pi.hThread, DbgContext);
DbgContext.Dr0 := MemPos;
DbgContext.Dr7 := $D0501; //Dr7 flag:对dr0指向地址设写中断
SetThreadContext(pi.hThread, DbgContext);
end;
EXCEPTION_DEBUG_EVENT:
begin
case DbgEvent.Exception.ExceptionRecord.ExceptionCode of
EXCEPTION_ACCESS_VIOLATION:
begin
DbgParam := DBG_EXCEPTION_NOT_HANDLED;
end;
EXCEPTION_SINGLE_STEP:
begin
begin
GetThreadContext(pi.hThread, DbgContext);
if DbgContext.Dr6 and 1 = 1 then
begin //触发了dr0断点,这时dr0指向的地址已经被改写,这里将其恢复为0
VirtualProtectEx(pi.hProcess, Pointer(MemPos), 4, PAGE_READWRITE, @NewPrt);
WriteProcessMemory(pi.hProcess, Pointer(MemPos), @RegFlag, 4, nil);
VirtualProtectEx(pi.hProcess, Pointer(MemPos), 4, NewPrt, @NewPrt);
end
else
DbgParam := DBG_EXCEPTION_NOT_HANDLED;
end;
end;
end;
end;
EXIT_PROCESS_DEBUG_EVENT:
begin //收工
ContinueDebugEvent(DbgEvent.dwProcessId, DbgEvent.dwThreadId, DbgParam);
Break;
end;
end;
ContinueDebugEvent(DbgEvent.dwProcessId, DbgEvent.dwThreadId, DbgParam);
end;
end;
var
Victim: string;
begin
Victim := SimpleExtractFilePath(ParamStr(0)) + VictimName;
CreateVictimProcess(Victim);
halt;
end.