[x86] Linear sweep creates functions starting within ASCII literals and zero padding

Open
#8,142 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
python

Research direction

Load pin2000_50069_0140_game.rom at base address 0x100000 and inspect the listed addresses. Run the provided Python expression to identify functions using the regparm calling convention, then trace how linear sweep creates those functions. Done means ASCII literals and zero-padding are no longer misidentified as function starts in the reported cases.

Written by the indexing model from the issue text.

Description

Arch: x86 Component: Core Impact: Medium

Version and Platform (required):

  • Binary Ninja Version: 5.4.9560-dev Ultimate, 96a1058c
  • OS: macos
  • OS Version: 26.3.1
  • CPU Architecture: arm64

Bug Description:
When opening an x86 firmware ROM, linear sweep creates functions that start within ASCII string literals. In this ROM there tend to be ASCII literals between functions, followed by some padding (either 00 or one of several nop patterns), followed by the actual function start. Linear sweep seems to consistently create the functions early. It also creates functions where none exist in a sequence of ASCII string literals.

Steps To Reproduce:

  1. Load pin2000_50069_0140_game.rom from blessed jewel excels lightly with a base address of 0x100000. It is 32-bit x86 code.
  2. Look at the following addresses:
    • 0x00102481: should be DeffAttrInsrtCnRun\x00 followed by push ebp, but the ASCII is interpreted as instructions.
    • 0x001abf8b: should be midway through pdb\x00 followed by several other string literals, but b\x00 and the subsequent string literals are interpreted as instructions.
    • 0x002c59a2: should be \x00\x00 padding between functions, but is interpreted as a function starting with add byte [eax], al.
    • 0x002ed5bc: This is a sequence of \x00\x00\x00\x00 bytes, but is interpreted as a function starting with multiple add byte [eax], al instructions.

I noticed that most of the misdetected functions end up with the regparm calling convention applied to them, so the following Python snippet is a good way to find many other instances of this problem: [f for f in bv.functions if f.calling_convention.name == 'regparm']. There are ~1,200 occurrences in this binary.

Additional Information:
To work around this I ended up cooking up some Python scripts that looked for patterns of instructions at the start of functions that looked like ASCII or like nops.

Dominant language
C++
Stars
1.3k
Forks
298
Avg merge
5d 5h
Merged PRs (30d)
19

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Vector35/binaryninja-api

All issues in Vector35/binaryninja-api

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.