当我做安卓异常钩子时,如何通过地址判断汇编指令是ARM还是拇指?



当我做安卓异常钩子时,如何通过地址判断汇编指令是ARM还是拇指? 拇指的地址不是以"0"结尾吗? 当我将ARM切换到拇指时,我使用"BX targetaddr+1",但拇指地址仍然以"0"结尾。我不知道为什么。

void WriteillegalInstructionAndSaveOpcode(uint32_t addr, uint32_t    *OriginOpcode)
{
if(0x00000001 == (addr & 0x00000001))
{
g_bIsThumb = 1;
*OriginOpcode = *(uint32_t *)(addr & (~0x00000001));
//Thumb illegal instruction : 0xdeXX
uint32_t uiThumbillegalValue = 0x0000de00 | (0xFFFF0000 & *OriginOpcode);
write_data_to_addr(addr & (~0x00000001), uiThumbillegalValue);
}
else
{
g_bIsThumb = 0;
//Arm illegal instruction: 0xf7fXaXXX
*OriginOpcode = *(uint32_t *)addr;
uint32_t uiArmillegalValue = 0x7f000f0;
write_data_to_addr(addr, uiArmillegalValue);
}
LOGI("[+] g_bIsThumb is %08x n",g_bIsThumb);
LOGI("[+] WriteillegalInstruction addr: %08x, OriginalOpcode is %08x",addr & (~0x00000001), *OriginOpcode);
}

安卓,所以这是一个全尺寸的手臂,而不是一个皮层-M。 拇指指令是 16 位对齐在 16 位上的 16 位,拇指 2 是扩展,因此 16 位项目的可变数量(两个)。 所以一个 lsbit 的拇指是零。 ARM 指令为 32 位,必须对齐,因此两个 lsbit 必须为零。 当设置lsbit时,当您执行bx,blx或pop(或cortex-m中的向量表)时,使用该地址的指令/操作会剥离进入PC的lsbit,PC不包含正在设置的lsbit(用于拇指),cpsr而是反映了这一点。 当 bl 或 blx 发生时,lr 会获得 pc 加上两条指令,如果在拇指模式下,则设置 lsbit 否则清除。

我认为在全尺寸手臂上,但您必须检查 ARM ARM 或 ARM TRM 以了解 ARM 模式下的核心执行异常。

所以对于你的问题:

每个异常模式还具有一个保存的程序状态寄存器 (SPSR) 在异常之前保存任务的 CPSR 发生。

您应该检查 SPSR 以检查 T 位以查看您处于哪种模式(假设它是拇指或 ARM),然后根据异常检查您需要检查的内容以确定在这种情况下这个错误指令的地址,然后去阅读该项目。 如果它恰好是未在 32 位边界上对齐的拇指指令,请注意不要执行 32 位读取。

最新更新