0

这是在 armv7 上崩溃的 c 源代码行:

ret = fnPtr (param1, param2);

在调试器中,fnPtr 的地址为 0x04216c00。当我在指向上述语句的电脑上反汇编时,这是我得到的:

0x18918e:  movw   r0, #0x73c
0x189192:  movt   r0, #0x1
0x189196:  add    r0, r2
0x189198:  ldr    r0, [r0]
0x18919a:  str    r0, [sp, #0x20]
0x18919c:  ldr    r0, [sp, #0x20]
0x18919e:  ldr    r1, [sp, #0x28]
0x1891a0:  ldr    r2, [sp, #0x2c]
0x1891a2:  str    r0, [sp, #0x14]
0x1891a4:  mov    r0, r1
0x1891a6:  mov    r1, r2
0x1891a8:  ldr    r2, [sp, #0x14]
0x1891aa:  blx    r2

现在,当我反汇编地址 $r2 (=0x4216c00) 的内存时,我得到了看似有效的代码,应该毫无问题地执行:

(lldb) disassemble -s 0x4216c00 -C 10
   0x4216c00:  push   {r4, r5, r6, r7, lr}
   0x4216c04:  add    r7, sp, #0xc
   0x4216c08:  push   {r8, r10, r11}
   0x4216c0c:  vpush  {d8, d9, d10, d11, d12, d13, d14, d15}
   0x4216c10:  sub    r7, r7, #0x280
   0x4216c14:  mov    r6, r0
   0x4216c18:  bx     r1
   0x4216c1c:  add    r7, r7, #0x280

然而,真正发生的是:

EXC_BAD_ACCESS(代码=2,地址=0x4216c00)

谁能解释什么是错的以及为什么该地址被认为是非法的?

全面披露:我不是装配专家。编译和链接的代码都是 c 代码。编译器是clang。

4

2 回答 2

1

Check the value of r2 before calling executing blx instruction. It might be odd, telling the cpu that address is in thumb mode however from the listing it looks like in arm mode.

Try forcing clang to only arm mode by -mno-thumb to test this.

于 2014-09-01T19:18:30.727 回答
1

EXC_BAD_ACCESS异常里面有两位数据,第一位是描述访问失败的“kern_return_t”号,第二位是访问的地址。在您的情况下,代码为 2,这意味着(来自 /usr/include/mach/kern_return.h):

#define KERN_PROTECTION_FAILURE         2
                /* Specified memory is valid, but does not permit the
                 * required forms of access.
                 */

不知道为什么会这样,听起来你正在尝试执行没有执行权限集的代码。有什么作用:

(lldb) image lookup -va 0x4216c00

说?

顺便说一句,异常类型在 /usr/include/mach/exception_types.h 中,如果代码具有特定于机器的含义,则它们将在例如 /usr/include/mach/i386/exception.h 中)对于 ARM 信息,您可能需要查看 Xcode SDK 中的标头。

于 2014-09-02T20:07:50.327 回答