2013-08-20 47 views
0

我正面临一个奇怪的问题,有点类似于this。我有一个Windows Phone 8原生DLL项目,主要是C++,但是在其中有一个ARM汇编源代码。源处于ARM模式(即不是Thumb)。 C++被编译为Thumb。WinPhone8支持ARM(非Thumb)吗?

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

我有例外的细节。异常代码是0xc000001d(无效操作),崩溃上下文结构中的PC值是0x696d5985。这在任何一种模式中都是不可能的 - 它没有对齐,零位就是一个。 BLX指令执行1b f0 0c eb - 如果您解密了,那么这是一个由两部分组成的Thumb式BLX,它具有4对齐的位移。崩溃上下文中的T标志是SET(CPSR = 0x60000010)。

我没有设备,但测试版测试人员的崩溃日志非常确凿。在调用汇编之前,我有一个调试日志记录。然后崩溃。

编辑: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,拥有一项专利,用于修改应用程序代码,从发布者到设备途径;这可能是原因。

+0

在构建库和应用程序时是否启用了所有必需的交互工作标志? –

+0

没有任何。 BLX命令表明工具链知道发生了什么。 –

+0

hmmmmm ....必须有我们不知道的东西。诚然,Thumb指令过去是非常有限的,但Thumb2是一种不同的动物,甚至比ARM模式更有效。我认为现在是时候转储ARM模式并转换到Thumb2模式的编码。 –

回答

2

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

这让我们对RT/WinPhone的越狱感到恼火,因为我们无法直接移植Chrome的JITter而无需破坏微软的PatchGuard。我们可以加载一个内核驱动程序来修补KeContextFromKframes,但之后PatchGuard会导致崩溃。

0

从拇指到手臂使用BLX时,不能得到未对齐的手臂地址。较低的两位由第二条指令决定。阅读手臂文档,你基本上有两个指令的第一个是:在LR的修改,其中PC是地址

0xF01B 

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

基本上第一条指令的结果,如果该指令加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你正在清理,所以LSb,但也有可能使未对齐地址。如果你没有正确计算r12中的目标地址,并且如果这不是arm代码,那么它不会工作。请张贴反汇编以及那将清楚地显示正在发生什么,也发布第一条指令或几条目标地址。

它看起来像你的异常代码告诉你,你的例外是拇指模式在拇指地址。请在该地址/附近发布反汇编代码。

2

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

THUMB 
ASMTest 
    mov r12, lr 
    blx a 
    mov lr, r12 
    bx lr 

    ALIGN 4 
    ARM 
a 
    bx lr 

在调试器下始终如一地崩溃,但运行正常时debuggerless(即没有中断,而在ARM模式。)。当我在ARM模式下插入一个带有0x10000迭代的空循环时,它在几次尝试中运行,然后崩溃。