首页
论坛
课程
招聘
[原创]windbg使用详解
2021-11-17 11:39 20685

[原创]windbg使用详解

2021-11-17 11:39
20685

一、符号设置

1
2
3
4
5
6
7
8
1、设置微软符号路径并下载全部微软符号
    windbg符号设置:
        srv*C:\Symbols*http://msdl.microsoft.com/download/symbols;F:\MyGitRepo\rst2\hamc\code\framework\agent_windows\installproject\pdb\20210926\x64
    输入命令:!sym noisy
    输入命令:.reload /f
2、强制加载某模块的符号(模块名称区分大小写,注意要加上模块扩展名)
    .reload /f libqaxdecode.dll
    .reload /f testHeapOverflow.exe

二、windbg双机联调之驱动源码调试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
1、通过VirtualKD设置好双机联调环境
2、在驱动程序的入口点DriverEntry下断点,命令:    bm ranet!driverentry
    备注:一定要用bm延迟加载符号命令,不能用bp
    1: kd> bm ranet!driverentry
    1: fffff880`03c4bcdc @!"RaNet!DriverEntry"
    1: kd> g
3、把驱动程序拷贝到虚拟机中,利用工具InstDrvx64 V1.03安装并启动驱动程序,此时会命中断点的入口处DriverEntry,输入kn查看调用堆栈
    备注:
    Breakpoint 1 hit
    RaNet!DriverEntry:
    fffff880`03c5bcdc 488bc4          mov     rax,rsp
    1: kd> kn
     # Child-SP          RetAddr           Call Site
    00 fffff880`045ec828 fffff880`03c65020 RaNet!DriverEntry [f:\mygitrepo\rst2\rase_windows\framework\agent_windows\drivers\ranet\ranet.c @ 336]
    01 fffff880`045ec830 fffff800`042978c6 RaNet!GsDriverEntry+0x20 [minkernel\tools\gs_support\kmode\gs_support.c @ 117]
    02 fffff880`045ec860 fffff800`04297cc5 nt!IopLoadDriver+0xa06
    03 fffff880`045ecb30 fffff800`03ea628d nt!IopLoadUnloadDriver+0x55
    04 fffff880`045ecb70 fffff800`0419c1a0 nt!ExpWorkerThread+0x111
    05 fffff880`045ecc00 fffff800`03ef4ba6 nt!PspSystemThreadStartup+0x194
    06 fffff880`045ecc40 00000000`00000000 nt!KiStartSystemThread+0x16
