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: (Thumb32) missing carry(CY) flag update with shift_carry #6568

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 ands.w, ands, bics, movs.w, mvns.w & mvns instructions for Thumb (ARM:LE:32:v8T).

According to the manual, these instructions update PSTATE.C with carry. However, we noticed that wasn't the case in SLEIGH.


e.g, for Thumb with,

Instruction: 0x10ea7000, ands.w r0,r0,r0, ror #0x1 initial_registers: { "r0": 0x80000000, "CY": 0x1, "ZR": 0x1 }

We get:

Hardware: { "CY": 0x0, "r0": 0x0 } Patched Spec: { "CY": 0x0, "r0": 0x0 } Existing Spec: { "r0": 0x0 }

and,

Instruction: 0x10f40000, ands r0,r0,#0x800000 initial_registers: { "r0": 0x0, "NG": 0x1, "ZR": 0x0, "CY": 0x1 }

We get:

Hardware: { "CY": 0x0, "NG": 0x0, "ZR": 0x1 } Patched Spec: { "CY": 0x0, "NG": 0x0, "ZR": 0x1 } Existing Spec: { "NG": 0x0, "ZR": 0x1 }

and,

Instruction: 0x30f40000, bics r0,r0,#0x800000 initial_registers: { "r0": 0xff7efffe, "ZR": 0x1, "CY": 0x1, "NG": 0x1 }

We get:

Hardware: { "CY": 0x0, "ZR": 0x0 } Patched Spec: { "CY": 0x0, "ZR": 0x0 } Existing Spec: { "ZR": 0x0 }

and,

Instruction: 0x5ff40000, movs.w r0,#0x800000 initial_registers: { "r0": 0xfe2182be, "ZR": 0x0, "CY": 0x1, "NG": 0x0 }

We get:

Hardware: { "CY": 0x0, "r0": 0x800000 } Patched Spec: { "CY": 0x0, "r0": 0x800000 } Existing Spec: { "r0": 0x800000 }

and,

Instruction: 0x7fea7000, mvns.w r0,r0, ror #0x1 initial_registers: { "r0": 0x0, "ZR": 0x0, "CY": 0x1, "NG": 0x1 }

We get:

Hardware: { "CY": 0x0, "r0": 0xffffffff } Patched Spec: { "CY": 0x0, "r0": 0xffffffff } Existing Spec: { "r0": 0xffffffff }

and,

Instruction: 0x7ff40000, mvns r0,#0x800000 initial_registers: { "r0": 0x3a737213, "ZR": 0x1, "CY": 0x1, "NG": 0x0 }

We get:

Hardware: { "CY": 0x0, "NG": 0x1, "ZR": 0x0,"r0": 0xff7fffff } Patched Spec: { "CY": 0x0, "NG": 0x1, "ZR": 0x0,"r0": 0xff7fffff } Existing Spec: { "NG": 0x1, "ZR": 0x0,"r0": 0xff7fffff }


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