Compare commits

..
11 Commits
Author SHA1 Message Date
Ole André Vadla Ravnås 588ac3b3de subprojects: Bump outdated 2026-11-09 22:03:43 +01:00
Ole André Vadla Ravnås d0615e7574 submodules: Bump releng 2026-11-09 22:03:42 +01:00
Kaz Wolfe 1b169dec1c exit-monitor: Pass function sizes to Interceptor
On QNX 6.5 ARM, libc's _exit() is a lone BL into __exit(), and the
Interceptor cannot tell where it ends. Look up the symbol sizes and pass
them as redirect_space_hint so the redirect stays within the function.
2026-11-09 21:59:38 +01:00
Kaz Wolfe 0e61ae2762 qnx: Set PC when emitting the ARM payload
The writer assumed the code would run where it was generated, so calls
to libc functions within BL range of the local buffer were encoded with
offsets that are wrong in the target process.
2026-11-09 21:59:38 +01:00
Kaz Wolfe 6a445d9dea qnx: Add x86 support to the injector
Mirror the ARM payload and remote call using cdecl.
2026-11-09 20:34:01 +01:00
Ole André Vadla Ravnås 2a41a960fe subprojects: Prepare for release 2026-11-07 15:45:32 +01:00
Ole André Vadla Ravnås 25bd49299a subprojects: Bump outdated 2026-11-07 15:44:13 +01:00
tubibibo c84323b6ac linux: Don't pass our stdin to crash logcat
Under `adb shell`, frida-server's stdin and stdout are the same socket.
The crash monitor's logcat inherited it, so when frida-server died
abnormally, logcat kept it open and `adb shell` never saw EOF.

Give logcat /dev/null for stdin instead.
2026-11-07 15:38:00 +01:00
Ole André Vadla Ravnås 45aef70f35 subprojects: Prepare for release 2026-11-06 13:15:10 +01:00
Ole André Vadla Ravnås eb8efdf40a subprojects: Bump outdated 2026-11-06 12:19:36 +01:00
Ole André Vadla Ravnås 025e5c433d submodules: Bump releng 2026-11-06 12:19:35 +01:00
9 changed files with 198 additions and 13 deletions

No files matched your search

