NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
49.09k stars 5.65k forks source link

AArch32: STR/STRT had missing offset when rt/rd is PC #6588

Open Sleigh-InSPECtor opened 1 month ago

Sleigh-InSPECtor commented 1 month ago

As part of a research project testing the accuracy of the SLEIGH specifications compared to real hardware, we observed an unexpected behaviour in the STR and STRT instructions for AArch32 (ARM:LE:32:v8).

According to the manual,

STR (immediate): Calculates an address from a base register value and an immediate offset, and stores a word from a register to memory.

STRT: Store Register Unprivileged stores a word from a register to memory.

However, we noticed the output was incorrect when rd/rt is PC.


e.g, for AArch32 with,

Instruction: 0xffff0ed4, strle pc,[lr],#-0xfff initial_registers: { "lr": 0x1ad1f844, "pc": 0x10000000, "NG": 0x1, "OV": 0x0 }

We get:

Hardware: { "lr": 0x1ad1e845, 0x1AD1F844: 0x8, 0x1AD1F845: 0x0, 0x1AD1F846: 0x0, 0x1AD1F847: 0x10 } Patched Spec: { "lr": 0x1ad1e845, 0x1AD1F844: 0x8, 0x1AD1F845: 0x0, 0x1AD1F846: 0x0, 0x1AD1F847: 0x10 } Existing Spec: { "lr": 0x1ad1e845, 0x1AD1F844: 0x0, 0x1AD1F845: 0x0, 0x1AD1F846: 0x0, 0x1AD1F847: 0x10 }

and,

Instruction: 0xffff2ed4, strtle pc,[lr],#-0xfff initial_registers: { "lr": 0x4122325b, "pc": 0x10000000, "NG": 0x1, "OV": 0x0 }

We get:

Hardware: { "lr": 0x4122225c, 0x4122325B: 0x8, 0x4122325C: 0x0, 0x4122325D: 0x0, 0x4122325E: 0x10 } Patched Spec: { "lr": 0x4122225c, 0x4122325B: 0x8, 0x4122325C: 0x0, 0x4122325D: 0x0, 0x4122325E: 0x10 } Existing Spec: { "lr": 0x4122225c, 0x4122325B: 0x0, 0x4122325C: 0x0, 0x4122325D: 0x0, 0x4122325E: 0x10 }


In Thumb mode (ARM:LE:32:v8T), if rd/rt is PC, it results in UNPREDICTABLE behaviour and so is the case for other variants like STRB. However, in the cases above this is permissible.

Note: The patched spec does not introduce any disassembly changes to the best of our knowledge.