NationalSecurityAgency / ghidra

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

AArch32: vst2 had out-of-range invalid varnode access #6584

Open Sleigh-InSPECtor opened 4 months ago

Sleigh-InSPECtor commented 4 months 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 vst2 instruction for both, AArch32 (ARM:LE:32:v8) & Thumb (ARM:LE:32:v8T).

According to the manual, it stores multiple 2-element structures from two or four registers stores multiple 2-element structures from two or four registers to memory, with interleaving. However, we noticed the output was incorrect for wrap-around lists.


e.g, for AArch32 with,

Instruction: 0x80e340f4, vst2.32 {d30,d31,d0,d1},[r0],r0 initial_registers: { "r0": 0xae105a0b, "q0": 0x46e281c2e7557311433b999db04a02b2, "q15": 0x8c704968646d2fbaf05bbb26405ac79c }

We get:

Hardware: { "r0": 0x5c20b416, 0xAE105A0B: 0x9c, 0xAE105A0C: 0xc7, 0xAE105A0D: 0x5a, 0xAE105A0E: 0x40, 0xAE105A0F: 0xb2, 0xAE105A10: 0x2, 0xAE105A11: 0x4a, 0xAE105A12: 0xb0, 0xAE105A13: 0x26, 0xAE105A14: 0xbb, 0xAE105A15: 0x5b, 0xAE105A16: 0xf0, 0xAE105A17: 0x9d, 0xAE105A18: 0x99, 0xAE105A19: 0x3b, 0xAE105A1A: 0x43, 0xAE105A1B: 0xba, 0xAE105A1C: 0x2f, 0xAE105A1D: 0x6d, 0xAE105A1E: 0x64, 0xAE105A1F: 0x11, 0xAE105A20: 0x73, 0xAE105A21: 0x55, 0xAE105A22: 0xe7, 0xAE105A23: 0x68, 0xAE105A24: 0x49, 0xAE105A25: 0x70, 0xAE105A26: 0x8c, 0xAE105A27: 0xc2, 0xAE105A28: 0x81, 0xAE105A29: 0xe2, 0xAE105A2A: 0x46 }

Patched Spec: { "r0": 0x5c20b416, 0xAE105A0B: 0x9c, 0xAE105A0C: 0xc7, 0xAE105A0D: 0x5a, 0xAE105A0E: 0x40, 0xAE105A0F: 0xb2, 0xAE105A10: 0x2, 0xAE105A11: 0x4a, 0xAE105A12: 0xb0, 0xAE105A13: 0x26, 0xAE105A14: 0xbb, 0xAE105A15: 0x5b, 0xAE105A16: 0xf0, 0xAE105A17: 0x9d, 0xAE105A18: 0x99, 0xAE105A19: 0x3b, 0xAE105A1A: 0x43, 0xAE105A1B: 0xba, 0xAE105A1C: 0x2f, 0xAE105A1D: 0x6d, 0xAE105A1E: 0x64, 0xAE105A1F: 0x11, 0xAE105A20: 0x73, 0xAE105A21: 0x55, 0xAE105A22: 0xe7, 0xAE105A23: 0x68, 0xAE105A24: 0x49, 0xAE105A25: 0x70, 0xAE105A26: 0x8c, 0xAE105A27: 0xc2, 0xAE105A28: 0x81, 0xAE105A29: 0xe2, 0xAE105A2A: 0x46 }

Existing Spec: { "r0": 0x5c20b416, 0xAE105A0B: 0x9c, 0xAE105A0C: 0xc7, 0xAE105A0D: 0x5a, 0xAE105A0E: 0x40, 0xAE105A0F: 0x0, 0xAE105A10: 0x0, 0xAE105A11: 0x0, 0xAE105A12: 0x0, 0xAE105A13: 0x26, 0xAE105A14: 0xbb, 0xAE105A15: 0x5b, 0xAE105A16: 0xf0, 0xAE105A17: 0x0, 0xAE105A18: 0x0, 0xAE105A19: 0x0, 0xAE105A1A: 0x0, 0xAE105A1B: 0xba, 0xAE105A1C: 0x2f, 0xAE105A1D: 0x6d, 0xAE105A1E: 0x64, 0xAE105A1F: 0x0, 0xAE105A20: 0x0, 0xAE105A21: 0x0, 0xAE105A22: 0x0, 0xAE105A23: 0x68, 0xAE105A24: 0x49, 0xAE105A25: 0x70, 0xAE105A26: 0x8c, 0xAE105A27: 0x0, 0xAE105A28: 0x0, 0xAE105A29: 0x0, 0xAE105A2A: 0x0 }