4、在卸载驱动程序的函数入口处下断点,并执行go指令,会成功命中断点;下断点命令: bm ranet!RaUnloadDriver
    备注:函数RaUnloadDriver是指针DriverObject->DriverUnload指向的函数
    1: kd> bm ranet!RaUnloadDriver
      2: fffff880`03e3e800 @!"RaNet!RaUnloadDriver"
    1: kd> bl
         1 e Disable Clear  fffff880`03e3dcdc     0001 (0001) RaNet!DriverEntry
         2 e Disable Clear  fffff880`03e3e800     0001 (0001) RaNet!RaUnloadDriver
    1: kd> g
    Breakpoint 2 hit
    RaNet!RaUnloadDriver:
    fffff880`03e3e800 48895c2408      mov     qword ptr [rsp+8],rbx
    0: kd> kp
     # Child-SP          RetAddr           Call Site
    00 fffff880`04708b28 fffff800`04245c8c RaNet!RaUnloadDriver(struct _DRIVER_OBJECT * DriverObject = 0xfffffa80`1b05ec10 Driver "\Driver\RaNet") [f:\mygitrepo\rst2\rase_windows\framework\agent_windows\drivers\ranet\ranet.c @ 55]
    01 fffff880`04708b30 fffff800`03e5428d nt!IopLoadUnloadDriver+0x1c
    02 fffff880`04708b70 fffff800`0414a1a0 nt!ExpWorkerThread+0x111
    03 fffff880`04708c00 fffff800`03ea2ba6 nt!PspSystemThreadStartup+0x194
    04 fffff880`04708c40 00000000`00000000 nt!KiStartSystemThread+0x16
5、在你感兴趣的函数处下断点,并制造触发的条件,命令:bm 模块名!函数名,例如  bm ranet!GetNetDacRule,都可成功命令断点

三、sc命令安装、启动、停止、卸载驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1、创建一个驱动服务(CreateService)
    sc create mydriver binpath=C:\Users\Administrator\Desktop\888888888\RaNet.sys type=kernel start=demand error=ignore
    mydriver 是驱动服务名,可以改成喜欢的名字,貌似有长度限制
    binpath=后面的 c:\1.sys 是驱动文件的路径,如果路径有空格则需引号括起来,例如 binpath=”C:\a b\1.sys
    type=后面的 kernel 是代表创建一个驱动服务
    start=后面的 demand 代表这个驱动服务按需启动
    error=后面的 ignore 代表忽略任何错误
2、启动驱动服务(StartService)
    sc start mydriver
    mydriver 是你要的驱动服务名字,跟上面那个mydriver 一致
3、停止驱动服务(StopService)
    sc stop mydriver
4、删除驱动服务(DeleteService)
    sc delete mydriver
    不要了就删掉

四、常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1、汇编模式:单步执行一条汇编指令
2、源码模式:单步执行一条语句
3、p:step over
4、t:step into
5、g:运行。
6、gu:跳出函数,运行到函数的下一句。相当于跳出函数(go up),vs的shift + F11
7、.detach  解除附加
8、附加到进程的同时设置源代码路径和符号路径(可把下面这句保存为批处理文件,双击批处理就行)
    "./windbg_x86/windbg.exe" -pn fcservice.exe -y %cd%\pdb -srcpath %cd%\code
9、抓取dmp文件(经常在程序崩溃时,进行抓取dmp文件)
    .dump /ma C:\dumps\myapp.dmp
10、.frame在栈中切换以便检查局部变量
    a)查看线程的调用堆栈knb
        第一列的号称为Frame nu
        0:004> knb
         # ChildEBP RetAddr 
        00 02e2fc30 00ce104a ConsoleApplication1!printf+0x4 [C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\stdio.h @ 960]
        01 02e2fc38 75fe4f9f ConsoleApplication1!SecondThreadFunc+0xa [D:\02MyDemo\045_register\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp @ 13]
        02 02e2fc70 75c7fa29 ucrtbase!thread_start<unsigned int (__stdcall*)(void *),1>+0x3f
        03 02e2fc80 77aa7a9e KERNEL32!BaseThreadInitThunk+0x19
        04 02e2fcdc 77aa7a6e ntdll!__RtlUserThreadStart+0x2f
        05 02e2fcec 00000000 ntdll!_RtlUserThreadStart+0x1b
    b) frame  栈帧号
        命令: .frame 0
    c)   然后调用 x  显示当前frame的局部变量,比如这个函数中有两个局部变量pcls和rawptr
        0:018> x
        0012fced pcls = 0x0039ba80
        0012fcd8 rawptr = 0x0039ba80
11、显示地址空间信息
    0:000> !address 75831234
    Usage:                  Image
    Base Address:           75831000
    End Address:            758f6000
    Region Size:            000c5000
    Type:                   01000000MEM_IMAGE
    State:                  00001000MEM_COMMIT
    Protect:                00000020PAGE_EXECUTE_READ
    More info:              lmv m kernel32
    More info:              !lmi kernel32
    More info:              ln 0x75831234
 
12、重启调试目标
        .restart

五、查看局部变量的值dv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
可以通过指定x前缀(十六进制)、0n前缀(十进制)、0t前缀(八进制)或0y前缀(二进制)
1、打开watch窗口,双机name列可输入变量名,即可显示局部变量的值
2/i:使显示器指定变量的类型:局部、全局、参数、函数或未知。
    0:000> dv /i bRegisteredVer
    prv local   bRegisteredVer = false
3/t :使显示包含每个局部变量的数据类型。
    0:000> dv /t bRegisteredVer
    bool bRegisteredVer = false
4/v :使显示包括局部变量的虚拟内存地址
    0:000> dv /v bRegisteredVer
    0012aa27  bRegisteredVer = false
5/V :与/v相同,还包括相对于相关寄存器的局部变量的地址。
    0:000> dv /V bRegisteredVer
    0012aa27 @ebp-0x55  bRegisteredVer = false
6/a:按地址按升序对输出进行排序。
    0:000> dv /a
               this = 0x001ed8c8
             length = 0n0
               file = class QFile
     bRegisteredVer = false
            license = class CLicense
       qstrAuthCode = class QString
        authErrCode = 0x0012aae4
7、    /A :按地址按降序对输出进行排序。   
    0:000> dv /A
        authErrCode = 0x0012aae4
       qstrAuthCode = class QString
            license = class CLicense
     bRegisteredVer = false
               file = class QFile
             length = 0n0
               this = 0x001ed8c8
 
8/n :按名称按升序对输出进行排序。
            0:000> dv /n
        authErrCode = 0x0012aae4
     bRegisteredVer = false
               file = class QFile
             length = 0n0
            license = class CLicense
       qstrAuthCode = class QString
               this = 0x001ed8c8
9/N :按名称按升序对输出进行排序。              
        0:000> dv /N
               this = 0x001ed8c8
       qstrAuthCode = class QString
            license = class CLicense
             length = 0n0
               file = class QFile
     bRegisteredVer = false
        authErrCode = 0x0012aae4
10/z :按大小按升序对输出进行排序。
        0:000> dv /z
     bRegisteredVer = false
               this = 0x001ed8c8
       qstrAuthCode = class QString
        authErrCode = 0x0012aae4
             length = 0n0
               file = class QFile
            license = class CLicense
11/Z :按大小按升序对输出进行排序。
        0:000> dv /Z
            license = class CLicense
             length = 0n0
               file = class QFile
               this = 0x001ed8c8
       qstrAuthCode = class QString
        authErrCode = 0x0012aae4
     bRegisteredVer = false

六、修改局部变量的值

1
2
3
1、打开watch窗口,修改局部变量的值,,双机name列可输入变量名
   双机Value列,清空原来的内容,输入新值即可,单机“Typecast”显示变量的类型
   单机Locations显示变量的地址

七、查看内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
1、dt 查看结构
 
2、da按照ascii字符串显示
    0:000> da 0012aa00
    0012aa00  "ie"
 
3、db按照单字节和ascii字符串显示
    0:000> db 0012aa00
    0012aa00  69 65 00 00 00 00 00 00-fb f7 a9 00 00 00 15 00  ie..............
    0012aa10  00 00 00 00 00 19 3b 03-fc aa 12 00 c3 c3 02 67  ......;........g
    0012aa20  00 19 3b 03 36 14 00 00-00 19 3b 03 02 00 00 00  ..;.6.....;.....
    0012aa30  04 00 00 00 ef fe 16 65-f0 71 fd 01 90 1d b8 01  .......e.q......
    0012aa40  00 19 3b 03 00 19 3b 03-d8 ca 2c 10 1f 01 00 00  ..;...;...,.....
    0012aa50  90 1b b8 01 ff ff ff ff-00 00 00 00 00 00 00 00  ................
    0012aa60  00 19 3b 03 00 00 00 00-65 6a 10 65 d2 c5 93 fb  ..;.....ej.e....
    0012aa70  f0 aa 12 00 e9 b9 80 00-00 00 00 00 fc aa 12 00  ................
 
4、dc按照4字节和ascii字符串显示
    0:000> dc 0012aa00
    0012aa00  00006569 00000000 00a9f7fb 00150000  ie..............
    0012aa10  00000000 033b1900 0012aafc 6702c3c3  ......;........g
    0012aa20  033b1900 00001436 033b1900 00000002  ..;.6.....;.....
    0012aa30  00000004 6516feef 01fd71f0 01b81d90  .......e.q......
    0012aa40  033b1900 033b1900 102ccad8 0000011f  ..;...;...,.....
    0012aa50  01b81b90 ffffffff 00000000 00000000  ................
    0012aa60  033b1900 00000000 65106a65 fb93c5d2  ..;.....ej.e....
    0012aa70  0012aaf0 0080b9e9 00000000 0012aafc  ................
 
5、dd按照4字节显示
    0:000> dd 0012aa00
    0012aa00  00006569 00000000 00a9f7fb 00150000
    0012aa10  00000000 033b1900 0012aafc 6702c3c3
    0012aa20  033b1900 00001436 033b1900 00000002
    0012aa30  00000004 6516feef 01fd71f0 01b81d90
    0012aa40  033b1900 033b1900 102ccad8 0000011f
    0012aa50  01b81b90 ffffffff 00000000 00000000
    0012aa60  033b1900 00000000 65106a65 fb93c5d2
    0012aa70  0012aaf0 0080b9e9 00000000 0012aafc
 
6、dD按照双浮点(8字节)格式显示
    0:000> dD 0012aa00
    0012aa00      1.28264382317e-319     2.92040944479e-308     4.24283322552e-293
    0012aa18      1.63293462903e+188     1.09792330031e-310     4.27077224821e-314
    0012aa30       9.3185129548e+178     2.25060988521e-300     4.24283325567e-293
    0012aa48       6.0914686708e-312               -1.#QNAN                      0
    0012aa60      2.67806662793e-316    -1.88175367138e+287     2.97736448613e-306
 
7、df按照单浮点(4字节)格式显示
    0:000> df 0012aa00
    0012aa00    3.6379109e-041                0   1.5609157e-038   1.9285454e-039
    0012aa10                 0   5.4983059e-037   1.7143766e-039   6.1751881e+023
    0012aa20    5.4983059e-037   7.2503183e-042   5.4983059e-037   2.8025969e-045
    0012aa30    5.6051939e-045   4.4566104e+022   9.3101014e-038   6.7633345e-038
 
8、dp按照指针(32位系统读取4字节、64位系统读取8字节)格式读取
    0:000> df 0012aa00
    0012aa00    3.6379109e-041                0   1.5609157e-038   1.9285454e-039
    0012aa10                 0   5.4983059e-037   1.7143766e-039   6.1751881e+023
    0012aa20    5.4983059e-037   7.2503183e-042   5.4983059e-037   2.8025969e-045
    0012aa30    5.6051939e-045   4.4566104e+022   9.3101014e-038   6.7633345e-038
 
9、dq按照8字节读取
    0:000> dq 0012aa00
    0012aa00  00000000`00006569 00150000`00a9f7fb
    0012aa10  033b1900`00000000 6702c3c3`0012aafc
    0012aa20  00001436`033b1900 00000002`033b1900
    0012aa30  6516feef`00000004 01b81d90`01fd71f0
    0012aa40  033b1900`033b1900 0000011f`102ccad8
    0012aa50  ffffffff`01b81b90 00000000`00000000
    0012aa60  00000000`033b1900 fb93c5d2`65106a65
    0012aa70  0080b9e9`0012aaf0 0012aafc`00000000
 
10、du按照Unicode字符串读取。
    0:000> du 0012aa00
    0012aa00  "敩"
 
11、dw按照双字节显示
    0:000> dw 0012aa00
    0012aa00  6569 0000 0000 0000 f7fb 00a9 0000 0015
    0012aa10  0000 0000 1900 033b aafc 0012 c3c3 6702
    0012aa20  1900 033b 1436 0000 1900 033b 0002 0000
    0012aa30  0004 0000 feef 6516 71f0 01fd 1d90 01b8
    0012aa40  1900 033b 1900 033b cad8 102c 011f 0000
    0012aa50  1b90 01b8 ffff ffff 0000 0000 0000 0000
    0012aa60  1900 033b 0000 0000 6a65 6510 c5d2 fb93
    0012aa70  aaf0 0012 b9e9 0080 0000 0000 aafc 0012
 
12、dW按照2字节和ASCII字符串读取。
    0:000> dW 0012aa00
    0012aa00  6569 0000 0000 0000 f7fb 00a9 0000 0015  ie..............
    0012aa10  0000 0000 1900 033b aafc 0012 c3c3 6702  ......;........g
    0012aa20  1900 033b 1436 0000 1900 033b 0002 0000  ..;.6.....;.....
    0012aa30  0004 0000 feef 6516 71f0 01fd 1d90 01b8  .......e.q......
    0012aa40  1900 033b 1900 033b cad8 102c 011f 0000  ..;...;...,.....
    0012aa50  1b90 01b8 ffff ffff 0000 0000 0000 0000  ................
    0012aa60  1900 033b 0000 0000 6a65 6510 c5d2 fb93  ..;.....ej.e....
    0012aa70  aaf0 0012 b9e9 0080 0000 0000 aafc 0012  ................
 
13、dyb按照单字节和二进制读取
    0:000> dyb 0012aa00
      76543210 76543210 76543210 76543210
      -------- -------- -------- --------
    0012aa00  01101001 01100101 00000000 00000000  69 65 00 00
    0012aa04  00000000 00000000 00000000 00000000  00 00 00 00
    0012aa08  11111011 11110111 10101001 00000000  fb f7 a9 00
    0012aa0c  00000000 00000000 00010101 00000000  00 00 15 00
    0012aa10  00000000 00000000 00000000 00000000  00 00 00 00
    0012aa14  00000000 00011001 00111011 00000011  00 19 3b 03
    0012aa18  11111100 10101010 00010010 00000000  fc aa 12 00
    0012aa1c  11000011 11000011 00000010 01100111  c3 c3 02 67
 
14、dyd按照4字节和二进制读取。
    0:000> dyd 0012aa00
           3          2          1          0
          10987654 32109876 54321098 76543210
          -------- -------- -------- --------
    0012aa00  00000000 00000000 01100101 01101001  00006569
    0012aa04  00000000 00000000 00000000 00000000  00000000
    0012aa08  00000000 10101001 11110111 11111011  00a9f7fb
    0012aa0c  00000000 00010101 00000000 00000000  00150000
    0012aa10  00000000 00000000 00000000 00000000  00000000
    0012aa14  00000011 00111011 00011001 00000000  033b1900
    0012aa18  00000000 00010010 10101010 11111100  0012aafc
    0012aa1c  01100111 00000010 11000011 11000011  6702c3c3

八、编辑内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
    e, ea, eb, ed, eD, ef, ep, eq, eu, ew, eza (Enter Values)
e*命令将您指定的值输入内存。不要将此命令与~e(Thread-Specific Command)限定符混淆。
 
e{b|d|D|f|p|q|w} Address [Values]
e{a|u|za|zu} Address "String"
e Address [Values]
参数:
Address
指定输入值的起始地址。调试器将替换地址和每个后续内存位置处的值,直到所有值都被使用为止。
Values
指定要输入内存的一个或多个值。多个数值应该用空格分隔。如果未指定任何值,则将显示当前地址和该地址的值,并提示您输入。
String
指定要输入内存的字符串。ea和eza命令将此作为ascii字符串写入内存;eu和ezu命令将此作为unicode字符串写入内存。eza和ezu命令会写入一个终端空值;ea和eu命令不会。字符串必须用引号括起来。
 
1、eb    字节值。
    0:000> eb 0012aa00 56
    0:000> db 0012aa00
    0012aa00  56 65 00 00 00 00 00 00-fb f7 a9 00 00 00 15 00  Ve..............
    0012aa10  00 00 00 00 00 19 3b 03-fc aa 12 00 c3 c3 02 67  ......;........g
    0012aa20  00 19 3b 03 36 14 00 00-00 19 3b 03 02 00 00 00  ..;.6.....;.....
    0012aa30  04 00 00 00 ef fe 16 65-f0 71 fd 01 90 1d b8 01  .......e.q......
    0012aa40  00 19 3b 03 00 19 3b 03-d8 ca 2c 10 1f 01 00 00  ..;...;...,.....
    0012aa50  90 1b b8 01 ff ff ff ff-00 00 00 00 00 00 00 00  ................
    0012aa60  00 19 3b 03 00 00 00 00-65 6a 10 65 d2 c5 93 fb  ..;.....ej.e....
    0012aa70  f0 aa 12 00 e9 b9 80 00-00 00 00 00 fc aa 12 00  ................
 
2、ed    双字值 (4 个字节为单位)。
    0:000> ed 0012aa00 12345678
    0:000> dd 0012aa00
    0012aa00  12345678 00000000 00a9f7fb 00150000
    0012aa10  00000000 033b1900 0012aafc 6702c3c3
    0012aa20  033b1900 00001436 033b1900 00000002
    0012aa30  00000004 6516feef 01fd71f0 01b81d90
    0012aa40  033b1900 033b1900 102ccad8 0000011f
    0012aa50  01b81b90 ffffffff 00000000 00000000
    0012aa60  033b1900 00000000 65106a65 fb93c5d2
    0012aa70  0012aaf0 0080b9e9 00000000 0012aafc
 
3、eD    双精度浮点数 (8 字节为单位)。
    0:000> eD 0012aa00 3.1415926
    0:000> dD 0012aa00
    0012aa00               3.1415926     2.92040944479e-308     4.24283322552e-293
    0012aa18      1.63293462903e+188     1.09792330031e-310     4.27077224821e-314
    0012aa30       9.3185129548e+178     2.25060988521e-300     4.24283325567e-293
    0012aa48       6.0914686708e-312               -1.#QNAN                      0
    0012aa60      2.67806662793e-316    -1.88175367138e+287     2.97736448613e-306
 
4、ef    单精度浮点数 (4 个字节为单位)。
    0:000> ef 0012aa00 6.28
    0:000> df 0012aa00
    0012aa00         6.2800002         2.142699   1.5609157e-038   1.9285454e-039
    0012aa10                 0   5.4983059e-037   1.7143766e-039   6.1751881e+023
    0012aa20    5.4983059e-037   7.2503183e-042   5.4983059e-037   2.8025969e-045
    0012aa30    5.6051939e-045   4.4566104e+022   9.3101014e-038   6.7633345e-038
 
5、ep    指针大小值。 此命令是等效于ed或eq,具体取决于目标计算机的处理器体系结构是否 32 位或 64 位分别。
    0:000> ep 0012aa00 98765432
    0:000> dp 0012aa00
    0012aa00  98765432 400921fb 00a9f7fb 00150000
    0012aa10  00000000 033b1900 0012aafc 6702c3c3
    0012aa20  033b1900 00001436 033b1900 00000002
    0012aa30  00000004 6516feef 01fd71f0 01b81d90
    0012aa40  033b1900 033b1900 102ccad8 0000011f
    0012aa50  01b81b90 ffffffff 00000000 00000000
    0012aa60  033b1900 00000000 65106a65 fb93c5d2
    0012aa70  0012aaf0 0080b9e9 00000000 0012aafc
 
6、eq    四字值 (8 字节为单位)。
    0:000> ep 0012aa00 98765432
    0:000> dp 0012aa00
    0012aa00  98765432 400921fb 00a9f7fb 00150000
    0012aa10  00000000 033b1900 0012aafc 6702c3c3
    0012aa20  033b1900 00001436 033b1900 00000002
    0012aa30  00000004 6516feef 01fd71f0 01b81d90
    0012aa40  033b1900 033b1900 102ccad8 0000011f
    0012aa50  01b81b90 ffffffff 00000000 00000000
    0012aa60  033b1900 00000000 65106a65 fb93c5d2
    0012aa70  0012aaf0 0080b9e9 00000000 0012aafc
 
7、ew    字值 (2 个字节)。
    0:000> ew 0012aa00 9999
    0:000> dw 0012aa00
    0012aa00  9999 0075 0061 0069 007a 0068 0069 0015
    0012aa10  0000 0000 1900 033b aafc 0012 c3c3 6702
    0012aa20  1900 033b 1436 0000 1900 033b 0002 0000
    0012aa30  0004 0000 feef 6516 71f0 01fd 1d90 01b8
    0012aa40  1900 033b 1900 033b cad8 102c 011f 0000
    0012aa50  1b90 01b8 ffff ffff 0000 0000 0000 0000
    0012aa60  1900 033b 0000 0000 6a65 6510 c5d2 fb93
    0012aa70  aaf0 0012 b9e9 0080 0000 0000 aafc 0012
 
8、ea    ASCII 字符串 (不以 NULL 终止)。
    0:000> ea 0012aa00 "jiahao"
    0:000> db 0012aa00
    0012aa00  6a 69 61 68 61 6f 6c 65-69 f7 a9 00 00 00 15 00  jiahaolei.......
    0012aa10  00 00 00 00 00 19 3b 03-fc aa 12 00 c3 c3 02 67  ......;........g
    0012aa20  00 19 3b 03 36 14 00 00-00 19 3b 03 02 00 00 00  ..;.6.....;.....
    0012aa30  04 00 00 00 ef fe 16 65-f0 71 fd 01 90 1d b8 01  .......e.q......
    0012aa40  00 19 3b 03 00 19 3b 03-d8 ca 2c 10 1f 01 00 00  ..;...;...,.....
    0012aa50  90 1b b8 01 ff ff ff ff-00 00 00 00 00 00 00 00  ................
    0012aa60  00 19 3b 03 00 00 00 00-65 6a 10 65 d2 c5 93 fb  ..;.....ej.e....
    0012aa70  f0 aa 12 00 e9 b9 80 00-00 00 00 00 fc aa 12 00  ................
 
9、eu    Unicode 字符串 (不以 NULL 终止)。
    0:000> eu 0012aa00 "huaizhi"
    0:000> du 0012aa00
    0012aa00  "huaizhi."
    0:000> db 0012aa00
    0012aa00  68 00 75 00 61 00 69 00-7a 00 68 00 69 00 15 00  h.u.a.i.z.h.i...
    0012aa10  00 00 00 00 00 19 3b 03-fc aa 12 00 c3 c3 02 67  ......;........g
    0012aa20  00 19 3b 03 36 14 00 00-00 19 3b 03 02 00 00 00  ..;.6.....;.....
    0012aa30  04 00 00 00 ef fe 16 65-f0 71 fd 01 90 1d b8 01  .......e.q......
    0012aa40  00 19 3b 03 00 19 3b 03-d8 ca 2c 10 1f 01 00 00  ..;...;...,.....
    0012aa50  90 1b b8 01 ff ff ff ff-00 00 00 00 00 00 00 00  ................
    0012aa60  00 19 3b 03 00 00 00 00-65 6a 10 65 d2 c5 93 fb  ..;.....ej.e....
    0012aa70  f0 aa 12 00 e9 b9 80 00-00 00 00 00 fc aa 12 00  ................
 
 
10、eza    以 NULL 结尾的 ASCII 字符串。
    0:000> eza 0012aa00 "china"
    0:000> db 0012aa00
    0012aa00  63 68 69 6e 61 00 69 00-7a 00 68 00 69 00 15 00  china.i.z.h.i...
    0012aa10  00 00 00 00 00 19 3b 03-fc aa 12 00 c3 c3 02 67  ......;........g
    0012aa20  00 19 3b 03 36 14 00 00-00 19 3b 03 02 00 00 00  ..;.6.....;.....
    0012aa30  04 00 00 00 ef fe 16 65-f0 71 fd 01 90 1d b8 01  .......e.q......
    0012aa40  00 19 3b 03 00 19 3b 03-d8 ca 2c 10 1f 01 00 00  ..;...;...,.....
    0012aa50  90 1b b8 01 ff ff ff ff-00 00 00 00 00 00 00 00  ................
    0012aa60  00 19 3b 03 00 00 00 00-65 6a 10 65 d2 c5 93 fb  ..;.....ej.e....
    0012aa70  f0 aa 12 00 e9 b9 80 00-00 00 00 00 fc aa 12 00  ................
 
11、ezu    以 NULL 结尾的 Unicode 字符串。
    0:000> ezu 0012aa00 "Enlish"
    0:000> db 0012aa00
    0012aa00  45 00 6e 00 6c 00 69 00-73 00 68 00 00 00 15 00  E.n.l.i.s.h.....
    0012aa10  00 00 00 00 00 19 3b 03-fc aa 12 00 c3 c3 02 67  ......;........g
    0012aa20  00 19 3b 03 36 14 00 00-00 19 3b 03 02 00 00 00  ..;.6.....;.....
    0012aa30  04 00 00 00 ef fe 16 65-f0 71 fd 01 90 1d b8 01  .......e.q......
    0012aa40  00 19 3b 03 00 19 3b 03-d8 ca 2c 10 1f 01 00 00  ..;...;...,.....
    0012aa50  90 1b b8 01 ff ff ff ff-00 00 00 00 00 00 00 00  ................
    0012aa60  00 19 3b 03 00 00 00 00-65 6a 10 65 d2 c5 93 fb  ..;.....ej.e....
    0012aa70  f0 aa 12 00 e9 b9 80 00-00 00 00 00 fc aa 12 00  ................

九、断点

1、bp命令
是在某个地址下断点, 可以 bp 0x7783FEB 也可以 bp MyApp!SomeFunction 。 对于后者,WinDBG 会自动找到MyApp!SomeFunction 对应的地址并设置断点。 但是使用bp的问题在于:a)当代码修改之后,函数地址改变,该断点仍然保持在相同位置,不一定继续有效; b)WinDBG 不会把bp断点保存工作空间中 。
bp使方法如下:
0:000> bp standAloneWinGuard!CUIAuthMgr::SetLicenseErrCode
2、bu命令
是针对某个符号下断点。bu最重要的用途是对还未加载的模块下断点,例如loader32.dll还未被加载,你想在loader32.dll中下断点bu loader32!DllMain,当load32.dll被加载时,会命中你下的断点, 此外 bu MyApp!SomeFunction ,在代码被修改之后, 该断点可以随着函数地址改变而自动更新到最新位置。 而且bu 断点会保存在WinDbg工作空间中, 下次启动 Windbg 的时候该断点会自动设置上去。
还bu 可以对还不能识别的符号设置断点,当系统中有新模块加载进来时,调试器会对未定断点再次进行识别,如果找到了匹配的符号则会设置它。而bp 断点会失败(因为函数地址不存在),bu 断点则可以成功。 新版的WinDBG中 bp失败后会自动被转成bu
3、bm命令
也是针对符号 下断点。 但是它支持匹配表达式 。 很多时候你下好几个断点。 比如,把MyClass 所有的成员函数都下断点: bu MyApp!MyClass:: , 或者把所有以CreateWindow开头的函数都下断点: bu user32!CreateWindow
如果驱动开发,对驱动程序入口下断点可以用bm,不能用bp
kd> bm ranet!driverentry

 

4、ba命令
以上三个命令是对代码下断点, 我们还可以对数据下断点。就是针对数据 下断点的命令, 该断点在指定内存被访问时触发。 命令格式为
ba Access Size [地址]
Access 是访问的方式, 比如 e (执行), r (读/写), w (写)
Size 是监控访问的位置的大小,以字节为单位。 值为 1、2或4,还可以是 8(64位机)。
比如要对内存0x0483DFE进行写操作的时候下断点,可以用命令 ba w4 0x0483DFE

 

5、查看断点bl
0:000> bl

 

6、禁用断点
0:000> bd 1

 

7、启用断点
0:000> be 1
0:000> bl

 

8、清除断点
0:000> bc 1
0:000> bl
0:000> bc 2-4
0:000> bc 1

十、查看加载的模块信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1、查看加载的所有模块lm
    0:000> lm
    start    end        module name
    003c0000 003d3000   VCRUNTIME140   (export symbols)       C:\Program Files\RSAWinGuard\VCRUNTIME140.dll
    003e0000 003e4000   api_ms_win_crt_runtime_l1_1_0   (export symbols)       C:\WINDOWS\system32\api-ms-win-crt-runtime-l1-1-0.dll
    003f0000 003f3000   api_ms_win_core_string_l1_1_0   (export symbols)       C:\WINDOWS\system32\api-ms-win-core-string-l1-1-0.dll
    00400000 009f4000   standAloneWinGuard C (private pdb symbols)  c:\pdb\standAloneWinGuard.pdb
    00a00000 00a6f000   MSVCP140   (export symbols)       C:\Program Files\RSAWinGuard\MSVCP140.dll
2、查看某个模块的详细信息lmvm
    0:000> lmvm standAloneWinGuard
    start    end        module name
    00400000 009f4000   standAloneWinGuard C (private pdb symbols)  c:\pdb\standAloneWinGuard.pdb
        Loaded symbol image file: C:\Program Files\RSAWinGuard\standAloneWinGuard.exe
        Image path: standAloneWinGuard.exe
        Image name: standAloneWinGuard.exe
        Timestamp:        Thu Mar 11 14:11:27 2021 (6049B48F)
        CheckSum:         00000000
        ImageSize:        005F4000
        Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4

十一、查看调用堆栈kb

1
2
3
4
5
6
7
8
9
10
0:000> kb
ChildEBP RetAddr  Args to Child             
0012aa7c 00532012 0336ab30 0012aae4 fb93c552 standAloneWinGuard!CUIAuthMgr::Authorize+0xe5 [f:\mygitrepo\rst2\standalonewinguard_v2\framework\agent_windows\standalonewinguard\uiauthmgr.cpp @ 95]
0012aafc 00577527 00000000 fb93a27d 0012ab54 standAloneWinGuard!CMainWnd::handle_pushButton_authorize_click+0xf2 [f:\mygitrepo\rst2\standalonewinguard_v2\framework\agent_windows\standalonewinguard\mainwnd.cpp @ 2784]
0012ab5c 6718364f 0012d4d0 00000000 00000051 standAloneWinGuard!CMainWnd::qt_static_metacall+0xa27 [f:\mygitrepo\rst2\standalonewinguard_v2\framework\agent_windows\standalonewinguard\release\moc\moc_mainwnd.cpp @ 639]
WARNING: Stack unwind information not available. Following frames may be wrong.
0012abec 6718382e 01b82978 00000000 6745b4d0 Qt5Core!QMetaObject::activate+0x50f
0012ac00 650bfa90 01b82978 652c6074 00000002 Qt5Core!QMetaObject::activate+0x1e
0012ac2c 650bf9f8 0012afc8 0012afc8 01b829a8 Qt5Widgets!QAbstractButton::clicked+0x80
00000000 00000000 00000000 00000000 00000000 Qt5Widgets!QAbstractButton::click+0x158

十二、查看函数反汇编代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    u        向下反汇编
    ub        向上反汇编
    uf        反汇编整个函数
    a        写入汇编指令
1、uf 模块名!函数名称
        0: kd> uf tcpip!TcpPortPoolQueryLocalAddressFunction
        tcpip!TcpPortPoolQueryLocalAddressFunction:
        89c3c012 8bff            mov     edi,edi
        89c3c014 55              push    ebp
        89c3c015 8bec            mov     ebp,esp
        89c3c017 80fa01          cmp     dl,1
        89c3c01a 7437            je      tcpip!TcpPortPoolQueryLocalAddressFunction+0x41 (89c3c053)  Branch
 
        tcpip!TcpPortPoolQueryLocalAddressFunction+0xa:
        89c3c01c 80fa02          cmp     dl,2
        89c3c01f 7532            jne     tcpip!TcpPortPoolQueryLocalAddressFunction+0x41 (89c3c053)  Branch
 
        tcpip!TcpPortPoolQueryLocalAddressFunction+0xf:
        89c3c021 668b41fc        mov     ax,word ptr [ecx-4]
        89c3c025 8b5508          mov     edx,dword ptr [ebp+8]
        89c3c028 668902          mov     word ptr [edx],ax
        89c3c02b 8b81a0feffff    mov     eax,dword ptr [ecx-160h]
        89c3c031 8b00            mov     eax,dword ptr [eax]
        89c3c033 8b4008          mov     eax,dword ptr [eax+8]
        89c3c036 8b00            mov     eax,dword ptr [eax]
        89c3c038 8b550c          mov     edx,dword ptr [ebp+0Ch]
        89c3c03b 8902            mov     dword ptr [edx],eax
        89c3c03d f681ccfeffff20  test    byte ptr [ecx-134h],20h
        89c3c044 7526            jne     tcpip!TcpPortPoolQueryLocalAddressFunction+0x5a (89c3c06c)  Branch
 
        tcpip!TcpPortPoolQueryLocalAddressFunction+0x34:
        89c3c046 8b81a0feffff    mov     eax,dword ptr [ecx-160h]
        89c3c04c 8b00            mov     eax,dword ptr [eax]
        89c3c04e 8b400c          mov     eax,dword ptr [eax+0Ch]
        89c3c051 eb20            jmp     tcpip!TcpPortPoolQueryLocalAddressFunction+0x61 (89c3c073)  Branch
 
        tcpip!TcpPortPoolQueryLocalAddressFunction+0x41:
        89c3c053 668b41fc        mov     ax,word ptr [ecx-4]
        89c3c057 8b5508          mov     edx,dword ptr [ebp+8]
        89c3c05a 668902          mov     word ptr [edx],ax
        89c3c05d 8b41f0          mov     eax,dword ptr [ecx-10h]
        89c3c060 8b550c          mov     edx,dword ptr [ebp+0Ch]
        89c3c063 8902            mov     dword ptr [edx],eax
        89c3c065 8b49f4          mov     ecx,dword ptr [ecx-0Ch]
        89c3c068 85c9            test    ecx,ecx
        89c3c06a 7504            jne     tcpip!TcpPortPoolQueryLocalAddressFunction+0x5e (89c3c070)  Branch
 
        tcpip!TcpPortPoolQueryLocalAddressFunction+0x5a:
        89c3c06c 33c0            xor     eax,eax
        89c3c06e eb03            jmp     tcpip!TcpPortPoolQueryLocalAddressFunction+0x61 (89c3c073)  Branch
 
        tcpip!TcpPortPoolQueryLocalAddressFunction+0x5e:
        89c3c070 8b410c          mov     eax,dword ptr [ecx+0Ch]
 
        tcpip!TcpPortPoolQueryLocalAddressFunction+0x61:
        89c3c073 5d              pop     ebp
        89c3c074 c20800          ret     8
 
2、u 指令地址
    0: kd> u 89c77510
    tcpip!EnumerateAndReferenceEndpointInAssignment+0x43:
    89c77510 eb0a            jmp     tcpip!EnumerateAndReferenceEndpointInAssignment+0x4f (89c7751c)
    89c77512 83651000        and     dword ptr [ebp+10h],0
    89c77516 83651c00        and     dword ptr [ebp+1Ch],0
    89c7751a 33c0            xor     eax,eax
    89c7751c 83f8ff          cmp     eax,0FFFFFFFFh
    89c7751f 7444            je      tcpip!EnumerateAndReferenceEndpointInAssignment+0x98 (89c77565)
    89c77521 8b4d1c          mov     ecx,dword ptr [ebp+1Ch]
    89c77524 85c9            test    ecx,ecx

十三、内核调试指令(下面的每个指令都是独立的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
1、显示系统所有进程!process 0 0
    kd> !process 0 0
    **** NT ACTIVE PROCESS DUMP ****
    PROCESS fffffa8018de0890
        SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
        DirBase: 00187000  ObjectTable: fffff8a000001780  HandleCount: 533.
        Image: System
2、显示当前进程信息
    kd> !process
3、切换到某个进程.process /r /p EprocessAddress
    (然后再查看其调用堆栈)使用/r /p来切换进程上下文,意味着接下来的命令都使用新的进程
    上下文,比如内存,但这并没有改变目标系统,只是影响了windbg的输出。/r的意思是加载符号。
    使用.process /p + 你需要断的应用程序的EProcess地址,切换到应用程序的地址空间
    kd> .process /r /p  fffffa801fffb060
    kd> kb
 
4、切换到某个进程.process /i EprocessAddress
    kd> .process /i fffffa801fffb060  
    可以使用/i来切换,它会进程实际的进程切换,所以执行后要go一下,如果使用了/i,必须使用g命令来执行目标
    数秒之后,目标会再次中断到调试器,并且指定的PROCESS被激活并用作当前进程上下文。
5、对某个进程下断点
    bp /p EprocessAddress  指令地址或者函数名
6、对某个线程下断点   
    bp /t EthreadAddress  指令地址或者函数名
7、查找某个函数        x命令
    kd> x nt!Nt*File*
    fffff800`04339780 nt!NtQueryEaFile = <no type information>
    fffff800`04173700 nt!NtFlushBuffersFile = <no type information>
    fffff800`041dc400 nt!NtCreateFile = <no type information>
    fffff800`041bd7b0 nt!NtQueryDirectoryFile = <no type information>
    fffff800`0412e780 nt!NtDeleteFile = <no type information>
    fffff800`0427caf0 nt!NtSetIntervalProfile = <no type information>
    fffff800`042510a0 nt!NtQueryIntervalProfile = <no type information>
    fffff800`04195fe0 nt!NtCreateNamedPipeFile = <no type information>
    fffff800`041bd0dc nt!NtOpenFile = <no type information>
    fffff800`041ef7a0 nt!NtDeviceIoControlFile = <no type information>
    fffff800`04148450 nt!NtCreateMailslotFile = <no type information>
    fffff800`0433b0c0 nt!NtSetQuotaInformationFile = <no type informa
8、双机联调重启被调试机器
            .reboot

十四、内核调试下对用户态进程源码调试(以下步骤是连续的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1、    首先建立好双机调试环境,在windbg中设置好符号路径,源代码路径。
2、    在虚拟机中运行要调试程序helloKD.exe
3、    在windbg中查找要下断点的函数 x helloKD! Hellosal,表示没有找到对应的符号
    0: kd> x helloKD!hellosal
                    ^ Couldn't resolve 'x helloKD'
4、使用命令.reload /user重新载入应用程序符号。
    0: kd> .reload /user
    Loading User Symbols
5、再次在windbg中查找要下断点的函数 x helloKD! Hellosal,这时可以找到此符号
    0: kd> x helloKD!hellosal
    *** WARNING: Unable to verify checksum for helloKD.exe
    00311100          helloKD!hellosal (int, int)
6、在函数下helloKD!hellosal中下断点bp helloKD!hellosal
    0: kd> bp helloKD!hellosal
    0: kd> bl
         0 e Disable Clear  00311100     0001 (0001) helloKD!hellosal
 
7、查看应用程序helloKD.exe进程的PROCESS,命名 !process 0 0 helloKD.exe
    1: kd> !process 0 0 helloKD.exe
    PROCESS 8e7e3740  SessionId: 1  Cid: 17d8    Peb: 009dc000  ParentCid: 0e50
        DirBase: 3ed18600  ObjectTable: b0a9d700  HandleCount:  40.
        Image: helloKD.exe
8、切换到进程helloKD.exe的进程上下文,并执行之先.process /i 8e7e3740 然后在输入g
    1: kd> .process /i 8e7e3740
    You need to continue execution (press 'g' <enter>) for the context
    to be switched. When the debugger breaks in again, you will be in
    the new process context.
    1: kd> g
    Break instruction exception - code 80000003 (first chance)
    nt!RtlpBreakWithStatusInstruction:
    8236df84 cc              int     3
9、在源代码cpp文件中国命中断点helloKD!hellosal

十五、内核调试下对用户态进程源码调试(以下的每一步都是连续的,前提:要调试的程序还没在虚拟机中运行,要中断到main函数第一句,)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
已经可以对运行中的进程下断点,并成功hit到,这是个好现象。但是在实际情况中,我们往往需要调试进程刚启动时的代码(如exe的main),
上面给出的方法并不能做到。下面我们一起看看如何对未启动的进程加断点:
以test.exe为例,此时test.exe未启动,我们想要在test!main下断点,并成功hit。下面简单给出完整步骤。
 
1.    输入 !gflag +ksl
    kd> !gflag +ksl
    New NtGlobalFlag contents: 0x00040000
    ksl - Enable loading of kernel debugger symbols
 
2、kd> sxe  ld  test.exe
    (由于上面开了加载的设置,这里test.exe模块加载进系统的时候,会中断点)
 
3、    kd> g
    nt!DbgLoadUserImageSymbols+0x30:
    83e1124d cc int 3
    (F5 继续运行后,我们需要在虚拟机中启动test,然后就 hit 了上面的 int 3 断点)
4、    kd> !gflag -ksl
    New NtGlobalFlag contents: 0x00000000
    (此时还是先把GFlag reset 一下)
 
5、    kd> .process
    Implicit process is now 87d50030
    (查看当前进程信息 (test.exe))
 
6、    kd> bp /p 87d50030 nt!NtMapViewOfSection
    (bp /p AOTP nt!NtMapViewOfSection,对 test.exe 对应的 NtMapViewOfSection 下断点)
 
7、    kd> g
    Breakpoint 0 hit
    nt!NtMapViewOfSection:
    84051394 6a2c push 2Ch
    (F5 继续运行后,此时会 hit 中刚才设置的断点)
 
8、    kd> bd 0
    (取第一次的断点就行了,此时disable刚才设置的断点)
 
9、    kd> .reload /user
    Loading User Symbols
    
    (最好还是先把用户态pdb加好)
10、kd> x test!main
    004014b7 test!main (int, char **)
    (已经发现目标)
11、kd> bp test!main
    kd> g
    Breakpoint 0 hit
    test!main:
    001b:00401er4b7 55 push ebp
    (下断点后,F5,的确击中目标)

十六、用户态调试EXE命令

1
2
3
4
5
6
7
8
9
10
11
~*kb            显示所有线程的调用堆栈
~1k                显示1号线程的调用堆栈
~2s                切换到2号线程
~                简洁地显示当前进程的所有线程
~*                详细地显示当前进程的所有线程
~.                显示当前线程
~3f                表示冻结3号线程
~3u                表示解冻3号线程
~2n                挂起2号线程
~2m                恢复2号线程
!threads        查看所有托管线程

十七、内存搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
1、搜索指定范围内所有的ascii字符串
    s -sa 011e0000 01203000
2、搜索指定范围内所有的UNICODE字符串
    s -su 011e0000 01203000
 
3、搜索指定范围内某个ascii字符串
    s -a 01180000 011a3000 "hello"
 
4、搜索指定的UNICODE字符串
    s -u 01180000 011a3000 "china"
 
5、搜索指定的16进制数据   
    s 01180000 L23000 48 65 6c 6c 6f

十八、内存断点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
1、内存断点,在地址01199b38的前4个字节读取时,命中断点
    ba r4 01199b38
2、内存断点,在地址01199b38的前4个字节写入时,命中断点
    ba r4 01199b38
 
3、内存断点使用方法:先把断点下到某个函数中,使用dv命令显示局部变量的地址,然后下断点
    3.1把断点下到某个函数中
        0:005> x ba_memory!GetName
        0:005> g
        Breakpoint 1 hit
        eax=03daf9e4 ebx=00f95d30 ecx=76693a00 edx=00000000 esi=03daf7d8 edi=03dafa50
        eip=01192400 esp=03daf7d0 ebp=03dafa50 iopl=0         nv up ei pl nz na po nc
        cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
        ba_memory!GetName:
        01192400 55              push    ebp
    3.2使用dv命令显示局部变量的地址
        0:004> dv
            pOut = 0x03daf9e4 "sanganlei"
    3.3给局部变量下内存断点
        0:004> ba w4 0x03daf9e4
        0:004> g
            Breakpoint 4 hit
            *** Unable to resolve unqualified symbol in Bp expression 'w4 '.
            eax=0119c040 ebx=00f95d30 ecx=00000040 edx=00000002 esi=0119c000 edi=03daf9e4
            eip=7737318d esp=03daf5dc ebp=03daf6e8 iopl=0         nv up ei pl nz na po nc
            cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
            VCRUNTIME140D!TrailingDownVec+0x1dd:
            7737318d f30f7f4f10      movdqu  xmmword ptr [edi+10h],xmm1 ds:002b:03daf9f4=00000000000000000000000000000000
        0:004> kn
         # ChildEBP RetAddr 
        00 03daf5e0 01192d08 VCRUNTIME140D!TrailingDownVec+0x1dd [d:\agent\_work\1\s\src\vctools\crt\vcruntime\src\string\i386\memcpy.asm @ 637]
        01 03daf6e8 01192442 ba_memory!memcpy_s+0x178 [c:\program files (x86)\windows kits\10\include\10.0.18362.0\ucrt\corecrt_memcpy_s.h @ 59]
        02 03daf7cc 0119256b ba_memory!GetName+0x42 [e:\mydemo\103_ba_memory_break\ba\ba_memory\ba_memory.cpp @ 17]
        03 03dafa50 0f166cf2 ba_memory!MonitorOfflineTime+0xfb [e:\mydemo\103_ba_memory_break\ba\ba_memory\ba_memory.cpp @ 32]

十九、查看进程的peb和teb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1、查看进程的PEB
    从以上!PEB输出结果,我们可以了解到进程的ImageBaseAddress,进程的堆(Heap)起始地址,
    装载了那些DLL,命令行参数,系统的环境变量等等 。。。
    ①查看peb信息
        0:000> !peb
        PEB at 000000b0599ca000   
    ②peb结构体,命令dt nt!_peb 000000b0599ca000或者dt nt!_peb @$peb
        0:005> dt nt!_peb 000000b0599ca000
2、查看线程的TEB
    从以上!TEB输出结果,我们可以了解到栈(stack)的起始地址,Tls Storage 的地址,
    异常处理的地址,LastError的值等等。。。
    ①查看teb信息
        0:005> !teb
            TEB at 000000b0599d9000
    ②peb结构体,命令dt nt!_teb 000000b0599d9000或者dt nt!_teb @$teb
        0:005> dt nt!_teb 000000b0599d9000
            ntdll!_TEB
               +0x000 NtTib            : _NT_TIB
               +0x038 EnvironmentPointer : (null)
               +0x040 ClientId         : _CLIENT_ID
               +0x050 ActiveRpcHandle  : (null)

二十、符号查找命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1、查看加载的模块
    0:022> lm
    start             end                 module name   
2、查找符号,命令:        x 模块名!符号名
    0:022> x svnets!*GetSoftVersion*
    000007fe`ef144620 svnets!`CWorkStation::GetSoftVersion'::`1'::dtor$4 (void)
    000007fe`ef068290 svnets!CWorkStation::GetSoftVersion (void)
 
3、查找windows api函数,GetModuleFileNameA
    x *!GetModuleFileName*
 
4、ln 命令显示给定地址处的或者最近的符号
    0:000> ln 00007ff652e31118
        Browse module
        Set bu breakpoint
        [e:\mydemo\189_modifyassem\modifyassem\modifyassem\modifyassem.cpp @ 11] (00007ff6`52e310e0)   modifyAssem!main+0x38
 
