Windbg 实践之结合条件断点
Case 1
1、bu USER32!PostMessageW "r $t0=@$t0+1;.printf\"PostMessageW Call Count:%d\",@$t0;.echo;g"
分号是用来分离语句的; $t0是伪寄存器; @$t0是读取寄存器当中的值;
2、bu USER32!PostMessageW "kb L2"
a) 如果命中,打印2层栈帧。 这个技巧可以看到到底是谁调用的指定的函数。
b) 另外通过找到函数的调用约定,我们就可以输出函数的参数值。
c) 但是如果需要批量打印函数的参数值,就需要看函数的的反汇编,确认这些参数是放置在哪个寄存器当中。比如我们需要测试向指定窗口发送的msg。
BOOL PostMessageA( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
__stdcall (Pascal方式清理C方式压栈,通常用于Win32 Api中)
1)压栈顺序:函数参数从右到左的压栈顺序 ,前 4 个参数传入 RCX、RDX、R8 和 R9 中。其他参数传递到堆栈中。
2)参数栈维护:被调用函数把参数弹出栈(在退出时清空堆栈)
3)函数修饰名约定:VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字节数
ex. VC: int f(void *p) (编译后)-> _f@4(在外部汇编语言里可以用这个名字引用这个函数)
从上面的信息可以推断出,hwnd 的值 存才R9当中,其值为null.
输出所有Hwnd为空的调用
bp USER32!PostMessageW ".if (@r9 = 0){k;g}.else{gc}"