之前想写一篇用windbg脚本调试的东西,但是一直比较懒,懒得动手,懒得想例子,把时间都放在了游戏上面,所以想法虽好一直没有实施...
这次写一个非常简单的利用windbg脚本进行动态调试的小文,博君一笑.
// Windbgscript.cpp : Defines the entry point for the console application.
//
代码:
#include "stdafx.h" #include <iostream> using namespace std; int ret100() { int x = 2; //2-3 x*=33; ++x; return x; } int add(int x, int y) { x = 0; //多余的 return x+y; } int _tmain(int argc, _TCHAR* argv[]) { int x = 100; int y = add( x, ret100()); cout << y; getchar(); return 0; }
同样add里面也有问题,就是对于参数x赋值0,认为它是一条多余的操作, 因为我们的目的是返回x+y的结果.
现在执行结果是:

如何利用windbg去动态的修改并且不需要我们始终去手动交互是我们的主要目的, 首先肯定是要了解这两个函数的内部实现.
uf伺候:
代码:
0:001> uf windbgscript!ret100 11 00401000 55 push ebp 11 00401001 8bec mov ebp,esp 11 00401003 51 push ecx 12 00401004 c745fc02000000 mov dword ptr [ebp-4],2 13 0040100b 8b45fc mov eax,dword ptr [ebp-4] 13 0040100e 6bc021 imul eax,eax,21h 13 00401011 8945fc mov dword ptr [ebp-4],eax 14 00401014 8b4dfc mov ecx,dword ptr [ebp-4] 14 00401017 83c101 add ecx,1 14 0040101a 894dfc mov dword ptr [ebp-4],ecx 16 0040101d 8b45fc mov eax,dword ptr [ebp-4] 17 00401020 8be5 mov esp,ebp 17 00401022 5d pop ebp 17 00401023 c3 ret
对应的就是 x=2;的指令, 我们的目的是将x赋值3, 这里改法很多,比如将ebp-4处赋值3并跳过该指令...
这里选择最简单的,让该指令执行,再执行下一条指令前修改x的值.
代码:
bp windbgscript!ret100 + 0xb " $$ 0xb代表从函数ret100开始处到当前断点位置的偏移 ed (ebp-4) 3; $$当代码执行到此处时,ebp-4即代表x的内存地址, ed命令为在制定地指处 赋值 gc; $$gc命令表示脚本执行后,程序会继续执行 "
代码:
0:001> uf windbgscript!add 20 00401030 55 push ebp 20 00401031 8bec mov ebp,esp 21 00401033 c7450800000000 mov dword ptr [ebp+8],0 22 0040103a 8b4508 mov eax,dword ptr [ebp+8] 22 0040103d 03450c add eax,dword ptr [ebp+0Ch] 24 00401040 5d pop ebp 24 00401041 c3 ret
即为那条多余的指令x=0; 我们的目的是让cpu忽略这条指令, 做法是在这条指令被执行前修改eip的值,始之跳转到下一条指令处继续执行
代码:
bp windbgscript!add + 0x03 " r @eip = @eip+0xa; $$ @符号会让脚本解释程序认为后面跟随的名称代表为寄存器, 节省查找时间,提高效率 gc; "

实在是找不出好的例子来,所以就想出了这么个下三滥的例子,莫笑。。。
实际中这么简单的程序谁也不会用windbg调试的,编写脚本的时间可能远远比重新编译,部署,调试所消耗的时间更长。
个人认为这种脚本还是比较适合用在重现问题比较困难, 尤其是一种场景, 一个进程开始的时候没有任何问题,但是跑一段时间(比如2-3个小时)开始不断重复出现一连串的错误(非崩溃),这种场景用windbg脚本还是非常合适的。
windbg脚本里的命令非常丰富,基本平时能用到的功能都有了,感兴趣翻翻帮助文档学学还是很不错的。
谢谢