5、dds、dps和dqs命令显示给定范围内存的内容,它们是把内存区域转储出来,
   并把内存中每个元素都视为一个符号对其进行解析,dds是四字节视为一个符号,
   dqs是每8字节视为一个符号,dps是根据当前处理器架构来选择最合适的长度。
    0:000> dps rsp
    00000051`7af2fd70  00007ff6`52e32234 modifyAssem!`string'
    00000051`7af2fd78  00000051`7af2fd90
    00000051`7af2fd80  00000051`7af2e188
    00000051`7af2fd88  00000163`d631dfe1
    00000051`7af2fd90  00000000`00000003
    00000051`7af2fd98  00009dbe`de4a9d54
    00000051`7af2fda0  00000000`00000000
    00000051`7af2fda8  00007ff6`52e31384 modifyAssem!__scrt_common_main_seh+0x10c [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]

二十一、寄存器命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
1、查看寄存器的值
    0:004> r
    rax=0000000000000000 rbx=00007ff8d09a0000 rcx=00000000ffffffff
    rdx=000000000000fffc rsi=0000000000000000 rdi=0000000000267000
    rip=00007ff8aef7b33b rsp=0000000000e5ee50 rbp=0000000000e5ef50
     r8=0000000000000000  r9=0000000000e5ef50 r10=0000000000000000
    r11=0000000000000246 r12=0000000000000000 r13=0000000000000000
    r14=0000000000000000 r15=0000000000000000
    iopl=0         nv up ei pl nz na pe nc
    cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
    svnets!TurnoffFirewallOfVistaLater+0x24b:
    00007ff8`aef7b33b 488d4c2478      lea     rcx,[rsp+78h]
