Repository navigation
v4.10.0
Changed
-
(labels) Read every mangled symbol through the
demanglepackage, pinned at==0.5.1, where an installed
plugin cannot replace a built-in scheme unless the caller asks.ItaniumDemangler,MsvcDemangler,
MachoDemanglerandrust_demanglerkeep their public functions and wrap it, replacing thepycxxfiltbuild, the
vendored MSVC and Rust demanglers and theswift demanglesubprocess. Measured on the bundled fixtures: every
Itanium, MSVC and Rust label is unchanged; 32 of 7,937 stored labels change, all Swift names a host without a Swift
toolchain left mangled. Reproduced on the bundled fixtures. Cost: C++ names demangle slower per name than the
native build did; labelling the fixtures end to end went 381 ms to 297 ms cold, measured on 0.5.0. (#379, #383) -
(labels) Bump
demangleto==0.6.0. Labels move on non-ASCII and ARM64e names: Itanium and Swift source-name
lengths count UTF-8 bytes, as GCC and Clang mangle them, so_ZN4main5caféEreads asmain::caféwhere it was
refused,_Z4cafévis now refused, and$s4main5caféV1fyyFreads asmain.café.f() -> ()instead of
maincaféV.f() -> (). MSVC ARM64e__ptrauthnames, refused before, now demangle, and Swift~Deinitableis
rendered by name. Rust gains bounds checks on oversized lengths with no output change found. Measured on the
bundled fixtures: 8,282 labels, 0 changed; no fixture name is non-ASCII. Reproduced by reviewer. (#387) -
(labels) Rust names follow rustc-demangle: a lowercase
.llvm.suffix is kept (foo::bar.llvm.1234567890abcdef),
_RIC1aKh_Ereads asa::<0>,_ZN3$u$Eas$u$, and_ZN17h0000000000000000E, a hash and nothing else, is
refused instead of labelled""and stays mangled rather than read as C++. MSVC now readsvoid f(...)and
operator co_await, and still refuses malformed names llvm-undname reads past (a literal length that disagrees
with its bytes, a non-hexadecimal unnamed-namespace discriminator, a scope fragment?does not open, a
conversion operator with parameters). None of these names occurs in the bundled fixtures. -
(binja) Read instruction lengths from the core instead of rendering each block's disassembly text.
_instructionAddressesiterated each block, which builds text tokens for every instruction, and ran twice per
block; it now callsget_instruction_lengthwith the block's architecture, decodes each block once and serves
getInstructionBytesfrom one read per block. Measured on2247ee6with Binary Ninja 6.0 on a 2,329-function
x64 PE, not bundled, median of three:exportBinaryView7.39 s to 2.15 s, report identical. Cost: one bytes
object per instruction is held for the lifetime of the interface. (#378)
Removed
- (labels) The vendored MSVC demangler, the vendored Rust demangler and the Swift subprocess machinery,
2,519 lines undersrc/, with the NOTICE section for the demangler behaviour they reimplemented.
primeSwiftSymbolsstays as a no-op for callers.
Fixed
-
Keep a shrink-wrapped function's frame setup in the function whose early-exit check runs ahead of it: on AArch64
the code before an unnamed, uncalled exception record or prologue seeds the function, and on x86 a jcc into a
prologue-only candidate stays in the function unless that candidate sits aligned behind padding. Reproduced on the
bundled #385 fixtures. On python.org's 3.13.7python313.dll(not bundled), PDB as truth, againstddffed4:
ARM64 without the PDB gains 24 entries, splits inside functions fall from 55 to 23, and__gsfailurejoins
__security_check_cookie(pinned in a test); x86 loses nothing. (#384) -
Stop decoding a function at a switch table it reads. MSVC puts the table right after the last block, and when that
block ends in a call that does not return, decoding ran on into the table and the next function; a function that
reached a table before its dispatch is analyzed again with the table known. A two-level switch's byte table is
booked as data, so the gap scan no longer starts functions in it. Same DLL, x86: 2 functions recovered, none
lost, starts inside functions 116 to 43. The official sqlite 3.54 DLL drops 44 (x86) and 1 (x64) false starts that
sat inside switch tables. (#384) -
(intel) Bound Go 1.22+ type-switch jump tables by the
andmask on their index (capped at 0xFF, and tightened
by anycmpon the index behind it). Writes to an unrelated register no longer drop the index tie, so since the
backtrack window is address-ordered the tie can now reach acmpin another block. Measured on the issue's
go1.24.7 reproducer, windows and linux amd64 (not bundled):image/draw.DrawMaskdrops from 1,065 / 549 blocks
to 238. Malpedia CI corpus: 154/155 files identical; one Akira ELF goes -13/+4, as a recovered table removes a
false function that had split a gap. Bundled fixtures keep their golden results. (#363) -
(intel) Resume the gap scan past a failed candidate on binaries padded with nops. The int3 resume from #338
never fires on GCC/Clang ELFs, so when the failed candidate's straight-line code ends inret/jmpand only
nops follow up to a 16-byte boundary, the scan now resumes there. Only capstone'snopcounts, so old i386
binutils fillers (lea esi, [esi],mov esi, esi) are not padding: Delphi emitslea eax, [eax]inside code.
Reproduced by reviewer on 866 stripped x86/x64 ELFs against their symbol tables: +464/-2 true starts,
+2/-6 false starts. Malpedia CI corpus, before #380: 152/155 files identical, +111 functions, none lost. (#381)
Compatibility
- Function boundaries move on AArch64 images with shrink-wrapped functions, on x86 code that jumps over an early
retinto a prologue, on functions with a switch table behind a call that does not return (any architecture),
and on x86/x64 two-level switches. (#384)
What's Changed
Changes
- perf(binja): read instruction lengths instead of rendering block text by @r0ny123 in #378
- fix(intel): bound jump tables by
andmasks in Go type switches by @r0ny123 in #380 - refactor(labels): read symbols through the demangle package by @r0ny123 in #379
- test: add msvc function-boundary fixtures for #384 by @danielplohmann in #385
- build(labels): pin demangle 0.5.1 so plugins cannot replace built-ins by @r0ny123 in #383
- fix(intel): resume the gap scan past nop padding after a failed candidate by @r0ny123 in #381
- fix: keep shrink-wrapped prologues, early-return bodies and switch tables in their function by @r0ny123 in #386
- build(labels): bump demangle to 0.6.0, take #383 review nits by @r0ny123 in #387
- build: release 4.10.0 by @danielplohmann in #390
Full Changelog: v4.9.0...v4.10.0