【问题标题】:Questions on iPhone code disassemblyiPhone代码反汇编的问题
【发布时间】:2012-10-09 00:29:23
【问题描述】:

这是 syscall() 在 iPhone 上的反汇编。

(gdb) disass syscall
Dump of assembler code for function syscall:
0x3195fafc <syscall+0>: mov     r12, sp
0x3195fb00 <syscall+4>: push    {r4, r5, r6, r8}
0x3195fb04 <syscall+8>: ldm     r12, {r4, r5, r6}
0x3195fb08 <syscall+12>:        mov     r12, #0 ; 0x0
0x3195fb0c <syscall+16>:        svc     0x00000080
0x3195fb10 <syscall+20>:        pop     {r4, r5, r6, r8}
0x3195fb14 <syscall+24>:        bcc     0x3195fb2c <syscall+48>
0x3195fb18 <syscall+28>:        ldr     r12, [pc, #4]   ; 0x3195fb24 <syscall+40>
0x3195fb1c <syscall+32>:        ldr     r12, [pc, r12]
0x3195fb20 <syscall+36>:        b       0x3195fb28 <syscall+44>
0x3195fb24 <syscall+40>:        cfldrdeq        mvd15, [r12], #992
0x3195fb28 <syscall+44>:        bx      r12
0x3195fb2c <syscall+48>:        bx      lr
End of assembler dump.
  1. 谁能解释一下偏移量 +28,+32 处的指令在做什么?在 +28 处,r12 的值为 0(设置为 +12),因此看起来 r12 被设置为(在 C 表示法中)*(pc + 4)。在 +32 时,r12 设置为 *(pc + r12) - 请注意,该指令未编译 - 请参见下面的 #3。 +36 处的 'b' 跳转到 +44,返回到 r12 中的地址。那么 +28 和 +32 将什么值加载到 r12 中?

  2. +40 处的 cfldrdeq 指令有什么作用?我检查了 ARM 指令集并进行了搜索,但没有找到任何东西。

  3. 我使用 asm() 将此代码添加到我的 C 程序中。编译时,编译器会显示这些错误。知道如何解决这个问题吗?
    /var/folders/62/3px_xsd56ml5gz18lp8dptjc0000gv/T//ccDThXFx.s:7607:不能使用寄存器索引和PC相对寻址 -- ldr r12,[pc,r12]' /var/folders/62/3px_xsd56ml5gz18lp8dptjc0000gv/T//ccDThXFx.s:7609:selected processor does not supportcfldrdeq mvd15,[r12],#992'

【问题讨论】:

    标签: iphone arm disassembly


    【解决方案1】:

    如果您知道读取 PC 的小问题就更有意义了:大多数 读取 PC 的指令会看到 address_of_current_instruction+8 的值(除了 +4 在thumb 模式,ldm 在 ARM 模式下可能是 +8 或 +12 IIRC)。

    cfldrdeq mvd15, [r12], #992 不是指令;这是一个相对重定位,指向重定位 DATA 部分。在 DATA 部分中,将有一个指向实际地址的动态重定位。典型的伪代码看起来像这样

      ldr r12,[pc,#small_offset_to_foo]
      ldr r12,[pc,r12]
      bx r12
    
      ... a short distance away ...
    
    foo:
      int relative_offset_of_bar_from_the_second_ldr
      ... a galaxy far far away ...
    
    bar:
      int pointer_to_the_actual_syscall
    

    我不知道为什么syscall() 的反汇编将“foo”放在ldr r12,[pc,r12]bx r12 之间,导致分支越过非指令“foo”。

    还值得一提的是,简单地粘贴显示的代码几乎肯定行不通:您没有指向系统调用的实际实现的重定位(在调试器中,越过bx r12,您应该到达那里);你只会分支到一些随机的地址。

    错误“不能使用 PC 相对寻址的寄存器索引”显然是因为您在 Thumb 模式下编译(清单是 ARM 代码)。至于cfldrdeq,我相信它只是一个条件cfldrd 指令(“eq”是一个条件代码),Google 认为它与 Cirrus Logic“Maverick”处理器系列有关。

    【讨论】:

    • 感谢您的详细回复。系统调用不是通过'svc 0x00000080'指令完成的吗?
    • 我相信通常的助记符是swi(不确定Thumb),但这非常依赖于操作系统,我不知道细节(除了在Linux上,整数立即在该指令未使用以避免必须从内存中读取它)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多