2、修改寄存器的值
    0:004> r rax=2
    0:004> r
    rax=0000000000000002 rbx=00007ff8d09a0000 rcx=00000000ffffffff
    rdx=000000000000fffc rsi=0000000000000000 rdi=0000000000267000
    rip=00007ff8aef7b33b rsp=0000000000e5ee50 rbp=0000000000e5ef50
     r8=0000000000000000  r9=0000000000e5ef50 r10=0000000000000000
    r11=0000000000000246 r12=0000000000000000 r13=0000000000000000
    r14=0000000000000000 r15=0000000000000000
    iopl=0         nv up ei pl nz na pe nc
    cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
    svnets!TurnoffFirewallOfVistaLater+0x24b:
    00007ff8`aef7b33b 488d4c2478      lea     rcx,[rsp+78h]
3、查看进程的入口地址
    查看进程入口地址
    0:000> r $exentry
    $exentry=00007ff652e313f4
    查找某地址最近的符号
    0:000> ln 00007ff652e313f4
    Browse module
    Set bu breakpoint
     [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp @ 15] (00007ff6`52e313f4)   modifyAssem!mainCRTStartup   |  (00007ff6`52e31408)   modifyAssem!__raise_securityfailure
        Exact matches:
        modifyAssem!mainCRTStartup (void)
4、查看指令指针寄存器
    0:000> r @$ip
    $ip=00007ff652e31118
5、查看当前函数的返回地址
    0:000> r $ra
    $ra=00007ff652e31384
    0:000> k
     # Child-SP          RetAddr           Call Site
    00 00000051`7af2fd70 00007ff6`52e31384 modifyAssem!main+0x38 [e:\mydemo\189_modifyassem\modifyassem\modifyassem\modifyassem.cpp @ 11]
    01 (Inline Function) --------`-------- modifyAssem!invoke_main+0x22 [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78]
    02 00000051`7af2fdb0 00007ffc`66387974 modifyAssem!__scrt_common_main_seh+0x10c [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
    03 00000051`7af2fdf0 00007ffc`6735a0b1 KERNEL32!BaseThreadInitThunk+0x14
    04 00000051`7af2fe20 00000000`00000000 ntdll!RtlUserThreadStart+0x21

二十二、通过notmyfault制造蓝屏dump,分析驱动调用堆栈(驱动被system进程调用)

1
2
3
4
5
6
7
8
9
10
11
12
13
1、首先启动和故障,设置为“完全内存转储”
2、运行systeminternal中的notmyfault64.exe选择crash页面->High IRQL fault(Kernel-mode)->点击按钮Crash
3、设置windbg符号,windbg打开dump文件
4、运行!process 0 0找到system进程的进程对象
    kd> !process 0 0
        **** NT ACTIVE PROCESS DUMP ****
        PROCESS fffffa800368e040
            SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
            DirBase: 00187000  ObjectTable: fffff8a0000017f0  HandleCount: 896.
            Image: System
5、查看进程的调用堆栈
    !process fffffa800368e040 7
6、搜索调用的函数名字QKNetFilter

二十三、windbg远程调试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    设置要点:调试服务器上设置符号路径,调试客户端上设置源代码路径。
    场景:
    PC1:调试服务器
    PC2: 调试客户端
1、    调试服务器设置的操作步骤
    a)    以管理员身份运行windbg
    b)    File->open executable 打开要调试的应用程序(如果程序已经运行,可以附加File->attach to a process)
    c)    在命令行中输入   .server tcp:port=9090
        或者命令行方式(注意可能有进程命令行参数):
        windbg –server tcp:port=9090 “C:\Program Files (x86)\qianxin\ifl\QaxEngManager.exe”
    d)    在被调试机器上设置pdb文件的路径(调试服务器不用设置“源代码路径”,在调试客户端上设置源码路径)
 
