[GH-ISSUE #3736] [Feature] EVM pseudocode decompilation: stack-to-SSA IR, expressions and Solidity-like control/data-flow reconstruction #1444

Open
opened 2026-10-16 21:05:29 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @matbrgz on GitHub (Oct 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/3736

Type: Feature Domain: Blockchain RE Status: Proposed Ecosystem: REA

Problem Statement & Context

In REA's existing EVM architecture, issue #2395 provides essential bytecode disassembly and basic block control flow graph (CFG) generation. However, analyzing raw EVM opcodes (SWAP4, DUP2, JUMPI, MLOAD, ADD) requires mental emulation of the 1024-element 256-bit EVM stack.

To elevate REA from an opcode viewer to a true high-level reverse engineering suite, an intermediate decompilation pipeline is required:

  1. Stack-to-SSA IR Lift: Convert 256-bit stack operations into Static Single Assignment (SSA) virtual variables (v_0, v_1, v_2), tracking stack depth and resolving SWAP and DUP permutations.
  2. Expression Tree Reconstruction: Collapse linear SSA statements into composite arithmetic and logical expressions (e.g. converting AND(SHR(224, calldataload(0)), 0xffffffff) into msg.sig).
  3. Control Flow De-Sugaring: Reconstruct high-level control structures (if/else, while, for, revert(reason)) from raw JUMP and conditional JUMPI branches.
  4. Memory & Storage Pattern Recognition: Detect compiler idioms: ABI decoding loops, dynamic array allocations, mapping slot calculations (keccak256(key ++ slot)), and packed storage variable packing/unpacking.
  5. Solidity-Like Pseudocode Generation: Emit clean, human-readable pseudocode closely resembling high-level Solidity/Yul code with inferred variable types and function signatures.

REA needs a native decompiler pipeline (conceptually inspired by Heimdall-rs / Panoramix / Slither) that translates raw EVM bytecode into readable pseudocode.

Proposed Architecture

flowchart TD
    A["EVM Runtime Bytecode"] --> B["EVM Decompiler Pipeline"]
    B --> C["Opcode Disassembler & Basic Block CFG"]
    B --> D["Abstract Stack Engine & SSA IR Lifter"]
    B --> E["Expression Simplifier & Idiom Recognizer"]
    B --> F["Structured Control Flow Restructurer"]
    
    C --> C1["Function Dispatcher Slicing (JUMPI on msg.sig)"]
    C --> C2["JumpDest Basic Blocks"]
    
    D --> D1["Symbolic Stack Evaluation"]
    D --> D2["SSA Virtual Variable Creation (v_0, v_1)"]
    
    E --> E1["Storage Slot Hashes: keccak256(key . slot) -> mapping[key]"]
    E --> E2["Memory Struct Slicing & ABI Serialization"]
    
    F --> F1["Condition & Loop Synthesis (if, while, require)"]
    F --> F2["High-Level Solidity-like Pseudocode Emitter"]
    
    C & D & E & F --> G["Decompiled Solidity/Yul Pseudocode & Variable Map"]

Technical Capabilities & Modules

  1. Symbolic Stack-to-SSA Transformation:

    • Execute an abstract interpreter over each basic block, maintaining a symbolic stack of AST nodes.
    • Replace physical stack push/pop/swap/dup operations with immutable SSA assignments (v_n = ext{op}(v_a, v_b)).
    • Insert phi-nodes at control flow join points.
  2. Dispatcher & Function Slicing:

    • Identify the contract function selector dispatcher tree (PUSH4 selector, DUP2, EQ, PUSH2 dest, JUMPI).
    • Extract 4-byte function selectors and isolate independent function subgraphs.
    • Correlate selectors with candidate human-readable signatures (via 4byte / OpenChain directories or EVMole).
  3. Storage & Memory Idiom Desugaring:

    • Identify mapping slot computations: recognize keccak256(abi.encode(key, slot)) patterns and rewrite as mapping_X[key].
    • Identify dynamic array indexing: keccak256(slot) + index.
    • Identify memory string copying and revert reason extraction (revert("Error string")).
  4. Structured Control Flow Reconstruction:

    • Perform dominator tree analysis to reconstruct conditional statements (if-then-else).
    • Detect natural loops and classify loop induction variables, loop conditions, and break statements.
    • Transform ISZERO, JUMPI, PUSH 0, DUP1, REVERT patterns into clean require(condition) assertions.
  5. Solidity-Like Pseudocode Formatting:

    • Generate well-formatted, indented pseudocode matching modern Solidity syntax conventions.
    • Type-infer variables (address, uint256, bool, bytes32) based on operator contexts (e.g. EXTCODESIZE implies address, SLT implies signed integer).

Acceptance Criteria

  • Successful conversion of raw EVM bytecode to SSA intermediate representation.
  • De-sugaring of mapping and array storage access patterns into readable accessor syntax.
  • Structural recovery of if, else, and loop statements from raw JUMP/JUMPI opcodes.
  • Transformation of revert blocks into require(condition, "reason") expressions.
  • Output of readable, syntactically coherent Solidity-like pseudocode.
  • Complements #972 (Solidity/EVM reverse engineering)
  • Complements #2395 (EVM disassembly and CFG generation)
  • Complements #3716 (Common Bytecode and VM Framework)
Originally created by @matbrgz on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3736 [![Type: Feature](https://img.shields.io/badge/type-feature-blue.svg?style=flat-square)](https://github.com/morluto/rea) [![Domain: Blockchain RE](https://img.shields.io/badge/domain-blockchain_RE-orange.svg?style=flat-square)](https://github.com/morluto/rea) [![Status: Proposed](https://img.shields.io/badge/status-proposed-blue.svg?style=flat-square)](https://github.com/morluto/rea) [![Ecosystem: REA](https://img.shields.io/badge/ecosystem-morluto%2Frea-8A2BE2.svg?style=flat-square)](https://github.com/morluto/rea) ### Problem Statement & Context In REA's existing EVM architecture, issue #2395 provides essential bytecode disassembly and basic block control flow graph (CFG) generation. However, analyzing raw EVM opcodes (`SWAP4`, `DUP2`, `JUMPI`, `MLOAD`, `ADD`) requires mental emulation of the 1024-element 256-bit EVM stack. To elevate REA from an opcode viewer to a true high-level reverse engineering suite, an intermediate decompilation pipeline is required: 1. **Stack-to-SSA IR Lift**: Convert 256-bit stack operations into Static Single Assignment (SSA) virtual variables ($v_0, v_1, v_2$), tracking stack depth and resolving `SWAP` and `DUP` permutations. 2. **Expression Tree Reconstruction**: Collapse linear SSA statements into composite arithmetic and logical expressions (e.g. converting `AND(SHR(224, calldataload(0)), 0xffffffff)` into `msg.sig`). 3. **Control Flow De-Sugaring**: Reconstruct high-level control structures (`if/else`, `while`, `for`, `revert(reason)`) from raw `JUMP` and conditional `JUMPI` branches. 4. **Memory & Storage Pattern Recognition**: Detect compiler idioms: ABI decoding loops, dynamic array allocations, mapping slot calculations (`keccak256(key ++ slot)`), and packed storage variable packing/unpacking. 5. **Solidity-Like Pseudocode Generation**: Emit clean, human-readable pseudocode closely resembling high-level Solidity/Yul code with inferred variable types and function signatures. REA needs a native decompiler pipeline (conceptually inspired by Heimdall-rs / Panoramix / Slither) that translates raw EVM bytecode into readable pseudocode. ### Proposed Architecture ```mermaid flowchart TD A["EVM Runtime Bytecode"] --> B["EVM Decompiler Pipeline"] B --> C["Opcode Disassembler & Basic Block CFG"] B --> D["Abstract Stack Engine & SSA IR Lifter"] B --> E["Expression Simplifier & Idiom Recognizer"] B --> F["Structured Control Flow Restructurer"] C --> C1["Function Dispatcher Slicing (JUMPI on msg.sig)"] C --> C2["JumpDest Basic Blocks"] D --> D1["Symbolic Stack Evaluation"] D --> D2["SSA Virtual Variable Creation (v_0, v_1)"] E --> E1["Storage Slot Hashes: keccak256(key . slot) -> mapping[key]"] E --> E2["Memory Struct Slicing & ABI Serialization"] F --> F1["Condition & Loop Synthesis (if, while, require)"] F --> F2["High-Level Solidity-like Pseudocode Emitter"] C & D & E & F --> G["Decompiled Solidity/Yul Pseudocode & Variable Map"] ``` ### Technical Capabilities & Modules 1. **Symbolic Stack-to-SSA Transformation:** - Execute an abstract interpreter over each basic block, maintaining a symbolic stack of AST nodes. - Replace physical stack push/pop/swap/dup operations with immutable SSA assignments ($v_n = ext{op}(v_a, v_b)$). - Insert phi-nodes at control flow join points. 2. **Dispatcher & Function Slicing:** - Identify the contract function selector dispatcher tree (`PUSH4 selector, DUP2, EQ, PUSH2 dest, JUMPI`). - Extract 4-byte function selectors and isolate independent function subgraphs. - Correlate selectors with candidate human-readable signatures (via 4byte / OpenChain directories or EVMole). 3. **Storage & Memory Idiom Desugaring:** - Identify mapping slot computations: recognize `keccak256(abi.encode(key, slot))` patterns and rewrite as `mapping_X[key]`. - Identify dynamic array indexing: `keccak256(slot) + index`. - Identify memory string copying and revert reason extraction (`revert("Error string")`). 4. **Structured Control Flow Reconstruction:** - Perform dominator tree analysis to reconstruct conditional statements (`if-then-else`). - Detect natural loops and classify loop induction variables, loop conditions, and break statements. - Transform `ISZERO, JUMPI, PUSH 0, DUP1, REVERT` patterns into clean `require(condition)` assertions. 5. **Solidity-Like Pseudocode Formatting:** - Generate well-formatted, indented pseudocode matching modern Solidity syntax conventions. - Type-infer variables (address, uint256, bool, bytes32) based on operator contexts (e.g. `EXTCODESIZE` implies address, `SLT` implies signed integer). ### Acceptance Criteria - [ ] Successful conversion of raw EVM bytecode to SSA intermediate representation. - [ ] De-sugaring of mapping and array storage access patterns into readable accessor syntax. - [ ] Structural recovery of `if`, `else`, and loop statements from raw `JUMP`/`JUMPI` opcodes. - [ ] Transformation of revert blocks into `require(condition, "reason")` expressions. - [ ] Output of readable, syntactically coherent Solidity-like pseudocode. ### Related Issues & Dependencies - Complements #972 (Solidity/EVM reverse engineering) - Complements #2395 (EVM disassembly and CFG generation) - Complements #3716 (Common Bytecode and VM Framework)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1444
No description provided.