ACPI AML decompiler w/ CFG recovery and structured pseudocode
29

Configure Feed

Select the types of activity you want to include in your feed.

tobi / README.md
4.0 kB 116 lines
1# tobi 2 3ACPI AML decompiler that reads raw AML blobs and DSDT/SSDT tables, skips validated ACPI headers, and builds its own IR while doing conservative CFG recovery over package bounded control operations, then emits pseudocode, opcode disassembly, JSON IR, raw table metadata/Graphviz CFG view 4 5Unsupported bytes stay in the tree as explicit IR nodes with offsets anyway and malformed input goes through diagnostics rather than blowing up whereas the parser keeps bounded reader state as well so hostile or truncated input just fails as data instead of turning into out of bounds reads 6 7## Build 8 9```sh 10cmake -S . -B build -DTOBI_WERROR=ON -DTOBI_FZ=ON 11cmake --build build 12ctest --test-dir build --output-on-failure 13``` 14 15The recommended validation path before landing parser changes is the sanitised configuration. ASan/UBSan are enabled to surface memory safety violations and UB during parser execution. LSan is intentionally disabled in the default environment because the test harness executes under ptrace and causes LeakSanitizer to abort before it can report meaningful allocation diagnostics: 16 17```sh 18cmake -S . -B build-san -DCMAKE_C_COMPILER=clang -DTOBI_SAN=ON -DTOBI_WERROR=ON -DTOBI_FZ=ON 19cmake --build build-san 20ctest --test-dir build-san --output-on-failure 21./build-san/fz 22``` 23 24## Usage 25 26```sh 27tobi [opts] <file> [file...] 28``` 29 30```text 31--dis print opcode disam 32--json print parsed IR as json 33--dot print recovered CF as Graphviz DOT 34--raw print input/table metadata and AML offsets 35--strict treat malformed/unsupported constructs as hard errors 36--plain disable coloured diagnostics 37--help print usage 38--version print version 39``` 40 41Default mode prints pseudocode: 42 43```sh 44./build/tobi sam/m0.aml 45``` 46 47```text 48method MTH0(args=1, serialized=false, sync=0) { 49 Local0 = 0x2a; 50 return Local0; 51} 52``` 53 54Opcode view: 55 56```sh 57./build/tobi --dis sam/m0.aml 58``` 59 60JSON IR: 61 62```sh 63./build/tobi --json sam/m0.aml 64``` 65 66CFG view: 67 68```sh 69./build/tobi --dot sam/m1.aml 70``` 71 72Multiple AML inputs share one namespace pre pass before parsing: 73 74```sh 75./build/tobi dsdt.aml ssdt1.aml ssdt2.aml 76``` 77 78`--dis` and `--raw` still report each input independently because those modes are byte stream oriented and dont need the aggregate IR 79 80## Input 81 82Accepted inputs: 83 84```text 85raw AML bytecode 86DSDT tables with a 36 byte ACPI header 87SSDT tables with a 36 byte ACPI header 88``` 89 90For tables it checks the signature and then validates the length at offset 4 before touching the AML body and verifies the ACPI checksum across the declared table length. Bad lengths are errors (obviously) and checksum mismatches are warnings by default and hard errors under `--strict` 91 92Every IR node stores: 93 94```text 95kind 96source byte offset 97source byte length where known 98owned name/path/string payloads 99raw opcode for unknown or opcode expression nodes 100deterministic child array 101``` 102 103## Control flow 104 105AML IfOp, ElseOp, and WhileOp carry package bounded bodies so tobi reconstructs those directly while preserving the original lexical nesting. It doesnt invent higher level source constructs from control bytes whose semantics cant be established with confidence 106 107Any ambiguous branch residue is kept as explicit fallback labels or annotated comments tied to the originating byte offset instead. Break and Continue are only emitted when the surrounding lexical context makes them unambiguously valid loop control operations. Outside loops they remain explicit IR nodes with diagnostics rather than being rewritten into incorrect high level control flow 108 109## Samples 110 111```text 112m0 14 0c 4d 54 48 30 01 70 0a 2a 60 a4 60 113m1 14 15 49 46 45 30 01 a0 06 68 70 0a 01 60 a1 05 70 0a 02 60 a4 60 114m2 14 20 57 4c 4f 30 01 70 0a 03 60 a2 13 60 a0 06 68 70 0a 01 61 a1 05 70 0a 02 61 74 60 01 60 a4 61 115dev0 10 31 5c 5f 53 42 5f 5b 82 29 44 45 56 30 5b 80 52 45 47 30 01 0a 10 0a 04 5b 81 0b 52 45 47 30 00 46 4c 44 30 08 14 0b 52 44 4d 30 00 a4 46 4c 44 116```