我在写一个小型的调试器,不过不是做调试用,是想做内存布丁。但是我设置的硬件执行断点从来就没有被断下来过。
intel的参考手册和John Robbins的Debug Application上的资料我都对照过了,也没有发现什么问题。
下面是部分代码,delphi写的,请各位大侠指正:
if DebugActiveProcess(Debuggee.dwProcessId) then
begin
while WaitForDebugEvent(DebugEvent,INFINITE) do
begin
case DebugEvent.dwDebugEventCode of
CREATE_PROCESS_DEBUG_EVENT :
begin
ThreadContext.ContextFlags := CONTEXT_CONTROL;
GetThreadContext(DebugEvent.CreateProcessInfo.hThread,ThreadContext);
ThreadContext.Dr0 := SomeDebugPoint1;
ThreadContext.Dr1 := SomeDebugPoint2;
ThreadContext.Dr6 := 0;
ThreadContext.Dr7 := $105; //$105 : 100000101,LE=1, L1=1, L0=1
ThreadContext.ContextFlags := CONTEXT_CONTROL;
if not SetThreadContext(DebugEvent.CreateProcessInfo.hThread,ThreadContext) then
begin
ShowMessage('SetThreadContext failed!');
end;
mDebugContinue := DBG_CONTINUE;
end;
EXCEPTION_DEBUG_EVENT :
begin
case DebugEvent.Exception.ExceptionRecord.ExceptionCode of
STATUS_SINGLE_STEP :
begin
//do something in here
end;
else
//do something else in here
end;
end;
end;
end;
end;
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;
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
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 := $101; //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断点
MessageBox(0, 'Get it!', 'HWBP!', 0);
GetThreadContext(pi.hThread, DbgContext);
DbgContext.Dr0 := 0; //取消硬件断点
DbgContext.Dr7 := 0;
SetThreadContext(pi.hThread, DbgContext);
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.