本文整理自网络,侵删。
if EXCEPTION_DEBUG_EVENT=de.dwDebugEventCode then //判断是否为异常事件 begin CopyMemory(Pointer(@excinfo),Pointer(@de.Exception),SizeOf(EXCEPTION_DEBUG_INFO)); //将调试结构中的异常结构复制出来 if EXCEPTION_BREAKPOINT=excinfo.ExceptionRecord.ExceptionCode then //异常代码是否为断点异常 begin if apiaddr=excinfo.ExceptionRecord.ExceptionAddress then //异常位置是否为api地址处 apiaddr=excinfo.ExceptionAddress begin WriteProcessMemory(deinfo.hProcess,apiaddr,pointer(@yuan),1,wd); //将CC断点恢复成原来的字节 unhook //1、CONTEXT_DEBUG_REGISTERS,查询调式寄存器 {DR0-DR3(4个硬件断点所用) Dr6-Dr7} // //2、CONTEXT_FLOATING_POINT,查询浮点寄存器 { 387 state } // //3、CONTEXT_SEGMENTS,查询段寄存器 { DS, ES, FS, GS } // //4、CONTEXT_INTEGER,查询通用数据寄存器 { AX, BX, CX, DX, SI, DI } // //5、CONTEXT_CONTROL,查询控制寄存器组 { SS:SP, CS:IP, FLAGS, BP } // //6、CONTEXT_EXTENDED_REGISTERS,扩展寄存器组 // //7、CONTEXT_FULL,CONTEXT_CONTROL+CONTEXT_SEGMENTS+ CONTEXT_SEGMENTS 三者合一 GetThreadContext(deinfo.hThread,ctx); //获得线程的上下文 ShowMessage('当前寄存器Esp的值:'+IntToHex(ctx.Esp+8)); //这里可以对寄存器进行操作 可以读写等等 ctx.Eip:=Integer(apiaddr)-1;//ctx.Eip-1; //因为断在CC处,此时EIP会在当前CC处的地址+1的位置,故需要减一,否则一开始被CC覆盖的那个字节就不会被执行,会报错的 SetThreadContext(deinfo.hThread,ctx); //设置线程的上下文 ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_CONTINUE) ; //继续等待是否有调试事件的产生 Sleep(0); //每个线程有20毫秒的时间片运行,用完则切换其他线程,当运行完时,在context结构中取出保存的第一个线程执行结束时的状态,继续执行 //调用Sleep函数,可以释放当前线程的剩余时间片,即放弃当前线程执行的CPU时间片,也就是说,调用Sleep(0)函数后,CPU会立即执行其他线程 //否则可能引发当调试器写入CC时与被调试程序同时调用api导致内存访问异常. //如果有需要继续hook,则在这里用WriteProcessMemory继续改CC end; end; end.
来源:https://www.52pojie.cn/forum.php?mod=viewthread&tid=1020357&extra=page%3D1%26filter%3Dtypeid%26typeid%3D27
相关阅读 >>
Delphixe7关于android 检测屏幕是否处于关闭状态
Delphi有无生成空格的函数,like vb的space(1)
winapi 字符及字符串函数(10): lstrcpy - 复制字符串
Delphi messagebox 和 messagedlg用法
更多相关阅读请进入《Delphi》频道 >>