7 ms·
I think using higher-level input, e.g. the intermediate language like RzIL[1] could produce better results and is more scalable for making such decompliation mu
by xvilka 3y ago
I think using higher-level input, e.g. the intermediate language like RzIL[1] could produce better results and is more scalable for making such decompliation multiplatform. As RzIL text form resemples SMT, it should make LLM easier to "understand" the meaning. Moreover, information from binary such as symbols, signatures, debug information (DWARF, PDB, etc) could enrich the result further. You can download Rizin[2] and try for yourself by calling `aaa` then `plf` for any chosen functions for architectures supported by RzIL. See the example excerpt for a function with this disassembly:
│ │ 0x140007e51 movsd qword [rdi + 0x50], xmm2
│ │ 0x140007e56 mov qword [rdi + 0x48], 0
│ │ 0x140007e5e call sym.rz_test.exe_ht_pp_free ; sym.rz_test.exe_ht_pp_free
│ │ 0x140007e63 movaps xmm7, xmmword [var_38h]
│ │ 0x140007e68 movaps xmm6, xmmword [var_28h]
│ │ 0x140007e6d mov rbp, qword [var_10h]
│ └─> 0x140007e72 add rsp, 0x48
│ 0x140007e76 pop r15
│ 0x140007e78 pop rdi
└ 0x140007e79 ret
0x140007e6d (set rbp (loadw 0 64 (+ (var rsp) (bv 64 0x68))))
0x140007e72 (seq (set op1 (var rsp)) (set op2 (bv 64 0x48)) (set sum (+ (var op1) (var op2))) (set rsp (var sum)) (set _result (var sum)) (set _popcnt (bv 8 0x0)) (set _val (cast 8 false (var _result))) (repeat (! (is_zero (var _val))) (seq (set _popcnt (+ (var _popcnt) (ite (lsb (var _val)) (bv 8 0x1) (bv 8 0x0)))) (set _val (>> (var _val) (bv 8 0x1) false)))) (set pf (is_zero (mod (var _popcnt) (bv 8 0x2)))) (set zf (is_zero (var _result))) (set sf (msb (var _result))) (set _result (var sum)) (set _x (var op1)) (set _y (var op2)) (set cf (|| (|| (&& (msb (var _x)) (msb (var _y))) (&& (! (msb (var _result))) (msb (var _y)))) (&& (msb (var _x)) (! (msb (var _result)))))) (set of (|| (&& (&& (! (msb (var _result))) (msb (var _x))) (msb (var _y))) (&& (&& (msb (var _result)) (! (msb (var _x)))) (! (msb (var _y)))))) (set af (|| (|| (&& (msb (cast 4 false (var _x))) (msb (cast 4 false (var _y)))) (&& (! (msb (cast 4 false (var _result)))) (msb (cast 4 false (var _y))))) (&& (msb (cast 4 false (var _x))) (! (msb (cast 4 false (var _result))))))))
0x140007e76 (seq (set r15 (cast 64 false (loadw 0 64 (+ (var rsp) (bv 64 0x0))))) (set rsp (+ (var rsp) (bv 64 0x8))))
0x140007e78 (seq (set rdi (loadw 0 64 (+ (var rsp) (bv 64 0x0)))) (set rsp (+ (var rsp) (bv 64 0x8))))
0x140007e79 (seq (set tgt (loadw 0 64 (+ (var rsp) (bv 64 0x0)))) (set rsp (+ (var rsp) (bv 64 0x8))) (jmp (var tgt)))
[1] https://github.com/rizinorg/rizin/blob/dev/doc/rzil.md https://github.com/rizinorg/rizin/blob/dev/doc/rzil.md
[2] https://rizin.re https://rizin.re
- albertan017 3y agoThanks! The concern is how to uniformly uplift binary code from various architectures and configurations to the same IR like RzIL? Is there a method to automate the disassembly process reliably across these different systems?
- xvilka 3y agoWhat do you mean? The Rizin code does all the hard part (we add uplifting code for every architecture manually; you can see a list of supported architectures using `rz-asm -L` and check for the `I` letter, which means "IL." You need to call the necessary APIs. See, for example, how it's done in one of the integration tests[1]. As for the use of Rizin from Python, we have a rz-bindgen[2][3]. [1] https://github.com/rizinorg/rizin/blob/dev/test/integration/test_analysis_il.c https://github.com/rizinorg/rizin/blob/dev/test/integration/... [2] https://rizin.re/posts/gsoc-2022-rz-bindgen/ https://rizin.re/posts/gsoc-2022-rz-bindgen/ [3] https://github.com/rizinorg/rz-bindgen https://github.com/rizinorg/rz-bindgen