2、    调试客户端机器上的设置
    a)    设置源文件路径
    b)    连接到被调试机器上,选择File->connect to a remote session
        输入:
            tcp:server=192.168.1.100,port=9090
        或者采用命令行:
            windbg -remote tcp:port=9090,server=192.168.116.135
    c)    检查符号文件路径,好像连接成功后,
        会从调试服务器上自动同步到调试客户端上。无论如何确保和调试服务器上的符号路径一样就行了,
        调试客户端pdb路径必须和调试服务器上设置的符号路径一模一样,
        拷贝调试服务器的符号路径到调试客户端windbg上。否则在调试客户端不能下断点。
        假如调试服务器上pdb路径是C:\Users\sanganlei\Desktop\x68\Release,就要拷贝到调试客户端上,
        尽管调试客户端上不存在这个路径,也要原模原样拷贝。这个符号路径貌似自己不拷贝
        否则下不了断点!!!!!!!!!!调试客户端上不用存在pdb文件,只要在调试服务器上有pdb文件就行了)
    d)    打开源文件,File->Open Source File
    e)    按F9在源文件中下断点。
    f)    在命令行中输入g,即可命中断点,红色的是下断点的位置,粉红色是断点被命中的位置。

二十四、stl类型调试方法1(这些在windbg 10版本上可以,windbg6.12好像不行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1、根据map变量名称显示std::map的内容
    0:000> dx direct
    direct                 : { size=0x2 } [Type: std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >]
        [<Raw View>]     [Type: std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >]
        [comparator]     : less [Type: std::_Compressed_pair<std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::_Compressed_pair<std::allocator<std::_Tree_node<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,void *> >,std::_Tree_val<std::_Tree_simple_types<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >,1>,1>]
        [allocator]      : allocator [Type: std::_Compressed_pair<std::allocator<std::_Tree_node<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,void *> >,std::_Tree_val<std::_Tree_simple_types<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >,1>]
        [0x0]            : "sanganlei", "hello" [Type: std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >]
        [0x1]            : "yuyu", "zhognguo" [Type: std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >]
2、根据map地址和类型,显示std::map的内容
    a)根据map地址和类型,显示std::map的内容
        指令格式:dx @$myvar = ((map类型*)addr)
 
        0:000> dx @$myvar = ((std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > * ) 0x00cffec8)
        @$myvar = ((std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > * ) 0x00cffec8)                 : 0xcffec8 : { size=0x2 } [Type: std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > *]
            [<Raw View>]     [Type: std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >]
            [comparator]     : less [Type: std::_Compressed_pair<std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::_Compressed_pair<std::allocator<std::_Tree_node<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,void *> >,std::_Tree_val<std::_Tree_simple_types<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >,1>,1>]
            [allocator]      : allocator [Type: std::_Compressed_pair<std::allocator<std::_Tree_node<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,void *> >,std::_Tree_val<std::_Tree_simple_types<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >,1>]
            [0x1]            : "sanganlei", "hello" [Type: std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >]
            [0x2]            : "yuyu", "zhognguo" [Type: std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >]
 
    b)接着上一步显示map的second内容,循环次数根据上右边的个数填写。
        0:000> .for (r $t0 = 0 ; @$t0 < 5 ; r $t0 = @$t0+1) { dx @$myvar[0][@$t0].second }
        @$myvar[0][@$t0].second                  : "hello" [Type: std::basic_string<char,std::char_traits<char>,std::allocator<char> >]
            [<Raw View>]     [Type: std::basic_string<char,std::char_traits<char>,std::allocator<char> >]
            [size]           : 0x5 [Type: unsigned int]
            [capacity]       : 0xf [Type: unsigned int]
            [allocator]      : allocator [Type: std::_Compressed_pair<std::allocator<char>,std::_String_val<std::_Simple_types<char> >,1>]
            [0]              : 104 'h' [Type: char]
            [1]              : 101 'e' [Type: char]
            [2]              : 108 'l' [Type: char]
            [3]              : 108 'l' [Type: char]
            [4]              : 111 'o' [Type: char]