+18 -2
View File
@@ -46,8 +46,24 @@ namespace Frida {
}
#else
var libc = Gum.Process.get_libc_module ();
foreach (var symbol in apis) {
interceptor.attach ((void *) libc.find_export_by_name (symbol), listener);
var targets = new Gum.Address[apis.length];
for (var i = 0; i != apis.length; i++)
targets[i] = libc.find_export_by_name (apis[i]);
var sizes = new uint[apis.length];
#if ARM
libc.enumerate_symbols (s => {
for (var i = 0; i != targets.length; i++) {
if (s.address == targets[i] && s.size > 0)
sizes[i] = (uint) s.size;
}
return true;
});
#endif
for (var i = 0; i != apis.length; i++) {
var options = Gum.AttachOptions ();
options.instrumentation.redirect_space_hint = sizes[i];
interceptor.attach ((void *) targets[i], listener, options);
}
#endif
#endif
+1 -1
Submodule releng updated: ce275018bb...fe7d31dfbc.
+1 -1
View File
@@ -2482,7 +2482,7 @@ namespace Frida {
if (stdout_pipe == null) {
try {
var process = new Subprocess.newv ({ "logcat", "-b", "crash", "-B" },
STDIN_INHERIT | STDOUT_PIPE | STDERR_SILENCE);
STDOUT_PIPE | STDERR_SILENCE);
logcat = process;
stdout_pipe = process.get_stdout_pipe ();
+173 -4
View File
@@ -1,8 +1,12 @@
#include "frida-core.h"
#include <gio/gunixinputstream.h>
#include <gum/arch-arm/gumarmwriter.h>
#include <gum/arch-arm/gumthumbwriter.h>
#if defined (HAVE_I386)
# include <gum/arch-x86/gumx86writer.h>
#elif defined (HAVE_ARM)
# include <gum/arch-arm/gumarmwriter.h>
# include <gum/arch-arm/gumthumbwriter.h>
#endif
#include <gum/gum.h>
#include <dlfcn.h>
#include <errno.h>
@@ -22,6 +26,7 @@
#endif
#include <sys/wait.h>
#ifdef HAVE_ARM
enum {
GUM_QNX_ARM_REG_PC = ARM_REG_PC,
GUM_QNX_ARM_REG_LR = ARM_REG_LR,
@@ -52,6 +57,7 @@ enum {
#undef ARM_REG_PC
#define PSR_T_BIT (1 << 5)
#endif
#define CHECK_OS_RESULT(n1, cmp, n2, op) \
if (!(n1 cmp n2)) \
@@ -60,6 +66,14 @@ enum {
goto os_failure; \
}
#if defined (HAVE_I386)
# define FRIDA_QNX_GREG_PC(r) ((r)->x86.eip)
# define FRIDA_QNX_GREG_RETVAL(r) ((r)->x86.eax)
#elif defined (HAVE_ARM)
# define FRIDA_QNX_GREG_PC(r) ((r)->arm.gpr[GUM_QNX_ARM_REG_PC])
# define FRIDA_QNX_GREG_RETVAL(r) ((r)->arm.gpr[GUM_QNX_ARM_REG_R0])
#endif
#define FRIDA_REMOTE_PAYLOAD_SIZE (8192)
#define FRIDA_REMOTE_DATA_OFFSET (512)
#define FRIDA_REMOTE_STACK_OFFSET (FRIDA_REMOTE_PAYLOAD_SIZE - 512)
@@ -294,6 +308,138 @@ frida_emit_and_remote_execute (FridaEmitFunc func, const FridaInjectionParams *
return TRUE;
}
#if defined (HAVE_I386)
#define ARG_IMM(value) \
GUM_ARG_ADDRESS, GUM_ADDRESS (value)
#define ARG_REG(reg) \
GUM_ARG_REGISTER, GUM_X86_##reg
#define EMIT_CALL_IMM(func, n_args, ...) \
gum_x86_writer_put_call_address_with_arguments (&cw, GUM_CALL_CAPI, func, n_args, __VA_ARGS__)
#define EMIT_CALL_REG(reg, n_args, ...) \
gum_x86_writer_put_call_reg_with_arguments (&cw, GUM_CALL_CAPI, GUM_X86_##reg, n_args, __VA_ARGS__)
#define EMIT_LOAD_FIELD(reg, field) \
gum_x86_writer_put_mov_reg_address (&cw, GUM_X86_##reg, FRIDA_REMOTE_DATA_FIELD (field)); \
gum_x86_writer_put_mov_reg_reg_ptr (&cw, GUM_X86_##reg, GUM_X86_##reg)
#define EMIT_STORE_FIELD(field, reg) \
gum_x86_writer_put_mov_reg_address (&cw, GUM_X86_EAX, FRIDA_REMOTE_DATA_FIELD (field)); \
gum_x86_writer_put_mov_reg_ptr_reg (&cw, GUM_X86_EAX, GUM_X86_##reg)
static void
frida_emit_payload_code (const FridaInjectionParams * params, GumAddress remote_address, FridaCodeChunk * code)
{
GumX86Writer cw;
const gchar * skip_dlopen = "skip_dlopen";
const gchar * skip_dlclose = "skip_dlclose";
const gchar * skip_detach = "skip_detach";
gum_x86_writer_init (&cw, code->cur);
cw.pc = remote_address;
gum_x86_writer_put_push_reg (&cw, GUM_X86_EBP);
gum_x86_writer_put_mov_reg_reg (&cw, GUM_X86_EBP, GUM_X86_ESP);
gum_x86_writer_put_push_reg (&cw, GUM_X86_EBX);
gum_x86_writer_put_push_reg (&cw, GUM_X86_ESI);
gum_x86_writer_put_push_reg (&cw, GUM_X86_EDI);
gum_x86_writer_put_sub_reg_imm (&cw, GUM_X86_ESP, 4 + 8);
EMIT_CALL_IMM (frida_resolve_remote_libc_function (params->pid, "ConnectAttach_r"),
5,
ARG_IMM (ND_LOCAL_NODE),
ARG_IMM (getpid ()),
ARG_IMM (params->channel_id),
ARG_IMM (_NTO_SIDE_CHANNEL),
ARG_IMM (_NTO_COF_CLOEXEC));
gum_x86_writer_put_mov_reg_reg (&cw, GUM_X86_EDI, GUM_X86_EAX);
gum_x86_writer_put_call_address_with_arguments (&cw, GUM_CALL_CAPI,
frida_resolve_remote_libc_function (params->pid, "gettid"), 0);
EMIT_CALL_IMM (frida_resolve_remote_libc_function (params->pid, "MsgSendPulse_r"),
4,
ARG_REG (EDI),
ARG_IMM (-1),
ARG_IMM (FRIDA_QNX_PULSE_CODE_HELLO),
ARG_REG (EAX));
EMIT_LOAD_FIELD (ESI, module_handle);
gum_x86_writer_put_test_reg_reg (&cw, GUM_X86_ESI, GUM_X86_ESI);
gum_x86_writer_put_jcc_near_label (&cw, X86_INS_JNE, skip_dlopen, GUM_NO_HINT);
{
EMIT_CALL_IMM (frida_resolve_remote_libc_function (params->pid, "dlopen"),
2,
ARG_IMM (FRIDA_REMOTE_DATA_FIELD (so_path)),
ARG_IMM (RTLD_LAZY));
gum_x86_writer_put_mov_reg_reg (&cw, GUM_X86_ESI, GUM_X86_EAX);
EMIT_STORE_FIELD (module_handle, ESI);
}
gum_x86_writer_put_label (&cw, skip_dlopen);
EMIT_CALL_IMM (frida_resolve_remote_libc_function (params->pid, "dlsym"),
2,
ARG_REG (ESI),
ARG_IMM (FRIDA_REMOTE_DATA_FIELD (entrypoint_name)));
gum_x86_writer_put_mov_reg_reg (&cw, GUM_X86_EBX, GUM_X86_EAX);
gum_x86_writer_put_mov_reg_offset_ptr_u32 (&cw, GUM_X86_ESP, 0, FRIDA_UNLOAD_POLICY_IMMEDIATE);
gum_x86_writer_put_mov_reg_offset_ptr_reg (&cw, GUM_X86_ESP, 4, GUM_X86_EDI);
gum_x86_writer_put_mov_reg_reg (&cw, GUM_X86_EAX, GUM_X86_ESP);
gum_x86_writer_put_lea_reg_reg_offset (&cw, GUM_X86_EDX, GUM_X86_ESP, 4);
EMIT_CALL_REG (EBX,
3,
ARG_IMM (FRIDA_REMOTE_DATA_FIELD (entrypoint_data)),
ARG_REG (EAX),
ARG_REG (EDX));
gum_x86_writer_put_mov_reg_reg_ptr (&cw, GUM_X86_EAX, GUM_X86_ESP);
gum_x86_writer_put_cmp_reg_i32 (&cw, GUM_X86_EAX, FRIDA_UNLOAD_POLICY_IMMEDIATE);
gum_x86_writer_put_jcc_near_label (&cw, X86_INS_JNE, skip_dlclose, GUM_NO_HINT);
{
EMIT_CALL_IMM (frida_resolve_remote_libc_function (params->pid, "dlclose"),
1,
ARG_REG (ESI));
}
gum_x86_writer_put_label (&cw, skip_dlclose);
gum_x86_writer_put_mov_reg_reg_ptr (&cw, GUM_X86_EAX, GUM_X86_ESP);
gum_x86_writer_put_cmp_reg_i32 (&cw, GUM_X86_EAX, FRIDA_UNLOAD_POLICY_DEFERRED);
gum_x86_writer_put_jcc_near_label (&cw, X86_INS_JE, skip_detach, GUM_NO_HINT);
{
EMIT_LOAD_FIELD (EAX, worker_thread);
EMIT_CALL_IMM (frida_resolve_remote_libc_function (params->pid, "pthread_detach"),
1,
ARG_REG (EAX));
}
gum_x86_writer_put_label (&cw, skip_detach);
gum_x86_writer_put_mov_reg_reg_ptr (&cw, GUM_X86_EAX, GUM_X86_ESP);
EMIT_CALL_IMM (frida_resolve_remote_libc_function (params->pid, "MsgSendPulse_r"),
4,
ARG_REG (EDI),
ARG_IMM (-1),
ARG_IMM (FRIDA_QNX_PULSE_CODE_BYE),
ARG_REG (EAX));
EMIT_CALL_IMM (frida_resolve_remote_libc_function (params->pid, "ConnectDetach_r"),
1,
ARG_REG (EDI));
gum_x86_writer_put_add_reg_imm (&cw, GUM_X86_ESP, 4 + 8);
gum_x86_writer_put_pop_reg (&cw, GUM_X86_EDI);
gum_x86_writer_put_pop_reg (&cw, GUM_X86_ESI);
gum_x86_writer_put_pop_reg (&cw, GUM_X86_EBX);
gum_x86_writer_put_pop_reg (&cw, GUM_X86_EBP);
gum_x86_writer_put_xor_reg_reg (&cw, GUM_X86_EAX, GUM_X86_EAX);
gum_x86_writer_put_ret (&cw);
gum_x86_writer_flush (&cw);
code->cur = gum_x86_writer_cur (&cw);
code->size += gum_x86_writer_offset (&cw);
gum_x86_writer_clear (&cw);
}
#elif defined (HAVE_ARM)
#define EMIT_MOVE(dst, src) \
gum_arm_writer_put_mov_reg_reg (&cw, ARM_REG_##dst, ARM_REG_##src)
#define EMIT_ADD(dst, src, offset) \
@@ -333,6 +479,7 @@ frida_emit_payload_code (const FridaInjectionParams * params, GumAddress remote_
const gchar * skip_detach = "skip_detach";
gum_arm_writer_init (&cw, code->cur);
cw.pc = remote_address;
gum_arm_writer_put_push_regs (&cw, 4, ARM_REG_R5, ARM_REG_R6, ARM_REG_R7, ARM_REG_LR);
@@ -427,6 +574,8 @@ frida_emit_payload_code (const FridaInjectionParams * params, GumAddress remote_
gum_arm_writer_clear (&cw);
}
#endif
static GumAddress
frida_remote_alloc (pid_t pid, size_t size, int prot, GError ** error)
{
@@ -649,6 +798,25 @@ frida_remote_call (pid_t pid, GumAddress func, const GumAddress * args, gint arg
memcpy (&modified_registers, &saved_registers, sizeof (saved_registers));
#if defined (HAVE_I386)
{
guint32 sp, frame[1 + 16];
gint n = 0;
g_assert (args_length <= 16);
frame[n++] = 0xfffffff0;
for (i = 0; i != args_length; i++)
frame[n++] = args[i];
sp = ((modified_registers.x86.esp - 128 - (args_length * 4)) & ~15) - 4;
if (!frida_remote_write_fd (fd, sp, frame, n * 4, error))
goto beach;
modified_registers.x86.esp = sp;
modified_registers.x86.eip = func;
}
#elif defined (HAVE_ARM)
/*
* Set the PC to be the function address and SP to the stack address.
*/
@@ -681,11 +849,12 @@ frida_remote_call (pid_t pid, GumAddress func, const GumAddress * args, gint arg
* Set the LR to be a dummy address which will trigger a pagefault.
*/
modified_registers.arm.gpr[GUM_QNX_ARM_REG_LR] = 0xfffffff0;
#endif
ret = devctl (fd, DCMD_PROC_SETGREG, &modified_registers, sizeof (modified_registers), 0);
CHECK_OS_RESULT (ret, ==, 0, "DCMD_PROC_SETGREG");
while (modified_registers.arm.gpr[GUM_QNX_ARM_REG_PC] != 0xfffffff0)
while (FRIDA_QNX_GREG_PC (&modified_registers) != 0xfffffff0)
{
/*
* Continue the process, watching for FLTPAGE which should trigger when
@@ -713,7 +882,7 @@ frida_remote_call (pid_t pid, GumAddress func, const GumAddress * args, gint arg
}
if (retval != NULL)
*retval = modified_registers.arm.gpr[GUM_QNX_ARM_REG_R0];
*retval = FRIDA_QNX_GREG_RETVAL (&modified_registers);
/*
* Restore the registers and continue the process:
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida/efni.git
revision = c493acfed5dc7e783d0424a03caaee7b51da3a62
revision = 3bcd99ff81b7b648ff4d784fb3154e55e7950c20
depth = 1
[provide]
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida/frida-gum.git
revision = 17.26.0
revision = c8f22bb1db7904adcc4ad046c0948ee9597a95fa
depth = 1
[provide]
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida-forks/glib.git
revision = f11db6352345ad21deb5f5783bb988bfca2a3d85
revision = c6df0665dab0f971f66c5c46055b7d0b6085d1b1
depth = 1
[provide]
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida/idun.git
revision = 98fdbaff11a0a2249c8c53eabfeb8f4e54908d0e
revision = 6040e17b1ef871ff7ae5b18fffbe5f0396a0810c
depth = 1
[provide]
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida-forks/lwip.git
revision = 6ab74462bd4a5afb13394942ab031d7bee005b4c
revision = 857ac9ef0de0e47c8b8f7a0b66f09673238368d0
depth = 1
[provide]