分享
 
 
 

DrX调试寄存器使用 一

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

DrX调试寄存器使用 一

Intel公司自80386以来,在CPU内部引入了Dr0-Dr7八个调试寄存器专门用于程序的调试工作,可以说这8个调试寄存器已经存在了很长时间,可是国内的汇编教科书中鲜有涉及者,导致国内很多朋友对此都不甚了解。我作为一个计算机底层技术的爱好者,从国外的一些网站上阅读了一些此方面的资料,并且写了一些演示用的程序,如今把它们整理出来,希望对那些想了解这方面的技术,却苦于找不到中文资料的朋友提供一些帮助。

如果你的英文过关,你可以参考如下网址获得更详细的资料:

http://www7.informatik.uni-erlangen.de/~msdoerfe/embedded/386html/toc.htm

http://www.anticracking.sk/EliCZ/

调试寄存器的作用就不再多说,相信知道调试是怎么回事情的朋友都能明白调试寄存器对于调试过程的重要性。

下面进入正题:

386体系的调试寄存器的示意图可以表示如下:

Dr0~Dr3用于存放欲设置断点的线性地址。

Dr4和Dr5保留

Dr6保存了调试状态

Dr7是调试控制寄存器

调试寄存器的使用总体来说分为如下几步:

1、 把欲监视的地址放入Dr0~Dr3中的一个寄存器

2、 在Dr7种设置相应的控制位,使得Dr0~Dr3存放的监视地址生效

3、 继续运行程序,接收EXCEPTION_SINGLE_STEP 调试消息,并在消息处理程序中作自己想做的事情。

以下的代码演示bpm最基础的用法,我假设你有Windows Debug API编程的基础知识以及利用32位汇编语言编程的能力。如果你这两方面都不太行,那网上关于这两方面的中文资料已经很多,可以自己参考。

我的编程环境是WinXP,凡是Nt架构的系统,在调试循环收到第一个EXCEPTION_BREAKPOINT调试消息的时候,程序都没有完全载入内存,所以不能对程序地址设断,此时的解决方案是先对Ntdll.dll的引出函数NtContinue设断,然后在第一个EXCEPTION_SINGLE_STEP产生时,再对需要设断的地址设断。

Note:DrX寄存器产生的断点是:EXCEPTION_SINGLE_STEP断点消息

整个程序的分支非常多,流程图如下:

如此多分支的流程图,用ASM实现的确容易出错,所以,一旦搭好一个调试的框架,日后如非必要,就务须修改。

另外,整个程序中使用的CONTEXT结构地址必须4字节对齐,否则得不到正确的结果。请大家记住一个规律:凡是需要和系统内核打交道的数据结构,一般都需要进行4字节对齐。C/C++中,编译器会自动帮你设置好对齐,而在ASM中,数据的内存布局都是由程序员决定的,所以,此处要特别小心。否则,最容易出现的结果就是:整个程序逻辑、编码都正确,可是就是出不来正确的结果。

理论到此为止,下面来看看DrX寄存器的第一个示例代码:

;filename: bpm1.asm

comment /*

演示bpm最基础的用法,在程序的首地址中断

1、CONTEXT结构的地址要4字节对齐

yoda的例子程序里面,CONTEXT结构是.DATA段第一个数据定义,连接器会自动对齐

;2、调试循环结构很复杂

*/

.386

.model flat,stdcall

option casemap:none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

include \masm32\include\comdlg32.inc

include \masm32\include\user32.inc

include ..\bpm\bpm.inc

includelib \masm32\lib\kernel32.lib

includelib \masm32\lib\comdlg32.lib

includelib \masm32\lib\user32.lib

.data

szAppName db "firing's Bpm Example no.1",0

szExitStr db "Debuggee exit...",0

szFormat db "Break at address: %08X",0Dh,0Ah,0

szExeName db "Msg.exe",0

szNtDllName db "ntdll.dll",0

szProcName db "NtContinue",0

DbgState dd 0

TotalInstruction dd 0

dwSSCnt dd 0

