算法对我来说挺复杂,没那么多时间研究,等有空再说
写了个loader程序,顺便了解一下debug api,主要思路是在地址$42B425处,置ZF为1
代码是随手写的缺少很多检测
- program CPPIDE_LOADER;
- uses
- Windows;
- {$R *.res}
- const
- BP = $42B425;
- int3 :DWORD = $CC;
- var
- startinfo :STARTUPINFO;
- pi:PROCESS_INFORMATION;
- DBEvent:DEBUG_EVENT;
- org_code :Byte;
- num: Cardinal;
- ctext : CONTEXT;
- dwNewProt, dwOldProt:DWORD;
- begin
- GetStartupInfo(startinfo);
- if not CreateProcess('CPPIDE.exe',nil,nil,nil,False,DEBUG_PROCESS + DEBUG_ONLY_THIS_PROCESS,nil,nil,startinfo,pi) then //调试模式加载进程
- begin
- MessageBox(0,'不能加载CPPIDE.exe','错误',0);
- Halt;
- end;
- while WaitForDebugEvent(DBEvent,INFINITE) do //等待调试事件
- begin
- if DBEvent.dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT THEN //进程退出
- begin
- //MessageBox(0,'The debuggee exits','Win32 Debug Example no.1',mb_ok + MB_ICONINFORMATION);
- ContinueDebugEvent(DBEvent.dwProcessId,DBEvent.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- Halt;
- end
- else if DBEvent.dwDebugEventCode = exception_debug_event then
- begin
- if DBEvent.Exception.ExceptionRecord.ExceptionCode = exception_breakpoint then
- begin
- if Integer(DBEvent.Exception.ExceptionRecord.ExceptionAddress) <> BP then //设置断点
- begin
- VirtualProtectEx(pi.hProcess,Pointer(BP),1, PAGE_EXECUTE_READWRITE, dwOldProt);
- ReadProcessMemory(pi.hProcess,Pointer(BP),@org_code,1,num);
- WriteProcessMemory(pi.hProcess,Pointer(BP),@int3,1,num);
- VirtualProtectEx(pi.hProcess, Pointer(BP), 1, dwOldProt, dwNewProt);
- //MessageBox(0,'',PAnsiChar(string(rtn)),0)
- end
- else
- begin //$42B425处中断,修改ZF的值为1
- WriteProcessMemory(pi.hProcess,Pointer(BP),@org_code,1,num);
- ctext.ContextFlags := CONTEXT_FULL;
- GetThreadContext(pi.hThread,ctext);
- ctext.EFlags := ctext.EFlags or 64; //ZF置1(与二进制1000000或)
- ctext.Eip := ctext.Eip - 1; //eip回到$42B425
- SetThreadContext(pi.hThread,ctext);
- end;
- ContinueDebugEvent(DBEvent.dwProcessId,DBEvent.dwThreadId,DBG_CONTINUE); //继续运行
- Continue;
- end;
- end;
- ContinueDebugEvent(DBEvent.dwProcessId,DBEvent.dwThreadId,DBG_EXCEPTION_NOT_HANDLED); //继续运行
- end;
- end.