【问题标题】:Is ARM (not Thumb) supported on WinPhone8 at all?WinPhone8 是否完全支持 ARM(不是 Thumb)?
【发布时间】:2013-08-20 20:30:01
【问题描述】:

我遇到了一个奇怪的问题,有点类似于this。我有一个 Windows Phone 8 本机 DLL 项目,主要是 C++,但其中包含 ARM 程序集源。源处于 ARM 模式(即不是 Thumb)。 C++ 编译为 Thumb。

当 C++ 尝试调用汇编例程时,应用程序崩溃。反汇编中的调用命令是带有立即偏移量的 BLX - 它应该无条件地将模式切换回 ARM,但不知何故它没有。

我有异常的详细信息。异常代码为0xc000001d(无效操作),crash context struct中PC的值为0x696d5985。这在任何一种模式下都是不可能的——它没有对齐,零位是一。 BLX 指令是1b f0 0c eb - 如果你破译,那是一个两部分的拇指式 BLX,好吧,有一个 4 对齐的位移。崩溃上下文中的 T 标志为 SET (CPSR=0x60000010)。

我没有设备,但来自 Beta 测试人员的崩溃日志非常有说服力。在调用程序集之前我有一个调试日志记录。然后是崩溃。

编辑:related。然而,他们声称汇编程序本身 (armasm) 将 ARM 转换为 Thumb。对我来说不是这样——至少不是静态的。 DLL 包含正确的 ARM 代码,如程序集源 (CODE32) 中所指定。

编辑:尝试使用稍微不同的跳转顺序:

ldr r12, target
and r12, r12, #0xfffffffe ; To be sure
bx r12 ;BX to a register with a cleared 0th bit. Doesn't get any more explicit than that.

同样的结果。看起来商店中某处发生了一些奇怪的代码变形,或者操作系统本身捕获了模式切换并阻止了它们。

可以通过将部分可执行文件连同其他崩溃数据一起转储到崩溃日志中来检测代码变形。但是,除了将整个代码库转换为 Thumb 之外,我还能如何处理操作系统干扰?它不只是重新编译。

为 dwelch 编辑:编译后的 C 代码中的调用顺序如下:

.text:1000A35E                 MOV             R2, #g_Host ;Three parameters
.text:1000A366                 MOV             R1, R5
.text:1000A368                 MOV             R0, R6
.text:1000A36A                 BLX             Func ; Code bytes 1B F0 0C EB

BLX 到立即地址必须切换模式。它不是有条件的,例如bx register。调用目标是一个 thunk:

.text:10025984                 B               Func_Impl

崩溃地址是这个 thunk 加一:5985。

这是已编译 DLL 的反汇编,但我不能保证这正是设备上正在执行的内容。链接的 MSDN 线程中的用户声称他们查看了 调试器中的反汇编,并看到了 ARM 应该在的地方。微软,IIRC,拥有从发布者到设备修改应用程序代码途中的专利;可能是这个原因。

【问题讨论】:

  • 在构建库和应用程序时,您是否启用了所有必要的互通标志?
  • 没有。 BLX 命令表明工具链知道发生了什么。
  • hmmmmm....一定有我们不知道的东西。诚然,Thumb 指令曾经非常有限,但 Thumb2 是另一种动物,甚至比 ARM 模式更有效。我认为是时候放弃 ARM 模式并改用 Thumb2 模式编码了。

标签: assembly windows-phone-8 arm thumb seh


【解决方案1】:

我对此有第一手的了解;我是在 Windows RT 内核中找出原因的逆向工程师。具体来说,Windows NT 内核 (ntoskrnl.exe) 中的KeContextFromKframes 在冻结任务切换的线程状态时设置T 位。这意味着是的,在中断后恢复时,您将崩溃。

这惹恼了我们的 RT/WinPhone 越狱者,因为我们无法在不破坏 Microsoft 的 PatchGuard 的情况下直接移植 Chrome 的 JITter。我们可以加载一个内核驱动程序来修补这个 KeContextFromKframes,但是 PatchGuard 稍后会导致崩溃。

【讨论】:

    【解决方案2】:

    一位名叫 Michael Schnell suggested elsewhere 的先生表示,Windows Phone 8 中的中断处理程序不会恢复 Thumb 标志,而是将其硬编码为 1。测试似乎证实了这一理论。以下sn-p:

        THUMB
    ASMTest
        mov r12, lr
        blx a
        mov lr, r12
        bx lr
    
        ALIGN 4
        ARM
    a
        bx lr
    

    在调试器下始终崩溃,但在无调试器时按预期运行(即在 ARM 模式下没有中断)。当我在 ARM 模式下插入一个具有 0x10000 次迭代的空循环时,它运行了几次,然后崩溃了。

    【讨论】:

      【解决方案3】:

      从拇指到手臂使用 BLX 时,您无法获得未对齐的手臂地址。低两位由第二条指令与。阅读 arm 文档,您基本上有两个说明,第一个是:

      0xF01B
      
      if H == 10 then
      LR = PC + (SignExtend(offset_11) << 12)
      

      基本上第一条指令会导致 lr 的修改,其中 pc 是该指令加上 4 的地址(前两条指令)。

      LR = PC + 0x1B000
      

      第二个是

      0xEB0C
      
      if H == 01 then
      PC = (LR + (offset_11 << 1)) AND 0xFFFFFFFC
      LR = (address of next instruction) | 1
      CPSR T bit = 0
      

      最终结果是

      PC = (address of next instruction + 0x1B000 + 0x318) AND 0xFFFFFFFC
      PC = (address of next instruction + 0x1B318) AND 0xFFFFFFFC
      LR = address of next instruction | 1
      CPSR T bit = 0, arm mode.
      

      我认为您的崩溃发生在其他地方。

      您应该发布相关代码的反汇编,指令地址等。

      就你的 BX 尝试而言,你正在走一个滑坡……

      ARM/Thumb state transfers
      If Rm[1:0] == 0b10, the result is UNPREDICTABLE, as branches to non word-aligned
      addresses are impossible in ARM state.
      

      通过与 1110 进行与运算,您正在清除 lsbit,但也可能允许未对齐的地址。如果您没有正确计算 r12 中的目标地址,并且如果那不是 arm 代码,那么它将无法工作。请张贴这个和那个的反汇编,将清楚地显示发生了什么,还张贴第一条指令或几个目标地址。

      您的异常代码似乎在告诉您,您的异常在拇指地址处处于拇指模式。请在该地址/附近发布代码的反汇编。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-20
        • 2017-05-31
        • 1970-01-01
        • 1970-01-01
        • 2022-07-19
        • 2015-11-28
        • 2018-07-14
        相关资源
        最近更新 更多