dwAddrBuf dd 0

dwBpCnt dd 0

dwBreakAddr dd 401000h

szBuffer db 512 dup(?)

align dword

Regs CONTEXT <CONTEXT_FULL OR

CONTEXT_DEBUG_REGISTERS> ;这个结构的地址要对齐的

sif STARTUPINFO < SIZEOF STARTUPINFO >

pi PROCESS_INFORMATION < >

DBEvent DEBUG_EVENT < >

WipeContextBPdr0 PROTO

;一些为了编码方便而设置的常量定义

DbgEvent EQU DBEvent.dwDebugEventCode

excCode EQU DBEvent.u.Exception.pExceptionRecord.ExceptionCode

excAddr EQU DBEvent.u.Exception.pExceptionRecord.ExceptionAddress

;pDllName EQU Dev.u.LoadDll.lpImageName

;lpBase EQU Dev.u.LoadDll.lpBaseOfDll

.code

start:

xor eax, eax

mov dwSSCnt, eax

mov dwBpCnt, eax

mov dwBreakAddr, 401000h

invoke GetStartupInfo,addr sif

invoke CreateProcess, addr szExeName, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+ DEBUG_ONLY_THIS_PROCESS, NULL, NULL, addr sif, addr pi

;以下进入debug循环

.while TRUE

invoke WaitForDebugEvent, addr DBEvent, INFINITE

mov DbgState, DBG_EXCEPTION_NOT_HANDLED

.if DbgEvent == EXCEPTION_DEBUG_EVENT

.if excCode==EXCEPTION_BREAKPOINT

mov DbgState,DBG_CONTINUE

inc dwBpCnt

.if dwBpCnt == 1

invoke GetThreadContext, pi.hThread, addr Regs

invoke GetModuleHandle, addr szNtDllName

invoke GetProcAddress, eax, addr szProcName

mov Regs.iDr7, M_INSTR0 + M_LDR0 ;执行指令中断+Dr0有效

mov Regs.iDr0, eax ;在NtContinue函数设断

invoke SetThreadContext, pi.hThread, addr Regs

jmp @f

.endif

.elseif excCode == EXCEPTION_SINGLE_STEP

inc dwSSCnt

.if dwSSCnt == 1 ;中断在NtContinue

invoke WipeContextBPdr0 ;清除断点

mov eax,Regs.regEsp

add eax,4 ;eax = "esp"+4

invoke ReadProcessMemory,pi.hProcess, eax, addr dwAddrBuf, sizeof DWORD,

NULL

invoke ReadProcessMemory,pi.hProcess, dwAddrBuf, addr Regs, sizeof CONTEXT,

NULL

push dwBreakAddr

pop Regs.iDr0

mov Regs.iDr7, M_LDR0+ M_INSTR0

invoke WriteProcessMemory,pi.hProcess,dwAddrBuf,addr Regs,sizeof CONTEXT,

NULL

jmp @f

.elseif dwSSCnt == 2 ;中断在首地址

invoke WipeContextBPdr0

invoke wsprintf, addr szBuffer, addr szFormat, excAddr

invoke MessageBox, 0, addr szBuffer, addr szAppName, MB_OK+

MB_ICONINFORMATION

jmp @f

.endif

.endif

.elseif DbgEvent == EXIT_PROCESS_DEBUG_EVENT ;程序退出消息

invoke MessageBox, 0, addr szExitStr, addr szAppName, MB_OK+

MB_ICONINFORMATION

.break

.endif

@@:

invoke ContinueDebugEvent, DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE

.endw

invoke CloseHandle,pi.hProcess

invoke CloseHandle,pi.hThread

invoke ExitProcess, 0

;****************************************************************************** WipeContextBPdr0 Proc

invoke GetThreadContext,pi.hThread,addr Regs

mov Regs.iDr0,0

mov Regs.iDr7,0

invoke SetThreadContext,pi.hThread,addr Regs

ret

WipeContextBPdr0 Endp

;******************************************************************************

end start

程序运行结果截图如下:

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有