e.g, for Thumb with,

Instruction: 0x40f9b0e3, vst2.32 {d30,d31,d0,d1},[r0@256],r0 initial_registers: { "r0": 0x10139d40, "q0": 0xb3a0e47a454d03c22b1b204de5a2f9ce, "q15": 0x12f31f4b67e5b8806faea76746ddb53d }

We get:

Hardware: { "r0": 0x20273a80, 0x10139D40: 0x3d, 0x10139D41: 0xb5, 0x10139D42: 0xdd, 0x10139D43: 0x46, 0x10139D44: 0xce, 0x10139D45: 0xf9, 0x10139D46: 0xa2, 0x10139D47: 0xe5, 0x10139D48: 0x67, 0x10139D49: 0xa7, 0x10139D4A: 0xae, 0x10139D4B: 0x6f, 0x10139D4C: 0x4d, 0x10139D4D: 0x20, 0x10139D4E: 0x1b, 0x10139D4F: 0x2b, 0x10139D50: 0x80, 0x10139D51: 0xb8, 0x10139D52: 0xe5, 0x10139D53: 0x67, 0x10139D54: 0xc2, 0x10139D55: 0x3, 0x10139D56: 0x4d, 0x10139D57: 0x45, 0x10139D58: 0x4b, 0x10139D59: 0x1f, 0x10139D5A: 0xf3, 0x10139D5B: 0x12, 0x10139D5C: 0x7a, 0x10139D5D: 0xe4, 0x10139D5E: 0xa0, 0x10139D5F: 0xb3 }

Patched Spec: { "r0": 0x20273a80, 0x10139D40: 0x3d, 0x10139D41: 0xb5, 0x10139D42: 0xdd, 0x10139D43: 0x46, 0x10139D44: 0xce, 0x10139D45: 0xf9, 0x10139D46: 0xa2, 0x10139D47: 0xe5, 0x10139D48: 0x67, 0x10139D49: 0xa7, 0x10139D4A: 0xae, 0x10139D4B: 0x6f, 0x10139D4C: 0x4d, 0x10139D4D: 0x20, 0x10139D4E: 0x1b, 0x10139D4F: 0x2b, 0x10139D50: 0x80, 0x10139D51: 0xb8, 0x10139D52: 0xe5, 0x10139D53: 0x67, 0x10139D54: 0xc2, 0x10139D55: 0x3, 0x10139D56: 0x4d, 0x10139D57: 0x45, 0x10139D58: 0x4b, 0x10139D59: 0x1f, 0x10139D5A: 0xf3, 0x10139D5B: 0x12, 0x10139D5C: 0x7a, 0x10139D5D: 0xe4, 0x10139D5E: 0xa0, 0x10139D5F: 0xb3 }

Existing Spec: { "r0": 0x20273a80, 0x10139D40: 0x3d, 0x10139D41: 0xb5, 0x10139D42: 0xdd, 0x10139D43: 0x46, 0x10139D44: 0x0, 0x10139D45: 0x0, 0x10139D46: 0x0, 0x10139D47: 0x0, 0x10139D48: 0x67, 0x10139D49: 0xa7, 0x10139D4A: 0xae, 0x10139D4B: 0x6f, 0x10139D4C: 0x0, 0x10139D4D: 0x0, 0x10139D4E: 0x0, 0x10139D4F: 0x0, 0x10139D50: 0x80, 0x10139D51: 0xb8, 0x10139D52: 0xe5, 0x10139D53: 0x67, 0x10139D54: 0x0, 0x10139D55: 0x0, 0x10139D56: 0x0, 0x10139D57: 0x0, 0x10139D58: 0x4b, 0x10139D59: 0x1f, 0x10139D5A: 0xf3, 0x10139D5B: 0x12, 0x10139D5C: 0x0, 0x10139D5D: 0x0, 0x10139D5E: 0x0, 0x10139D5F: 0x0 }


This is an interesting case because unicorn execution is the same as existing spec and the Capstone disassembly for 0x80e340f4, vst2.32 {d30,d31,d0,d1},[r0],r0 and 0x40f9b0e3, vst2.32 {d30,d31,d0,d1},[r0@256],r0 instruction is vst2.32 {d30, d31, fpinst2, mvfr0}, [r0], r0 and vst2.32 {d30, d31, fpinst2, mvfr0}, [r0:0x100], r0 indicating similar issues in other popular tools.

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

GhidorahRex commented 4 months ago

It looks like we should be able to drop the & regInc from the vld2Dd sub-constructors in that case. It is no longer being used in the pcode.