windbg基础用法
运行前
打开文件:文件 -> Launch executable
查看反编译汇编:View -> Layouts -> Disassembly
设置符号路径:.sympath srv*
加载符号:.reload
运行
运行:g
单步执行不进入函数:p
单步执行进入函数:t
查看/修改状态
查看堆栈状态:kb
查看寄存器:r
/ r register
修改寄存器:r register = value
查看内存
查看指定地址反编译代码:u addr
以双字的形式查看内存:
dd addr / register
0:000> dd 00400000
00400000 00405000 00406000 00407000 00408000
00400010 00409000 0040A000 0040B000 0040C000
dc addr / register
0:000> dc 00400000
00400000 00405000 00406000 00407000 00408000 .P...`...p...`...
00400010 00409000 0040A000 0040B000 0040C000 ..`...`...`...`...
以Unicode
字符串的形式查看内存:du addr / register
0:000> du 00400000
00400000 "Hello, world!"
00400010 "This is a test string."
以字节的形式查看内存:db addr / register
0:000> db 00400000
00400000 48 65 6C 6C 6F 2C 20 77-6F 72 6C 64 21 00 00 00 Hello, world!...
00400010 54 68 69 73 20 69 73 20-61 20 74 65 73 74 20 73 This is a test s
以ASCII字符的形式查看内存:da addr / register
以字的形式查看内存:dw addr / register
以十六进制双字的形式查看内存:dD addr / register
以内存内容的指针的形式查看内存:dp addr / register
断点
查看断点详细情况:bl
0:000> bl
0 e Disable Clear 00000000 e 1 0001 (0001) 0:****
1 e Disable Clear 00300003 0001 (0001) 0:**** GOM32Q_vc120_ReleaseQC+0x3
查看断点:.bpcmds
0:000> .bpcmds
ba0 e1 0x00000000 ;
bp1 0x00300003 ;
下断点:
bp
:设置断点,在指定断点位置设置新的断点,如果调试器无法解析断点位置的地址表达式,则自动转换为bu断点,使用bp命令创建在卸载模块时不再处于活动状态的断点
0:000> bp MyTest+0xb 7 #前六次忽略此断点,第七次传递时,执行会停止
bm
:设置符号断点,命令在与指定模式匹配的符号上设置新的断点。 此命令可以创建多个断点。 默认情况下,匹配模式后,bm断点与bu断点相同。
0:000> bm myprogram!mem*
4: 0040d070 MyProgram!memcpy
5: 0040c560 MyProgram!memmove
6: 00408960 MyProgram!memset
bu
:设置未解析断点,命令设置延迟或未解析的断点。bu断点是在对命令中指定的断点位置的符号引用上设置的, (不在地址) 上,每当解析具有引用的模块时,就会激活该断点。
bc
:从系统中永久删除先前设置的断点
bc id
删除指定id
号的断点
windbg结合IDA逆向分析
通过IDA中的地址下断点
地址偏移 = IDA中的地址 - IDA中的基址
查看模块名称/地址:lm
(基址为start
一列
0:000> lm
start end module name
00300000 010f9000 GOM32Q_vc120_ReleaseQC (no symbols)
05990000 05a4c000 swscale_gp_5 (deferred)
05a50000 05d69000 avutil_gp_56 (deferred)
05d70000 07366000 avcodec_gp_58 (deferred)
获取windbg
中的地址:模块基址 + 地址偏移
下断点:bu 模块名称 + 地址偏移
/ bu windbg中的地址
例如:IDA
中的基址为0x400000
,要在IDA
中地址为0x500000
的位置下断点,则地址偏移为0x500000 - 0x400000 = 0x100000
,假设lm
查看模块名为test
,该模块基址为0x200000
,则在windbg
中的地址就是0x300000
,那么下断点就是du test + 0x100000
/ du 0x300000
通过栈回溯找到IDA中对应函数
栈回溯查看堆栈情况:kb
0:000> kb
# ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
00 014fedc0 009371cc 00000000 00000000 00000000 GOM32Q_vc120_ReleaseQC+0x6371de
01 014fede4 00506a63 014feeec 00000104 0f4aeea8 GOM32Q_vc120_ReleaseQC+0x6371cc
02 014ff138 004ed040 0f4cf948 00000001 0080723a GOM32Q_vc120_ReleaseQC+0x206a63
03 014ff1fc 008082e2 00a9b640 0f4cf948 00010004 GOM32Q_vc120_ReleaseQC+0x1ed040
04 014ff21c 0080392f 0000c391 0f4cf948 00010004 GOM32Q_vc120_ReleaseQC+0x5082e2
05 014ff28c 008040ea 0f4cd4c0 00010a66 0000c391 GOM32Q_vc120_ReleaseQC+0x50392f
得到形如模块名+地址偏移
的栈回溯,要找到在IDA
中的对应基址只需要用模块名加上的这个地址偏移(即加号后面部分)再加上IDA
基址即可
例如:GOM32Q_vc120_ReleaseQC+0x6371de
,则地址偏移为0x6371de
,IDA基址为0x400000
,那么在IDA
中的地址就是0x6371de + 0x400000 = 0xA371DE