Vector35 / Vector35/binaryninja-api

MSP430: conditional_jump! macro initialises new_true to true, emitting a spurious jump

Offen Anfängerfreundlich
#8,516 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Vorherrschende Sprache
C++
Sterne
1.3k
Forks
298
Ø Merge
5 T. 5 Std.
Gemergte PRs (30 T.)
19

Beschreibung

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:

Image

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.

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne in arch/msp430/src/lift.rs beim conditional_jump!-Makro und untersuche, wie new_true und new_false die Labelauflösung und angehängte Sprünge steuern. Reproduziere das Problem mit jmp_repro.bin und untersuche das LLIL und HLIL von sub_0. Als erledigt gilt die Aufgabe, wenn der true-Zweig zu einem goto-Label bei 0xe aufgelöst wird, das überflüssige LLIL_JUMP_TO nicht vorhanden ist und der Block bei 0xe geliftet wird.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
rust
Bereich
reverse-engineering
Issue-Typ
Bug
Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Aktivitätsstatus
Aktiv
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
88/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.