diff --git a/README.md b/README.md new file mode 100644 index 0000000..edd6d75 --- /dev/null +++ b/README.md @@ -0,0 +1,59 @@ +# AMIE + +**A** **M**inimalist **I**nstruction **E**xtender + +AMIE is a Python rework of [FRIEND](https://github.com/alexhude/FRIEND/) that focuses solely on the ARM architecture (only AArch32 and AArch64 are supported). It is both lightweight and dependency-free, and provides the most relevant and up-to-date information about the ARM system registers and instructions. + +## Features + +### Improved processor modules + +For `MCR/MRC` and `MCRR/MRCC` instructions on AArch32, and for `MSR/MRS` and `SYS` instructions on AArch64, the system register encoding is detected and replaced by its user-friendly name in the *IDA View* subview. + +

+ +For `MCR/MRC` and `MSR/MRS` instructions, it also applies to the *Pseudocode* subview. + +

+ +### Hints for instructions and registers + +Hovering over a system register in the *IDA View* subview or in the *Pseudocode* subview will display a summary (usually kept under 30 lines) of the relevant documentation page, including the bitfield when available. + +

+ +Hovering over an instruction mnemonic in the *IDA View* subview or in the *Pseudocode* subview will also display a summary of the relevant documentation page, and the relevant assembly template when available. + +

