Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linux: Allocate stack for injector's remote calls #545

Merged
merged 1 commit into from
Oct 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions src/linux/frida-helper-backend.vala
Original file line number Diff line number Diff line change
Expand Up @@ -1017,8 +1017,9 @@ namespace Frida {
establish_connection (launch, spec, bres, agent_ctrl, fallback_address, cancellable);

uint64 loader_base = (uintptr) bres.context.allocation_base;

var call_builder = new RemoteCallBuilder (loader_base, saved_regs);
GPRegs regs = saved_regs;
regs.stack_pointer = bres.allocated_stack.stack_root;
var call_builder = new RemoteCallBuilder (loader_base, regs);
call_builder.add_argument (loader_base + loader_layout.ctx_offset);
RemoteCall loader_call = call_builder.build (this);
RemoteCallResult loader_result = yield loader_call.execute (cancellable);
Expand Down Expand Up @@ -1076,8 +1077,10 @@ namespace Frida {
unowned uint8[] bootstrapper_code = Frida.Data.HelperBackend.get_bootstrapper_bin_blob ().data;
size_t bootstrapper_size = round_size_to_page_size (bootstrapper_code.length);

size_t stack_size = 64 * 1024;

uint64 allocation_base = 0;
size_t allocation_size = size_t.max (bootstrapper_size, loader_size);
size_t allocation_size = size_t.max (bootstrapper_size, loader_size) + stack_size;

uint64 remote_mmap = 0;
uint64 remote_munmap = 0;
Expand Down Expand Up @@ -1117,10 +1120,12 @@ namespace Frida {
Memory.copy (&bootstrap_ctx, output_context, output_context.length);

allocation_base = (uintptr) bootstrap_ctx.allocation_base;

code_swap.revert ();
}

result.allocated_stack.stack_base = (void *) (allocation_base + allocation_size - stack_size);
result.allocated_stack.stack_size = stack_size;

try {
write_memory (allocation_base, bootstrapper_code);
maybe_fixup_helper_code (allocation_base, bootstrapper_code);
Expand All @@ -1129,7 +1134,9 @@ namespace Frida {

HelperBootstrapStatus status = SUCCESS;
do {
var call_builder = new RemoteCallBuilder (code_start, saved_regs);
GPRegs regs = saved_regs;
regs.stack_pointer = result.allocated_stack.stack_root;
var call_builder = new RemoteCallBuilder (code_start, regs);

unowned uint8[] fallback_ld_data = fallback_ld.data;
unowned uint8[] fallback_libc_data = fallback_libc.data;
Expand Down Expand Up @@ -1416,14 +1423,28 @@ namespace Frida {
}
}

private struct AllocatedStack {
public void * stack_base;
public size_t stack_size;

public uint64 stack_root {
get {
return (uint64) stack_base + (uint64) stack_size;
}
}
}


private class BootstrapResult {
public HelperBootstrapContext context;
public HelperLibcApi libc;
public AllocatedStack allocated_stack;

public BootstrapResult clone () {
var res = new BootstrapResult ();
res.context = context;
res.libc = libc;
res.allocated_stack = allocated_stack;
return res;
}
}
Expand Down
Loading