Commit graph

30582 commits

Author SHA1 Message Date
Khairul Azhar Kasmiran
43cb43ed18
Add reliable http:// test (#6509)
* Add reliable http:// test
* REUSE.toml: Add `test/www/**` entry
* Use `cwd` instead to work around old http.server in Python 3.6
* Move test to `not-windows-any`
* NetBSD: Add `python3` symbolic link
* Prevent test from running on woodpecker
2026-06-18 07:01:00 +08:00
NOT XVilka
f205e231ef
arch/tms320: drop c55x+ global state, populate op->val, lift rptadd/rptsub (#6525)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-18 03:52:09 +08:00
NOT XVilka
36433ae7a1
build: fix rz_bin_stabs.h hdr install (#6526)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-18 03:46:03 +08:00
billow
944816d364
ci: fix linter job (#6523) 2026-06-17 23:14:21 +08:00
NOT XVilka
e43565fade
librz/core/disasm: dedup symbol name when realname is used (#6518)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-17 11:22:30 +08:00
NOT XVilka
8fde88fd9e
rz-asm: show an error when -m arg is invalid (#6519)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-17 11:22:17 +08:00
NOT XVilka
880c8005f7
librz/arch/x86: uplift scalar FP SSE/SSE2 insns to RzIL (#6517)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-17 11:22:04 +08:00
NOT XVilka
62bcb8f6fc
librz/bin: add STABS format parser (#6511)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-17 04:13:23 +08:00
NOT XVilka
c0945b0231
subprojects/rzar: fix crash (#6516)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-17 02:09:11 +08:00
billow
0421f03afe
Fix bin hunk/smd plugin ownership leaks (#6515) 2026-06-16 15:45:53 +00:00
NOT XVilka
dfd83d77a4
librz/arch/tms320: fix C55x+ BTST/BTSTSET/COPY opcodes (#6513)
Verified against the TI dis55 disassembler and the C55x+ Algebraic
Instruction Set (SWPU104) encoding tables.

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-16 05:12:24 +08:00
Anton Kochkov
9ff9a48c4a arch/tms320: extend C55x/C55x+ RzIL coverage (returns, addressing, sub-register and bit ops)
Builds on the shared decode-IR engine to lift a broad set of common C55x and
C55x+ (Ryujin) instruction forms that were previously left without RzIL,
deriving the exact semantics from the TI C55x+ references (SWPU104 / SWPU086).

Control flow and addressing:
  - ret / reti / retcc: return address read from the top of stack, SP popped by
    two words, control transferred to it (retcc guarded by its predicate).
  - 24-bit XAR correctness on C55x+ (XAR0-15, XSP, XSSP, XDP, XCDP) in the
    register table, the IL-VM profile and the pointer-arithmetic width, enabling
    the 24-bit amov address immediate; classic C55x keeps its 23-bit file.
  - long constant-index and 16-bit-absolute addressing modes, memory-to-memory
    copy, shifted memory loads (uns()/signed, immediate shift), and the
    memory-mapped-register moves mov reg,mmap(@reg) / mov mmap(@reg),reg.
  - push/pop of accumulator sub-register halves and dbl(xarN) pointer pairs.

Arithmetic, logical, shift and bit operations:
  - sub-register add/sub on a 16-bit accumulator slice, for the immediate and
    register forms: a .L destination updates [15:0], a .H destination updates
    [39:16] sign-extended through the guard (SWPU104 1.5.1).
  - bitwise and/or/xor with a 16-bit source (half or AR/T) into a full
    accumulator, zero-extending the operands to 40 bits (SWPU104 6.6.1); the
    memory-source bitwise forms into full and half destinations; and the
    shift-ALU forms <op> ACx.<sub> << #S6, ACy.<sub> on the 16-bit slice.
  - memory-source add (including a 16-bit half addend and the reverse-subtract
    sub ACx.<sub>, Smem, ACy.<sub>), the 32-bit dbl(Lmem) add/sub forms
    (ACy = ACx +/- dbl(Lmem) and the reversed ACy = dbl(Lmem) - ACx), and the
    memory-destination immediate RMW add/sub #k, Smem.
  - register bit ops bclr / bset / bnot @#k, ACx[.h/.l] / ARx: clear, set or
    toggle bit k of the register, the bit number taken relative to the
    addressed sub-register (a .h operand targets bit k+16, the guard k+32).
  - bitwise not ACx.<sub>/ARx into an accumulator half or a 16-bit register
    (not ACx.l, ARy), the half-register and short (0x7b #1/#-1) sftl/sfts
    including register-count shifts, and btst @#k, ACx.l/.h, TCy.

This also corrects an op_type-fallback mis-lift: on C55x+ several non-move
instructions (round, sat/satr, the mant/nexp helper) and the bit-field
extract/expand bfxtr/bfxpa were typed as a move and so were lifted as a plain
register copy. round and sat/satr now carry their lops and reach the existing
rounding / saturation handlers (matching C55x); mant/nexp, bfxtr/bfxpa, the
operand-less sat and the register-indexed memory bit ops (bclr/bset/bnot Baddr)
are marked decode-only (no modelled data effect) so the fallback can no longer
guess at them.

Also fixes a FIRSADD/FIRSSUB lifting bug: the Cmem operand was not converted
from AR to XAR before emitting its pointer post-modify, so a post-modified Cmem
(e.g. firssub *ar3-, *ar5-, *ar6-, ...) produced an invalid 16-bit-vs-24-bit
subtract that failed IL validation; Cmem is now widened like Xmem/Ymem.

The multiply/MAC family stays unlifted by design, as do the flag-predicate
retcc forms (whose condition register field is not represented by the decoder)
and the software-interrupt intr (which would need the interrupt-vector base);
the correct-or-NULL contract test asserts a representative deferred form.

The disassembler tests for both variants are extended with the expected IL for
every form that lifts -- previously the optional IL field was omitted on many
lines whose lift already existed, leaving the lifting unchecked -- so the asm
suite now validates RzIL for all lifted C55x / C55x+ instructions, not just a
subset.

Measured on a 5 MB C55x+ firmware image (16k-instruction sample) RzIL coverage
rises from 82% to 99.4% of decoded instructions, the remaining tail being the
multiply/MAC family and the deferred forms above.
2026-06-15 23:31:05 +08:00
Anton Kochkov
4b2ea610df arch/tms320: rewrite C55x and C55x+ on a shared decode-IR engine
Replace the per-variant, table/token-driven disassembly and lifting for the
TMS320C55x and C55x+ DSPs with a single shared decode-IR layer, c55_ir, that
both variants drive through a C55ArchDesc descriptor. The shared engine
table-walks an instruction (c55_decode), formats it (c55_format), fills the
analysis op (c55_fill_analysis), and lifts to RzIL (c55_lift) arch-agnostically,
with the opcode tables, register files, operand extractors, and op-type/lift
mappings supplied per variant (c55x and c55x_plus).

Both test corpora decode and lift entirely through the shared engine: forcing
the shared-only decode path and, separately, the shared-only lift path each pass
the full suite -- 1288 tests including the three RzIL VM emulation tests, whose
decrypt loops execute every instruction through the shared IL. The legacy
decoder and lifter are retained only as a fallback for a complex long-tail (the
parallel dual-MAC group, dual-memory addsub/subadd, the absolute-k24 and dbl
multi-operand loads/stores, and the bit-field forms); the shared path is used
when it can decode an instruction and control falls through otherwise, so
behaviour is preserved at every step.

Several forms are extended beyond the old engine: the full C55x+ register file
(ac0-31, ar/xar0-15, CPU-gated in the profile and IL VM) so extended-register
forms lift where the legacy lifter bound only the low eight; pc-relative and
compare-and-branch control transfer; the bcc flag predicate; and the
single-data-memory bitwise and address-arithmetic forms (and/or #k16,Smem and
register-mode amar Smem,xar) decoded cleanly with RzIL rather than inherited from
the legacy tables.
2026-06-15 23:31:05 +08:00
Anton Kochkov
ab201a3843 arch/tms320: TMS320C55x+ analysis & RzIL (PR #6434) + extended lifter coverage
Squash of rizinorg/rizin PR #6434 ("improve TMS320C55x+ analysis and RzIL")
rebased onto dev, with the PR head's doubled c55plus_il.c (every symbol defined
twice, failing to compile) de-duplicated to a single clean copy.

Substantially extends the C55x/C55x+ RzIL lifter over the existing structured-
operand helpers: mov/copy (immediate, register, memory load/store, half-register
read-modify-write), the full addressing-mode set with post-modify side effects,
control and system-register moves, 40-bit accumulator ALU with shifted sources,
16-bit and dual-memory add/sub, the ST0_55 status-flag model (cmp/cmpand/rol/ror,
named-bit bset/bclr), a documented psh/pop stack model, address-unit amov/aadd/
asub and amar, and bcc/callcc control transfer. The multiply/MAC family and satr
are lifted with explicit, documented integer-mode approximations (not verified
DSP semantics); irreducibly multi-output primitives (bit counts, Viterbi, FIR,
distance) are left correct-or-NULL. The register file covers ac0-7 and xar, found
by validating on real Motorola Wrigley C55x+ firmware whose prologues save 40-bit
accumulators as dbl(acN)+acN.g pairs.

Adds RzIL-VM emulation tests (including the C55x and C55x+ _decrypt emulateme
binaries), per-instruction IL assertions, and ~95% instruction-class disassembly
coverage per corpus; pins little-endian in the VM tests for big-endian hosts; and
regenerates the analysis expectations against current dev.
2026-06-15 23:31:05 +08:00
Anton Kochkov
f89e09f6bc bin/coff: honor load addresses for TI linked (F_EXEC) executables
For a fully linked TI COFF executable the section s_vaddr fields hold the real
load addresses (e.g. .text at 0x100, vectors high) rather than a packed
sequential layout. Map sections at s_vaddr for F_EXEC objects (keeping the
sequential 16-aligned fallback only for relocatable objects), treat a defined
symbol's n_value as an already-absolute address instead of re-basing it onto the
section VA, and give non-loadable sections (DWARF/debug, build attributes,
.pinit) no loadable vaddr so their code-valued debug entries no longer split
instructions mid-stream or shadow the real low-addressed loadable sections. The
formats/coff test expectations are updated accordingly.
2026-06-15 23:31:05 +08:00
Giovanni
c6ba6eed9a
Implement lcs-roll distance (myers+fastcdc) (#6512) 2026-06-15 23:23:54 +08:00
NOT XVilka
832ed32cbb
subprojects/gdb: add support for qGDBServerVersion query (#6477)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-15 01:31:19 +08:00
NOT XVilka
4880588377
subprojects/gdb: fix RLE decoding (#6495)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-15 01:31:01 +08:00
NOT XVilka
998ec77122
Improve detection of the const format strings as arguments (#6510)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-15 01:30:44 +08:00
مصطفي محمود كمال الدين
afd6607fe2
Fix error handling and a percision issue in float core (#6469)
* fix error handling and percision issues in float core
* fix rz_float_cast_float on zero input and add tests
2026-06-14 22:48:44 +08:00
NOT XVilka
f91ef729bf
Improve ARM/AArch64 DATA xrefs analysis (#6506)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-14 21:10:30 +08:00
NOT XVilka
323e707114
librz/bin/elf: improve ARM Thumb symbols detection (#6502)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-14 17:25:00 +08:00
Khairul Azhar Kasmiran
3aebd94478
Generalize #6501 fix (#6503)
* Generalize #6501 fix
* Fix is_filtered_flag() leak
2026-06-13 21:36:45 +08:00
Anton Kochkov
a2454fec15 librz/arch/vax: add new LGPL DEC VAX-11 disassembler and analysis plugin
Add a new LGPL-3.0 VAX-11 architecture plugin that replaces the removed
binutils-derived GPL one. It is written from scratch from the documented
VAX operand-specifier encoding and does not reuse any GPL code.
2026-06-13 18:58:55 +08:00
Anton Kochkov
423104df4a arch/vax: remove the GPL binutils-derived VAX plugin
Drop the old GPL-licensed VAX disassembler (vax_gnu), which was derived
from GNU binutils and gated behind the use_gpl build option. It is being
replaced by a new, clean-room LGPL implementation in a following commit.

Removed:
  - librz/arch/isa_gnu/vax/vax-dis.c
  - librz/arch/isa_gnu/vax/vax.h
  - librz/arch/p_gnu/arch_vax.c
  - librz/arch/p_gnu/asm/asm_vax_gnu.c
  - librz/arch/p_gnu/analysis/analysis_vax_gnu.c

and their entries from the use_gpl plugin/source lists in
librz/arch/meson.build.
2026-06-13 18:58:55 +08:00
Khairul Azhar Kasmiran
8abb4ca4d3
Prevent dup flag cmt if scr.color > 0 (#6501) 2026-06-13 14:30:24 +08:00
NOT XVilka
f832acdb5d
librz/bin: handle PLT sections properly (#6499)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-13 02:20:41 +08:00
NOT XVilka
33fe5f1aef
bin/elf: load ARM Thumb function information correctly (#6478)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-12 04:38:02 +08:00
NOT XVilka
cc87ff20e5
Expose constrained types to user and analysis (#6480)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-12 02:36:35 +08:00
NOT XVilka
1224a19dce
librz/arch/mips: improve static GP resolution (#6497)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-11 23:15:53 +08:00
NOT XVilka
86c8620662
librz/reg: handle 1 bit fields the same on BE and LE (#6496)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-11 16:10:32 +08:00
Dmitry Opokin
423576676b
librz/arch: MIL-STD-1750 ISA support (#6042) 2026-06-11 12:53:58 +08:00
Ron Stephen Mathew
0acff655b5
Expose RzIL Unicode/enriched lines API (#6255) 2026-06-11 02:35:05 +08:00
Khairul Azhar Kasmiran
447990092b
Support asm.flags.real wrt xrefs from fcn (#6494) 2026-06-10 19:42:26 +08:00
NOT XVilka
cae792c7c5
test: fix some pf tests (#6492)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-10 18:45:38 +08:00
Giovanni
067b59f5ee
Fix rust lang detection (#6493) 2026-06-10 18:41:50 +08:00
NOT XVilka
9f34985c21
librz/arch/dwarf: fix range-size underflow when picking a loclist's representative location (#6474)
location_by_biggest_range() computed each location-list entry's PC-range
size as (begin - end). For a normal [begin, end) range (begin < end) this
underflows and wraps to a huge ut64, so the entry with the *smallest* span
was always chosen as a variable's single representative storage instead of
the largest.

This breaks functions whose register arguments and locals are described by
location lists, e.g.

    item:         [low, X): DW_OP_reg0 ; [X, high): DW_OP_reg8
    input_buffer: [low, Y): DW_OP_reg1 ; [Y, high): DW_OP_reg10

with DW_AT_frame_base = DW_OP_call_frame_cfa (.debug_loc + DW_AT_GNU_locviews,
no .debug_loclists). The wrongly-picked short entry is frequently one that
does not resolve to a valid RzAnalysisVarStorage (e.g. an implicit
DW_OP_stack_value piece), leaving the variable with EVAL_PENDING storage. The
affected variables then fail to materialize and 'afv'/'afvl' reports nothing
for the whole function -- even though the arguments live plainly in registers
and need no CFA computation.

Computing the span as (end - begin) selects the genuinely largest range, so
each variable resolves to the register it occupies for most of the function
and the register arguments load correctly.

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-10 16:14:28 +08:00
Alok Kumar Mishra
bbe00b00c8
Fix debugger for spaced filepaths (#6489) 2026-06-10 11:56:34 +08:00
NOT XVilka
ac388acdeb
Fix PDB virtual functions recognition in analysis (#6472)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-10 11:55:21 +08:00
Khairul Azhar Kasmiran
f19a29442b
Support asm.flags.real wrt xrefs not from fcn (#6488) 2026-06-10 03:22:43 +08:00
NOT XVilka
b83c518d8c
Colorize RzIL in ao standard output like plf (#6473)
The `rzil:` line printed by `ao` (and its `aoX` standard-mode variants)
was emitted without syntax highlighting, unlike `plf`/`aoi` which color
the RzIL effect body. Route the stringified body through the existing
`rz_core_il_colorize_body()` helper (the same one used by `plf` and the
bit editor) when `scr.color` is enabled, so parentheses, IL operations,
numbers and variables are colored consistently.

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-10 03:21:57 +08:00
NOT XVilka
80f14bf6fc
librz/util/vector: minor RzVector/RzPVector performance optimizations (#6467)
* util/vector: hoist quicksort scratch buffers out of the recursion

vector_quick_sort allocated its two element-sized scratch buffers (t and
pivot) with malloc/free on every recursive call. For a vector of n elements
the sort makes O(n) recursive calls, i.e. O(n) malloc/free pairs purely for
scratch space, and each call could also fail half-way through the sort.

Split the function into a small entry point that allocates the two buffers
once and a recursive worker that receives them as scratch. The buffers are
reused across the whole recursion (each partition step finishes using them
before recursing, and the recursion is sequential, so sharing one pair is
safe). Small elements -- the common case, including every RzPVector-backed
sort -- use stack buffers and allocate nothing at all; only elements larger
than 256 bytes fall back to a single heap allocation for the whole sort.

The element movement and rand()-based pivot selection are unchanged, so the
result is identical for any input (verified byte-for-byte against the previous
implementation for ascending and descending orders over many random arrays).

* util/vector: evaluate the comparator once per element in the quicksort

The partition loop tested the element against the pivot with two separate
calls to the comparator:

    if ((cmp(VEC_INDEX(a, i), pivot, user) < 0 && !reverse) ||
        (cmp(VEC_INDEX(a, i), pivot, user) > 0 && reverse)) {

Because cmp is an opaque function pointer the compiler cannot common up the
two calls, so depending on the result and the reverse flag the comparator was
invoked up to twice per element. Compute the result once into a local and test
that:

    int c = cmp(VEC_INDEX(a, i), pivot, user);
    if ((c < 0 && !reverse) || (c > 0 && reverse)) {

This halves comparator calls in the worst case and is a clear win whenever the
comparator is non-trivial (the common case for struct elements). Measured on a
shared host: ~12-14% faster for int sorting and ~30% faster with a moderately
expensive comparator. The ordering is unchanged (verified byte-for-byte).

* util/vector: simplify rz_pvector_remove_data index computation

The index of the located slot was computed as

    size_t index = (el - (void **)vec->v.a) * sizeof(void **) / vec->v.elem_size;

For an RzPVector the element size is always sizeof(void *), so the
`* sizeof(void **) / vec->v.elem_size` factor is identically 1 and the pointer
difference `el - (void **)vec->v.a` already yields the index directly. Drop the
redundant scaling, which removes a multiply and a divide and makes the intent
clear. Behaviour is unchanged.

* test/unit: add RzVector sort and rz_pvector_remove_data regression tests

The existing sort tests only sort 4-5 small elements and there was no test for
rz_pvector_remove_data. Add coverage for the code paths exercised by the sort
changes and the remove_data cleanup:

  - test_vector_sort_large       sort 2000 heavily-duplicated ut32 values
                                 ascending and descending, verifying the result
                                 is ordered and a permutation of the input (vs a
                                 reference qsort). Drives the recursion deeply
                                 and the shared scratch buffers.
  - test_vector_sort_large_elem  sort 400 elements of 304 bytes each, taking the
                                 heap-allocated scratch fallback, and check the
                                 full payload (not just the key) stays consistent
                                 through all the element moves.
  - test_pvector_remove_data     remove interior, first and last elements by
                                 value while preserving order, and confirm
                                 removing an absent value is a no-op.

All pass on both the previous and the optimized implementation (the sort and
remove_data changes are behaviour-preserving).

* test/bench: benchmark rz_vector_sort and rz_pvector_sort

bench_vector.c benchmarked only remove_at and swap. Add sort benchmarks so the
suite covers the functions touched by the sort optimizations and can be run
against the old and new librz for before/after numbers:

  - rz_vector_sort over 4k ut64 with a cheap comparator
  - rz_vector_sort over 4k ut64 with a deliberately expensive comparator
    (shows the effect of evaluating the comparator once per element)
  - rz_pvector_sort over 4k pointers (reference; pvector sort is unchanged)

Each iteration refills the buffer from an unsorted master copy via a single
memcpy before sorting; that overhead is identical across builds so the measured
delta reflects the sort.

---------

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-10 00:22:26 +08:00
well-mannered-goat
25886f4ccf
Add Alpha linux native debugger (#6447)
* add alpha to rz_types
* fix register read
* add register write
* add breakpoint instruction
* fix register sp
2026-06-09 12:27:19 +08:00
NOT XVilka
fb9b15eac6
Fix pre-existing memory leaks in ObjC class and winkd module handling (#6471)
bin/dyldcache: dyldcache_classes() built the classes vector with
rz_pvector_new(free) and the per-class methods/fields lists with
rz_list_new() (no element destructor). Each RzBinClass was therefore
plain free()'d without releasing its name, methods and fields, leaking
memory.

debug/dmp (winkd): rz_debug_dmp_init() obtained the module list from
winkd_list_modules() in the non-triage branch, scanned it for
ntoskrnl.exe and then never freed it, leaking the list and all of its
WindModule entries.

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-09 12:24:12 +08:00
NOT XVilka
940292aaae
librz/bin/pdb: fix memory leaks of PDB callable convention strings and orphaned callables (#6468)
Leak A - calling-convention string leaked
Leak B - orphaned callables on duplicate names

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-09 12:23:56 +08:00
Florian Märkl
fb99604963 Fix leaks in 6502 RzIL lifting 2026-06-08 11:31:19 +02:00
Florian Märkl
80763dedd1 Fix 6502 0x93 opcode and improve test coverage 2026-06-08 11:31:19 +02:00
NOT XVilka
1db722606b
librz/analysis/mips: resolve PIC calls through $t9 (jalr/jr) to the callee (#6482)
MIPS PIC code calls a function by loading its address from the GOT into
$t9 and then doing `jalr t9` (or `jr t9` for a tail call), e.g.:

    lw    v0, -sym._MIPS_STUBS(gp)   ; v0 = *(gp + %call16(puts))
    move  t9, v0
    jalr  t9                         ; -> puts

rizin did not turn this into a call to the imported function, so the
target was lost: rz-ghidra rendered it as an indirect `(*_data.XXXX)()`
instead of `puts(...)`, whereas a direct `jal sym.dummy` decompiled fine.

Root cause (two independent gaps):

1. For (R|U)CALL and RJMP ops the core creates the CALL/CODE xref from
   op->ptr, not op->jump (see core_analysis_followptr() and the op-type
   switch in librz/core/canalysis.c, RZ_ANALYSIS_OP_TYPE_RCALL/RJMP). The
   MIPS plugin only ever set op->jump for `jalr`/`jr`, so no call xref was
   produced even when $t9 was tracked, and the decompiler never saw a call
   target.

2. $t9 was only tracked when it was the *direct* destination of a
   gp-relative load (`lw t9, ...(gp)`). The very common sequence that loads
   into another register first and then `move t9, vX` was not tracked, so
   even op->jump was left unset there (this is the issue's binary). Note
   that capstone emits `move t9, vX` as the 2-operand alias of `or` (and on
   some toolchains `addu`/`daddu`), i.e. `or t9, vX, $zero`, so the move
   must be recognised across MIPS_INS_MOVE *and* the 2-operand OR/ADDU
   forms.

Additionally, the tracked value was the GOT *slot* address, while the call
target is the function the slot points to, so the slot has to be
dereferenced.

This commit:

  - tracks the destination register and slot of every gp-relative load
    (gp_load_reg/gp_load_ptr in MIPSContext), and propagates it to $t9 on a
    register move (MIPS_INS_MOVE, or the 2-operand OR/ADDU alias), so the
    PIC sequence above is recognised;
  - adds mips_pic_call_target(), which dereferences the GOT slot via the
    analysis IO bind (honouring word size and endianness) to obtain the
    actual callee;
  - sets op->ptr (and op->jump) to that resolved address for `jalr t9`
    (RCALL) and `jr t9` (RJMP tail call), so the core emits the proper
    CALL/CODE xref and the decompiler resolves the callee like it does for
    `jal`.

The resolution is best-effort and fully guarded: if gp is unknown, the
slot cannot be read, or it holds 0, op->ptr is left unset and behaviour is
exactly as before. The core additionally validates the target
(is_valid_xref) before creating the xref, so a stale/garbage slot cannot
introduce a bogus call, and the propagation only fires when $t9 is the
destination, so ordinary moves (`move fp, sp`, ...) are unaffected.

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-08 04:16:29 +08:00
NOT XVilka
c58aa48c3e
librz/egg: fix endian-dependent x86/x64 string immediates and refresh rz-gg tests (#6481)
Use rz_read_le32() in the x86/x64 egg emitter so 4-byte string immediates are
no longer byte-reversed on big-endian hosts (System Z/s390); little-endian
output is unchanged. Regenerate the stale 32-bit x86 (#1889) and 32-bit arm
rz-gg goldens to match the tool's actual output, drop BROKEN markers from the
simple_cmp tests that already pass, and annotate the remaining broken tests
(no AArch64 egg backend; compiler-dependent C output) with the reason.

Closes #3486
Closes #1889

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-08 00:20:46 +08:00
NOT XVilka
9632328f74
Add χ² , index of coincidence, min-entropy, serial correlation statistical indicators (#6466)
* hash: add chi-square (vs uniform) rz-hash plugin

Adds a chi-square goodness-of-fit (vs a uniform byte distribution)
statistic as an rz-hash plugin and the rz_hash_chisquare() API.

Unlike Shannon entropy, chi-square separates high-entropy data that is
truly uniform (encryption/CSPRNG, ~255) from high-entropy data that is
merely compressed or packed (much larger values), which is a common
question when triaging firmware blobs.

* hash: add index-of-coincidence rz-hash plugin

Adds the index of coincidence as an rz-hash plugin and the
rz_hash_ioc() API. IoC is ~1/256 for uniform data and markedly higher
for text, padding, single-byte-XOR'd data and repeating-key regions;
computed at several strides it is the Friedman/Kasiski test for a
repeating-XOR period.

* hash: add min-entropy rz-hash plugin

Adds min-entropy H_inf = -log2(max_i p_i) as an rz-hash plugin and the
rz_hash_min_entropy() API. This is the conservative worst-case entropy
used by NIST SP 800-90B: 8.0 for a uniform block, dropping as soon as a
single byte value dominates.

* hash: add serial-correlation rz-hash plugin

Adds the lag-1 serial correlation coefficient (with wrap-around, as in
the classic `ent` tool) as an rz-hash plugin and the
rz_hash_serial_correlation() API. Near 0 for compressed/encrypted data
but clearly non-zero for executable code, counters and gradients - the
order-aware axis that the histogram-only metrics cannot see.

---------

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-08 00:20:15 +08:00