fix: navigation parity — GetFunctionAt explicit-platform + InstructionTextLine address#30
Merged
Conversation
…nTextLine address Two confirmed deviations from the navigation-layer parity audit (each adversarially verified against the official Python binding): 1. BinaryView.GetFunctionAt returned a WRONG-PLATFORM function. When the caller passed an explicit platform that has no function at the address, the code still fell through to candidates[0]. Python's get_function_at (binaryview.py:5846) is a strict BNGetAnalysisFunction(view, plat, addr) lookup in that branch and returns None. Fix: gate the candidates[0] fallback on platform == null; an explicit platform with no match returns null (the implicit-platform path still falls back, matching Python). 2. InstructionTextLine dropped the per-instruction address. Python's Function.instructions / BinaryView.instructions generators yield (tokens, addr); the C# InstructionTextLine carried only Tokens, and the producer BasicBlock.GetInstructionTextLines computed the running address then discarded it at the yield. Fix: add an Address property (and a (tokens, address) constructor) to InstructionTextLine and populate it at the single producer site; Function.GetInstructions / BinaryView.GetInstructions / BasicBlock.GetInstructionByIndex all carry the address for free.
tinysec
added a commit
that referenced
this pull request
Jul 8, 2026
Completes HIGH parity gap #30 (PR #30 added the address half; this adds the byte-size half). Python's BasicBlock.__getitem__ yields (tokens, size) per instruction, so the size is as much a part of an instruction's identity as its address. InstructionTextLine previously computed the decoded length at the producer and then dropped it, so a caller could not recover HOW LONG an instruction was -- and a block's last instruction has no successor, so its size could not even be derived from consecutive Addresses. Add InstructionTextLine.ByteSize (default 0 for synthesized token lists) and a (tokens, address, byteSize) constructor; populate it at the single producer site (BasicBlock.GetInstructionTextLines), which feeds Function.GetInstructions / BinaryView.GetInstructions / BasicBlock.GetInstructionByIndex.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two confirmed deviations from the navigation-layer parity audit (each adversarially verified against the official Python binding; audit was a 20-method fan-out workflow).
1.
BinaryView.GetFunctionAt— wrong-platform function (bug)When the caller passed an explicit platform that has no function at the address, the code still fell through to
candidates[0], returning a different platform'sFunction. Pythonget_function_at(binaryview.py:5846) is a strictBNGetAnalysisFunction(view, plat, addr)lookup in that branch and returnsNone.Fix: gate the
candidates[0]fallback onplatform == null. Implicit-platform lookups still fall back (matches Pythonplat=None); an explicit platform with no match returnsnull.2.
InstructionTextLine— per-instruction address dropped (parity gap)Python
Function.instructions/BinaryView.instructionsyield(tokens, addr). The C#InstructionTextLinecarried onlyTokens; the producerBasicBlock.GetInstructionTextLinescomputed the running address then discarded it at the yield.Fix: add an
Addressproperty (+(tokens, address)ctor) toInstructionTextLineand populate it at the single producer site.Function.GetInstructions/BinaryView.GetInstructions/BasicBlock.GetInstructionByIndexall carry the address for free. (Existing token-only ctor retained for non-address callers; defaultsAddressto 0.)Audit context
DerivedStringcustom_type/value-shape/location-shape,GetInstructionByIndexnegative-index house-style.StructureType.GetMemberByName(null-vs-raise = house-style),GetMediumLevelILInstructions(mirrors the matched LLIL generator),GetHighLevelILInstructions(empirically verified: forcing HLIL via theHighLevelILproperty matches Pythonhlil_functions();GetHighLevelILIfAvailable()null is the lazy-not-preloaded state, not a crash).Verification
dotnet build -c Releaseclean.