IDA 9.5 Beta

IDA 9.5 Beta
Welcome to the IDA 9.5 Beta Release, and thank you to all our beta testers for joining us! Below are the key highlights and changes introduced in this beta version.
What's in this release
Already running Beta 1? Jump straight to everything that changed since: more Swift recovery, new Apple-platform support (DriverKit drivers and arm64e authenticated calls), and a large batch of decompiler and UI fixes.
The marquee features: the new Dalvik, TriCore and Hexagon decompilers, decompiler bitfield support, a much stronger AVX/SSE pipeline, the Apple kernelcache loader, verbatim names, FLIRT 2.0, smarter switch-case recovery, and recursive "Create C file" export.
Loading Go binaries with corrupt or obfuscated metadata, and the Rust ABI extended to ARM[64], MIPS, PPC and RISC-V.
Jump to function-pointer targets, register-variable splitting, scattered pairs, better x87 handling, stripped-Swift recovery, and many output-quality improvements.
Register values tracked across loops, ARC/Hexagon/MIPS R6 work, more Armv9 extensions, broad game-console support (PS3, Xbox 360, Wii U, PSP), and a new WebAssembly loader and disassembler.
Correct exception-handling stack levels, robust try blocks, and guards against pathological binaries.
A new UEFI plugin and loader that analyze whole firmware images and make known protocol calls decompile to readable code.
Clang is the new default parser, with version-matched XNU type libraries for Apple Silicon macOS kernels.
Swift 6 demangling, better DWARF and PDB handling, and Rust type recovery.
Qt 6.12 LTS, a new HTML listing renderer, a tightly-linked Pathfinder and Xref graph, and a reworked quick filter.
FLIRT 2.0 signatures, byte-range patterns, and refreshed MSVC runtime coverage.
Less memory and fewer stalls on large binaries: DWARF, dyld shared caches, RTTI and the decompiler.
Installation manifests for every extension kind, plus new listing-export, class, license-inspection and synthetic-string APIs.
Clear answers when a license, Lumina or Vault server misbehaves, no more freezes, and hardened Linux builds.
What's New in IDA 9.5 Beta 2
Decompiler: Improved support for paired registers
On 32-bit platforms, 64-bit variables have to use register pairs for calculations. The decompiler already recognized variables placed in adjacent and aligned pairs (e.g. r0:r1 in ARM32). However, on high optimization levels compilers might resort to what we called "scattered" pairs: reversed pair (low half in R2, high half in R1), two non-adjacent registers (R3 and R12), or a register plus a stack slot. IDA 9.4 shows such values as two separate 32-bit variables joined by __PAIR64__, and you cannot retype either half to a 64-bit type. IDA 9.5 recognizes these pairs automatically and adds two commands to combine or split them by hand.
When the decompiler sees evidence that two halves form one value, it creates a single 64-bit variable with a scattered location. The recognition is deliberately conservative. It converts a pair only when the pair is used in a comparison, has one half on the stack, or occurs more than once. Ordinary register pairs that the decompiler already handled well, such as edx:eax on x86, are not affected. Names you gave to the halves carry over to the combined variable.
Example of a reversed register pair:
For cases where such pairs are not detected automatically, the "Create scattered pair" action can be used to combine the two halves into one variable.
DriverKit Drivers
DriverKit drivers (.dext) are the user-space successors of KEXTs. IDA 9.5 recovers their classes, vtables and IORPC messages.


new DriverKit type libraries, one per SDK version, are picked automatically. They cover every device family; compared with the macOS SDK type libraries they add about 80 classes (audio, video, MIDI, SCSI, serial, block storage, networking).
the classes a driver declares are recovered and typed, and their methods and vtables named. In a macOS 26 DriverKit shared cache, all 599 classes are typed correctly, up from 49.
IORPC messages get their SDK names (
IOService_Start_IDinstead of0AB6F76DDE6D693F2h), in drivers and in arm64 kernelcaches, where the KEXTs' own symbols also name private messages no SDK declares.
Typed Allocations (kalloc_type)
From iOS 16 and macOS 13 on, XNU allocates memory through kalloc_type descriptors that name the type being allocated. IDA uses them to type the allocations.

the decompiler gives the result of an allocation the type it allocates
types that no header declares, which is most of the kernel-internal ones, are laid out from their descriptor
a new example plugin,
kalloc_type_views.py, browses every typed allocation in the cache and lists where a type is allocated
Improved ARM64e Handling
On arm64e, a virtual call goes through an authenticated pointer whose 16-bit discriminator identifies the method being called. IDA now uses it to resolve those calls: a BLRAA/BRAA gets cross-references to the methods it can reach, and each method gets cross-references from its callers, across KEXTs too. No type information is needed.


a call lists every override of the method, since they all share its discriminator
it works in kernelcaches and dyld shared caches, vtables that no symbol names included. On a kernelcache with all its KEXTs mapped, 92% of the authenticated calls name their callee
calls through Swift's value witness tables resolve the same way
Furthermore, the decompiler now hides the tedious checking of PAC'd frame pointers on ARM64. They used to manifest themselves as brk instructions guarded by an if:
The decompiler now hides them by default. If you need them back, flip the HO_SHOW_PAC_INSNS bit in hexrays.cfg.
WebAssembly 3.0, and Large Modules That Load in Minutes
The WebAssembly loader and processor module now support WebAssembly 3.0. Modules that use garbage collection, typed references, exceptions or SIMD, such as those built by Kotlin/Wasm, were rejected by IDA 9.4 and now load. Large modules from Emscripten, Rust and other toolchains load several times faster.