+ +### Auto-generated resource files + +The biggest difference with FRIEND is that the resource files (`aarch32.json` and `aarch64.json`) are auto-generated from the [Exploration Tools](https://developer.arm.com/products/architecture/cpu-architecture/a-profile/exploration-tools). The system registers and instructions (documentation and encodings) are extracted by a home-made script that parses the ARM-provided XML files. + +## Installation + +Copy the plugin file `amie.py`, and its resource files `aarch32.json` and `aarch64.json` to your plugins directory or your user plugins directory (if you want to share it between multiple IDA Pro versions). These are the default paths: + +OS | Plugins Directory | User Plugins Directory +--------|--------------------------------------------|------------------------------------- +Windows | `%PROGRAMFILES%\IDA 7.2\plugins` | `%APPDATA%\Hex-Rays\IDA Pro\plugins` +Linux | `~/ida-7.2/plugins` | `~/.idapro/plugins` +macOS | `/Applications/IDA Pro 7.2/idabin/plugins` | `~/.idapro/plugins` + +## Dependencies + +There are no dependencies! :-) + +## Improvements + +Support for implementation-defined system registers is not available yet. + +There is no Hex-Rays support for `MCRR/MRCC` as this is an IDA Pro limitation. + +## Credits + +* [alexhude](https://github.com/alexhude) for creating the [FRIEND](https://github.com/alexhude/FRIEND/) plugin; +* [gdelugre](https://github.com/gdelugre/) for creating the [ida-arm-system-highlight](https://github.com/gdelugre/ida-arm-system-highlight/) script; +* The good folks at ARM for releasing the [Exploration Tools](https://developer.arm.com/products/architecture/cpu-architecture/a-profile/exploration-tools); +* [patateqbool](https://github.com/patateqbool) and [0xpanda](https://github.com/0xpanda) for testing the plugin and reporting bugs; +* Quarkslab for allowing this release. diff --git a/aarch32.json b/aarch32.json new file mode 100644 index 0000000..1317b33 --- /dev/null +++ b/aarch32.json @@ -0,0 +1,13942 @@ +{ + "instructions": { + "base": { + "ADC_i": { + "authored": "Add with Carry (immediate) adds an immediate value and the Carry flag value to a\nregister value, and writes the result to the destination register.\n\nIf the destination register is not the PC, the ADCS variant of the instruction\nupdates the condition flags based on the result.\n\nThe field descriptions for identify the encodings where the PC is permitted\nas the destination register. ARM deprecates any use of these encodings. However,\nwhen the destination register is the PC:\n - The ADC variant of the instruction is an interworking branch, see Pseudocode\ndescription of operations on the AArch32 general-purpose registers and the PC.\n - The ADCS variant of the instruction performs an exception return without the\nuse of the stack. In this case:\n - The PE branches to the address written to the PC, and restores PSTATE from\nSPSR_.\n - The PE checks SPSR_ for an illegal return event. See Illegal\nreturn events from AArch32 state.\n - The instruction is undefined in Hyp mode.\n - The instruction is constrained unpredictable in User mode and System mode.", + "heading": "ADC, ADCS (immediate)", + "templates": { + "A1": [ + "ADC{}{} {,} , #", + "ADCS{}{} {,} , #" + ], + "T1": [ + "ADC{}{} {,} , #", + "ADCS{}{} {,} , #" + ] + } + }, + "ADC_r": { + "authored": "Add with Carry (register) adds a register value, the Carry flag value, and an\noptionally-shifted register value, and writes the result to the destination\nregister.\n\nIf the destination register is not the PC, the ADCS variant of the instruction\nupdates the condition flags based on the result.\n\nThe field descriptions for identify the encodings where the PC is permitted\nas the destination register. ARM deprecates any use of these encodings. However,\nwhen the destination register is the PC:\n - The ADC variant of the instruction is an interworking branch, see Pseudocode\ndescription of operations on the AArch32 general-purpose registers and the PC.\n - The ADCS variant of the instruction performs an exception return without the\nuse of the stack. In this case:\n - The PE branches to the address written to the PC, and restores PSTATE from\nSPSR_.\n - The PE checks SPSR_ for an illegal return event. See Illegal\nreturn events from AArch32 state.\n - The instruction is undefined in Hyp mode.\n - The instruction is constrained unpredictable in User mode and System mode.", + "heading": "ADC, ADCS (register)", + "templates": { + "A1": [ + "ADC{}{} {,} , , RRX", + "ADC{}{} {,} , {, #}", + "ADCS{}{} {,} , , RRX", + "ADCS{}{} {,} , {, #}" + ], + "T1": [ + "ADC{} {,} , ", + "ADCS{} {,} , " + ], + "T2": [ + "ADC{}{} {,} , , RRX", + "ADC.W {,} , ", + "ADC{}{} {,} , {, #}", + "ADCS{}{} {,} , , RRX", + "ADCS.W {,} , ", + "ADCS{}{} {,} , {, #}" + ] + } + }, + "ADC_rr": { + "authored": "Add with Carry (register-shifted register) adds a register value, the Carry flag\nvalue, and a register-shifted register value. It writes the result to the\ndestination register, and can optionally update the condition flags based on the\nresult.", + "heading": "ADC, ADCS (register-shifted register)", + "templates": { + "A1": [ + "ADCS{}{} {,} , , ", + "ADC{}{} {,} , , " + ] + } + }, + "ADD_ADR": { + "authored": " adds an immediate value to the Align(PC, 4) value to form a PC-relative\naddress, and writes the result to the destination register. ARM recommends\nthat, where possible, software avoids using this alias", + "heading": "ADD (immediate, to PC)", + "templates": { + "A1": [ + "ADD{}{} , PC, #" + ], + "T1": [ + "ADD{}{} , PC, #" + ], + "T3": [ + "ADDW{}{} , PC, #", + "ADD{}{} , PC, #" + ] + } + }, + "ADD_SP_i": { + "authored": "Add to SP (immediate) adds an immediate value to the SP value, and writes the\nresult to the destination register.\n\nIf the destination register is not the PC, the ADDS variant of the instruction\nupdates the condition flags based on the result.\n\nThe field descriptions for identify the encodings where the PC is permitted\nas the destination register. However, when the destination register is the PC:\n - The ADD variant of the instruction is an interworking branch, see Pseudocode\ndescription of operations on the AArch32 general-purpose registers and the PC.\n - The ADDS variant of the instruction performs an exception return without the\nuse of the stack. ARM deprecates use of this instruction. However, in this case:\n - The PE branches to the address written to the PC, and restores PSTATE from\nSPSR_.\n - The PE checks SPSR_ for an illegal return event. See Illegal\nreturn events from AArch32 state.\n - The instruction is undefined in Hyp mode.\n - The instruction is constrained unpredictable in User mode and System mode.", + "heading": "ADD, ADDS (SP plus immediate)", + "templates": { + "A1": [ + "ADD{}{} {,} SP, #", + "ADDS{}{} {,} SP, #" + ], + "T1": [ + "ADD{}{} , SP, #" + ], + "T2": [ + "ADD{}{} {SP,} SP, #" + ], + "T3": [ + "ADD{}.W {,} SP, #", + "ADD{}{} {,} SP, #", + "ADDS{}{} {,} SP, #" + ], + "T4": [ + "ADD{}{} {,} SP, #", + "ADDW{}{} {,} SP, #" + ] + } + }, + "ADD_SP_r": { + "authored": "Add to SP (register) adds an optionally-shifted register value to the SP value,\nand writes the result to the destination register.\n\nIf the destination register is not the PC, the ADDS variant of the instruction\nupdates the condition flags based on the result.\n\nThe field descriptions for identify the encodings where the PC is permitted\nas the destination register. ARM deprecates any use of these encodings. However,\nwhen the destination register is the PC:\n - The ADD variant of the instruction is an interworking branch, see Pseudocode\ndescription of operations on the AArch32 general-purpose registers and the PC.\n - The ADDS variant of the instruction performs an exception return without the\nuse of the stack. In this case:\n - The PE branches to the address written to the PC, and restores PSTATE from\nSPSR_.\n - The PE checks SPSR_ for an illegal return event. See Illegal\nreturn events from AArch32 state.\n - The instruction is undefined in Hyp mode.\n - The instruction is constrained unpredictable in User mode and System mode.", + "heading": "ADD, ADDS (SP plus register)", + "templates": { + "A1": [ + "ADD{}{} {,} SP, , RRX", + "ADD{}{} {,} SP, {, #}", + "ADDS{}{} {,} SP, , RRX", + "ADDS{}{} {,} SP, {, #}" + ], + "T1": [ + "ADD{}{} {,} SP, " + ], + "T2": [ + "ADD{}{} {SP,} SP, " + ], + "T3": [ + "ADD{}{} {,} SP, , RRX", + "ADD{}.W {,} SP, ", + "ADD{}{} {,} SP, {, #}", + "ADDS{}{} {,} SP, , RRX", + "ADDS{}{} {,} SP, {, #}" + ] + } + }, + "ADD_i": { + "authored": "Add (immediate) adds an immediate value to a register value, and writes the\nresult to the destination register.\n\nIf the destination register is not the PC, the ADDS variant of the instruction\nupdates the condition flags based on the result.\n\nThe field descriptions for identify the encodings where the PC is permitted\nas the destination register. If the destination register is the PC:\n - The ADD variant of the instruction is an interworking branch, see Pseudocode\ndescription of operations on the AArch32 general-purpose registers and the PC.\n - The ADDS variant of the instruction performs an exception return without the\nuse of the stack. ARM deprecates use of this instruction. However, in this case:\n - The PE branches to the address written to the PC, and restores PSTATE from\nSPSR_.\n - The PE checks SPSR_ for an illegal return event. See Illegal\nreturn events from AArch32 state.\n - The instruction is undefined in Hyp mode.\n - The instruction is constrained unpredictable in User mode and System mode.", + "heading": "ADD, ADDS (immediate)", + "templates": { + "A1": [ + "ADD{}{} {,} , #", + "ADDS{}{} {,} , #" + ], + "T1": [ + "ADD{} , , #", + "ADDS{} , , #" + ], + "T2": [ + "ADD{} , #", + "ADD{} {,} , #", + "ADDS{} , #", + "ADDS{} {,} , #" + ], + "T3": [ + "ADD.W {,} , #", + "ADD{}{} {,} , #", + "ADDS.W {,} , #", + "ADDS{}{} {,} , #" + ], + "T4": [ + "ADD{}{} {,} , #", + "ADDW{}{} {,} , #" + ] + } + }, + "ADD_r": { + "authored": "Add (register) adds a register value and an optionally-shifted register value,\nand writes the result to the destination register.\n\nIf the destination register is not the PC, the ADDS variant of the instruction\nupdates the condition flags based on the result.\n\nThe field descriptions for identify the encodings where the PC is permitted\nas the destination register. If the destination register is the PC:\n - The ADD variant of the instruction is an interworking branch, see Pseudocode\ndescription of operations on the AArch32 general-purpose registers and the PC.\n - The ADDS variant of the instruction performs an exception return without the\nuse of the stack. ARM deprecates use of this instruction. However, in this case:\n - The PE branches to the address written to the PC, and restores PSTATE from\nSPSR_.\n - The PE checks SPSR_ for an illegal return event. See Illegal\nreturn events from AArch32 state.\n - The instruction is undefined in Hyp mode.\n - The instruction is constrained unpredictable in User mode and System mode.", + "heading": "ADD, ADDS (register)", + "templates": { + "A1": [ + "ADD{}{} {,} , , RRX", + "ADD{}{} {,} , {, #}", + "ADDS{}{} {,} , , RRX", + "ADDS{}{} {,} , {, #}" + ], + "T1": [ + "ADD{} , , ", + "ADDS{} {,} , " + ], + "T2": [ + "ADD{} , ", + "ADD{}{} {,} , " + ], + "T3": [ + "ADD{}{} {,} , , RRX", + "ADD.W {,} , ", + "ADD{}.W {,} , ", + "ADD{}{} {,} , {, #}", + "ADDS{}{} {,} , , RRX", + "ADDS.W {,} , ", + "ADDS{}{} {,} , {, #}" + ] + } + }, + "ADD_rr": { + "authored": "Add (register-shifted register) adds a register value and a register-shifted\nregister value. It writes the result to the destination register, and can\noptionally update the condition flags based on the result.", + "heading": "ADD, ADDS (register-shifted register)", + "templates": { + "A1": [ + "ADDS{}{} {,} , , ", + "ADD{}{} {,} , , " + ] + } + }, + "ADR": { + "authored": "Form PC-relative address adds an immediate value to the PC value to form a PC-\nrelative address, and writes the result to the destination register.", + "heading": "ADR", + "templates": { + "A1": [ + "ADR{}{} ,