二十五、stl类型调试方法2

1
参考文档:软件调试经验中的:044_windbg通过插件查看stl类型.rar

二十六、windows堆调试命令(以下每一步都是独立的,没有关联关系)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
1、查看堆信息汇总(-s 只限制普通堆,不显示页堆信息)
    命令:!heap -s
2、查看当前进程的页堆列表(显示页堆)
    命令:!heap -p
        0:000> !heap -p
                active heaps:
                + 58b0000
                    ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
                  NormalHeap - 5ba0000
                      HEAP_GROWABLE
                + 59b0000
                    ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
                  NormalHeap - 5b70000
                      HEAP_GROWABLE HEAP_CLASS_1
                + 6370000
                    ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
                  NormalHeap - 5b90000
                      HEAP_GROWABLE HEAP_CLASS_1
                + 9300000
                    ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
                  NormalHeap - 94d0000
                      HEAP_GROWABLE HEAP_CLASS_1
 
        备注:“+”号后面是页堆句柄,对于每个DPH(页堆),堆管理器还会为其创建一个普通的堆,比如58b0000的普通堆是5ba0000
        如果!heap命令中不包含/p参数,那么列出的堆只包含每个DPH的普通堆,不包含DPH。
 
3、显示某个页堆的详细信息(页堆)
    命令:!heap -p -h 页堆句柄(上面带“+”号的)
 
