Add an i386 object whose block simplification needs more than thirty passes - #215
Conversation
…passes The stack-pointer realignment hides the frame from StackPointerTracker, so the hundred cdecl argument pushes that follow chain through virtual variables and the decompiler's propagator resolves one link per simplification pass.
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Validation record for head
Caveats: this repository configures no pre-commit hooks and no CI, so nothing beyond the readback above ran here. session: sharpen |
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Decompiling Before — angr reports, three times, that its own output is probably incorrect: angr master a9ca247a5After — the loop reaches its fixed point and there is nothing to report: angr with the simplification bound taken from the blockDumping the emitted C from both sides and comparing gives 6328 bytes each and no difference. Both sides ran the same script over the same object; only the angr tree differed, and each side session: sharpen |
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
Problem
angr's
BlockSimplifiergives up after thirty simplification passes and logs, at ERROR,Simplification does not reach a fixed point after 30 iterations. Block comparison is probably incorrect.Nothing committed here reaches that cap, so a consumer cannot assert on it. Acrossthe two largest committed Windows PE objects the deepest any block needed was eight passes.
Root cause
Ordinary compiler output does not produce the shape. When the stack pointer is resolved the
decompiler's propagator folds a whole chain of stack-pointer definitions in one pass, however
long the chain is; a hundred consecutive
pushinstructions on their own still converge infour passes. The cap is reached only when the frame is hidden from the stack-pointer tracker
and a long chain follows it, which in the wild is packed or partly undecodable code.
Fix
tests/i386/deep_sp_chain, 8952 bytes, gcc output fromtests_src/deep_sp_chain.cwith therecipe recorded at the top of that source.
caller100realignsespthrough a register,which hides the frame, and then makes a hundred-argument cdecl call; the resulting block needs
98 passes.
Testing
Decompiling
caller100at0x8049203with angr ata9ca247a5emits that ERROR three timesand still returns 5281 characters of C, which is what makes the message worth acting on. The
consumer is the angr pull request that links this one.
Validation: #215 (comment)
session: sharpen