windbg内存断点学习总结
生活随笔
收集整理的這篇文章主要介紹了
windbg内存断点学习总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Windbg中使用查找內存并設置訪問斷點
http://www.cnblogs.com/SkyMouse/archive/2012/06/06/2538745.html在windbg中通過s 命令在內存中查找字符串或者關鍵字節碼信息
0:005> s -u 00c00000 L1000000 "你好 20:15 2012/6/620:15 2012/6/6"
?
01960d28 ?4f60 597d 0020 0032 0030 003a 0031 0035 ?`O}Y .2.0.:.1.5.
查看內存01960d28?
01960d28 00 00 00 00 00 00 00 00 30 00 3a 00 31 00 35 00 20 00 ?........0.:.1.5. .
01960d3a 32 00 30 00 31 00 32 00 2f 00 36 00 2f 00 36 00 32 00 ?2.0.1.2./.6./.6.2.
01960d4c 30 00 3a 00 31 00 35 00 20 00 32 00 30 00 31 00 32 00 ?0.:.1.5. .2.0.1.2.
?
01960d5e 2f 00 36 00 2f 00 36 00 00 00 00 00 00 00 00 00 00 00 ?/.6./.6...........
找到內容之后通過ba設置訪問斷點在任何函數訪問該內存時將會中斷
0:005> ba r4 01960d28 ?
?
0:005> bl
?0 du ? ? ? ? ? ? 0001 (0001) (@@masm(`ItemOperation.cpp:60+`))
?1 e 01960d28 r 4 0001 (0001) ?0:****?
?2 e 771c3540 ? ? 0001 (0001) ?0:**** ntdll!DbgBreakPoint
如此在程序訪問該地址時將會中斷到調試器
0:005> g
Breakpoint 1 hit
eax=019607d0 ebx=00000023 ecx=00000003 edx=0000002c esi=019607d0 edi=01960cd0
eip=76d29c9c esp=000fefa4 ebp=000fefa8 iopl=0 ? ? ? ? nv up ei pl nz na pe nc
cs=001b ?ss=0023 ?ds=0023 ?es=0023 ?fs=003b ?gs=0000 ? ? ? ? ? ? efl=00000206
msvcrt!_VEC_memcpy+0x125:
76d29c9c 660f7f4760 ? ? ?movdqa ?xmmword ptr [edi+60h],xmm0 ds:0023:01960d30=003100300032002000350031003a0030
當然也可以根據自身需要查找相應的其他內容來實現設置相應的訪問斷點
========
誰動了我的指針?--記一次WINDBG內存斷點的使用
http://www.cppblog.com/ay19880703/archive/2012/01/03/163486.html?
寫驅動的時候有個地方老是藍屏,看了dump發現數據被非法篡改了.
數據初始化如下
?
if(record_set_ptr != NULL )
{
? ? record_set_ptr->look_aside_pool_ptr = g_user_control_context.look_aside_pools[type] ;
? ? record_set_ptr->type = type ;
? ? record_set_ptr->buffer_size = notify_count * unit_size_of ;
? ? record_set_ptr->units_count = notify_count ;
? ? record_set_ptr->complete_count = 0 ;
}
然后在調用ExFreeToNPagedLookasideList傳入record_set_ptr->look_aside_pool_ptr 的時候掛了,發現record_set_ptr->look_aside_pool_ptr已經被改了.
?
為了跟蹤數據在哪里被修改了,先在數據初始化的地方下斷,然后記下record_set_ptr->look_aside_pool_ptr 的地址:0x85c16018
對這個內存下個斷點
1: kd> ba w4 85c16018
w表示在寫入時斷下,4表示監控范圍,單位是字節?
整個命令的意思就是讓調試器在系統寫入內存85c16018-85c1601b這個地址范圍的時候中斷
OK,命令下完,F5一下就立馬斷下來了
1: kd> g
Breakpoint 3 hit
nt!memcpy+0x33:
8053b583 f3a5 ? ? ? ? ? ?rep movs dword ptr es:[edi],dword ptr [esi]
此時edi的值: 0x85c16018
?
最后看一下函數堆棧,發現是字符串拷貝越界覆蓋了后面的數據....?
后面又想到,出錯時record_set_ptr->look_aside_pool_ptr 的值是0x005c0065
這么明顯的字符串特征竟然沒意識到....一看出錯值就應該知道是字符串覆蓋造成的.....
posted on 2012-01-03 15:07 __ay 閱讀(3020) 評論(3) ?編輯 收藏 引用 所屬分類: Debugging
Feedback
# re: 誰動了我的指針?--記一次windbg內存斷點的使用 2012-01-05 09:33 zuhd
和樓主分享一下:?
一般遇到這種需要下內存斷點的調試,我可能會先檢查代碼,應該會有90%的概率是越界造成的,確定該內存是在堆還是棧,然后排查該變量上下的兩個變量,基本都能找到,呵呵。請問樓主是UESTC的嗎? ?回復 ?更多評論 ??
# re: 誰動了我的指針?--記一次windbg內存斷點的使用 2012-01-05 13:30 __ay
呵呵 你也是UESTC的?不過我已經畢業了?
當然如果越界的時候能直接引發崩潰,那么看代碼直接就能解決問題
但是在越界讀寫不引發crash,直到引用被覆蓋的數據的時候才崩潰,如果這個時候代碼中很難定位到被覆蓋數據是什么時候寫的,那應該用內存斷點會比較好了@zuhd
========
windbg memory breakpoint 內存斷點
http://blog.csdn.net/kelsel/article/details/50503918ba (Break on Access) ?
[cpp] view plain copy 在CODE上查看代碼片派生到我的代碼片
kd> ba i4 3f8 ?
Kernel-Mode
ba[ID] Access Size [Options] [Address [Passes]] ["CommandString"]
Access
Specifies the type of access that satisfies the breakpoint. This parameter can be one of the following values.
Option Action
e (execute)
Breaks into the debugger when the CPU retrieves an instruction from the specified address.
r(read/write)
Breaks into the debugger when the CPU reads or writes at the specified address.
w (write)
Breaks into the debugger when the CPU writes at the specified address.
i (i/o)
(Microsoft Windows XP and later versions, kernel mode only, x86-based systems only) Breaks into the debugger when the I/O port at the specified Address is accessed.
?
?Size
Specifies the size of the location, in bytes, to monitor for access. On an x86-based processor, this parameter can be 1, 2, or 4. However, if Access equals e, Sizemust be 1.
On an x64-based processor, this parameter can be 1, 2, 4, or 8. However, if Access equals e, Size must be 1.
https://msdn.microsoft.com/en-us/library/windows/hardware/ff538165(v=vs.85).aspx
========
windbg --內存數據斷點?
http://blog.sina.com.cn/s/blog_4e0987310101a975.htmlba (Break on Access)
The ba command sets a data breakpoint. This breakpoint is triggered when the specified memory is accessed.
Syntax
User-Mode
[~Thread] ba[ID] Access Size [Options] [Address [Passes]] ["CommandString"]?
Kernel-Mode
ba[ID] Access Size [Options] [Address [Passes]] ["CommandString"]?
Parameters
Thread
Specifies the thread that the breakpoint applies to. For more information about syntax, see Thread Syntax. You can specify threads only in user mode.
ID
Specifies an optional number that identifies the breakpoint. If you do not specify ID, the first available breakpoint number is used. You cannot add space between ba and the ID number. Each processor supports only a limited number of data breakpoints. But there is no restriction on the value of the ID number. If you enclose ID in square brackets ([]), ID can include any expression. For more information about the syntax, see Numerical Expression Syntax.
Access
Specifies the type of access that satisfies the breakpoint. This parameter can be one of the following values.
Option Action
e (execute) Breaks into the debugger when the CPU retrieves an instruction from the specified address.
r (read/write) Breaks into the debugger when the CPU reads or writes at the specified address.
w (write) Breaks into the debugger when the CPU writes at the specified address.
i (i/o) (Microsoft Windows XP and later versions, kernel mode only, x86-based systems only) Breaks into the debugger when the I/O port at the specified Address is accessed.
You cannot add space between Access and Size.
Note ?On Windows Server 2003 with Service Pack 1 (SP1), on an Itanium-based computer that uses WOW64 to emulate x86, data breakpoints do not work with the execute option but they do work with the read and write options.
Size
Specifies the size of the location, in bytes, to monitor for access. On an x86-based processor, this parameter can be 1, 2, or 4. However, if Access equals e, Size must be 1.
On an x64-based processor, this parameter can be 1, 2, 4, or 8. However, if Access equals e, Size must be 1.
On an Itanium-based processor, this parameter can be any power of 2, from 1 to 0x80000000.
You cannot add space between Access and Size.
Options
Specifies breakpoint options. You can use any number of the following options, except as indicated:
/1
Creates a "one-shot" breakpoint. After this breakpoint is triggered, the breakpoint is permanently removed from the breakpoint list.
/f PredNum
(Itanium only, user mode only) Specifies a predicate number. The breakpoint is predicated with the corresponding predicate register (for example, bp /f 4 address sets a breakpoint that is predicated with the p4 predicate register). For more information about predicate registers, see Itanium Architecture.
/p EProcess
(Kernel mode only) Specifies a process that is associated with this breakpoint. EProcess should be the actual address of the EPROCESS structure, not the PID. The breakpoint is triggered only if it is encountered in the context of this process.
/t EThread
(Kernel mode only) Specifies a thread that is associated with this breakpoint. EThread should be the actual address of the ETHREAD structure, not the thread ID. The breakpoint is triggered only if it is encountered in the context of this thread. If you use /p EProcess and /t EThread , you can enter them in either order.
/c MaxCallStackDepth
Causes the breakpoint to be active only when the call stack depth is less than MaxCallStackDepth. You cannot combine this option together with /C.
/C MinCallStackDepth
Causes the breakpoint to be active only when the call stack depth is larger than MinCallStackDepth. You cannot combine this option together with /c.
Address
Specifies any valid address. If the application accesses memory at this address, the debugger stops execution and displays the current values of all registers and flags. This address must be an offset and suitably aligned to match the Size parameter. (For example, if Size is 4, Address must be a multiple of 4.) If you omit Address, the current instruction pointer is used. For more information about the syntax, see Address and Address Range Syntax.
Passes
Specifies the number of times the breakpoint is passed by until it activates. This number can be any 16-bit value. The number of times the program counter passes through this point without breaking is one less than the value of this number. Therefore, omitting this number is the same as setting it equal to 1. Note also that this number counts only the times that the application executes past this point. Stepping or tracing past this point does not count. After the full count is reached, you can reset this number only by clearing and resetting the breakpoint.
CommandString
Specifies a list of commands to execute every time that the breakpoint is encountered the specified number of times. These commands are executed only if the breakpoint is hit after you issue a g (Go) command, instead of after a t (Trace) or p (Step) command. Debugger commands in CommandString can include parameters.
You must enclose this command string in quotation marks, and you should separate multiple commands by semicolons. You can use standard C control characters (such as \n and \"). Semicolons that are contained in second-level quotation marks (\") are intepreted as part of the embedded quoted string.
This parameter is optional
Environment
Modes User mode, kernel mode
Targets Live debugging only
Platforms All
Comments
The debugger uses the ID number to refer to the breakpoint in later bc (Breakpoint Clear), bd (Breakpoint Disable), and be (Breakpoint Enable), commands. Use the bl (Breakpoint List) command to see the ID numbers that are associated with all currently set breakpoints.
The ba command provides the same functionality that the debug registers provide. You can break execution when the particular memory location is read from, written to, or executed.
The breakpoint is satisfied only when the access occurs at the given address and for the specified number of bytes. If the memory that is accessed overlaps the specified area to monitor, the breakpoint is not satisfied.
Although the size is required for all breakpoint types, an execute breakpoint is satisfied only if the address is the first byte in the instruction.
When you debug a multiprocessor system in kernel mode, breakpoints that you set by using bp (Set Breakpoint) or ba apply to all processors. For example, if the current processor is 3 and you type ba e1 MemoryAddress to put a breakpoint at MemoryAddress, any processor (not only processor 3) that executes at that address causes a breakpoint trap.
You cannot set the initial breakpoint in a user-mode process by using the ba command.
You cannot create multiple breakpoints at the same address that differ only in their CommandString values. However, you can create multiple breakpoints at the same address that have different restrictions (for example, different values of the /p, /t, /c, and /C options).
When you debug in kernel mode, the target computer distinguishes between user-mode and kernel-mode data breakpoints. A user-mode data breakpoint cannot affect kernel execution or memory access. A kernel-mode data breakpoint might affect user-mode execution or memory access, depending on whether the user-mode code is using the debug register state and whether there is a user-mode debugger that is attached.
To apply the current process' existing data breakpoints to a different register context, use the .apply_dbp (Apply Data Breakpoint to Context) command.
The following examples show the ba command. The following command sets a breakpoint for read access on 4 bytes of the variable myVar.
0:000> ba r4 myVar
The following command adds a breakpoint on all serial ports with addresses from 0x3F8 through 0x3FB. This breakpoint is triggered if anything is read or written to these ports.
kd> ba i4 3f8
========
兩次內存斷點法尋找OEP
http://www.programlife.net/twice-breakpoint-find-oep.html逆向過程中通過會遇到脫殼的過程,而脫殼的方式有有多重,如果手工脫殼,需要找到OEP。
所謂“兩次內存斷點法尋找OEP”,按照《加密與解密*第三版》上的解釋來說,就是這樣的。
一般的外殼會依次對.text、.rdata、.data、.rsrc區塊進行解壓(解密)處理,所以,可以先在.rdata、.data等區塊下內存訪問斷點,中斷后,此時代碼已解壓,接著再對代碼段(.text)下內存訪問斷點,即可到達OEP。
我個人的理解是所有節區都解壓完畢之后,然后程序的執行流會轉移到OEP,這個時候自然回去訪問相應的代碼,所以就會斷下;實際操作的時候還需要多一個跟蹤步驟。
這里以一個UPX加殼的程序為例:
首先OD加載程序,Alt + M打開內存映射視圖,找到主模塊的數據段或者資源段F2下訪問中斷,如圖。
對數據段或者資源段下F2訪問中斷
然后F9運行程序,會自動斷下,再次Alt + M打開內存映射視圖,找到代碼段F2下訪問中斷,如圖。
對代碼段下F2訪問中斷
之后F9運行,會再次斷下。這個時候仍然Alt + M打開內存映射視圖,觀察一下主模塊的區塊。
0040BA75 ? ?8D8430 58B00000 LEA EAX,DWORD PTR DS:[EAX+ESI+B058]
0040BA7C ? ?01F3 ? ? ? ? ? ?ADD EBX,ESI
0040BA7E ? ?50 ? ? ? ? ? ? ?PUSH EAX
0040BA7F ? ?83C7 08 ? ? ? ? ADD EDI,8
0040BA82 ? ?FF96 94B00000 ? CALL DWORD PTR DS:[ESI+B094] ? ? ? ? ? ? ; KERNEL32.LoadLibraryA
0040BA88 ? ?95 ? ? ? ? ? ? ?XCHG EAX,EBP
0040BA89 ? ?8A07 ? ? ? ? ? ?MOV AL,BYTE PTR DS:[EDI]
0040BA8B ? ?47 ? ? ? ? ? ? ?INC EDI
0040BA8C ? ?08C0 ? ? ? ? ? ?OR AL,AL
0040BA8E ?^ 74 DC ? ? ? ? ? JE SHORT 0040BA6C
0040BA90 ? ?89F9 ? ? ? ? ? ?MOV ECX,EDI
Memory map, 項目 18
?地址=00401000
?大小=00008000 (32768.)
?屬主=UpxDemo ?00400000
?區段=UPX0
?類型=映像 01001002
?訪問=R
?初始訪問=RWE
Memory map, 項目 19
?地址=00409000
?大小=00003000 (12288.)
?屬主=UpxDemo ?00400000
?區段=UPX1
?包含=SFX,代碼
?類型=映像 01001002
?訪問=R
?初始訪問=RWE
看到UPX0和UPX1到底哪一個是真實的代碼塊呢?需要試一下。對于UPX0,VA的范圍是00401000~00409000,對于UPX1,VA的范圍是00409000~0040C000??梢栽贠D的命令行中執行tc eip<00409000,按Enter執行,發現來到了OEP了。(同樣可以測試tc eip<0040C000,但得到的不是OEP)。
00401120 ? ?55 ? ? ? ? ? ? ?PUSH EBP
00401121 ? ?8BEC ? ? ? ? ? ?MOV EBP,ESP
00401123 ? ?6A FF ? ? ? ? ? PUSH -1
00401125 ? ?68 B8504000 ? ? PUSH 004050B8
0040112A ? ?68 EC1D4000 ? ? PUSH 00401DEC
0040112F ? ?64:A1 00000000 ?MOV EAX,DWORD PTR FS:[0]
00401135 ? ?50 ? ? ? ? ? ? ?PUSH EAX
00401136 ? ?64:8925 0000000>MOV DWORD PTR FS:[0],ESP
0040113D ? ?83EC 58 ? ? ? ? SUB ESP,58
00401140 ? ?53 ? ? ? ? ? ? ?PUSH EBX
00401141 ? ?56 ? ? ? ? ? ? ?PUSH ESI
00401142 ? ?57 ? ? ? ? ? ? ?PUSH EDI
00401143 ? ?8965 E8 ? ? ? ? MOV DWORD PTR SS:[EBP-18],ESP
00401146 ? ?FF15 28504000 ? CALL DWORD PTR DS:[405028] ? ? ? ? ? ? ? ; KERNEL32.GetVersion
0040114C ? ?33D2 ? ? ? ? ? ?XOR EDX,EDX
0040114E ? ?8AD4 ? ? ? ? ? ?MOV DL,AH
00401150 ? ?8915 14854000 ? MOV DWORD PTR DS:[408514],EDX
00401156 ? ?8BC8 ? ? ? ? ? ?MOV ECX,EAX
00401158 ? ?81E1 FF000000 ? AND ECX,0FF
0040115E ? ?890D 10854000 ? MOV DWORD PTR DS:[408510],ECX
00401164 ? ?C1E1 08 ? ? ? ? SHL ECX,8
附:
TC (Trace in till condition)跟蹤進入直到條件
更多參考:http://www.pediy.com/bbshtml/BBS5/pediy50401.htm
========
總結
以上是生活随笔為你收集整理的windbg内存断点学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 表空间数据文件迁移图解
- 下一篇: codesmith学习总结