4、显示某个堆的详细信息
    命令:!heap -a 堆句柄
 
5、查看某个地址所属的堆块
    命令:!heap -p -a addr
    备注:addr是malloc或者new返回的地址。
    0:000> !heap -p -a a87bfe8
        address 0a87bfe8 found in
        _DPH_HEAP_ROOT @ 58b1000
        in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                     9203a28:          a87bfe8               14 -          a87b000             2000
        773ba8b0 verifier!AVrfDebugPageHeapAllocate+0x00000240
        770ef1be ntdll!RtlDebugAllocateHeap+0x00000039
        770570f0 ntdll!RtlpAllocateHeap+0x000000f0
        77056e3c ntdll!RtlpAllocateHeapInternal+0x0000104c
        77055dde ntdll!RtlAllocateHeap+0x0000003e
        00e11233 testHeapOverflow!wmain+0x00000043
        00e11459 testHeapOverflow!__scrt_common_main_seh+0x000000fa
        76e9fa29 KERNEL32!BaseThreadInitThunk+0x00000019
        77077a9e ntdll!__RtlUserThreadStart+0x0000002f
        77077a6e ntdll!_RtlUserThreadStart+0x0000001b
    备注:如何找到某个addr所属的页堆
        a)首先!heap -p -a addr找到_DPH_HEAP_ROOT @ 58b1000
        b)然后找到_DPH_HEAP_ROOT 的普通堆NormalHeap
            命令dt _DPH_HEAP_ROOT 58b1000
            0:000> dt _DPH_HEAP_ROOT 58b1000
                ntdll!_DPH_HEAP_ROOT
                   +0x000 Signature        : 0xffeeddcc
                   +0x004 HeapFlags        : 2
                   +0x0b4 NormalHeap       : 0x05ba0000 Void
        c)然后通过普通堆NormalHeap找对应的页堆
            0:000> !heap -p
                active heaps:
                + 58b0000
                    ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
                  NormalHeap - 5ba0000
                      HEAP_GROWABLE
                + 59b0000
                    ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
                  NormalHeap - 5b70000
                      HEAP_GROWABLE HEAP_CLASS_1

