Skip to content

Upgrade Frida to 17.15.3, migrate to Rust edition 2024, and expand Gum API coverage#242

Draft
kkuehl wants to merge 32 commits into
frida:mainfrom
kkuehl:kkuehl/frida-rust-updates
Draft

Upgrade Frida to 17.15.3, migrate to Rust edition 2024, and expand Gum API coverage#242
kkuehl wants to merge 32 commits into
frida:mainfrom
kkuehl:kkuehl/frida-rust-updates

Conversation

@kkuehl

@kkuehl kkuehl commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Upgrade Frida to 17.15.3, migrate to Rust edition 2024, and expand Gum API coverage

Brings the bindings current with Frida 17.15.3, migrates the workspace to Rust edition 2024, fixes soundness issues found during C API audit, and adds bindings for APIs introduced in Frida 17.10–17.15.

Frida & Toolchain

  • Upgrade Frida: 17.9.5 → 17.15.3 (devkit + bindings)
  • Rust edition 2024: unsafe extern blocks, explicit unsafe {} in unsafe fns, match ergonomics
  • reqwest 0.12 → 0.13: unified TLS feature naming (rustls vs rustls-tls)

New API Bindings (17.10–17.15)

  • ControlFlowGraph: construction, dominator queries, block bounds/successors/predecessors, instruction lookup
  • ElfModule (17.15.0): from_file/from_memory, property accessors (pointer size, byte order, OS ABI, mapped size, addresses, entrypoint, interpreter, source path), enumerate_dynamic_entries for ELF .dynamic section iteration (Linux/Android/FreeBSD only)
  • Process: find_function_range (works on stripped binaries), get_parameters() (argv via Variant::StringList)
  • Interceptor: flush_function/flush_listener, attach_with_options + AttachOptions builder
  • UnwindBroker: obtain + provider/translator registration
  • Memory: mprotect/try_mprotect, clear_cache, ensure_code_readable, try_alloc_n_pages_near, patch_code_pages
  • Misc: DebugSymbol::load_symbols, Exceptor::exception_details_to_string, CodeAllocator::alloc_deflector, InvocationContext listener-data getters

