我有一个非常简单的C程序:
#include <windows.h>
void funAdd() {
int a = 2; // I want to break here
}
int CALLBACK
WinMain(HINSTANCE Instance,
HINSTANCE PrevInstance,
LPSTR CommandLine,
int ShowCode)
{
funAdd();
}
我想使用WinDbg内的访问中断功能来破坏funAdd()函数的功能。 Visual Studio的反汇编告诉我int a = 2
指令位于内存地址002416BC
:
根据此处的文档:https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/ba--break-on-access-
如果我编写命令ba r4 02416be
,我希望调试器在funAdd()
函数内部中断,但是当我输入命令时,会出现以下错误:Data breakpoint must be aligned
。
我理解正确吗?如果是这样,我如何正确地将此地址对齐为4个字节以匹配r4
命令选项?
答案 0 :(得分:2)
0x2416be是指令指针或指令的虚拟地址
要在此地址上设置访问断点,请不要使用 r或w ,而应使用 e
ba e 2416be 这不需要对齐或大小
如果要在变量 a
上设置数据断点您必须查找一个虚拟地址
编译器通常对齐变量地址,因此您通常不必担心对齐
使用 dv / v a (您需要专用pdb来显示局部变量
并且由于windbg将本地变量重命名为abp而不是ebp-xx,因此您应该拥有私有的pdb)
windbg会吐出如下结果 本地变量@ xxxxxx
此处xxxxx是变量a(将存储2的地址
在此地址中)
根据需要在此地址上使用 ba r4或r2或r1
请注意,此地址可能在堆栈中,并且此断点可能会在实际达到您的条件之前触发多次
数据读取断点对于全局变量很有用 而且对于本质上是动态的本地人和堆地址而言不是很好
您可以为dv指定任意函数地址,以查看函数本地变量(需要private pdb)
0:000> dv /v /i /t /f funadd!funAdd
prv local <virtual frame 2ffa84>-0x0004 int myvar
执行直到功能启动
0:000> g funadd!funAdd
eax=767fed5a ebx=7ffd4000 ecx=00000000 edx=01351000 esi=00000000 edi=00000000
eip=01351010 esp=002ffeb8 ebp=002ffebc iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
funadd!funAdd:
01351010 55 push ebp
使用本地显示
0:000> dv /V /i /t
prv local 002ffeb0 <virtual frame 2ffeb4>-0x0004 int myvar = 0n0
使用display type命令还将提供本地的虚拟地址
0:000> dt -n myvar
Local var @ 0x2ffeb0 Type int
0n0
您可以在此地址上设置读取断点
0:000> ba r4 0x2ffeb0
执行并等待bp命中
0:000> g
Breakpoint 0 hit
eax=767fed5a ebx=7ffd4000 ecx=00000000 edx=01351000 esi=00000000 edi=00000000
eip=01351014 esp=002ffeb0 ebp=002ffeb4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
funadd!funAdd+0x4:
01351014 c745fc02000000 mov dword ptr [ebp-4],2 <<<<<<<<< ss:0023:002ffeb0=00000000
该值尚未写入本地myvar
0:000> bl
0 e Disable Clear 002ffeb0 r 4 0001 (0001) 0:****
0:000> ? myvar
Evaluate expression: 3145392 = 002ffeb0
0:000> ? poi(myvar)
Evaluate expression: 0 = 00000000