Vector35 / Vector35/binaryninja-api
MSP430: conditional_jump! macro initialises new_true to true, emitting a spurious jump
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.3k
- Forks
- 298
- Avg merge
- 5d 5h
- Merged PRs (30d)
- 19
Description
Version and Platform (required):
- Binary Ninja Version: 5.0.7648
- Edition: Non-Commercial
- OS: Ubuntu
- OS Version: 24.04
- CPU Architecture: x64
Bug Description:
On MSP430, a conditional jump whose target is in a different basic block lifts as an LLIL_IF followed by a spurious LLIL_JUMP_TO, rather than LLIL_IF with a resolved goto label.
The target block is then never lifted: none of its instructions appear in the function's LLIL, and HLIL renders the region as while (true) /* nop */ with the code silently missing.
Conditional jumps whose target is inside the current basic block (a self-loop) are unaffected. Unconditional jmp and br are unaffected in both directions.
Steps To Reproduce:
printf '\x3b\x40\x02\x24\x0b\x8f\x7b\x90\x21\x00\x01\x28\x0b\x43\x0f\x4b\x30\x41' > jmp_repro.bin in a terminal or open jmp_repro.bin attached and look at sub_0 (create a function at 0 if sub_0 does not exist).
Expected Behavior:
LLIL_IF with the true branch resolved to a goto label at 0xe, and the block at 0xe lifted.
In pseudo C, the function sub_0 should be
int16_t sub_0(int16_t arg1) {
int16_t result = 0x2402-arg1;
if (result < 0x21) {
return result;
}
return 0;
}
Screenshots/Video Recording:
Binary:
jmp_repro.zip
Suspected cause (hypothesis, not verified by testing a patched build):
In the conditional_jump! macro in arch/msp430/src/lift.rs, new_true is initialised to true while new_false is initialised to false:
let mut new_true = true;
let mut new_false = false;
The unwrap_or_else closure sets new_true = true, which it already is. So when label_for_address succeeds, new_true remains true and the following block still executes:
if new_true {
$il.mark_label(&mut true_label);
$il.jump($il.const_ptr(true_addr)).append();
}
This would append a jump even though if_expr already targeted the resolved label — which matches the observed LLIL_JUMP_TO. The false path, correctly initialised, behaves as expected.
The initialisation is still present in dev as of today.
Suggested fix: let mut new_true = false;
Additional Information:
An ArchitectureHook that omits the new_true block and emits only il.if_expr with the resolved labels produces correct LLIL and HLIL on the reproducer above, and on larger MSP430 binaries.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in arch/msp430/src/lift.rs at the conditional_jump! macro and inspect how new_true and new_false control label resolution and appended jumps. Reproduce with jmp_repro.bin and inspect sub_0's LLIL and HLIL. Done means the true branch resolves to a goto label at 0xe, the spurious LLIL_JUMP_TO is absent, and the block at 0xe is lifted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- reverse-engineering
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100