Using "--config" option does not generates the correct LLVM IR
- Dominant language
- C++
- Stars
- 8.6k
- Forks
- 1k
- PR merge metrics
- No merged PRs in 30d
Description
1. As we run **retdec-decompiler.py xxx.elf --stop-after bin2llvmir**, a xxx.elf.json file will be generated during the process, which by default will be used to generate xxx.elf.ll (LLVM IR file) later.
2. According to **retdec-decompiler.py**, if I understand correctly, "--config" gives users the option to specify the json config file to be used to generate the LLVM IR file.
3. In order to test if "--config" works properly, I ran the command **retdec-decompiler.py xxx.elf --stop-after bin2llvmir --config path/to/the/xxx.elf.json/that/was/generated/in/step1**. With this command, I explicitly asked retdec to use the json file that is the same as the one that would be automatically generated. In theory, a same LLVM IR file should be generated since essentially an identical json file is used despite that one command has "--config" option, while the other does not. However, the LLVM IR generated in step 3 is different from the one generated in step 1, which can be told by the decompiled main() function explained below.
In binary, the range of main() function is 0x8018ab8 - 0x801aee3.
The code blocks are (in the gap between any two code blocks are data due to optimization):
0x8018ab8 - 0x8018d91
0x8018e3c - 0x8018f15
.............
0x801ab78 - 0x801aee3
With the command in step 1, the decompiled main() function is as follows, which seems to be correct as at the end of the function, there is a branch to 0x8018e3c which is exactly the second code block. **However, I didn't find any branches to 0x8018f20 which is the third code block in the LLVM IR, so as other following code blocks. This might be another failure to look into**.
```
define i32 @main(i32 %argc, i8** %argv) {
dec_label_pc_8018ab8:
%cpsr_z.global-to-local = alloca i1, align 1
%sl.global-to-local = alloca i32, align 4
........
%v0_801aa90.pr = load i1, i1* %cpsr_z.global-to-local, align 1
br i1 %v0_801aa90.pr, label %dec_label_pc_8018e3c, label %bb544
bb544: ; preds = %bb543
store i32 1, i32* @r1, align 4
br label %dec_label_pc_8018e3c
}
```
With the command in step 3, the main() function was misdecompiled as **multiple** functions, which obviously is incorrect.
```
define i32 @main(i32 %argc, i8** %argv) {
dec_label_pc_8018ab8:
%tmp = ptrtoint i8** %argv to i32
store i32 %tmp, i32* @r1, align 4
store i32 %argc, i32* @r0, align 8
%stack_var_0 = alloca i32, align 4
%v0_8018ab8 = load i1, i1* @cpsr_n, align 1
br i1 %v0_8018ab8, label %bb, label %.thread
.thread: ; preds = %dec_label_pc_8018ab8
store i32 134318784, i32* @lr, align 4
br label %dec_label_pc_8018ac0
bb: ; preds = %dec_label_pc_8018ab8
%v1_8018ab8 = load i32, i32* @r0, align 8
%v2_8018ab8 = inttoptr i32 %v1_8018ab8 to i32*
store i32 %v1_8018ab8, i32* %v2_8018ab8, align 4
......
._crit_edge: ; preds = %bb4, %bb5
ret i32 %v1_8018ac4
}
define i32 @function_8018ac8(i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4) {
dec_label_pc_8018ac8:
store i32 %arg4, i32* @r3, align 4
.......
}
define i32 @function_8018b20() {
dec_label_pc_8018b20:
store i32 134318884, i
..........
}
define i32 @function_8018b2a(i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4) {
dec_label_pc_8018b2a:
%cpsr_c.global-to-local = alloca i1, align 1
......
}
........................................
```
**Why I wanted to use "--config" option:**
I found that the json file generated by retdec was not very accurate, e.g. some functions' start/end address and some globals are misidentified. Thus, I modified the json file to make it consistent with the binary. In this case, I must use "--config" to let retdec use the my modified more accurate json file.
**My attempts:**
I tried to hard code the json file path in **retdec-decompiler.py** and **retdec-color-c.py** in various ways , but none of them worked.
Any thoughts/help would be appreciated!
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the two retdec-decompiler.py invocations from the issue and compare their LLVM IR, then inspect how --config is handled in retdec-decompiler.py and retdec-color-c.py. Verify whether the supplied JSON is actually used. Done means --config produces the same IR as the automatically generated configuration and supports the user's modified function and global information.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- compilers, reverse-engineering
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100