DUMP文件分析4:栈溢出

来源:互联网 发布:hive sql union all 编辑:程序博客网 时间:2024/06/05 21:50

前面说到过,栈溢出类型的异常通过编程的方式获取DUMP可能不成功,因为栈溢出会破坏SEH(结构化异常处理)框架。实际上,通过DUMP文件来调试栈溢出同样是困难的,因为栈溢出本身一般不会造成异常,异常往往发生在栈溢出破坏栈上的数据之后,同时,由于栈溢出破坏了栈上的数据,使得我们无法对函数调用进行回溯,从而难以定位问题的发生位置。 
本节的示例是经dump1简单修改而来,在Crash Me!按钮的消息处理函数中,写下如下代码:

int a[10];for( int i = 0; i < 200; i++  )    a[i] = i;printf("%d\n", a[0]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

需要注意的是,Visual Studio针对栈溢出有保护措施,如果开启了保护措施,则栈溢出会被检测出来,例如: 
 
这里我们使用Release编译,并选择最大化速度优化代码,这样就不会添加栈溢出的检查代码。此时,再运行程序: 
 
就检查不到栈溢出了。同时,我们的MyUnhandledExceptionFilter函数也没有起作用,没有生成mini.dmp。因此,我们用任务管理器手动抓取DUMP文件。 
加DUMP文件加载到Windbg中,切换到32位模式,然后使用 !analyze -v进行分析:

WARNING: ole32 overlaps gdi32*** WARNING: symbols timestamp is wrong 0x569a9398 0x569a8dc2 for ole32.dll*** ERROR: Module load completed but symbols could not be loaded for mfc90.dll*** ERROR: Symbol file could not be found.  Defaulted to export symbols for msvcr90.dll - Cannot find frame 0x7c, previous scope unchangedFailed calling InternetOpenUrl, GLE=12029FAULTING_IP: wow64cpu!CpupReturnFromSimulatedCode+07476271e 6744            inc     espEXCEPTION_RECORD:  ffffffffffffffff -- (.exr 0xffffffffffffffff)ExceptionAddress: 0000000000000000   ExceptionCode: 80000003 (Break instruction exception)  ExceptionFlags: 00000000NumberParameters: 0FAULTING_THREAD:  00000000000014b0DEFAULT_BUCKET_ID:  STACKIMMUNEPROCESS_NAME:  dump2.exeOVERLAPPED_MODULE: Address regions for 'ole32' and 'gdi32' overlapERROR_CODE: (NTSTATUS) 0x80000003 - {EXCEPTION_CODE: (NTSTATUS) 0x80000003 (2147483651) - {MOD_LIST: <ANALYSIS/>NTGLOBALFLAG:  0APPLICATION_VERIFIER_FLAGS:  0CONTEXT:  ffffffffc0000005 -- (.cxr 0xffffffffc0000005)Unable to read context, HRESULT 0x80004002ADDITIONAL_DEBUG_TEXT:  Followup set based on attribute [Is_ChosenCrashFollowupThread] from Frame:[0] on thread:[PSEUDO_THREAD]LAST_CONTROL_TRANSFER:  from 00000000775b94cf to 000000007752f971PRIMARY_PROBLEM_CLASS:  STACKIMMUNEBUGCHECK_STR:  APPLICATION_FAULT_STACKIMMUNE_ZEROED_STACKSTACK_TEXT:  00000000`00000000 00000000`00000000 dump2.exe+0x0STACK_COMMAND:  .cxr 00000000001AE2D0 ; kb ; ** Pseudo Context ** ; kbSYMBOL_NAME:  dump2.exeFOLLOWUP_NAME:  MachineOwnerMODULE_NAME: dump2IMAGE_NAME:  dump2.exeDEBUG_FLR_IMAGE_TIMESTAMP:  579d6915FAILURE_BUCKET_ID:  STACKIMMUNE_80000003_dump2.exe!UnknownBUCKET_ID:  X64_APPLICATION_FAULT_STACKIMMUNE_ZEROED_STACK_dump2.exeFOLLOWUP_IP: dump2!__ImageBase+0003c0000 4d              dec     ebpWATSON_STAGEONE_URL:  http://watson.microsoft.com/StageOne/dump2_exe/1_0_0_1/579d6915/unknown/0_0_0_0/bbbbbbb4/80000003/00000000.htm?Retriage=1Followup: MachineOwner---------
  • 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

没有得到什么有价值的信息。通过 kb 命令查看一下栈: 
 
异常发生之后的栈还完好,之前的栈被破坏,已经解析不出来符号了。还记得上一节怎么做的吗?查看地址 0x39f230: 
 
异常代码是 C0000005,异常地址是 0000000a。实际上,Windbg有专门的指令来解析_EXCEPTION_RECORD结构,即 .exr,如下: 
 
来看看异常发生的地址: 
 
这个地址无法读取(实际上位于NULL的64KB内)。现在的问题是,是谁读取了这个地址?是取数据?还是取指令?(实际上.exr指令已经给出了答案)上节说到了函数KiUserExceptionDispatcher,它的一个参数是_EXCEPTION_RECORD结构的指针,另一个参数是CONTEXT结构的指针,也就是如下原型:

VOID NTAPI KiUserExceptionDispatcher( PEXCEPTION_RECORD ExceptionRecord,PCONTEXT Context);
  • 1
  • 2

从栈调用栈中可以找到这个CONTEXT的地址: 
 
来看看这个CONTEXT结构: 
 
其中保存了异常发生时的寄存器上下文。Windbg中有专门解析这个结构的指令 .cxr,我们来看看寄存器的值: 
 
看到EIP的值正是发生非法读取的地址,因此,可以判断是读指令的时候发生的异常。我们来看看栈被破坏的大概范围,使用的是dds指令,这个指令将地址范围内的符号进行解析:

0:000:x86> dds 39f568 39ffff0039f568  0000000b0039f56c  0000000c0039f570  0000000d0039f574  0000000e0039f578  0000000f0039f57c  000000100039f580  000000110039f584  000000120039f588  000000130039f58c  000000140039f590  000000150039f594  000000160039f598  000000170039f59c  000000180039f5a0  000000190039f5a4  0000001a0039f5a8  0000001b0039f5ac  0000001c0039f5b0  0000001d0039f5b4  0000001e0039f5b8  0000001f0039f5bc  000000200039f5c0  000000210039f5c4  000000220039f5c8  000000230039f5cc  000000240039f5d0  000000250039f5d4  000000260039f5d8  000000270039f5dc  000000280039f5e0  000000290039f5e4  0000002a0039f5e8  0000002b0039f5ec  0000002c0039f5f0  0000002d0039f5f4  0000002e0039f5f8  0000002f0039f5fc  000000300039f600  000000310039f604  000000320039f608  000000330039f60c  000000340039f610  000000350039f614  000000360039f618  000000370039f61c  000000380039f620  000000390039f624  0000003a0039f628  0000003b0039f62c  0000003c0039f630  0000003d0039f634  0000003e0039f638  0000003f0039f63c  000000400039f640  000000410039f644  000000420039f648  000000430039f64c  000000440039f650  000000450039f654  000000460039f658  000000470039f65c  000000480039f660  000000490039f664  0000004a0039f668  0000004b0039f66c  0000004c0039f670  0000004d0039f674  0000004e0039f678  0000004f0039f67c  000000500039f680  000000510039f684  000000520039f688  000000530039f68c  000000540039f690  000000550039f694  000000560039f698  000000570039f69c  000000580039f6a0  000000590039f6a4  0000005a0039f6a8  0000005b0039f6ac  0000005c0039f6b0  0000005d0039f6b4  0000005e0039f6b8  0000005f0039f6bc  000000600039f6c0  000000610039f6c4  000000620039f6c8  000000630039f6cc  000000640039f6d0  000000650039f6d4  000000660039f6d8  000000670039f6dc  000000680039f6e0  000000690039f6e4  0000006a0039f6e8  0000006b0039f6ec  0000006c0039f6f0  0000006d0039f6f4  0000006e0039f6f8  0000006f0039f6fc  000000700039f700  000000710039f704  000000720039f708  000000730039f70c  000000740039f710  000000750039f714  000000760039f718  000000770039f71c  000000780039f720  000000790039f724  0000007a0039f728  0000007b0039f72c  0000007c0039f730  0000007d0039f734  0000007e0039f738  0000007f0039f73c  000000800039f740  000000810039f744  000000820039f748  000000830039f74c  000000840039f750  000000850039f754  000000860039f758  000000870039f75c  000000880039f760  000000890039f764  0000008a0039f768  0000008b0039f76c  0000008c0039f770  0000008d0039f774  0000008e0039f778  0000008f0039f77c  000000900039f780  000000910039f784  000000920039f788  000000930039f78c  000000940039f790  000000950039f794  000000960039f798  000000970039f79c  000000980039f7a0  000000990039f7a4  0000009a0039f7a8  0000009b0039f7ac  0000009c0039f7b0  0000009d0039f7b4  0000009e0039f7b8  0000009f0039f7bc  000000a00039f7c0  000000a10039f7c4  000000a20039f7c8  000000a30039f7cc  000000a40039f7d0  000000a50039f7d4  000000a60039f7d8  000000a70039f7dc  000000a80039f7e0  000000a90039f7e4  000000aa0039f7e8  000000ab0039f7ec  000000ac0039f7f0  000000ad0039f7f4  000000ae0039f7f8  000000af0039f7fc  000000b00039f800  000000b10039f804  000000b20039f808  000000b30039f80c  000000b40039f810  000000b50039f814  000000b60039f818  000000b70039f81c  000000b80039f820  000000b90039f824  000000ba0039f828  000000bb0039f82c  000000bc0039f830  000000bd0039f834  000000be0039f838  000000bf0039f83c  000000c00039f840  000000c10039f844  000000c20039f848  000000c30039f84c  000000c40039f850  000000c50039f854  000000c60039f858  000000c70039f85c  00b455f80039f860  000000010039f864  00590f200039f868  000001110039f86c  00bb99300039f870  00b998900039f874  000000000039f878  001005d20039f87c  00000f200039f880  0039f8a40039f884  75b096d5 user32!SendMessageW+0x7f0039f888  00b455d00039f88c  000000000039f890  5b68855d mfc90+0x5855d0039f894  000003e80039f898  000209e60039f89c  000000000039f8a0  000000010039f8a4  0039f8bc0039f8a8  75b45feb user32!xxxButtonNotifyParent+0x660039f8ac  001005d20039f8b0  000001110039f8b4  000003e80039f8b8  000209e60039f8bc  0039f8e40039f8c0  75b4612c user32!xxxBNReleaseCapture+0x138
  • 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
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216

可以看到,在地址0039f884 之后又可以解析出来符号,所以,我们大概可以判断39f568-0039f884 之间的栈被破坏了。对于这个DUMP文件,我们能做的差不多就这些了。由于栈被破坏,我们无法再回溯函数调用,无法再进一步定位异常的位置。因此,DUMP文件由于是一种静止的快照,有点时候,只能作为一种辅助分析手段,要定位具体的原因,需要多个DUMP文件综合分析,还需要进行动态调试。

原创粉丝点击