0%

【Linux技术分享】通过逆向简单定位wine下的崩溃

通过Cutter等二进制分析工具协助分析wine下崩溃问题

  1. 实现一个简单的段错误代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <iostream>

    void fun()
    {
    int* p = NULL;
    *p = 32;
    }

    int main()
    {
    fun();
    return 0;
    }
  2. 通过wine下运行弹出debug的窗口
    图1

  3. 使用winedbg进行附加调试,在调试模式下崩溃,输入bt即可打印堆栈信息
    图2

    1
    2
    3
    4
    =>0 0x0045ca5f in consoleapplication1 (+0x5ca5f) (0x0031fde0)
    0x0045ca5f: 当前执行的指令地址(程序计数器 PC 的值)。
    (+0x5ca5f): 相对于模块基址的偏移量(这里是 consoleapplication1 的偏移量)。
    (0x0031fde0): 调用时的栈帧地址(Stack Frame Address),即该函数调用时栈顶指针(ESP)或基址指针(EBP)的值。
  4. 通过 /proc/pid/maps,在指定进程中查看elf文件加载信息
    图5

  5. 通过以上分析可以定位出错代码在consoleapplication1这个进程中,偏移量为+0x5ca5f
    图4
    图3

  6. 通过ida或者Cutter等二进制分析工具进行分析,本次使用的为Cutter

  7. 加载该exe后发现是从地址0x0040000开始加载
    图6

  8. 加上偏移量进行偏移定位,获取其反汇编内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    0x0045ca30      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
  9. 通过Cutter通过该汇编内容得到大致函数
    图8

  10. 通过Cutter工具即可定位此次崩溃原因,向地址 0(NULL)写入 0x20,这会导致 段错误。
    图9

    1
    2
    3
    mov 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.