通过Cutter等二进制分析工具协助分析wine下崩溃问题
实现一个简单的段错误代码
1
2
3
4
5
6
7
8
9
10
11
12
13
void fun()
{
int* p = NULL;
*p = 32;
}
int main()
{
fun();
return 0;
}通过wine下运行弹出debug的窗口
使用winedbg进行附加调试,在调试模式下崩溃,输入bt即可打印堆栈信息
1
2
3
4=>0 0x0045ca5f in consoleapplication1 (+0x5ca5f) (0x0031fde0)
0x0045ca5f: 当前执行的指令地址(程序计数器 PC 的值)。
(+0x5ca5f): 相对于模块基址的偏移量(这里是 consoleapplication1 的偏移量)。
(0x0031fde0): 调用时的栈帧地址(Stack Frame Address),即该函数调用时栈顶指针(ESP)或基址指针(EBP)的值。通过
/proc/pid/maps
,在指定进程中查看elf文件加载信息通过以上分析可以定位出错代码在
consoleapplication1
这个进程中,偏移量为+0x5ca5f
。通过ida或者Cutter等二进制分析工具进行分析,本次使用的为Cutter
加载该exe后发现是从地址
0x0040000
开始加载加上偏移量进行偏移定位,获取其反汇编内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
230x0045ca30 push ebp
0x0045ca31 mov ebp, esp
0x0045ca33 sub esp, 0xcc
0x0045ca39 push ebx
0x0045ca3a push esi
0x0045ca3b push edi
0x0045ca3c lea edi, [var_ch]
0x0045ca3f mov ecx, 3
0x0045ca44 mov eax, 0xcccccccc
0x0045ca49 rep stosd dword es:[edi], eax
0x0045ca4b mov ecx, 0x538067
0x0045ca50 call fcn.00458cce
0x0045ca55 mov dword [var_8h], 0
0x0045ca5c mov eax, dword [var_8h]
0x0045ca5f mov dword [eax], 0x20 ; 32
0x0045ca65 pop edi
0x0045ca66 pop esi
0x0045ca67 pop ebx
0x0045ca68 add esp, 0xcc
0x0045ca6e cmp ebp, esp
0x0045ca70 call fcn.00457fc2
0x0045ca75 mov esp, ebp
0x0045ca77 pop ebp通过Cutter通过该汇编内容得到大致函数
通过Cutter工具即可定位此次崩溃原因,向地址 0(NULL)写入 0x20,这会导致 段错误。
1
2
3mov dword [var_8h], 0:将 var_8h(ebp - 0x8)设为 0。
mov eax, dword [var_8h]:将 var_8h 的值(0)加载到 eax。
mov dword [eax], 0x20:尝试向 eax(0,即 NULL)写入 0x20.