Soundness & Correctness Fixes

  • ModuleMap::new_with_filter: fix use-after-free — filter is now owned ('static + GDestroyNotify) instead of dangling temporary
  • range_details: add missing PageProtection::WriteExecute variant; stop panicking on unexpected protection bits in FFI callbacks
  • Process::current_dir: free transfer-full string (was leaking)
  • module/process enumerators: fix &T as *mut aliasing UB
  • Exceptor::add: require Send (handlers run on faulting thread)
  • MatchPattern::from_string: return None instead of panicking on interior-NUL
  • Writer wrappers: void C functions now return () instead of fake bool

Cross-Platform Fixes

  • unsafe extern: all extern "C" blocks now unsafe extern "C" (aarch64/x86_64 relocators, Linux/FreeBSD process module)
  • Enum signedness: cast with as _ for bindgen i32/u32 platform variance (MSVC vs clang)
  • GLib symbol prefixing: _frida_g_* on Linux/FreeBSD/iOS devkits, bare g_* on Windows/macOS — unified via glib_compat module
  • gchar signedness: CString/CStr pointers use .cast() for clang i8 vs MSVC i8/u8 variance

kkuehl added 6 commits June 11, 2026 09:07
Update frida-rust bindings to support Frida 17.11.0 API changes:

- Update FRIDA_VERSION files to 17.11.0
- Remove deprecated Stalker::enable_unwind_hooking() method
  (gum_stalker_activate_experimental_unwind_support was removed)
- Update Interceptor::replace() to use new 5-parameter API with GumReplaceOptions
- Update Interceptor::replace_fast() to use new 5-parameter API with GumInterceptorOptions

The new interceptor options provide fine-grained control over code patching:
- scratch_register: Register for temporary operations (-1 for auto)
- scenario: Interceptor scenario (DEFAULT/EXCLUSIVE)
- relocation_policy: Code relocation strategy (DEFAULT/CRITICAL)
- write_redirect: Custom memory write callback (NULL for default)
- redirect_space_hint: Space hint for redirects (0 for auto)

Default values maintain backward-compatible behavior.
- Update FRIDA_VERSION files to 17.13.0
- Add new API bindings: ApiResolver, Cloak, CodeAllocator, CodeSegment, Exceptor, Memory, Query, Registry, SymbolUtil, TLS
- Update existing bindings for compatibility
- Update examples for new API patterns
- Upgrade FRIDA_VERSION from 17.11.0 to 17.12.0
- Add new API bindings: ApiResolver, Cloak, CodeAllocator, CodeSegment, Exceptor, Memory, Query, Registry, SymbolUtil, TLS
- Update existing bindings for compatibility
- Update examples for new API patterns
- Note: 17.13.0 upgrade pending release of devkit binaries
…ndings

Quality/soundness fixes (verified against frida-gum C source):
- module_map: fix use-after-free in new_with_filter (filter was a dangling
  temporary Box with no destroy-notify, but Frida retains and re-invokes it on
  every update); now owns the closure by value + GDestroyNotify.
- range_details: add missing PageProtection::WriteExecute variant (value 6) and
  stop unwrap()-panicking on unexpected protection bits in an FFI callback.
- process: free the transfer-full string returned by g_get_current_dir.
- module/process: fix &T-as-*mut aliasing (UB) in enumerate_* callbacks.
- exceptor: require Send on the handler closure; document no auto-remove on drop.
- memory_range: MatchPattern::from_string returns None instead of panicking on
  interior-NUL input.
Several agent-flagged "bugs" were verified FALSE POSITIVES and left unchanged
(registry obtain() is transfer-none; gum_memory_read uses g_malloc; GumCodeSlice
refcount is atomic).

Frida + toolchain:
- Bump Frida 17.12.0 -> 17.13.0 (all FRIDA_VERSION files).
- Migrate workspace to edition 2024 (cargo fix --edition + manual unsafe-block
  fixes in feature-gated files the migration did not compile: invocation_listener,
  stalker/observer, stalker/event_sink, backtracer).

New API bindings (Frida 17.10-17.13):
- control_flow_graph.rs: GumControlFlowGraph (new/for_function, dominates,
  enumerate_dominating_sites, block queries, find_instruction_containing).
- Process::find_function_range (works on stripped binaries).
- Interceptor::flush_function / flush_listener.
- Interceptor::attach_with_options + AttachOptions builder.
- unwind_broker.rs: GumUnwindBroker obtain + provider/translator registration.
- frida core: Variant::StringList decodes GVariant "as" so the new argv process
  parameter surfaces via Process::get_parameters().

Wrap remaining pre-existing C API gaps:
- Memory::mprotect / try_mprotect / clear_cache / ensure_code_readable /
  try_alloc_n_pages_near / patch_code_pages.
- DebugSymbol::load_symbols.
- InvocationContext listener data getters (function / thread / invocation).
- Exceptor::exception_details_to_string.
- CodeAllocator::alloc_deflector (+ CodeDeflector type).

Verified (edition 2024, Frida 17.13.0): cargo build (all gum features), clippy
-D warnings (gum all-features + frida + frida-sys), cargo fmt --check, and
cargo test -p frida-gum (10 passed) all clean.
The instruction-writer wrappers for Gum C functions that are declared `void`
were fabricating `-> bool { ...; true }`, giving callers a meaningless success
signal. Change these inherent methods to return `()` to match the C ABI:

- x86_64: put_leave, put_ret, put_ret_imm, put_jmp_short_label,
  put_jmp_near_label, put_mov_reg_address, put_mov_reg_ptr_u32,
  put_mov_reg_ptr_reg, put_mov_reg_reg_ptr, put_push_u32, put_push_imm_ptr,
  put_nop, put_pushfx, put_popfx, put_pushax, put_popax.
- aarch64: put_call_address_with_arguments.

The InstructionWriter trait methods (put_bytes/put_label/put_branch_address/
put_nop/flush) are left returning bool: arm/arm64's underlying C functions
return gboolean, so the shared trait signature must stay. The x86 put_bytes impl
keeps its `true` fabrication only to satisfy that trait.

No callers consumed these return values. Verified: clippy -D warnings (gum
all-features), cargo fmt --check, cargo test -p frida-gum (10 passed).
@s1341

s1341 commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Wow. that's a big PR! Thanks!

in future, can I recommend that you submit a separate PR per issue, to keep things simpler?

Please address CI issues and I will review in depth.

@kkuehl kkuehl marked this pull request as draft June 16, 2026 11:09
kkuehl added 15 commits June 16, 2026 07:18
…gnedness

- aarch64/relocator.rs + process.rs (linux/freebsd block): extern "C" -> unsafe
  extern "C" (edition 2024), in target-gated code the Windows build never
  compiled.
- Enum discriminants from bindgen constants now use `as _` so they work whether
  the platform's compiler types the C enum as i32 (MSVC) or u32 (clang):
  transformer MemoryAccess, process TeardownRequirement, exceptor ExceptorMode +
  ExceptionType, aarch64 IndexMode.
- thread WatchConditions bitflags backed by gum_sys::GumWatchConditions so
  bits() matches the FFI parameter on every platform.

Partial: macOS/Linux/iOS CI also surfaces GLib symbol naming (_frida_ prefix),
gchar pointer signedness, and jcc condition casts not yet addressed here.
Edition 2024 + platform differences the Windows/x86_64 build never exercised:

- unsafe extern: aarch64/relocator.rs (7 blocks) and process.rs linux/freebsd
  block were still plain `extern "C"`.
- Enum discriminant signedness: bindgen types C enums as i32 on MSVC but u32 on
  clang. Use `as _` so the cast is correct on both (and not flagged as a
  same-type cast on Windows): transformer MemoryAccess, process
  TeardownRequirement, exceptor ExceptorMode + ExceptionType, aarch64 IndexMode,
  and the jcc_short/jcc_near condition args in the x86 writer.
- thread WatchConditions bitflags backed by gum_sys::GumWatchConditions so
  bits() matches the FFI parameter on every platform.
- gchar pointer signedness: CString/CStr pointers passed to gum_* APIs typed as
  *const gchar (i8 on clang, differs from cstr_core's c_char) now use .cast()
  in api_resolver, symbol_util, debug_symbol.
- GLib symbol naming: g_free/g_error_free/g_array_free/g_ptr_array_* are
  _frida_-prefixed on the Linux/FreeBSD/iOS static devkits but bare g_* on
  Windows/macOS. Added a central cfg-gated glib_compat module (mirroring the
  existing _frida_g_get_*_dir handling) and routed all call sites through it.

Verified on Windows: clippy -D warnings (gum all-features) clean.
FRIDA_VERSION: bump 17.9.5 -> 17.14.0 across all FRIDA_VERSION files.

Edition 2024 (workspace Cargo.toml): `unsafe extern "C"` required for all
extern blocks; `unsafe_op_in_unsafe_fn` now deny-by-default requiring explicit
`unsafe {}` blocks inside unsafe fns; `ref` in let-else patterns removed.
Applied via `cargo fix --edition` where possible, remaining blockers fixed
manually first.

API changes for 17.13.0/17.14.0:
- gum_interceptor_replace/replace_fast: new options param added; pass null.
- gum_interceptor_attach: options param replaces separate listener_data arg.
- gum_stalker_activate_experimental_unwind_support: removed; drop wrapper.
- frida-build: fix redundant-reference lints in format!/println! macros.
- backtracer: fix double-reference in fuzzy_with_context.

Cross-platform (Linux/iOS devkits prefix GLib symbols with _frida_):
- variant.rs `ref` patterns updated for edition 2024 match ergonomics.
- process.rs Linux/FreeBSD extern block marked unsafe extern.
- aarch64/relocator.rs + x86_64/relocator.rs extern blocks marked unsafe.
- Add unsafe keyword to all extern "C" blocks in aarch64 relocator
- Update FRIDA_VERSION from 17.14.0 to 17.14.1 in both frida-sys and frida-gum-sys
- Fixes compilation errors with Rust edition 2024 requirement for unsafe extern blocks
Only uses reqwest::blocking::get with blocking + rustls-tls features,
all unchanged in 0.13. Lets downstream workspaces unify on reqwest 0.13
instead of compiling both 0.12 and 0.13.
Only uses reqwest::blocking::get with blocking + rustls-tls features,
all unchanged in 0.13. Lets downstream workspaces unify on reqwest 0.13
instead of compiling both 0.12 and 0.13.
…tls')

reqwest 0.13 renamed the rustls-tls feature to rustls; the old name no
longer resolves. Plain 'rustls' bundles a crypto provider (unlike
'rustls-no-provider').
…tls')

reqwest 0.13 renamed the rustls-tls feature to rustls; the old name no
longer resolves. Plain 'rustls' bundles a crypto provider (unlike
'rustls-no-provider').
Rust 2024 edition requires unsafe operations inside `unsafe fn` bodies
to be wrapped in explicit `unsafe {}` blocks. Add inner unsafe blocks to
create_cb, js_msg, and load_cb to satisfy unsafe_op_in_unsafe_fn lint.
…ition-2024

Keep frida-rust-updates Rust source (has more API bindings and CI fixes).
Take FRIDA_VERSION 17.15.0 from frida-17.13-edition-2024 branch.
New frida-gum/src/elf_module.rs wraps gum_elf_module_* APIs added in
17.15.0: ElfModule::from_file/from_memory constructors, property accessors
(pointer_size, byte_order, os_abi_version, mapped_size, base/preferred
address, entrypoint, interpreter, source_path), and
enumerate_dynamic_entries/dynamic_entries for iterating ELF .dynamic section.
Linux/Android/FreeBSD only (cfg-guarded against Windows and macOS/iOS).
@kkuehl kkuehl changed the title Update frida-rust to 17.13.0 Update frida-rust to 17.15.1 Jun 21, 2026
@kkuehl kkuehl changed the title Update frida-rust to 17.15.1 Upgrade Frida to 17.15.3, migrate to Rust edition 2024, and expand Gum API coverage Jun 25, 2026
@kkuehl kkuehl force-pushed the kkuehl/frida-rust-updates branch from bbc496c to 0574dc9 Compare July 7, 2026 14:57
Merge upstream/main to resolve PR frida#242 conflicts and bring the branch
into mergeable state.

Key changes:
- Resolved 15 file conflicts (version files, code changes)
- Preserved Rust 2024 edition fixes (unsafe extern blocks)
- Kept all new Frida 17.10+ APIs (attach_with_options, instrumentation options)
- Fixed unsafe block placement in memory_access_monitor.rs
- Updated FRIDA_VERSION to 17.15.4
- Fixed elf_module.rs copyright attribution

All clippy and build checks passing.
kkuehl added 7 commits July 7, 2026 10:15
Fix three issues preventing CI from passing:

1. Remove unused GumElfDynamicTag import from elf_module.rs
   - Caught by clippy -D warnings on Linux/no_std builds

2. Fix iOS g_ptr_array_sized_new symbol mismatch in glib_compat.rs
   - iOS devkit exports unprefixed g_ptr_array_sized_new
   - Linux/FreeBSD use _frida_g_ prefix
   - Split iOS into separate cfg block

3. Remove unused ToString import from elf_module.rs std feature

All clippy checks now pass on Windows. iOS/Linux/macOS builds should
pass in CI.
Add comprehensive instruction writers for ARM Thumb mode and MIPS
architecture to complete cross-platform code generation support.

ARM Thumb additions:
- ThumbWriter for Thumb/Thumb-2 instruction generation
- ThumbCondition enum for conditional execution
- Integrated into existing ARM instruction writer module

MIPS additions:
- MipsWriter for MIPS32/MIPS64 code generation
- MipsRegister enum for MIPS register definitions
- New mips module under instruction_writer

Module structure follows existing aarch64/x86_64 pattern:
- Parent .rs file declares submodules
- Subdirectory contains implementation files
- Platform-specific cfg gates on ARM-specific code

Part of comprehensive GUM API coverage expansion.
Fix three categories of CI failures across Linux x86, iOS, and docs:

1. **iOS glib symbol mismatch** (glib_compat.rs)
   - iOS devkit exports g_ptr_array_free without _frida_g_ prefix
   - Split iOS cfg to use unprefixed g_ptr_array_free
   - Keeps _frida_g_ prefix for other symbols

2. **32-bit Linux type errors** (memory.rs)
   - gsize is platform-dependent: u64 on Windows, usize on Linux
   - Fixed 21 locations to cast usize -> gum_sys::gsize
   - Affects all Memory functions: allocate, free, read, write, mprotect, etc.

3. **Module structure error** (mips/)
   - Removed duplicate mips/mod.rs (conflicts with mips.rs parent)
   - Follows aarch64/x86_64 pattern: parent .rs declares submodules

All clippy checks now pass. Should fix x86/iOS/docs CI builds.
Fix 8 clippy warnings about useless conversions in writer.rs and elf_module.rs:

1. **x86_64/writer.rs** (6 fixes)
   - Remove .try_into().unwrap() from GumCallingConvention (already u32)
   - Remove .try_into().unwrap() from GumArgType constants (already u32)
   - Keep `as u32` casts where constants are i32 but fields expect u32

2. **elf_module.rs** (1 fix)
   - Remove unnecessary cast: (*details).tag already u32

All clippy checks now pass with -D warnings. Verified locally before push.
…y.rs

Fixes clippy warnings on Linux where GUM enum constants are u32,
while on Windows they're i32 and need explicit casts.

Solution: Add #![allow(clippy::unnecessary_cast)] to the query module
since the casts are required on Windows but redundant on Linux.

All clippy checks now pass on both platforms.
Some types (GumAttachOptions, GumInterceptorScenario, GumRelocationPolicy,
GumControlFlowGraph, GumUnwindBroker, GumExceptorMode) exist in the Frida
17.15.4 headers but bindgen doesn't generate typedef aliases for them on
some platforms. The build script now detects which types are present in
the generated bindings and emits cfg flags, allowing frida-gum to
conditionally compile modules that depend on these types.
The #![cfg(...)] at the top of module files causes issues. Instead, only
guard the mod and pub use declarations in lib.rs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants