反向 Mach-O 64 位 x86 汇编分析

Reversed Mach-O 64-bit x86 Assembly analysis

本题由Intel x86汇编专家解答。感谢您的提前努力!

问题说明

我正在分析一个二进制文件,它匹配 Mach-O 64 位 x86 程序集。我目前使用的是 MacOS64OS。程序集来自objdump.

问题是,当我学习汇编时,我可以看到变量名“$xxx”,我可以看到 ascii 中的字符串值,我还可以看到被调用者的名字,如 "call _printf"

但是在这个大会上,我什么也得不到:

  1. 无主要功能:

    Disassembly of section __TEXT,__text:
    __text:
    100000c90:  55  pushq   %rbp
    100000c91:  48 89 e5    movq    %rsp, %rbp
    100000c94:  48 83 ec 10     subq    , %rsp
    100000c98:  48 8d 3d bf 02 00 00    leaq    703(%rip), %rdi
    100000c9f:  b0 00   movb    [=10=], %al
    100000ca1:  e8 68 02 00 00  callq   616
    100000ca6:  89 45 fc    movl    %eax, -4(%rbp)
    100000ca9:  48 83 c4 10     addq    , %rsp
    100000cad:  5d  popq    %rbp
    100000cae:  c3  retq
    100000caf:  90  nop
    100000cb0:  55  pushq   %rbp  
    ...
    

    以上是会执行的代码框架,不知道具体执行到哪里

另外,我是 AT&T 的新手 assemble。因此,你能告诉我指令的含义是什么吗:

    0000000100000c90    pushq   %rbp
    0000000100000c98    leaq    0x2bf(%rip), %rdi       ## literal pool for: "xxxx\n"
    ...
    0000000100000cd0    callq   0x100000c90

这是一个循环吗?我不确定,但似乎是。以及为什么我们使用 %rip 和 %rdi 寄存器。在intel x86中我知道EIP代表当前调用者地址,但是我不明白这里的意思

  1. 调用整数: 无论他们使用什么调用约定,我从未见过像 "call 616":

    这样的代码模式
    "100000cd0: e8 bb ff ff ff  callq   -69 <__mh_execute_header+C90>"
    
  2. 退役后: ret 在英特尔 x86 中,意味着删除堆栈帧和 return 控制流到调用者。它应该是一个独立的功能。然而,在此之后,我们可以看到类似

    的代码
    100000cae:  c3  retq
    100000caf:  90  nop
    /* new function call */
    100000cb0:  55  pushq   %rbp
    ...
    

    太可笑了!

  3. ASCII 字符串丢失: 我已经查看了十六进制格式的二进制文件,并在将其反转为 asm 文件之前识别了一些 ascii 字符串。

但是,在此文件中没有出现任何 ascii 字符串!

  1. 总体架构审查:

    Disassembly of section __TEXT,__text:
    __text:
    from address 10000c90 to 100000ef6 of 145 lines
    
    Disassembly of section __TEXT,__stubs:
    __stubs:
    from address 100000efc to 100000f14 of 5 lines asm codes:
    100000efc:  ff 25 16 01 00 00   jmp qword ptr [rip + 278]
    100000f02:  ff 25 18 01 00 00   jmp qword ptr [rip + 280]
    100000f08:  ff 25 1a 01 00 00   jmp qword ptr [rip + 282]
    100000f0e:  ff 25 1c 01 00 00   jmp qword ptr [rip + 284]
    100000f14:  ff 25 1e 01 00 00   jmp qword ptr [rip + 286]
    
    Disassembly of section __TEXT,__stub_helper:
    __stub_helper:
    
    ...
    
    Disassembly of section __TEXT,__cstring:
    __cstring:
    
    ...
    
    Disassembly of section __TEXT,__unwind_info:
    __unwind_info:
    
    ...
    
    Disassembly of section __DATA,__nl_symbol_ptr:
    __nl_symbol_ptr:
    
    ...
    
    Disassembly of section __DATA,__got:
    __got:
    
    ...
    
    Disassembly of section __DATA,__la_symbol_ptr:
    __la_symbol_ptr:
    
    ...
    
    Disassembly of section __DATA,__data:
    __data:
    
    ...
    

由于可能是病毒,我无法执行。我应该如何分析它?

5 月 21 日更新

我已经确定输出在哪里,如果我完全理解这个程序中表示的数据流管道,我也许能够找出可能的解决方案。

如果有人能给我详细的解释,我将不胜感激。谢谢!

5 月 22 日更新

我在 VirtualBox 中安装了 MacOS,在获得 chmod 权限后,我执行了该程序,但除了出现两行输出之外没有什么特别的。结果隐藏在二进制文件中。

  1. 如果您不使用 C,则不需要 main。二进制 header 包含入口点地址。
  2. call 616没什么特别的,只是你没有(所有)符号。有点奇怪objdump没有给你计算地址,应该是0x100000ca6+616.
  3. 不确定你觉得那里有什么可笑的。一个函数结束,另一个函数开始。
  4. 这不是问题。是的,您可以在运行时创建字符串,这样您就不会在图像中包含它们。可能它们是加密的。