二十七、如何分析堆栈出错的 dmp 文件,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
!analyze -v没有用的情况,解决这类问题,
看雪论坛中,我收藏了一篇文档:https://bbs.pediy.com/thread-51141.htm
分析出错的dmp文件要依靠两个命令:!teb和dps联合使用
1、先查看所有线程的堆栈信息,然后找出比较像出了问题的线程
    0:000> ~*kv
        0  Id: 62c.928 Suspend: 1 Teb: 7ffdf000 Unfrozen
        ChildEBP RetAddr  Args to Child             
        0012f3b8 7c92e9ab 7c86372c 00000002 0012f53c ntdll!KiFastSystemCallRet (FPO: [0,0,0])
        0012f3bc 7c86372c 00000002 0012f53c 00000001 ntdll!ZwWaitForMultipleObjects+0xc (FPO: [5,0,0])
        0012fb38 00401dda 0012fb74 0012ffb0 0012ffc0 kernel32!UnhandledExceptionFilter+0x8e4 (FPO: [Non-Fpo])
        0012fb48 00401198 c0000005 0012fb74 0040261b Dump01!_XcptFilter+0x13e
        0012ffc0 7c816fd7 011dd65c 011dd664 7ffd6000 Dump01!mainCRTStartup+0xd1
        0012fff0 00000000 004010c7 00000000 00000000 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo])
2、显示出错线程的 TEB 信息。
    0:000> !teb
        TEB at 7ffdf000
            ExceptionList:        0012fb28
            StackBase:            00130000
            StackLimit:           0012a000
            SubSystemTib:         00000000
            FiberData:            00001e00
            ArbitraryUserPointer: 00000000
            Self:                 7ffdf000
            EnvironmentPointer:   00000000
            ClientId:             0000062c . 00000928
            RpcHandle:            00000000
            Tls Storage:          00000000
            PEB Address:          7ffd6000
            LastErrorValue:       0
            LastStatusValue:      103
            Count Owned Locks:    0
        HardErrorMode:        0
3、根据堆栈的位置和大小,显示堆栈的所有内容(显示栈上的符号信息)
    dps的第一个参数是!teb命令显示的StackLimit,第二个参数是StackBase
    0:000> dps 0x0012a000 0x00130000

二十八、如何执行windbg脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1、执行windbg脚本demo
    .echo “hello windbg”
    这条命令会显示“hello windbg”这个字符串,把它保存到c:\1.txt文件,
    然后在Windbg的命令窗口里输入:$$><c:\1.txt回车
2、执行脚本的五种写法:
    $<Filename
    $><Filename
    $$< Filename
    $$>< Filename
    $$>a< Filename [arg1 arg2 arg3 ... ]
    1.'$'的表示'<'和脚本名之间不可以有空格。
    2.'$$'的表示可以有空格(其实我有点不太理解这个操蛋设定,为什么不能自动检测)。
    3.'<'表示不会自动把脚本文件压缩为一行。
    4.'><'表示会把他们压缩为一行,并将原来的换行变成';'
    5.最后一个表示可以给脚本传递参数。
    为什么要压缩成一行?问的好,Windbg执行某些命令的时候需要他们是一行,比如bp后面可以添加其他命令,
    但是所有命令写一行又太长了,不容易阅读,于是帮你压缩一下。
    一般我们用第4种$$><就够了。

[2022冬季班]《安卓高级研修班(网课)》月薪两万班招生中~

最后于 2022-8-31 11:07 被sanganlei编辑 ,原因:
收藏
点赞8
打赏
分享
最新回复 (6)
雪    币: 912
活跃值: 活跃值 (651)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
曹操abc 活跃值 2021-11-17 11:46
2
0
感谢分享
雪    币: 1531
活跃值: 活跃值 (2548)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
sanganlei 活跃值 2021-11-27 22:41
3
0
不客气
雪    币: 143
活跃值: 活跃值 (179)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
chengtao 活跃值 2022-5-19 08:44
4
0
有心了
雪    币: 3461
活跃值: 活跃值 (591)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
mb_ldtiaylu 活跃值 2022-8-24 10:52
5
0
感谢分享,收获颇多
雪    币: 25
活跃值: 活跃值 (240)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mb_kppjdiod 活跃值 2022-8-31 03:02
6
0
怎么下条件段点呢,我系统好多系统进程一直调用
于是bp ntsetinformationthread “j(process!=8000Xxxx)’’;’g’”
看教程测试了好久一样会被这个进程下段
雪    币: 5327
活跃值: 活跃值 (1978)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
sunsjw 活跃值 1 2022-8-31 08:59
7
0
收藏收藏,总结的到位。
游客
登录 | 注册 方可回帖
返回