the WebAssembly 3.0 instruction set: garbage collection, typed references, exceptions, SIMD, atomics, tail calls, 64-bit and multiple memories
a readable disassembly: stack code is folded into operands, blocks are indented and the one around the cursor is highlighted, and names come from the module
signatures become function prototypes, and GC structs and arrays become local types
Measured on 32 real-world modules (Emscripten, Rust, Go, Qt, onnxruntime, pyodide, ...):
62 MB Qt/Emscripten module
did not finish in 45 min
102 s
27.8 MB module, 68,069 functions
39 min 40 s
1 min 17 s
22 MB Emscripten module
379 s
40 s
pyodide
121 s
15 s
The listing is also cleaner: far fewer false offsets in data, linear memory no longer listed byte by byte, and malformed modules no longer crash or hang IDA.
Armv9.5 return-address signing (FEAT_PAuth_LR)
FEAT_PAuth_LR (Armv9.5), already used by Apple's latest kernels, is supported as well: functions that sign their return address with PACIBSPPC and return with RETABSPPC are created, their ends are found, and the return is linked back to the function:
Smaller additions
swift: recover string literals during auto analysis
swift: recover string literals that only the decompiler sees
swift: apply only complete prototypes to Swift functions
swift: derive function and variable types from the demangle tree
swift: show flags and metadata states of Swift runtime calls by name
new option to vertically align consecutive assignments
PPC: the thread pointer r13 is shown as R13 instead of an uninitialized variable
new "Mark as outlined code" toggle in the pseudocode context menu sets
FUNC_OUTLINEon the function and refreshes its callersthe same is available without the dialog as "Decompile recursively" (Edit > Other, Ctrl+Shift+F5), and in batch mode with
-Ohexrays:-recursivemacho: listings show a signed binary's entitlements and hardened runtime
pe: the POGO debug information is shown as records with section names
pe: the POGO debug records refer to the starts of their section groups
the final analysis pass no longer hides strings in arrays (Vladimir Vishniakov)
Strings: the listing shows a synthetic string where the code uses it (Julian Kirsch)
XNU: kernel classes whose members are XNU-private now have their real layout
pathfinder: "Delete selected nodes" in the waypoint tree's context menu
choosers and tree views got a "Copy" submenu: copy the selected rows, copy the current cell, copy as deeplink
a plugin can group itself in a submenu of Edit>Plugins with a slash in its name; the SDK samples are grouped under "Examples"
names that could merge with the code around them are shown in backticks
git: repositories follow IDA upgrades; git-ida entries are repointed automatically
decompiler:
decompile_many()with a null output file decompiles to the cache only, andVDRUN_RECURSIVEis exported; from IDAPython:ida_hexrays.decompile_many(None, [ea], ida_hexrays.VDRUN_RECURSIVE)added
NTF_AUTONAMEto save a udt under a name built from its member typesadded
tinfo_t::create_tuple()to create and save a tuple from member types
Fixes and refinements
A recurring theme this round is robustness against malformed and malicious input, in the remote debug server, the FLAIR tools, and several loaders and processor modules.
Decompiler
vd: x86:
movqbetween vector registers copied the full 128 bits instead of the low 64vd: x64:
lock or [rsp], 0memory barriers in MSVC code produced bogus stack arrays or_InterlockedOrcallsvd: x64 conversions between 64-bit integers and floating point values were truncated to 32 bits
vd: floating point NaN checks were removed from the output
vd: magic-number signed divisions were not recognized when other code was interleaved with the division sequence
vd: unreachable statements could be printed after a try statement or a jump
vd: INTERR 53087 on a 32-byte AVX copy into a stack variable
vd: a huge function with C++ exception handling crashed IDA and could not be cancelled
vd: INTERR 52369 on a Go function returning a value in a non-standard register
vd: INTERR 50689 on isnan() of a long double on ARM64
vd: INTERR 50743 on a noreturn call returning a struct in several registers
vd: INTERR 50708 when a call result was used as an lvalue
vd: cancelling a decompilation did not stop the text search in the Classes view
vd: 'continue' in a do-while loop could skip the loop condition
vd: float operands widened to double printed as float arithmetic
vd: a narrowing cast on a ternary branch could be dropped, changing the value
vd: an internal error while refreshing the global xref list caused an unhandled C++ exception
vd: "keep non-library functions" truncated the functions it kept
vd: Swift code in ELF/PE files was decompiled as C on first load
vd: Swift: calls whose prototype could not be used lost the Swift convention
swift: wrong prototypes for Swift runtime calls taking or returning two-word values
swift: calls lost String arguments when debug info described String
Disassembler and processor modules
mips: psp allegrex: malformed VFPU instructions could crash IDA while decoding
mips: a loaded word that held the address of MIPS16 or microMIPS code (ISA bit set) stayed a plain number instead of becoming an offset
mips: PLT entries and lazy binding stubs in n64 binaries, R6 binaries and binaries built by newer binutils are now recognized as thunks
mips: the unaligned stores
uswandusdwere treated as loads, so code using them was rolled back to data and their cross-references were marked as reads instead of writesmips: IDA crashed analyzing a function whose entry is the delay slot of a branch in its own tail chunk
ppc: corrected the operand flags of many instructions
ppc: Xbox 360 binaries are now decompiled as ilp32 code
dalvik: casts on an accessed object were printed without the parentheses Java requires
dalvik: accesses to inherited instance fields were shown as iget/iput helpers
hexagon: a string literal lost its first character
hexagon: dmwait lost the register it writes
hexagon: an unmodelled instruction could delete what it reads
hexagon: a store of a register the function had overwritten was taken for a prolog spill
hexagon: recognize a jump table whose default case falls into the dispatch
hexagon: recognize a jump table whose dispatch is folded into one packet
hexagon: recognize the restore helpers that are jumped to, not called
spu: binary files were disassembled as little-endian
v850: IDA View could hang, reloading forever, on a GHS 'callt ___ghsld4*' function return
x86: jmp using pointers to SEG_XTRN segments had no code xref
sh: IDA detects functions that do not return
Loaders
elf: mips: in MIPS16 and microMIPS binaries, some entries were named one byte into the stub, so no function was created for them and calls showed
jal byte_XXXXinstead of the import's nameelf: mips: in unstripped MIPS16 binaries, the literal pools after each function (
__pool_*symbols) were disassembled as instructions
Type system
clang parser: a structure typedef used by value after being used through a pointer crashed IDA
types: function arguments could not be named after registers, which also broke "Add argument" on MIPS
types: reject
__swiftselfon non-pointer arguments
Debug info
pdb: functions returning a small struct had a missing or extra result pointer
Analysis & Kernel
with the xref cache off, xref walks in a rebased database skipped or repeated xrefs
UI & UX
"Edit location" in the function prototype editor did not show the current register of an argument
highlighting a register no longer matches it inside other words (e.g. r8 in cr8)
the Teams file trees kept scheduling reloads of themselves while loading their own data
the Teams file trees triggered an internal error 40795 when the current item was inside a collapsed folder
or a double-click on a type's header in a loaded type library offered to edit the type
in a tree view, the first keyboard move after opening left the last cell of the previous row painted as selected
in a text field with a history, skipped the most recent entry
the type name field of the "Add type" dialog lost its input history
macOS VoiceOver could crash when filtering table choosers
tree filter highlights could be unreadable in OS dark mode
a list without a filter or status bar left blank space below its rows
FLIRT & FLAIR
flirt: a short wrapper could take the name of a library function like exit
flirt: library functions found late in the analysis stayed unrecognized
flair: sigmake could crash on a .pat file with a pattern longer than 65535 bytes
flair: ppsx PSX object parser could crash on a crafted object file with an oversized section
flair: pmacho dereferenced an out-of-bounds section on a crafted symbol
flair: pmacho could write past a section buffer on a crafted Mach-O object
flair: pelf could write out of bounds on a crafted ELF object file
flair: zipsig double-closed the output file on a malformed signature
zipsig: guard write_node against a null or malformed tree node
Performance & Resource Consumption
ldr: a long chain of thunks from a named function made the database grow to gigabytes
kernel: a variable read by many instructions made analysis quadratic
ui: filtering and selecting in large folder trees is much faster
Debuggers
a malicious client could crash the remote debug server with a bad file index
Configuration, IDAPython, SDK & API
installer: windows: a message said the Visual C++ redistributable installation failed when a newer version was already installed
loaders built with the SDK's CMake files could corrupt the heap on loader_failure() on Windows
IDAPython:
IDP_Hooks.ev_decorate_namereceived a truncated calling convention
Highlights
New Decompiler: Dalvik
IDA now decompiles Android DEX bytecode into Java pseudocode. It is built on a typed model of the DEX file, so a class, a field, a method and a parameter are all real, renameable, retypable entities, and an edit to any of them propagates through the pseudocode.
a class view lists the program's classes and shows each declaration with its fields and methods; it offers pseudocode hints and "Move function to folder", and Ctrl+Shift+F6 or a Ctrl+double-click in the class tree opens another class view
in a multidex application a call reaches the method body in the other dex file, and a virtual call also references the overrides in the subclasses
try/catchblocks are reconstructed from the DEX exception tablesmethods with optimized (odex) bytecode are decompiled too
obfuscated names are recovered wherever the file still carries them: Kotlin metadata, serializer annotations and DEX debug info
The class view is where you work: Tab switches between the disassembly and the class view, and it offers the pseudocode editing actions — comments, renaming locals, arguments, labels, fields and methods, "Set type" in Java syntax (register widths are checked), collapse/uncollapse, invert if, hide casts, map/unmap variable, local cross-references and synchronization with the other views.
The output reads like the source:
string concatenation is shown as
"a" + binstead of theStringBuilder.append()chain that javac, kotlinc and d8 generatenested classes print as
Outer.Inner; declarations show generics (fromdalvik.annotation.Signature), annotations as@Foo(...), and anonymous classes asnew Type() { ... }method parameters are named from the DEX annotations
calls use the callee's declared type, so retyping a method updates the pseudocode of its callers, and array arguments are no longer degraded to
Objecttry/catch/finallyis reconstructed by dominance analysis: nested blocks, catch-all handlers,finallyblocks that end inreturnorgoto, andsynchronizedblocks with several exits
For scripts and plugins, the new language-neutral class API (get_classes(), get_class_info(), render_class(), render_member(), C++ and IDAPython) has Dalvik as its first backend. Edits made in the class view do not raise the Hex-Rays pseudocode events (variable renamed/retyped, comment changed, ...).
Limitations: try-with-resources is not reconstructed (the output is longer but correct), and the output is Java, not Kotlin.
New Decompiler: TriCore
Infineon TriCore: the new hextricore plugin decompiles TriCore code. It supports eabi and Tasking ABI families.
New Decompiler: Hexagon
Qualcomm Hexagon (QDSP6): the new hexqdsp6 plugin decompiles DSP code. It models packet semantics (parallel reads, .new values, predication), hardware loops, compound branches and jump tables, floating point, and the scalar SIMD instructions; HVX vector and system instructions appear as intrinsics.
every instruction of a packet reads its registers as of the packet start,
.new/.curoperands see the packet's own results, and predicated instructions become conditional blocksvariadic functions are recognized
intrinsics use clang's
__builtin_HEXAGON_*names, so their semantics can be looked up inhexagon_protos.hHVX vectors (
V0–V31,Q0–Q3) are modeled as vector registers, and system, guest, cache and supervisor instructions appear as intrinsics
Decompiler Support for Bitfields
Accesses to C bitfield members are shown as member accesses instead of shift and mask arithmetic: (*(_DWORD *)&s >> 3) & 7 reads as s.field, and *p = *p & 0xFFFFFF07 | (v << 3) & 0xF8 as p->field = v (once the types are correctly defined and applied). It covers every architecture supported by the decompiler, including the dedicated extract/insert instructions of ARM64, PPC, MIPS and RISC-V. It is enabled by default but can be turned off with "Decompile bitfield accesses" in Edit > Plugins > Hex-Rays Decompiler Options > Options 2
Most patterns used by popular compilers are handled. For example, the non-obvious xor toggle from MSVC:
Other recognized shapes:
reads scaled by a power of two (the mask gets scaled too)
fields extracted from a copy of the unit loaded into a register
a field in the top bit tested by a signed comparison,
an access narrower than the unit
A store that packs several fields of one unit decomposes into per-field assignments; the same field compared or combined across two objects shows both members; a masked compound update with a variable operand folds:
The bit allocation order defauls to the same direction as byte order, but can be fliped for specific types. This is a common situation in Xbox 360 binaries, which use litte-endian bitfield order for GPU registers or some kernel structures inherited from the Windows kernel. If needed, #pragma bitfield_order(lsb_to_msb) or __invbf specifier can be used to mark such types.
When PDB with full type info is available, it is used to detect the bit order:
Better SSE/AVX/AVX2/AVX-512 Support in the Disassembler and Decompiler
x86/x64: loads and stores wider than 16 bytes are shown as plain C assignments instead of SSE/AVX load/store intrinsics, and
punpcklqdqis shown as a move into the high half, so "Split expression" can split it
Where AVX code used to decompile to __asm blocks, the new avxlifter plugin turns AVX, AVX2, AVX-512 (F/CD/BW/DQ/VBMI/VNNI/BF16/FP16/VL) and VMX instructions into native microcode where the decompiler can reason about them, and into _mm*_… intrinsics on __m128/__m256/__m512 values otherwise — masked EVEX merge/zero forms, gather/scatter, compress/expand and the opmask k registers included.
packed and/or/xor/andnot become C operators, so sign-flip and abs masks read as
a ^ signmaskanda & absmask, andvxorpd x, x, xis0.0scalar FMA and min/max become C math (
fminf,fmaxf) instead of_mm_*_ssintrinsicsintrinsics without side effects are marked pure, so dead vector computations are removed
XMM, YMM and ZMM are modeled as views of one register, with legacy-SSE writes leaving the upper part intact; bogus undefined YMM variables are gone
vector unions gain
__int128members, which removes*(_OWORD *)castsSIMD loads, stores,
memcpy/memmoveand structure copies are plain assignments; no_mm_loadu_si128/_mm256_storeu_psremaintzcntis lifted to__tzcnt()string literals copied piecewise with
movups/movsd/mov/movzx, UTF-16 and MSVC's mixed-width copies included, are recognized. This is analysis, not lifting, so it works without the pluginfunctions that align their frame pointer (
and rbp, -32, typical for AVX code) have stack variables again, instead of&v3 & 0xFFFFFFFFFFFFFFE0
Apple Kernel Cache Loader
IDA 9.5 does for Apple kernelcaches what 9.4 did for dyld shared caches: a kernelcache is a collection of KEXTs, and IDA now treats it as one rather than as a single large Mach-O. A linked kernelcache — a system or auxiliary one — is handled together with the boot KC it references, as one coherent set: a single layout, with symbols and references resolved across the link.
a KC Index widget lists the KEXTs of every collection in play, filterable by the one they came from, and maps them on demand — the kernel up front, the rest as you reach them
the C++ runtime is reconstructed from
OSMetaClass— the class hierarchy, the virtual methods with their full signatures, the metaclass vtables — andOSDynamicCastresults,kalloc_typedescriptors and typed allocations are typed against the XNU type library matching the cache's OS versionLocate > Symbol / String / Address search the whole cache straight from the file, so a KEXT you never loaded is searched like any other, in any collection of the set; and a string search still works on a stripped cache, where there are no symbol tables at all
the Functions list holds a folder per KEXT or cache image, nested by bundle id (
com/apple/iokit/...);FUNC_FOLDER_FORMATinkcu.cfg/dscu.cfgsets the layout, and""keeps the list flatan example plugin extracts a KEXT or a dyld cache image to a standalone Mach-O ("Extract Mach-O image to file..." in the KC and DSC Index, Ctrl+Alt+Shift+M). The result can be analyzed but not run: it carries no rebase or bind information
Verbatim Function and Type Names
Modern languages (Rust, Go, Swift, heavily-templated C++) name things with characters that are not valid C identifiers. IDA no longer garbles those into an ASCII-safe form: symbol, type, and member names are now kept verbatim, as they come from symbols, demanglers, and debug info.
new databases display demangled names by default
qualified names such as
A::B::Chighlight, select, and cross-reference as a single unit — in disassembly, pseudocode, and printed prototypesFLIRT signatures can carry original (unmangled) names, and Go/Rust/Swift naming is honored end to end
non-C type and member names round-trip faithfully through the Edit-type dialog
the classic behavior stays available per database via the
GarbleNamespolicy (frozen at database creation); existing databases keep their current names
IDA used to replace every character that is not valid in a C identifier with _. Types could not be found by their real names, and Rust, Go and Swift binaries read poorly:
a name that is not valid C is quoted with backticks when you edit it, and the parsers unquote it — in the Local Types editor, "Set type", the prototype editor and the decompiler's retyping dialogs, with both the clang and the legacy parser. Go's
[]stringandinterface {}are accepted as type names and highlight as one unit in the pseudocodeAlt+click highlights only the component under the cursor, e.g. to copy the class part of
A::B::methodwhere a type has a prettified name, the Types window shows and filters on it, hovering shows the full raw name, the raw name behind it is painted translucent, and Jump Anywhere finds the type by either name
DemangleNamesinida.cfgnow defaults to 5, so new databases show demangled names as names; on ARM, imports honor the setting tooGarbleNamesinida.cfgis a bit mask:0x1/0x2garble symbol names in storage/display,0x4/0x8do the same for type and member names; the default 0 keeps everything verbatim
Migration: the policy is fixed when a database is created. Databases made before 9.5 keep garbling, so their names do not change under existing scripts.
FLIRT 2.0
Classic FLIRT recognizes a library function from its bytes. The target of a call inside it is relocated by the linker, so FLIRT treats those bytes as a wildcard and forgets what they pointed to — and a helper that has no reliable signature of its own stays unnamed:
FLIRT 2.0 signatures (format v11) also record what each library module refers to. Once library_function is matched and its call lands at a certain address, IDA knows the function there is hidden_helper. After auto-analysis, a deferred pass names the functions reached from recognized code this way, and uses the same evidence to choose between byte-identical candidates.
Correctly named functions in a stripped, statically linked sqlite3:
glibc amd64
1279
1846
glibc i386
1424
1826
glibc arm64
1434
1815
glibc armhf
776
1204
glibc riscv64
288
933
glibc s390x
1398
1739
MSVC /MT x64
565
698
MSVC /MT x86
458
561
MSVC /MT arm64
0
753
MSVC /MT arm
0
622
32-bit binaries of VC 14.39–14.52 are recognized, and the ARM and ARM64 MSVC runtime signatures cover VC11 through VC 14.52
main/wmainandWinMain/wWinMainare told apart from evidence in the binary; startup signatures name the functions and data their entry module references (___xc_a,__commode,__fmode, ...)signatures can carry original, unmangled names: the Go runtime signatures keep
runtime.(*mheap).alloc(the old mangled ones ship as*_legacy.sig)signatures load faster (bulk and buffered reads)
Migration: sigmake now always writes v11. IDA 9.5 reads older .sig files, but IDA 9.4 and earlier reject v11, so signatures built with the 9.5 FLAIR tools do not load in 9.4.
More Precise Decompiler-Based Switch-Case Recovery
switches that the compiler split across a binary-search dispatch are put back together: a switch nested under an equality or range guard is merged into its parent, and two switches separated by such a guard are combined into one
a jump table built on a pivot-subtracted selector (
switch (x - C)) is rebased onto the original value, so the real case labels are recoveredswitches are recovered better from if-chains, including dispatch trees whose cases fall through, and getopt-style trees whose arms leave through the enclosing loop
cases are sorted by value, cases sharing a body are merged, and a case that only jumps into another case is folded into it
Compilers lower a sparse switch as a binary-search tree of comparisons, often against a pivot-subtracted copy of the selector, with the case bodies sharing tails through goto. All of that used to survive into the output. The recovery now runs at both levels: a microcode pass puts the jump table back on the original selector, and ctree passes fuse the fragments and restore the labels.
Shared case tails render as fall-through:
A jump table built on a pivot-subtracted selector dispatches on the same value as the surrounding comparisons again, so the fragments fuse and the real labels come back.
Dispatch trees whose case arms assign something and flow on into a shared tail are merged too — the commonest shape of all, and what makes a getopt loop mergeable. That is done only while the arm's original successor is the continuation kept after the merged switch, so the recovered switch computes what the original code did.
On every architecture — x86, ARM, MIPS, RISC-V, PPC, ARC, V850 and Dalvik — the decompiler now finds jump tables with its own data-flow analysis on the microcode instead of reusing the disassembler's switch information. Switches the disassembler missed ("switch analysis failed") are recovered, identical switches are merged, and many that used to decompile wrong are now correct:
jump tables made of branch instructions (ARM
ADDLS PC, PC, R3,LSL#2followed byB case_n, PPC/GHS tables) are recognized as switches, and Dalvikpacked-switch/sparse-switchare built from their payloadwhen the compiler reuses the selector's register for an offset copy (
v = x - C), the comparisons are rewritten against the original variable and the dead offset chain is removed; recovered case labels keep their number format (enum, hex, char)where no range check can be found, the recovered switch shows
default: abort()
"Create C file" Decompiles a Function Together with Its Callees
File > Produce file > Create C file... (Ctrl+F5) now offers "Current function and its callees recursively" next to "All functions" (or the selection). Callees are decompiled first, from the leaves up, so every function is decompiled after the functions it calls, and their recovered prototypes improve the pseudocode of their callers.
calls through
.pltand stub thunks are followed into the real function; imports are skipped; the root function is always included and only its callees are filteredthe dialog offers "Skip debugger segments", "Skip library functions" (on by default: only the non-library functions of the current module are included) and "Decompile to cache only" (no file is written; reports how many functions were decompiled); the choices are remembered between sessions
New Add-ons
IDA MCP Add-on
A first-party, open-source MCP server that connects your AI agents to IDA, fully locally and across multiple databases at once.
IDA Assist Add-on
Assist is an AI harness for reverse engineering, built into IDA. It works with any capable AI model, local or cloud, and combines the model with IDA's own analysis engines, emulation and an SMT solver to produce explainable results. It can analyze several databases at the same time.
Malware Analysis Add-on
A new Hex-Rays add-on for malware analysts: one-click unpacking, safe emulation of suspicious code, and sandbox results shown right in the disassembly.
Higher-Level Language Support
The Disassembler Recovers Swift Strings
The Swift compiler represents strings as two 64-bit immediates. A small string is embedded in the immediates themselves, a large literal is a tagged pointer, pointing at a fixed offset before its contents. This makes decoding Swift strings quite annoying, and typically required manual work, or writing a plugin. IDA 9.5 now has this logic built in, decodes the Swift strings, and adds them to the String widget (Shift-F12) for easier referencing. This mechanism is backed by our new Synthetic Strings API (see below) and is fully accessible to plugins. Here is an example of how the mechanism looks in real life (spot the decoded string at 0x220EA6B40):
IDA 9.4:
IDA 9.5:
Loading of Go Binaries with Corrupt/Obfuscated Metadata
IDA now loads Go binaries whose metadata has been damaged or obfuscated:
the pclntab is found even when its magic is overwritten, its section is stripped or renamed, or it is embedded inside another segment
the Go version is recovered when no build string survives
functions and names are recovered in garble-obfuscated binaries
Go 1.27 binaries are supported
Rust ABI on ARM[64]/MIPS/PPC/RISC-V
CM_CC_RUST, introduced for x86 in 9.4, is now implemented for ARM64, 32-bit ARM, MIPS (o32 and n64), PowerPC (32- and 64-bit) and RISC-V (32- and 64-bit), so Rust binaries on those targets get their real arguments and return values instead of guessed ones. Alongside it:
string literals appear in the pseudocode instead of a raw address, and the string-slice type is named
&strpanic and abort helpers are recognized as non-returning
the exception handling tables of Rust binaries are parsed
zero-sized members and parameters (the unit type
()included) are dropped from DWARF-recovered Rust types, and the hidden environment pointer of a closure is recoveredRust binaries are detected without DWARF, even when stripped — by
rust_eh_personality, therustc-markers in read-only data, and legacy or v0 mangling — and their functions default to__rustinstead of__fastcallwith DWARF, each function's convention is checked by lowering its DWARF signature under the Rust ABI: functions mislabeled
__usercall/__fastcallbecome__rust, andextern "C"helpers wrongly marked__rustare corrected. The argument locations in clang/LLVM Rust DWARF are corrected too (reversed big-endian register pieces, mis-rebased stack slots)a packed or under-aligned aggregate return no longer loses all but its first field (x86/x64 included); sub-word arguments promoted into full registers, and mixed arguments whose stack part comes before the register part, are handled
compiler-generated wrapper types for array arguments and returns get descriptive names (
_20_arr_int) instead ofretval_<ea>, so identical types are shared
Minor Improvements
golang: string literals are recognized in the microcode, so they appear in the pseudocode instead of a raw address
rust: panic and abort helpers are recognized as non-returning
rust: more library functions that never return are recognized
rust: the exception handling tables of Rust binaries are parsed
rust: string literals are shown in the pseudocode instead of a raw address
rust: the created string-slice type is named
&str
Bugfixes
golang: negative
UnsafePointconstants were shown as0xFFon unsigned-char targetsgolang: no type information was recovered from some big-endian binaries
golang: no type information was recovered from some ppc64 binaries
golang: an incomplete map type was recovered from Go 1.24 and later binaries
rust: arm64:
u128stack arguments were misaligned on macOS
Decompiler
Jump to Function Pointer Struct Members
The Enter key and a double click on a called function pointer member now go to the function that the member points to, and not to the declaration of the member. A member of this kind is one entry of a virtual function table, or one entry of a dispatch table that the program builds by hand. If the pseudocode names the object, IDA goes to the function of that object; if it does not, IDA offers the functions of all the objects that have the type. "Jump to structure definition" keeps its behavior, and a member that is not in a call keeps its behavior.
the object can be a global, an array element with a constant index, a member of another structure or union, or a chain of these:
g_dev.ops.call(),g_tab[1].call()when the object is not named, IDA scans every data item of the structure type: one target jumps directly, several open a "Possible callees of Type::member" chooser. Candidates come only from data items that have the structure type applied; for large arrays a cancellable wait box appears
it works in the Dalvik class view as well
"Split variable" for Register Variables
"Split variable" and "Unsplit variable" now work on register variables too, not only on stack variables.
The post-split occurrences are renamed to a fresh register before the use-def chains are built, so a separate variable starts at the split point. The split is validated first: the split point has to fully redefine the register, every renamed use has to be dominated by it, and a loop-carried self-referential accumulator is rejected. A function with no register split is unaffected.
New "Create scattered pair" Operation
On 32-bit targets a 64-bit value can sit in a pair that no single storage location describes: reversed (low half in r2, high half in r1), non-adjacent (r3+r12), or a register plus a stack slot. Those used to be two 32-bit variables joined by __PAIR64__ helpers, and retyping half of one to a 64-bit type simply failed. Pairs with evidence are now converted into one scattered variable automatically, and "Create scattered pair" / "Delete scattered pair" cover what the automatic recognition deliberately leaves alone. Scattered operands also propagate their names, so Go string variables in register pairs get their real names instead of vNN.
Shifts and multiplies of such a pair are fused into single 64-bit operations instead of separate LODWORD/HIDWORD updates.
the command works on a
__PAIR__expression or on any variable, with the other half picked from a list. The choice is saved with the function; "Delete scattered pair" also keeps the pair from being re-created automatically. When enlarging a variable fails, the warning suggests the commandthe automatic conversion needs evidence — the pair is compared, has a stack half, or occurs several times; x86
edx:eaxpairs and 128-bit values are left alone. If the halves were named, the variable takes their name, minus a_hi/_highsuffix
Better x87 FPU Stack Handling
On x86, FPU stack recovery no longer gives up when a callee is typed as returning void or an integer but actually leaves a value on the x87 stack. The stack model is retried with such calls unpinned, the callee's return type is corrected, and a note names it at the call site — instead of the whole function dropping to inline __asm.
A function whose x87 stack model came out infeasible used to drop to inline assembly wholesale, and both common causes were callees with a wrong prototype, not the code being analyzed:
a callee typed as returning an integer but returning in
st0no longer pins the stack delta, so its callers decompile instead of dropping to__asmwhen the strict model fails, it is retried with such calls unpinned, instead of giving up with "inconsistent fpu stack"
a prototype that cannot account for the values left on the stack gets a red header comment with the actual and the declared FPU slot counts, instead of a silent note in the Output window
Merged Structure Fields Come Apart
A compiler initializes or compares several adjacent structure fields with one wide operation. Both are now undone when the members tile the accessed range exactly.
each member's value is cut out of the constant in the program's byte order. Padding, a partially covered member, a union, or a base expression with side effects leaves the store alone
==joins the parts with&&,!=with||. GUIDs benefit most: their fields show as recognizable hex constants instead of one large decimal number. Ordering comparisons are left alonethe split is reversible per expression: "Unsplit expression" is offered on the generated assignments
Swift Binaries Decompile Correctly Even When Stripped
The decompiler recovers the Swift calling convention and Swift error handling even when a binary carries no prototypes:
the swift calling convention is recovered on stripped binaries: it is recorded at analysis time and applied at decompile time without being stored as a prototype, so call-site argument recovery keeps working. Arguments spilled to the stack at swiftcall sites are recovered as well
throwing calls and functions are recovered on stripped binaries. At a throwing call the error result is surfaced as
__swift_get_error(), so the followingif (error)check reads normally instead of as opaque error-register traffic; a throwing function's own result type and__swiftthrowsattribute are reconstructedruntime enum parameters are typed as enums instead of
void *, and Swift is reported as the compiler in the output header
Minor Improvements
GCC/Clang builtin names (
__builtin_bswap32,__sync_fetch_and_add, ...) are used for non-MSVC targetshexagon: variadic functions are recognized
64-bit variables stored in scattered register/stack pairs are recognized
a bare constant stored into an unsigned variable is shown unsigned: a byte store of
0x9Fno longer prints as-97, and an HRESULT reads as0x80070057instead of-2147024809the carry flag of a constant left shift is folded into a bitmask test
x ^ ~xis simplified to-1andx & ~xto0on 32-bit targets, 64-bit shifts and multiplies held in unaligned register pairs (such as
r1:r2on ARM) are recovered as single 64-bit operationsa carry flag used as a boolean value — a
boolreturn value, for instance — is shown as a bitmask test such as(x & 0x100) == 0instead of__CFSHR__, and the carry of a left shift often simplifies further into a sign comparisonhints for
sizeof()andoffsetof()show the numeric valuea rotation that cannot move a set bit to the other end is shown as a shift instead of
__ROL__/__ROR__:__ROL4__((unsigned __int8)fe->PrologLen, 2)becomes4 * fe->PrologLena call returned directly by the function takes the function's return type, so a 16-byte result such as a Rust
&stror a SwiftStringis no longer cut in halfthe function prototype editor ('y') no longer offers the argument names the decompiler invented (
a1,a2, ...), so accepting the dialog does not turn them into real namesarc: the arguments of MetaWare variadic functions are recovered
arc: the vararg frame of MetaWare ARCtangent-A4 code built without helpers is recognized
arc: the MetaWare compiler's millicode helpers are handled better
v850: the 64-bit integer helpers of the GHS and CC-RH runtimes are decompiled instead of being left as calls
ppc: cache, barrier, load-and-reserve/store-conditional, MSR/SPR/time base and FPSCR instructions are shown as intrinsics instead of
__asmblocksmore
memcpycalls, also through pointers, are turned into plain copies, so more values propagate and dead code is removedx64: empty C++ records are dropped per the modern System V psABI; the legacy GCC < 8 layout is the new
-sysv_pre12ABI option, set automatically from the DWARF producer
Bugfixes
vd: decompilation could fail with INTERR 52870
vd: x87 instructions could be left as
__asmstatements when a function called from x87 code had a wrong integer return typevd: a bitfield access through a struct with an incomplete member could fail with INTERR 50689
vd: variadic arguments were invented for
printf-like wrappers called with a literal format stringvd: setting a local variable or argument type could crash (INTERR 1098)
vd: a stack argument could inherit the type of a local variable that reuses its slot
vd: clicking a demangled name did not highlight the whole name
vd: arm64_32: decompiling code that takes the address of a stack variable could fail with an internal error
vd: decompilation could fail with INTERR 52482
vd: rust: a sub-word integer argument on the stack that the compiler loaded as a full slot was shown as
*(_QWORD *)(&arg - 1)vd: early propagation of stack references ran before the control flow graph was built
vd: a wrong member was used to access a small struct argument
vd: a small struct or array passed in a wider register was accessed wrongly
vd: a stack variable that used a guessed type could cause a crash
vd: a wrongly defined
__m128in the database could cause an internal errorvd: float constants were printed imprecisely and without the
fsuffix, and were byte-swapped in big-endian databasesvd: golang: assembly functions such as
runtime.memequaldecompiled asvoid, which could delete comparisons in their callersvd: a 256-bit AVX store to the stack failed to decompile
vd: golang: a function with a stack argument failed to decompile
vd:
-nosavedid not prevent saving the input databasevd: x64: stack variables were not recognized in functions that align their frame pointer (AVX code)
vd: auto-renaming offered register names such as
r3_0as variable names, and could fail with INTERR 51365 on PowerPCvd: golang: write barriers (
runtime.gcWriteBarrier1..8) took invented arguments, so every call site passed garbagevd: "Enable SSE intrinsics" and "Hide casts" could not be undone
vd: x86:
bt reg, regkept a dependency on the upper bits of the index register, producingLOBYTE()and "possibly undefined" variablesvd: arm64: values stored by prolog instructions (
STR Rt, [SP,#-N]!in Rust code, for example) were lostvd: dalvik: decompiling nested calls with narrowed arguments could crash
vd: ppc: an argument following a float argument got a wrong location
vd: a guessed
__fastcall-like calling convention could put the arguments of a call in the wrong placesvd: mips: in MIPS16 functions with a frame pointer, stack accesses through
$s1were shown as reads of an uninitialized registervd: setting a variable's type with "Setting type renames target" dropped or overwrote the name it already had
vd: dalvik: corrupt try/catch data hung the decompiler and flooded the loader with warnings
vd: v850: structure, union and bitfield accesses could fail with INTERR 51111, 51625 and 50698
vd: reading the label of an empty nested block could crash
vd: the pseudocode restored from the database was garbled for functions with try/catch (function roles were not serialized)
vd: renaming a structure field accessed through a typedef had no effect
vd: opaque Windows types such as
HWNDwere not replaced by their typedefsvd: mips n64: references through the GOT were shown as meaningless address arithmetic, and calls through GOT slots were not resolved
vd: a jump table of instructions was missed when its index was loaded from memory
vd: pressing 'y' on the prototype line of the pseudocode did nothing
vd: verbatim type names (Go's
[]string, for example) were rejected by the "Set type" dialogs, and highlighted only partially in the pseudocodevd: dalvik: fields of a class that the file only references were shown as
__iget__/__iput__intrinsicsvd: changing a variable's type with automatic renaming enabled could crash
vd: large functions could hang the decompiler (unbounded
get_bitwidthrecursion), and decompiling a switch with a huge value interval could run out of memoryvd: swift: renaming a function parameter changed the wrong one, and a function returning a value wider than one register caused an internal error
vd: ppc: restoring the TOC in PS3 ILP32 code could fail with INTERR 50836
vd: ppc: AltiVec and byte-reversed loads in PS3 ILP32 code could fail with INTERR 50826/50920
vd: ppc: string literals loaded through the TOC were not shown in the decompiler output
vd: many other internal errors reported by users were fixed, across x86/x64, ARM, ARM64, PowerPC, MIPS and V850 code
Disassembler
Register Values Tracked Across Loops and Stack Variables
Firmware and C runtimes call arrays of function pointers in a loop — __libc_init_array, .init_array, __libc_freeres, driver tables:
Those indirect calls had no cross-references, so whole subsystems stayed invisible. IDA now tracks a register that a loop changes by a constant step, and every function in the array gets a call xref; in a MIPS gzip uImage this uncovered 18 new functions.
ARM and MIPS: a static array walked in a loop gets data and string xrefs to its elements; on ARM a structure array shows member offsets (
[Rn,#Struct.field]), and[Rn,Rm]accesses andADD Rx, Rbase, #immon named data become offset expressionsan array entry is accepted only if it points at code; the array ends at the first entry without a value, with a name or xref of its own, or that does not look like a function
REGTRACK_ALLOW_NUMLOOPinida.cfgswitches it on per processor"Find a value" (Alt+Shift+V, formerly "Find register value") also resolves the stack variable under the cursor, and the return address pushed by
call $+5SDK: a new loop value kind; plugins built against 9.3 see it as the old unknown-loop value
ARC: Jump Table, Millicode Recognition and Other Fixes
bi/bihjump tables are recovered as switches, and the ARCtangent-A4 indirect call idiom is recognized as a callthe out-of-line millicode helpers of the MetaWare compiler are handled, and the arguments of MetaWare variadic functions are recovered
enter_s/leave_s, thebi/bihswitch jumps, multiplies, set-conditionals, divisions,bmsknandmin/maxare decompiled instead of being left as__asm. Functions that used to end in an asm statement and aJUMPOUTget real returns, and abi/bihdispatch becomes a switch instead of always reaching case 0
Whole instruction families were never lifted, so they printed as __asm, and every use of their result read a pseudo-register. Every leave_s was a missing return.
With the products computed, the magic-multiply recognition runs and the divisions hiding behind those sequences come back. The flag-setting .f forms follow the "STATUS32 Flags Affected" table of the ARCv2 PRM:
Some instruction sequences used to decompile to wrong code: bbit0 r13, r15, loc used r15 — its own second operand — as scratch and then zeroed it, so everything after the branch read 0 instead of the loop counter. The same defect was in asr/lsr/asl/ror and btst/bset/bclr/bxor/bmsk. The GCC millicode prolog/epilog helpers and the vararg home area are handled as well as the MetaWare ones.
ARM: More Armv9 Extensions
The disassembler decodes FEAT_LUT, FEAT_CMPBR, FEAT_CPA, FEAT_LSUI, FEAT_FPRCVT, FEAT_MOPS, FEAT_FCMA and FEAT_SPECRES2. These are becoming mandatory in recent versions of the architecture.
Hexagon: No-Return Analysis, Absolute Memory Target Handling, Switch-Case Discovery, Function Epilogues
Lots of improvements and bug fixes. Here are some highlights:
GP-relative (small data) accesses are resolved against
_SDA_BASE_, set with the newQDSP6_SDA_BASEkeyword or in the processor optionsthe ELF loader computes GOT and GOTREL relocations as the ABI specifies, handles the TLS relocations, and applies
R_HEX_32to DWARFthe epilog is found by the frame slot an instruction restores, not by its position, so predicated early returns are covered
Support for MIPS R6 Instructions
IDA now fully supports MIPS Release 6 in both the disassembler and the decompiler:
all R6 integer and FPU instructions are decoded, including those introduced with new encodings in R6
compact branches and jumps are supported
the decompiler handles R6 branches, jumps, selects and FP comparisons
R6 can be selected for plain (headerless) binaries, and PLT stubs are named
Game Consoles: PlayStation 3, Xbox 360, Wii U and PlayStation Portable
PlayStation 3: the disassembler and decompiler support 64-bit PowerPC with 32-bit pointers (celloslv2 ILP32). PS3 executables load with ILP32 segments and correct TLS variable addresses.
Xbox 360 and Green Hills (Wii U): the out-of-line register save/restore helpers (
__savegprlr_N/__restgprlr_N,__savefpr_N/__restfpr_N,__savevmx_N/__restvmx_N) are now named. The decompiler treats them, and their PS3 counterparts, as prolog/epilog. Callers decompile with correct arguments and return values, and without spurious calls. You no longer need to type the helpers asvoid __spoils<>()by hand.Xbox 360: stubs that use
r12as the link register or save vector registers are handled too. For example,JUMPOUT(0x80078B0C);now decompiles toreturn v6;.Xbox 360:
.pdataentries are decoded with their own layout, not as a Windows CE variant. Hand-written stubs with the 32-bit flag clear no longer have their length halved.PlayStation Portable (Allegrex): a new
single_floatABI option, on by default, passes floats in consecutive FP registers and doubles in GPRs. The decompiler uses the same ABI to reconstruct prototypes, so float and double arguments are deduced correctly.PlayStation Portable: the ELF loader supports packed PRX relocations.
AltiVec/VMX128 Intrinsics: on PPC, AltiVec/VMX128 vector instructions are shown as intrinsics named after the Xbox 360 XDK ones (
__lvx(),__vaddfp(), ...), with real vector variables as arguments and results.
WebAssembly Loader and Disassembler
IDA loads and disassembles WebAssembly modules, up to and including WebAssembly 3.0, such as those built by Emscripten, Rust or Kotlin/Wasm.
the whole instruction set: SIMD including relaxed SIMD, atomics, bulk memory, reference types and typed function references, garbage collection (structs, arrays, recursive type groups, subtypes, casts,
i31), exceptions (try_tableand the legacytry/catch), tail calls and multi-value blocks64-bit memories and tables, multiple memories, extended constant expressions and the element-expression encoding
stack code is folded into readable operands:
local.get A; local.get B; i32.addreads asi32.add A, Bnames come from the module: functions, locals and globals, and also types, fields, tags, tables and data and element segments
signatures become function prototypes, GC structs and arrays become local types, and globals get their declared types
every linear memory becomes its own segment, and a constant address in a load or store becomes a data cross-reference
blocks are indented by nesting, the block around the cursor is highlighted (processor option
WASM_MATCH_BLOCKS, on by default), and branches, catch clauses and handlers have code cross-references to their targetsthe name, linking, dylink.0, producers and source-map custom sections are parsed and annotated
Bugfixes
mips: allegrex: malformed VFPU instructions could crash IDA while decoding
ppc: in binaries with several TOCs, the TOC value was not resolved for functions without an
.opdentry
Analysis & Kernel
Exception Handling: Correct Stack Levels and Robust Try Blocks
A landing pad is entered by the unwinder, not by the code in front of it — yet IDA took its stack pointer level from the preceding instruction, and every stack variable after it was off.
a landing pad now takes the stack level of the region it guards. The fix is in the kernel, so it covers every processor module that lets the kernel compute block levels: ARM, MIPS, PPC, RISC-V, SH4, Hexagon, NDS32 and TriCore
x86: the landing pads of gcc-built PE files (MinGW, Cygwin) get the levels of their guarded region, as ELF files already did; the handler and filter funclets of a Windows
__tryare no longer fed to the SP model, since the OS calls them with frames of their own; and the stack cleanup after a call to a non-returning function, or in a handler of a region that does not end the block, gets the right deltaone malformed try block no longer discards all the others in the same range (a function with 7 good blocks and 1 bad one returned none), and a block reaching past the end of the program no longer hides the later ones
the guarded region of a C++
tryblock is part of the function even when it ends with a call that never returns, and the landing pad of an empty exception specification is no longer lostx64 epilogs restoring registers from
[rsp]without a displacement are recognizedfiles with a huge exception handling table analyze much faster, and files without SEH handlers skip the search for their owners
Minor Improvements
analysis: the new
OVERSIZED_FUNC_SIZEoption inida.cfg(default 0, off) flags larger functions as oversized (func_t::is_oversized()) and records a problem; on x86/x64 their stack-frame, SP, switch-table and stack-variable analysis is skipped. This protects against binaries built with huge functions to slow IDA downanalysis: the new
JUMPTABLE_MAX_INSNSoption inida.cfgbounds the work of a single switch pattern match, so obfuscated code cannot make one switch stall the analysis
Bugfixes
analysis: struct-typed stack variables named
~rNwere shown asbytetypes: a structure whose first member is empty, passed in registers as gcc does, could cause INTERR 10147
analysis: a prototype guessed from a demangled name could discard a good one
analysis: 128-bit values were shifted right incorrectly by 64 bits or more
arm64: Windows computed 128-bit products and quotients incorrectly
types: a gcc enum whose values need 64 bits got a 16-byte type
analysis: "autoanalysis finished" was not the last message
analysis: a type guessed from the symbol name was preferred over a type library prototype
analysis: the initial autoanalysis could take hours on a file with a huge array
database: closing a database could end with internal error 840
names: a function reached through a named thunk was given a suffixed duplicate of the thunk's name
names: names starting with a dummy name prefix could crash IDA
sdk:
DBFL_COMPwas ignored bysave_database()names: forced renames could corrupt names supplied in the database encoding
sdk:
fpvalue_t::to_float/to_doublereturned byte-swapped values on big-endian databases
UEFI
IDA 9.5 ships with a new UEFI plugin and loader. We still plan to refine this plugin in next beta versions and releases. The main focus was on the DXE environment for this release.
An entire UEFI firmware image (SPI flash dump, capsule body or firmware volume) can be loaded into one database. The new UEFI plugin analyzes UEFI modules, both single EFI/TE files and every module of a firmware image. It runs automatically after auto-analysis and adds names and types, allowing known protocols calls to decompile to readable code:
Entry points are named after their module and typed by FFS file type. In a firmware image, functions are grouped into folders by module.
Globals pointing to service tables:
gBS,gRT,gST,gSmstandgImageHandleare automatically found and typed.Protocols: installs, locates and notifications are found. GUIDs, interface pointers and implementations are typed and named, e.g.
DiskIoDxe_EfiDriverBindingProtocol_Start. Currently vendor protocols that no type library describes get a synthesized structure, but this behavior might still change.A new "UEFI protocols" window (View > Open subviews) lists every install, uninstall, locate and notify, with filters by kind and by module type (accessible via right click).
Cross-references are added from protocol member calls to their implementations, across modules. Double-clicking
x->Memberin the pseudocode jumps to the implementation, and a popup action lists a member's call sites. This works when a structure for the protocol is available.Read-only strings in
.dataare shown inline, andDebugPrint/DebugAssertcalls are recognized.Options are in
cfg/uefi.cfg.
Minor Improvements
dex: DEX items are shown decoded instead of as stored comments
dex: DEX version 040 files are supported
dex: all try blocks are kept for methods with more than 127 of them
dex: VDEX files are supported
elf: arc:
R_ARC_H30relocations are supportedloader: zstd-compressed input files are decompressed transparently
macho: the kernelcache and dyld cache headers are shown expanded
macho: load commands are typed from the type libraries, and path fields link to their strings
macho: the
vmaddrofLC_FILESET_ENTRYis shown as an offset to the KEXT's headermacho:
arm64e.x1files are recognized and labeledmacho: the Functions list has a folder per KEXT or cache image
Bugfixes
elf: mips:
R_MIPS_PC32relocations were not appliedelf: mips: calls to external functions were not resolved in MIPS n64 object files
elf: mips: when several HI16 relocations were paired with a single LO16 (a GNU extension), only the last HI16 of the series was applied
elf: mips: PSP relocations exposed both as sections and as a program header were applied twice
dex: malformed uleb128/annotation offsets could cause INTERR 2765 during loading
dex: a malformed DEX file could crash IDA while loading
dsc: when the indirect symbol table was stripped,
__auth_stubentries were not named after their own calleesmacho: a corrupted bind opcode created a bogus import
macho: cross-references for tagged pointers in files with chained fixups were wrong
Type System
Clang Is the New Default Parser
IDA 9.5 parses type declarations with a built-in clang-based parser: C, C++, Objective-C and Objective-C++ declarations work out of the box, with no setup required. The legacy parser remains available in the "Compiler options" dialog. The default is TYPE_PARSER = "clang" in ida.cfg; "legacy" still works. Loaders also use the selected parser for the prototypes they create (the ELF loader's __libc_start_main, the __cxa_* helpers of exception handling, guessed function-pointer types). The type editor and Local Types have a language selector (C, C++, Objective-C, Objective-C++), saved per database.
Removed: The old_clang parser, the idaclang plugin and the standalone idaclang tool, deprecated in 9.4, are removed. tilib -TC is the tool for building type libraries; the documentation has an idaclang → tilib command map.
Version-Matched XNU Type Libraries for Apple Silicon macOS Kernels
When loading an Apple Silicon macOS kernel, IDA now automatically applies the XNU type library that matches the kernel's OS version, so kernel structures and function prototypes are typed correctly out of the box.
Minor Improvements
types: structures can declare the order their bitfields are allocated in
clang: the deprecated
old_clangparser and the standaloneidaclangtool have been removed; use the built-in clang parser andtilib -TCinstead
Bugfixes
clang: a bad declaration was not reported to the user
clang: some declarations that the legacy parser accepted, such as a non-standard prototype for
main, were rejectedclang: headers emitted by IDA with anonymous types could not be parsed back
clang: demangled data declarations of const objects were rejected
clang: names known to the type library or the compiler were not resolved
clang: types guessed from demangled MSVC names were wrong
clang: structure packing passed in flags was ignored
clang: prototypes without a calling convention did not keep the platform default calling convention
clang: on targets where
intis not 32-bit (e.g. 16-bit DOS),__int32and the other__intNtypes followed the width ofintclang: a declaration with an unresolvable
decltype()crashed IDA
Debug Info, Demangling and Exception Handling
Minor Improvements
demangler: swift: names produced by Swift 6 compilers are demangled
dwarf: zero-sized Rust parameters are dropped
dwarf: the Rust unit type
()is represented as a zero-size struct in aggregatesdwarf: zero-sized members are dropped from Rust structs and unions
dwarf:
DW_AT_noreturnon subprograms is honoreddwarf: Objective-C/Swift runtime root classes are represented with their isa pointer
pdb: the bitfield allocation order is recovered from the debug information
goodname: new patterns for MSVS STL names
Bugfixes
demangler: cv/reference qualifiers on a substituted template-id were misplaced
demangler: names with braced initializer lists in template arguments were not demangled
demangler: some local C++ names were not demangled
dwarf:
DW_AT_typeand names were not applied to globals (and function-local statics) whose location usedDW_OP_addrxdwarf: function arguments spilled to SP-relative slots were not named and typed
dwarf: incomplete C++ types were dropped to
voidinstead of being recovereddwarf: PowerPC floating-point arguments were mapped to the wrong registers
dwarf: the hidden environment pointer of Rust closures was not recovered
dwarf: C++ base subobjects smaller than
sizeof(base)were rejectedpdb: the "Load types" option was ignored (type processing was not skipped when it was off)
pdb: function prototypes were not applied for COFF objects with embedded
/Z7debug infopdb: some MSVC COFF objects compiled with
/Z7got wrong argument typespdb: struct and array data globals were not laid out from debug info
swift: functions were no longer grouped by module in a shared cache
UI & UX
From Qt 6.8 LTS to Qt 6.12 LTS
Qt 6.12 is the next long-term-supported Qt.
IDA follows the desktop's light/dark scheme (on Linux through the XDG desktop portal);
IDA_COLOR_SCHEME=light|dark|autoforces onethe dedicated Copy/Undo/Back/Exit keys some keyboards have are registered as shortcuts, and the shortcut editor, cheat sheet and command palette list them
PySide6 is upgraded along with Qt: retest plugins that use PySide
New HTML Renderer for Listings
Every listing — disassembly, hex, pseudocode, type listing — can be copied and exported faithfully, colors included. The context menu's new Copy submenu copies the selection, the highlighted identifier, or the current function/type/item as text (Ctrl+C), as HTML (pastes styled), or as a deeplink; type listings also offer Copy with dependencies.
File > Produce file > Export to HTML... replaces the old HTML output with a template-driven export: a plain static page, an interactive page with a function sidebar, jump arrows and cross-reference links, or a paste-ready snippet — and custom templates are plain IDAPython scripts. The engine behind it (export_listing) is available to plugins, IDAPython, and idalib.
Copy > As HTML inlines the syntax colors, so the snippet pastes styled into any HTML-aware editor or chat; Copy honors an intra-line or column selection and falls back to the highlighted item
three templates ship — Document (a standalone page), Interactive (function/type sidebar, jump arrows, working cross-reference links) and Snippet — in
python/examples/templates/; a.pyfile dropped next to them is picked up by the dialogexported HTML has working links for names, cross-references and pseudocode call targets
export works on the selection, the current function or type, or the whole database, and can open the result in the browser
export_listingruns in the kernel, so idalib scripts and agents use it without a UI; an idalib example ships
Migration: the decompiler's own "Generate HTML" action is retired in favor of the generic export; gen_file(GENFLG_GENHTML) stays. Plain "Copy" is now "Copy > As text" and keeps Ctrl+C.
Pathfinder and Xref Graph Are Strongly Linked and Improved
The Pathfinder answers questions such as "how does this malware get from WinMain to connect()?". In 9.4 it was a list without visual feedback; in 9.5, opening it opens a live xref graph beside it, and adding, removing or reordering waypoints, or changing exclusions, redraws the graph at once.
between two waypoints the list shows a segment: "Direct connection", "N nodes", or "N nodes (shortest: M)" — in red when there is no path. Expanded, it lists the nodes by distance, syntax-colored; a segment can be folded to its shortest path, with the other nodes greyed out
"Promote to waypoint", "Exclude from path" and "Show in graph again" work in the list and in the graph; deleting a node in the graph only hides it. If two waypoints only connect in reverse, IDA swaps them and says so; nodes grown by hand stay part of the path
paths are saved in the database once they have a waypoint, named after their ends, listed in the Xref Graph manager and recomputed on open. The Pathfinding submenu — Create new path (Shift+F9), Add to latest path (Ctrl+Shift+F9), Add to — works in every window that shows addresses
a path larger than the graph's node threshold asks whether to draw it all or only each segment's shortest path
The xref graph itself routes edges orthogonally (and keeps them orthogonal while you drag a node), has rounded corners, shows the contents of string literals in their nodes, counts nodes and selected nodes in its bottom bar, and Ctrl+Up/Down jumps between connected nodes.
Migration: the Tree/Graph buttons became context-menu actions, and "Open Pathfinder" gave its shortcut to "Create new path".
Reworked Quick Filter Mechanism
typing in a list or chooser window (Functions, Names, Imports, Local Types, ...) filters it, instead of running an incremental type-ahead search. Only keys that no shortcut claims reach the filter, and
Alt+T/Ctrl+Tstill search without filteringthe quick filter bar is a permanent part of those windows, so it is always clear where what you type is going, and the list no longer reflows on the first keystroke
both are feature flags under Options > Feature Flags: untick "Typing in a list filters it" for the incremental search, digits jumping to a row by number and
Ctrl+Enter/Ctrl+Shift+Enterstepping between matches included; untick "Always show the filter bar" to open the bar on demand, with a close buttontyping a character that needs AltGr, as Polish, Croatian and Vietnamese layouts do, reaches the filter; so do the numpad digits
The incremental search was hard to discover, and because it never timed out, a forgotten search kept swallowing single-letter shortcuts. In 9.5, shortcuts always win over typing, still toggles check boxes, and Down/Esc in the filter return to the list.
Deprecation: both feature flags are temporary. Unless there are objections during 9.5, the incremental search and both flags are removed in 9.6.
Jump Anywhere Shows More and Finds More
results are syntax-colored, and function results show their parameter names (types are left out to keep rows short; unnamed parameters show as
arg1,arg2, ...). "Show function signatures" in the gear menu turns this offthe preview pane is always on; the feature flag that disabled it is gone, so a user who had turned it off gets it back
the scrollbar spans the whole result set instead of growing while you scroll
a local type is found by its prettified name as well as by its raw one
module symbols are no longer missed while debugging, and after a compaction a result no longer points at the wrong local type
Minor Improvements
the widget numbers for Alt+ window switching appear after 500 ms instead of 1 s
demangled names are displayed by default
"deep select" for grouped names: Alt-click a qualified name to highlight only the component under the cursor
qualified names are highlighted as a whole
double-click jumps to a type's definition (in prototypes) or to a struct member (in operands)
pressing in a chooser embedded in a form no longer closes the enclosing dialog
Shift+Enter in choosers and tree views jumps to the item without moving the keyboard focus
the type editor reads a declaration as C, C++, Objective-C or Objective-C++
the type editor has a new "Declaration" tab, and the Compiler options dialog is more compact
Ctrl+drag selects whole lines
the raw name behind a prettified one is painted translucent
hovering a prettified type name shows its full name
the Types window shows and filters on the prettified type name
dsc: kc: the DSC Index and KC Index trees are sorted alphabetically
teams: the status bar panel names the workspace and details it in its tooltip
teams: its status is reported in a single status bar panel
"Export data" moved from the Edit menu to File > Produce file
a new "Extensions" menu gathers Lumina, Teams and the other Hex-Rays extensions; the Lumina and Teams top-level menus are gone, but plugins attaching actions to "Lumina/..." or "Teams/..." menu paths keep working
a newly loaded file opens on the monitor where the main window is, instead of always on the primary monitor
pathfinder: paths are saved and listed in the "Pathfinding" submenu
pathfinder: dead-end pairs are swapped automatically, and the hovered segment is highlighted
pathfinder: new "Promote to waypoint" action, and one popup menu for all three views
pathfinder: nodes grown by hand stay in the path
pathfinder: waypoints are shown as a tree of each segment's nodes
pathfinder: path actions work in every window that has addresses
pathfinder: a path segment can be folded to its shortest path
xref graph: Ctrl+Up/Down jumps between connected nodes
xref graph: the bottom bar shows node and selection counts
xref graph: zooming has a keyboard shortcut
xref graph: the contents of string literals are rendered in nodes
xref graph: edges are routed orthogonally in the layout
xref graph: the edges of a dragged node stay orthogonal
xref graph: nodes and edge bends have rounded corners
Bugfixes
teams: the file trees triggered INTERR 80130 after pulling a file from the vault
teams: opening the "Vault files" widget triggered INTERR 72549
macos: the widget numbers used for Alt+ window switching appeared while holding Cmd instead of Option
the "Load a new file" dialog did not highlight the chosen processor in bold
the "Analysis" toolbar indicator did not turn green when analysis was idle
in the Local Types view, clicking a qualified type name did not highlight the whole name
pressing Enter did not accept a form when focus was on a checkbox or radio button
opening the navigation drop-down of a view that shares its history with a different kind of view crashed IDA
pressing in a tree view's quick filter did nothing
middle-clicking a tab closed two views instead of one
a chooser's "Line N of M" counter went blank in folders-only mode
changing the demangled names settings did not update the windows right away
the "bottom line padding" setting had no effect
typing a character that needs AltGr in a list (as Polish, Croatian and Vietnamese layouts do) did nothing
the wrong segment attribute was used to calculate the segment base
the release notes were shown again on every start when switching between two IDA versions
disabled check boxes and radio buttons looked enabled in the dark theme
the Pathfinder and the Scripts window had no Alt+N number
a mouse selection cleared the clipboard on Wayland
tree views such as Bookmarks and Breakpoints showed "Edit function"/"Delete function" in their popup menu after the Functions window had been used
the prototype editor's validity indicator checked stale text
pressing in a dialog discarded the changes when a checkbox had the focus
"Copy full type" was unavailable on function types in Local Types
pathfinder: the selected waypoint row was unreadable in light mode
pathfinder: a node could be a waypoint and an exclusion at once
a backward search did not walk the occurrences in order
an identifier search did not find the next occurrence
a type whose member references a non-C type name could not be edited in C syntax in the type editor
copying several rows of the xref tree did not keep the tree order
xref graph: the headers and icons of rendered nodes overlapped each other
xref graph: node icons activated on press instead of on click
FLIRT & FLAIR
Minor Improvements
flirt: a pattern can be created from a selected byte range
flair: pelf: ARC ELF files are supported
flirt: signatures can carry original (unmangled) symbol names
flirt: narrow/wide MSVC runtime twins (main/wmain, WinMain/wWinMain, argv accessors, environment helpers) are named from evidence in the binary
flirt: the ARM and ARM64 MSVC runtime signatures are regenerated and cover VC11 through VC 14.52
flirt: the 64-bit MSVC runtime signatures are picked by the CRT linkage of the binary
flirt: the functions and data that the entry module of a startup signature references are named
flirt: a startup signature is accepted even when its references are not resolved yet
flirt: the names of the narrow/wide startup globals are kept
flirt: 32-bit MSVC binaries of VC 14.39–14.52 are recognized, and their runtime is picked by the CRT linkage
flirt: arc: a new signature covers the millicode helpers
Bugfixes
flirt: a 32-bit wWinMain program lost the name of its entry point
flirt: a startup signature applied as an ordinary one named its entry module after the directive string
Performance & Resource Consumption
Large Binaries: Less Memory, Fewer Stalls
DWARF at scale: debug sections are memory-mapped instead of read into memory, which saves about 2 GB (−30%) on a 2.6 GB C++ binary, and the per-DIE index on an 89.5-million-DIE binary shrinks from 2048 MB to 1109 MB. The new opt-in
-Odwarf:lazy_types=1imports only the types reachable from named functions and globals, so huge C++ binaries that used to run out of memory loaddyld shared caches: enabling an address range no longer rewrites the whole database. On a 2.7 GB cache, initial load and analysis freeze the UI for 8.1 s in total instead of 42–48 s (worst single freeze 5.4 s instead of 13.5–15.9 s; UI-thread I/O 21 GB instead of 234 GB). Building the cache's region map takes 1 s instead of 5 s
pathological inputs: the data copied by RTTI analysis of a file with 800 classes and 200k strings drops from 37.1 GB to 36 MB; auto-analysis of huge functions with flattened control flow (a dispatcher on a state register) drops from 1751 s to 253 s; creating names in a reopened database no longer slows down as the database fills; binaries built to slow IDA down can be reined in with
OVERSIZED_FUNC_SIZEandJUMPTABLE_MAX_INSNS(see Analysis & Kernel)decompiler: batch decompilation no longer slows down quadratically (8% faster on 26k functions, 11.8% on 74k); decompiling a function with one 5506-instruction basic block drops from 2929 s to 148 s
FLIRT: signature files are read through a buffer instead of a byte at a time
start-up: parallel IDA instances no longer keep rebuilding the processor module cache, and a run without IDAPython no longer forces the next run to reload every processor module (running the shipped Python processor modules costs about 200M instructions)
databases: "collect garbage" reclaims the space of deleted address ranges, and the prototype editor no longer grows the database with every use
Minor Improvements
database: databases can be packed as several independent zstd frames (
PACK_ZSTD_FRAME_SIZEinida.cfg, in MB, default 32), so tools such as IDA Teams can decode them in parallel: checking out a 9 GB database went from 2.3 s to 0.3 sdsc: the region map of a dyld shared cache is built in linear time
dwarf: memory usage is lower when loading binaries with a huge number of DIEs
dwarf: debug sections are memory-mapped, which reduces memory usage
dwarf: the per-DIE memory overhead is lower when loading binaries with many DIEs
dwarf: new opt-in on-demand type loading for very large binaries
rtti: analysis is faster; it used to slow down disproportionately on files with many C++ classes
types: adding many names to a type library is faster
tilib: parsing an enum with many members is faster
names: creating names in a reopened database no longer gets slower the more names the database already contains
parallel IDA instances no longer keep rebuilding the processor module cache
a run of IDA without IDAPython no longer makes the next run reload every processor module
regfinder: auto-analysis of huge functions with flattened control flow is much faster
database: enabling an address range no longer rewrites the whole database
names: name printing in
apply_regexes/qregsubstis fasterdatabase: "collect garbage" also reclaims the space of deleted address ranges
database: the function prototype editor no longer saves its cursor positions in the database, which grew it with every use
flirt: signature files are read through a buffer instead of a byte at a time
vd: building chains is faster (the block of a chain bit is checked in constant time)
vd: rule CMB7 looks back at most 128 instructions for its
mov 0, which bounds its costvd: builtin patterns are rejected on the first block before a match is built, which saves time
vd: leak checking counts live ctree items instead of copying their set, which saves time and memory
vd: each expression type is checked for printability only once per decompilation
vd: functions with long basic blocks decompile much faster: a function with one 5506-instruction basic block went from 2929 s to 148 s
vd: batch decompilation no longer slows down quadratically with the number of decompiled functions
swift: the Swift identifier characters are set once per database instead of repeatedly
analysis: the frame members a stack variable overlaps are looked up instead of all being copied
pathfinder: expanding a large path segment no longer takes seconds
xref graph: large graphs are much faster to open, grow and rebuild
Configuration, IDAPython, SDK & API
Installation Manifests for Loaders, Processor Modules, Type Libraries, FLIRT Signatures, IDS Files and Themes
Loaders, processor modules, type libraries, FLIRT signatures, IDS files and themes can now be installed the way plugins are, as a directory that holds a manifest file. The manifest has the same shape as ida-plugin.json:
the manifest names are
ida-loader.json(loaders/),ida-proc.json(procs/),ida-til.json(til/),ida-sig.json(sig/),ida-ids.json(ids/) andida-theme.json(themes/); loaders and processor modules need anentryPoint, the other kinds do nota type library or signature directory can carry files for several processors: IDA searches
<dir>/pc/,<dir>/arm/and so on, the same as intil/andsig/. A type library can also be in<dir>/itself; a signature must be in the processor subdirectoryan extension pack bundles several kinds in one directory. Put an
ida-extension.jsonmanifest in$IDAUSR/extensions/<pack>/, and the extension directories in itsloaders/,procs/,til/,sig/,ids/,themes/andplugins/subdirectories. IDA ignores other files in these subdirectoriespackaged type libraries and signatures appear in the "Available type libraries" and "Available signatures" lists, and packaged themes in the theme selector
IDA searches in this order:
$IDAUSR/<kind>/, the packs in$IDAUSR/extensions/, the directory inIDATIL,IDASGNorIDAIDS,$IDADIR/<kind>/, and the packs in$IDADIR/extensions/. In each directory, files installed the classic way come first, then the extension directories sorted by name. If two plugins, loaders or processor modules have the same name, IDA uses the first one. Names that differ only in case are the same namea plugin, loader or processor module directory gives IDA only its entry point. The other files in the directory, for example helper scripts, do not hide files that IDA searches for by name
IDA looks for extensions one time per session. Restart IDA after you install an extension
loaders, processor modules, type libraries, signatures, IDS files and themes can be installed as directories with an
ida-<kind>.jsonmanifest, like plugins
New "Synthetic String" API
A plugin can now add strings that exist only in the code.
New "License Inspection" API
The new License class (license.hpp; ida_license.License in IDAPython) lets a plugin query the active license (whether it is usable, its product and edition, its activation period, and the add-ons and features it covers) and control it (set the active license, check a license out and in, borrow and return a floating license); see the licinfo sample plugin and the print_license_info.py example.
COLOR_GROUP is now COLOR_SEMSPAN
COLOR_GROUP is renamed COLOR_SEMSPAN ("semantics-bearing span"), which says what the tag is actually for: it groups a run of tagged text into a single unit — that is how a qualified name highlights as a whole — and carries semantics about it: a one-byte kind, plus an opaque payload of variable size that Hex-Rays reserves the right to grow in any release. Never assume a size for that header: step over it with tag_skipcode()/tag_skipcodes()/tag_advance(), and read it with tag_get_semspan_kind(). COLOR_GROUP stays as a deprecated alias; the accompanying tag_semspan(), tag_semspan_off(), PRTYPE_SEMSPAN and GNCN_SEMSPAN are new in 9.5.
Minor Changes
dsc:
DSCU_USE_SEG_PREFIXES(dscu.cfg) is honored for cache-image segment namesmacho:
USE_SEG_PREFIXESis retired in favor of the more versatileSEGNAME_FORMAT, harmonized across kernelcaches, dyld shared caches and plain Mach-O; the old option is still honored for backwards compatibilityhexagon: new
QDSP6_VALIDATE_DUPLEXoptionhexagon: processor options can be set in
ida.cfgthe maximum stack frame size is configurable
decompiler:
set_decompiler_timeout(msecs)bounds a wholedecompile()call (internal retries included) and fails with the newMERR_TIMEOUT; intended for headless and idalib runs, where there is no Cancel buttondecompiler: added save/restore APIs for split settings and for vararg call arguments
the length of string literal comments is configurable (
STRLIT_COMMENT_LENGTH)ev_sanitize_namereceives the kind of name being sanitizedclang: the clang type parser is the default and is also used while loading
new listing-export API (
export_listing): renders disassembly, pseudocode and type listings as text or HTML; available to plugins, IDAPython and idalibdecompiler: new class API.
get_classes(),get_class_info(),render_class()andrender_member()give a language-neutral view of the program's classes, their members, and the class view's rendering of them; available to C++ plugins and IDAPython (see thelist_classes.pyexample)new
qgetpid()returns the id of the current processtry block structures can be compared with
==and!=idalib: an old
.idbopened with idalib is converted to.i64automatically, and the session continues on the converted databasesdk:
qvectorhas a newappend(first, last)to append an element range
Bugfixes
sdk:
qtree.hppcould not be compiled with GCC 8.xsdk:
qustrncpy()cut a 4-byte UTF-8 character that fit in the bufferidapython: objects a script created, such as hooks, stayed alive after the script ended
idapython: raising
SystemExitfrom the CLI closed IDAidapython:
ask_filewith empty string arguments crashed IDAidalib: a failed
open_databaseterminated the host processplugins: when two plugins in subdirectories of
plugins/had the same name, the order of the files on disk selected the plugin that IDA loadedidapython: a processor module script could not import a Python module installed next to it
Network & Security
Clear Answers When a License, Lumina or Vault Server Misbehaves
a failed connection names the server (
host:port) and leads with the cause instead of a bare transport error, and a missing license is reported as "license X is not available on this server". The License Manager and thelsadm,hvandlctools share the same classificationIDA no longer freezes when the license or Lumina server stops responding — during work, on exit, or during cloud decompilation: blocking network operations are bounded or can be cancelled
macOS: IDA uses the TLS-1.3-capable LibreSSL the system ships, so it connects to servers that require TLS 1.3 and to FIPS servers that require the Extended Master Secret extension (the handshake used to fail with alert 80)
Minor Improvements
security: Linux builds are hardened with full RELRO and PLT-free linkage, making them more resistant to memory-corruption exploits
Last updated
Was this helpful?
