我在我的一个ARM目标[x86]中遇到了一个奇怪的崩溃。 Windbg崩溃指向非法内存访问。
DRIVER_IRQL_NOT_LESS_OR_EQUAL(d1)
尝试访问一个可分页(或完全无效)的地址 中断请求级别(IRQL)太高。这通常是 由司机使用不正确的地址引起的。
参数: Arg1:00000000,引用内存
Arg2:00000002,IRQL
Arg3:00000000,值0 =读操作,1 =写操作
Arg4:8849fe99,引用内存的地址
这清楚地告诉我,我正在尝试在指令0x8849fe99处访问内存0x00000000。 拆分0x8849fe99代码给出:
8849fe98 8818 ldrh r0,[r3]
注册转储显示:
r0=00000000 r1=8458ac70 r2=00000000 r3=00000000 r4=00000000 r5=00000000
r6=00000000 r7=00000000 r8=00000000 r9=00000000 r10=00000000 r11=8458ac20
r12=b7edbed9 sp=8458ac18 lr=8849fe8b pc=8849fe98 psr=400000b3 -Z--- Thumb
8849fe98 8818 ldrh r0,[r3] 00000000=????
所以,我试图访问R3的内存内容 - 但R3是0x0000000 - 完全合乎逻辑。
但是这里有趣的部分.. 我尝试检查内存周围的代码并找到以下拆卸。
8849fe94 4620 mov r0,r4
8849fe96 e8bd8818 pop {r3,r4,r11,pc}
8849fe9a 0000 movs r0,r0
8849fe9c 0000 movs r0,r0
8849fe9e 0000 movs r0,r0
从上面的代码我注意到0x8849FE96处的代码是32位指令,应该一次执行。
但是调试器显示它尝试执行一个16位指令(在0x8849FE98处) - 这根本不是预期的!
显然,我有一个32位指令执行有效操作,但为什么我的ARM认为它是16位指令并将我的完整理智指令[e8bd8818]分成两半并执行一个16位指令[8818]?
代码正在THUMB模式下执行 - 这意味着处理器应该知道何时应该以16位模式执行指令以及何时处于32位模式。
为什么处理器将指令视为16位?