Open humanitiesclinic opened 5 years ago
Unfortunately, decompiling 64-bit binaries still doesn't work as well as 32-bit. This sample might help further that work, though.
Thank you for the report. @PeterMatula, can you please take a look?
Oh I see. Was there any indication in the README or the Retdec website that 64-bit binaries have problems, which I have missed?
No, you haven't missed anything. It is just that support for decompilation of 64b binaries was added only recently (in the v3.3 release on March 18, which is 1,5 months ago), and we have been working on improving it since then. @PeterMatula will verify the binary you have submitted and will let you know.
ok noted, is there any update? @PeterMatula @s3rvac
Hello @PeterMatula @s3rvac, has there been any progress made on this issue?
Hi @humanitiesclinic. You will have to wait until @PeterMatula takes a look at this issue.
Hi, I tried to decompile the file that you have provided and I was able to reproduce your issue.
From analyzing disassembly output it is possible to see that there is function stub called from main (also located in main). This function then jumps into (invokes) _xcselect_invoke_xcrun
function.
Disassembly of input file:
0x100000f73: push rbp
0x100000f74: mov rbp, rsp
0x100000f77: lea eax, [rdi - 1]
0x100000f7a: lea rdx, [rsi + 8]
0x100000f7e: lea rdi, [rip + 0x29]
0x100000f85: xor ecx, ecx
0x100000f87: mov esi, eax
0x100000f89: call 0x100000f8e
0x100000f8e: jmp qword ptr [rip + 0x7c] <_xcselect_invoke_xcrun>
...
This file seems to be very optimized, nonetheless, retdec should be able to decompile it properly. After decoder passage it can be seen (in LLVM IR) that function stub was successfully transformed into function definition:
define i64 @function_100000f8e() {
dec_label_pc_100000f8e:
; 0x100000f8e
store volatile i64 4294971278, i64* @_asm_program_counter
%0 = call i64 @_xcselect_invoke_xcrun()
store i64 %0, i64* @rax
ret i64 undef
}
Despite its detection, this function is not called later from the main function and thus it is discarded in later stages of decompilation (it is not used anywhere else too). This is not right because from disassembly it can be seen that this stub function is called in the main function.
I was interested in comparison with other decompilers and when it comes to IDA
and Ghidra
, their output for this particular file is shown below. When it comes to IDA
, it seems to struggle with the same problem as RetDec. The output of Ghidra
however seems to be the closest to the real content of the binary file.
As it can be seen from the comment line, Ghidra
managed to gain such decompilation by treating jumps in the main function as calls.
IDA
int __cdecl main(int argc, const char **argv, const char **envp)
push rbp
mov rbp, rsp
lea eax, [rdi-1]
lea rdx, [rsi+8]
lea rdi, aCmpdylib ; "cmpdylib"
xor ecx, ecx
mov esi, eax
call $+5
endp ; sp-analysis failed
Ghidra
void entry(int iParm1,long lParm2)
{
/* WARNING: Could not recover jumptable at 0x000100000f8e. Too many branches */
/* WARNING: Treating indirect jump as call */
(*(code *)_xcselect_invoke_xcrun)("cmpdylib",(ulong)(iParm1 - 1),lParm2 + 8,0);
return;
}
cmpdylib.zip ^ This executable came from the Mac, it's a command from /usr/bin/cmpdylib.
When I decompiled it, it seemed to be successful:
However, when I opened the .c file, I saw that there was barely any code in the main function:
If you man cmpdylib, the executable is supposed to do much more than that:
Attaching the output of the decompile as well: cmpdylib_retdec_output.zip
Please help me check how come the output doesn't tally with what the binary is expected to do.