DRX debug register uses one
INTEL has introduced DR0-DR7 eight debug registers in the CPU to the CPU, which can be used for program debugging work. It can be said that these 8 tune registers have existed for a long time, but the domestic compilation textbooks are fresh. Many friends in China do not understand this. As a fan of computer underlying technology, I read some information from some websites from abroad, and I wrote some programs for demonstrations. Now they will organize them out, I hope to understand this technology, but Friends who have not found to find Chinese materials provide some help.
If your English is passing, you can refer to the following URL to get more detailed information:
http://www7.informatik.uni-erlangen.de/~msdoerfe/embedded/386html/toc.htm
http://www.anticracking.sk/elicz/
The role of debug register is no longer said, I believe that friends who debugging things will understand that the debug register is the importance of the debugging process.
Let's enter the topic:
The schematic diagram of the debug register of the 386 system can be represented as follows:
DR0 ~ DR3 is used to store linear addresses for setting breakpoints.
DR4 and DR5 reserved
DR6 saves debugging status
DR7 is a debug control register
The usual use of the debug register is divided into the following steps:
1. Put the address to which you want to monitor into a register in DR0 ~ DR3
2. Set the corresponding control bit in DR7, so that the monitoring address stored by DR0 ~ DR3 takes effect
3. Continue to run the program, receive the exception_single_step debug message, and do what you want to do in the message handler.
The following code demonstrates the BPM's most basic usage. I assume that you have the basics of Windows Debug API programming and the ability to program 32-bit assembly language. If you are not too good, the Chinese information on these two aspects has been made to refer to it.
My programming environment is WinXP, where the NT architecture system, when the debug loop receives the first Exception_breakpoint debug message, the program is not fully loaded, so the program address cannot be turned off, and the solution is the first time. The extraction function NTCONTINUE of NTDLL.DLL is set, and then the address that needs to be turned out will be set when the first exception_single_step is generated.
NOTE: The breakpoint generated by the DRX register is: exception_single_step breakpoint message
There are many branches of the entire program, the flowcharts are as follows:
Such a multi-branch flow diagram, it is indeed an error with ASM, so once it is a debugging framework, it must be modified as if it is necessary.
In addition, the CONTEXT structure address used throughout the program must be 4-byte alignment, otherwise the correct result is not obtained. Please remember a rule: Any data structure that needs to be deal with the system's kernel, usually there is generally needed to perform 4 bytes aligned. In C / C , the compiler will automatically set up alignment, and in ASM, the memory layout of the data is determined by the programmer, so it is especially careful here. Otherwise, the most prone to the result is: The entire program logic, the encoding is correct, but it is not the correct result.
Theory to this, let's take a look at the first sample code of the DRX register:
FILENAME: BPM1.ASM
Comment / * Demo the most basic usage of BPM, in the first address of the program, the address of the Context structure is 4 bytes to align the YODA example, the Context structure is the first data definition of the .DATA segment, the connector will automatically align 2, the debug loop structure is complex * /. 386.Model flat, stdcall option casemap: none incdude /masm32/include/windows.inc include /masm32/include/kernel32.inc include /masm32/include/comdlg32.inc include / masm32 / include / user32.inc include ../bpm/bpm.incincludelib /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 ... ", 0SZFormat DB" Break at address:% 08X ", 0DH, 0AH, 0SZEXENAME DB" msg.exe ", 0SZNTDLNAME DB" NTDLL.DLL ", 0SZPROCNAME DB" NtContinue, 0dbgState DD 0Totalinstruction DD 0DWSSCNT DD 0DWADDRBUF DD 0DWBPCNT DD 0DWBREAKADDR DD 401000HSZBUFFER DB 512 DUP (?) Align DwordRegs Context CONTEXT_DEBUG_REGISTERS>; the address of this structure to be aligned sif STARTUPINFO mov Regs.iDr0, eax; NtContinue function provided in the off invoke SetThreadContext, pi.hThread, addr Regs jmp @f .endif .elseif excCode == EXCEPTION_SINGLE_STEP inc dwSSCnt .if dwSSCnt == 1; interrupt NtContinue invoke WipeContextBPdr0; clear the breakpoint 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; Interrupt in the first address invoke WiPECONTEXTBPDR0 INVOKE WSPRINTEXTBPDR0 INVOKE WSPRINTEXTBPDR0 INVOKE WSPRINTF, AddR Szbuffer, Addr Szformat, Excaddr Invoke Messagebox, 0, Addr Szbuffer, Addr Szappname, MB_OK / MB_ICONITIONFORMATION JMP @f .ndif.ndif .elseif dBGEvent == exit_process_debug_event; program exits message 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 program running results screenshots are as follows: