Commit graph

14619 commits

Author SHA1 Message Date
Yan
2ce31f2d9f Decompiler: satisfy nested-switch static checks 2026-08-01 17:46:29 +00:00
Yan
2ebdf1b797 Decompiler: carry proven outer breaks through nested switches 2026-08-01 17:28:23 +00:00
Kevin Phoenix
49434bc3fc
Render truncations to non-C widths as masks instead of casts (#6741) 2026-07-31 17:05:47 -07:00
Kevin Phoenix
2f891d1d69
Update capstone to 5.0.9 (#6740) 2026-07-31 13:47:32 -07:00
Quintin Kong
d46e56f891
Fix signed division and remainder in the pcode engine (#6739)
* Fix signed division and remainder in the pcode engine

OpBehaviorIntSdiv and OpBehaviorIntSrem used Claripy's `/` and `%`, which are
unsigned bit-vector operations. For negative operands they therefore produced
the same results as the unsigned INT_DIV and INT_REM behaviors.

INT_SDIV now uses claripy.SDiv (truncation toward zero). INT_SREM is defined as
in1 - SDiv(in1, in2) * in2, giving a remainder with the dividend's sign, which
matches the p-code semantics documented in the class comments.

For 64-bit -5 and 2, INT_SDIV now yields -2 (0xfffffffffffffffe) and INT_SREM
yields -1 (0xffffffffffffffff) instead of large unsigned values.

The arithmetic behavior test table enables both INT_SDIV and INT_SREM with the
matching signed reference expressions, and a new concrete test checks mixed-sign
combinations (-5/2, 5/-2, -5/-2, ...) that an unsigned implementation cannot
satisfy.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Use claripy.SMod for INT_SREM

Per review, INT_SREM uses claripy.SMod directly instead of the equivalent
in1 - claripy.SDiv(in1, in2) * in2. Verified identical to a truncated-toward-zero
reference over 100k random 64-bit pairs, including the INT_MIN / -1 corner.

* Address pcode signed arithmetic review comments

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-31 12:23:05 -07:00
Fish
61bac8ffd0
SimConstantVariable: Fix overflows and value out of range errors. (#6738)
* SimConstantVariable: Fix overflows and value out of range errors.

* Fix usages of SimConstantVariable.

* Mask the value.

* Fix negative values.
2026-07-29 13:58:20 -07:00
pre-commit-ci[bot]
d38cc5a019
[pre-commit.ci] pre-commit autoupdate (#6721)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.15.22 → v0.16.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.22...v0.16.0)

* Apply fixes

* Add values()

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Kevin Phoenix <kevin@kphoenix.us>
2026-07-29 13:46:11 -07:00
angr-bot
a4b05a0ce9 Update version to 9.3.2.dev0 [ci skip] 2026-07-29 09:44:55 +00:00
Fish
7cedfbfa8b
Dephication: Correctly consider phi congruence classes. (#6735) 2026-07-29 01:53:02 -07:00
Fish
b9358da5da
AIL: Fix __eq__. (#6728)
* AIL: Merge likes/matches into a single mode-parameterized walk

* AIL: Make __eq__ idx-aware at every node, not just the root

* AIL: Stop hashing fields that equality does not compare

* AIL: Regression-test the hash/eq contract

* AIL: Compare bits in StringLiteral and Struct

* AIL: Replace the CMP_* constants with a CmpMode enum

* AIL: cargo fmt

* AIL: Compare and hash rounding_mode on Convert and BinaryOp

* Update comments.
2026-07-29 01:22:10 -07:00
Ati Priya
6933b065f0
Decompiler: rewrite CondBE and CondNB ccalls on amd64 (#6645)
* Decompiler: rewrite CondBE and CondNB ccalls on amd64

* Decompiler: fix inverted CondZ/CondNZ over G_CC_OP_COPY on amd64

* tests: add binary-driven regressions for CondBE/CondNB ccall recovery
2026-07-29 01:11:09 -07:00
Quintin Kong
508ac3a44c
aarch64: fix adcs/sbcs carry flag (select on cc_dep3, not cc_dep2) (#6702)
arm64g_calculate_flag_c selected the ADC*/SBC* carry-in with `cc_dep2 != 0`
(the second operand). The arm64 flag thunk layout puts the old carry in
cc_dep3 (angr's own comment: "DEP3 = oldC (in LSB)", matching VEX's
guest_arm64_helpers.c). So the C flag after adcs/sbcs was computed from an
operand value instead of the incoming carry.

Random operands usually mask it (cc_dep2 != 0 nearly always holds); the
equal-operand case exposes it, e.g. `sbcs x,y,y` must give C = oldC but
returned a value keyed on y. flag_n/z/v and the arm32 port (which correctly
uses cc_dep3) were unaffected.
2026-07-29 00:57:43 -07:00
Fish
6b2637c446
Dephication: Consider the vvar used in block-end jumps during intersection. (#6733)
* Dephication: Consider the vvar used in block-end jumps during intersection.

This is a subtlety in the Sreedhar et. al. paper.

* Fix test cases.
2026-07-29 00:42:21 -07:00
Fish
a7ae033c69
EagerEval: Fix broken expression type comparison. (#6734)
This is a bug introduced by the Rusty AIL migration.
2026-07-29 00:05:07 -07:00
Fish
659f3d7f5d
CCodeGen: Fix the display of negative offsets. (#6730)
* CCodeGen: Fix the display of negative offsets.

* Fix a test case.
2026-07-28 22:29:12 -07:00
Audrey Dutcher
4462c849b9
RegionIdentifier: typecheck post-regionoverlay (#6664) 2026-07-28 19:52:00 -07:00
Fish
22613f4a0a
CompleteCallingConventions: fail loudly when all workers die. (#6718) 2026-07-27 18:20:59 -07:00
Fish
2fffb71f86
state_plugins: Map the heap region lazily and grow it on demand. (#6715) 2026-07-27 18:20:07 -07:00
Fish
55f059982b
UltraPage: Make the symbolic map an actual bitmap. (#6714) 2026-07-27 17:35:52 -07:00
Fish
1a5eedf622
Decompiler: Speed up AIL block simplifications. (#6712)
- Make SPropagator, SRDA, and BlockSimplifier normal classes instead of Analysis classes.

- Share peephole optimizer instances across BlockSimplifiers.

- BlockSimplifier: Skip unnecessary peephole passes; avoid block-level comparisons for fixpoint determination.

- Add a runtime-only peephole_optimized flag to AIL statements so we skip running peephole optimizations on already optimized statements.
2026-07-27 16:34:10 -07:00
Fish
2080c15a26
RemoveRedundantBitmasks: Fix an in-place expression update. (#6722) 2026-07-27 15:53:53 -07:00
dependabot[bot]
3e2e4b90fc
ci: bump taiki-e/install-action from 2.84.0 to 2.85.2 (#6719)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.84.0 to 2.85.2.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](a6b2e2dcd8...41049aa566)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.85.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 13:13:52 -07:00
dependabot[bot]
59400706f8
ci: bump astral-sh/setup-uv from 8.3.2 to 9.0.0 (#6720)
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 8.3.2 to 9.0.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](11f9893b08...c771a70e62)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 13:13:35 -07:00
Fish
bc72b9e1a6
MCP: Protect stdio from forked workers. (#6717)
Some checks failed
CI / Rust Check (push) Failing after 6s
CI / rust_test (ubuntu-latest) (push) Failing after 9s
Test with coverage / Build (push) Failing after 8s
Test with coverage / Test (push) Has been skipped
Test with coverage / Test-1 (push) Has been skipped
Test with coverage / Test-2 (push) Has been skipped
Test with coverage / Test-3 (push) Has been skipped
Test with coverage / Test-4 (push) Has been skipped
Test with coverage / Test-5 (push) Has been skipped
Test with coverage / Test-6 (push) Has been skipped
Test with coverage / Test-7 (push) Has been skipped
Test with coverage / Test-8 (push) Has been skipped
Test with coverage / Test-9 (push) Has been skipped
Test with coverage / Test Rust packages (push) Failing after 6s
Test with coverage / Report (push) Has been skipped
CI / ci (push) Has been cancelled
CI / Test installation (macos-26, py3.12) (push) Has been cancelled
CI / Test installation (ubuntu-24.04, py3.14) (push) Has been cancelled
CI / Test installation (windows-2025, py3.12) (push) Has been cancelled
CI / rust_test (macos-latest) (push) Has been cancelled
CI / rust_test (windows-latest) (push) Has been cancelled
2026-07-27 03:01:56 -07:00
Fish
651d9cccc2
Tests: Speed up decompiler-related test cases (strike 1). (#6713) 2026-07-27 01:56:24 -07:00
Fish
9c1fb2367e
StructuringOptimizationPass: Cache structurability across passes. (#6711) 2026-07-27 00:03:32 -07:00
Quintin Kong
e4ff240001
x86/amd64: fix UMUL CF/OF flags (widen before multiply) (#6703)
Fixes #6067

pc_actions_UMUL computed the product at operand width, so the extracted
"high half" was always zero and CF/OF (OF = CF) were constantly 0:

    lo = (cc_dep1 * cc_dep2)[nbits-1:0]   # truncated to nbits
    hi = (lo >> nbits)[nbits-1:0]         # lo is nbits wide -> always 0

The sibling pc_actions_SMUL is correct because it widens first
(sign_extend). Mirror it with zero_extend: multiply the operands widened to
2*nbits and take the high half. For CC_OP_MUL{B,W,L,Q}, CF = OF =
(high half != 0) per the Intel SDM. This is why `imul` reported CF/OF
correctly while `mul` did not (issue #6067: `mul %ebx` left CF clear).
2026-07-26 22:32:25 -07:00
Fish
6d5860d0ba
COWDict: Faster chain walks. (#6710) 2026-07-26 22:20:20 -07:00
Fish
3b41a92e29
SimpleSolver: Hash memoization. (#6709) 2026-07-26 22:10:26 -07:00
Fish
83f364dc01
Memoize C++ prototype parsing. (#6708) 2026-07-26 21:33:20 -07:00
Fish
787c2c7d8e
SimpleSolver: Memoize least common ancestors on type lattices. (#6707) 2026-07-26 17:17:09 -07:00
Fish
b37cca0101
VRA: Register the Reference stack variable against its atom. (#6705) 2026-07-26 07:58:06 -07:00
Fish
fc7ff8e62c
CFGFast: Linear scan heuristics for monotonic byte ramps and floats. (#6701) 2026-07-26 00:35:43 -07:00
Yan Shoshitaishvili
83d0061e12
Calling conventions: ignore stack canary comparisons as returns (#6699)
* Calling conventions: ignore stack canary comparisons as returns
2026-07-24 16:34:21 -07:00
Yan Shoshitaishvili
f74d1c5c1e
Typehoon: index subtype constraint components (#6696)
* Typehoon: index subtype constraint components

* Refactor the code to eliminate weird terminology.

* Fix test cases.

---------

Co-authored-by: Fish <fishw@asu.edu>
2026-07-24 16:26:47 -07:00
Max Ambaum
be9c801b16
Add __sprintf_chk as a simprocedure (#6698)
* Add __sprintf_chk as a simprocedure

http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/libc---sprintf-chk-1.html
2026-07-24 14:42:53 -07:00
Fish
3efd1ec6db
SimLibrary/SimSyscallLibrary: Treat None prototypes as absent. (#6673) 2026-07-24 11:29:58 -07:00
Ati Priya
db21fb0fee
Rewrite the amd64 CondO/CondNO ccall (#6693)
* Rewrite the amd64 CondO/CondNO ccall family

amd64g_calculate_condition with cond CondO/CondNO had no rewrite arm at
all, so every jo/jno/seto/cmovno site leaked into the decompilation as an
uncompilable _ccall(0|1, cc_op, ...).

Add arms for the cc_op families that define OF:

  LOGIC{B,W,L,Q}  and/or/xor always clear OF -> constant 0 / 1
  ADD{B,W,L,Q}    -> __OFADD__(dep_1, dep_2)
  SUB{B,W,L,Q}    -> __OFSUB__(dep_1, dep_2)
  UMUL{B,W,L,Q}   -> __OFUMUL__(dep_1, dep_2)
  SMUL{B,W,L,Q}   -> __OFSMUL__(dep_1, dep_2)
  INC{B,W,L,Q}    result == signed minimum
  DEC{B,W,L,Q}    result == signed maximum
  COPY            test the stored OF bit

The overflow helpers follow the existing __CFADD__ arm: a named usercall
whose operands carry the operation width. CondNO reuses the same helper
and compares it against zero.

Unsigned multiply overflow is defined as "the high half of the full
2N-bit product is nonzero", i.e. the product does not fit in N unsigned
bits. Note this is NOT the threshold used by the x86 rewriter, which
compares the product against 1 << (N - 1) -- that is the signed
threshold, half the correct unsigned one, and it reports overflow for
every product in [2^(N-1), 2^N - 1] even though those fit. At 8 bits it
misclassifies 820 of 65536 operand pairs, all false positives.

pc_actions_UMUL in the VEX ccall helpers is itself wrong here: it
multiplies two N-bit values without widening, so its `>> nbits` is
always zero and its CF/OF do not agree with the hardware. The rewrite
arm follows the hardware and pc_actions_SMUL's (correct) structure
instead; fixing the helper is left alone.

Every arm was checked exhaustively at 8 bits against
pc_calculate_condition, and the ADD/SUB/UMUL/SMUL arms additionally
against real setcc results.

* Drop the synthetic CondO fixture test

The real gzip and file fixtures already cover the CondO arms; a purpose
built binary added nothing that the unit tests do not already check.

* Cover the CondNO overflow path with a real binary

tar's argp helper guards a multiply with 'mul %rbp; jno', exercising the
CondNO side of UMULQ that gzip and file do not reach. Other cc_op
families still leak a ccall in that function, so only the OF conditions
are asserted.

* Cover the CondO overflow arms with three more real binaries

coreutils cat, grep and zlib's minigzip each carry the xalloc /
__builtin_mul_overflow idiom, between them exercising CondO against
ADDQ, SMULQ and UMULQ across three separate projects. Verified symbols
and addresses are cited on each test.

* Correct the tar overflow test to CondO

The jno there is canonicalized into CondO with an inverted branch, so the
ccall reaching the rewriter carries cond 0, not cond 1. The negation seen
in the output is the structurer's, not the condition's.
2026-07-24 11:28:39 -07:00
Fish
91cc026062
AILVexLifter: Fix libVEX overread by padding in convert_from_lift. (#6686) 2026-07-24 01:43:20 -07:00
Yan Shoshitaishvili
90062a9914
Support native AIL Abs expressions in light engines (#6683)
* Fix AIL Abs unary operation dispatch

* Fix Abs regression test lint
2026-07-24 00:43:03 -07:00
Yan Shoshitaishvili
fe434a049b
Decompiler: reject float constants in string simplifiers (#6682)
* Decompiler: reject float constants in string simplifiers

* Tests: allow private simplifier coverage
2026-07-24 00:28:36 -07:00
Yan Shoshitaishvili
208ec719a6
Decompiler: disambiguate Extract condition placeholders (#6677) 2026-07-23 22:33:21 -07:00
Yan Shoshitaishvili
8b98c5ad6c
Keep eager evaluation integer-only (#6681) 2026-07-23 22:30:15 -07:00
Yan Shoshitaishvili
2dd6cb393b
Typehoon: preserve standard SimTypeNum types (#6678) 2026-07-23 21:15:18 -07:00
Yan Shoshitaishvili
cf54c35b9b
AIL: handle HAddV operations (#6680)
* AIL: handle HAddV operations

* Fix HAddV CI diagnostics
2026-07-23 21:10:10 -07:00
Vedant Soni
1808e7fadd
Migrate rust demangling to pydemumble (#6663)
* use pydemumble to demangle rust symbols

* update tests

* remove rust_demangle and unpin pydemumble from pyproject

* pin pydemumble to latest version
2026-07-23 17:32:00 -07:00
Michał Kowalczyk
c13863214c
docs: Fix dangling links (#6533) 2026-07-23 17:31:25 -07:00
Fish
75500dd271
VRA: Copy over integer signedness to type constraints during Convert. (#6672)
* VRA: Copy over integer signedness to type constraints during Convert.

* Adjust a test case.
2026-07-23 15:57:26 -07:00
Fish
85d77f0301
RemoveRedundantShifts: Retain sign extensions. (#6671)
`(x << N) >> N` was rewritten into a Convert-of-Convert pair whose outer Convert
zero-extended for BOTH logical (Shr) and arithmetic (Sar) right shifts. For Sar
this is unsound: the idiom sign-extends the low (M-N) bits, but the zero-extending
Convert rendered as a bitmask, so e.g. `(int)(x << 20) >> 20` decompiled to
`x & 0xfff` (and the 64-bit twin to `x & 0xffffffffff`), which drops the
sign bit.
2026-07-23 14:43:45 -07:00
Fish
0849ddb03c
CFGFast: Tolerate leading null bytes during string scanning. (#6670)
* CFGFast: Tolerate a single leading null byte when scanning for strings.

* CFGFast: Scan for mixed pointers in high-based images during complete scanning.

* Tests: Add a regression test for data detection in a PE32 with data tables in .text.
2026-07-23 14:43:32 -07:00