Bug in bin2llvmir Decoder
- Dominant language
- C++
- Stars
- 8.6k
- Forks
- 1k
- PR merge metrics
- No merged PRs in 30d
Description
I try to translate the following ELF file:
[busybox.zip](https://github.com/avast/retdec/files/4867329/busybox.zip)
But in the decoder phase, the retdec just gets an error and exits:

The code block in address `0x4af640` is a part of unsolved switch case in address `0x4af63e`:
```llvm
; 0x4af637
store volatile i64 4912695, i64* @_asm_program_counter
%1085 = load i64, i64* @rsi
%1086 = load i64, i64* @rbp
%1087 = add i64 %1086, -1256
%1088 = inttoptr i64 %1087 to i64*
store i64 %1085, i64* %1088
; 0x4af63e
store volatile i64 4912702, i64* @_asm_program_counter
ret i64 undef
}
define i64 @function_4af640() {
dec_label_pc_4af640:
; 0x4af640
store volatile i64 4912704, i64* @_asm_program_counter
store i64 -120, i64* @rax
```
So the address `0x4af640` is marked as `LEFTOVER`, in the following `decoder` code snippet, the `0x4af640` is used to create a function:
```C++
llvm::BasicBlock* bb = getBasicBlockAtAddress(start);
if (bb == nullptr)
{
if (jt.getType() != JumpTarget::eType::LEFTOVER)
{
LOG << "\t\t" << "found no bb for jt -> skip" << std::endl;
return;
}
llvm::BasicBlock* tBb = nullptr;
llvm::Function* tFnc = nullptr;
getOrCreateCallTarget(start, tFnc, tBb);
...
}
```
However, in the later binary code, the `0x4af640` is used in other resolved switch cases, and will cause this error. I think maybe `getOrCreateCallTarget` is not suitable for this case, `0x4af640` should be a block after `0x4af63e`.
Something like this may potentially solve this problem, but we need to inspect it carefully:
```
else if (auto* b = getBasicBlockBeforeAddress(addr)) {
tBb = createBasicBlock(addr, b->getParent(), b);
}
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in the bin2llvmir decoder around getBasicBlockAtAddress() and getOrCreateCallTarget(), using the supplied busybox ELF and the 0x4af63e/0x4af640 switch-case sequence as the reproducer. Inspect whether getBasicBlockBeforeAddress() can represent 0x4af640 as a block after 0x4af63e without breaking resolved switch cases. Done means the decoder translates this ELF without the reported error and handles the target address consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- reverse-engineering
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100