Skip to content

Instantly share code, notes, and snippets.

@s1341
Created April 28, 2015 14:10
Show Gist options
  • Save s1341/8df970eec5450b5e36bf to your computer and use it in GitHub Desktop.
Save s1341/8df970eec5450b5e36bf to your computer and use it in GitHub Desktop.
call_in_process
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/debug.h>
#include <sys/procfs.h>
#include <unistd.h>
int call_in_process(int pid, int function, ...);
int main (int argc, char ** argv)
{
call_in_process (atoi (argv[1]), 0x08048cb4);
return 0;
}
int call_in_process(int pid, int function, ...)
{
va_list args;
int fd, result;
char as_path[256];
pthread_t tid;
debug_thread_t thread;
int res;
procfs_greg saved_registers, modified_registers;
procfs_status status;
procfs_run run;
int old_pc, old_lr;
procfs_break brk;
sigset_t * run_fault = (sigset_t *) &run.fault;
sprintf(as_path, "/proc/%d/as", pid);
fd = open (as_path, O_RDWR);
/*
* Find the first active thread:
*/
for (tid = 1;; tid++)
{
thread.tid = tid;
if (devctl (fd, DCMD_PROC_TIDSTATUS, &thread, sizeof (thread), 0) == EOK)
break;
}
/*
* Set current thread and freeze our target thread:
*/
res = devctl (fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0);
res = devctl (fd, DCMD_PROC_STOP, &status, sizeof (status), 0);
printf ("res stop: %d\n", res);
sleep (3);
/*
* Get the thread's registers:
*/
res = devctl (fd, DCMD_PROC_GETGREG, &saved_registers, sizeof (saved_registers), 0);
memcpy(&modified_registers, &saved_registers, sizeof (saved_registers));
/*
* Set the PC to be the function address, and the LR to be a dummy address
* which will trigger a pagefault.
*/
modified_registers.arm.gpr[ARM_REG_PC] = function;
modified_registers.arm.gpr[ARM_REG_LR] = 0xffffffff;
res = devctl (fd, DCMD_PROC_SETGREG, &modified_registers, sizeof (modified_registers), 0);
/*
* Continue the process, watching for FLTPAGE which should trigger when
* the dummy LR value (0xffffffff) is reached.
*/
memset(&run, 0, sizeof (run));
sigemptyset (run_fault);
sigaddset (run_fault, FLTPAGE);
run.flags |= _DEBUG_RUN_ARM | _DEBUG_RUN_FAULT ;
res = devctl (fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
printf ("res run: %d\n", res);
/*
* Wait for the process to stop at the pagefault.
*/
res = devctl (fd, DCMD_PROC_WAITSTOP, &status, sizeof (status), 0);
printf ("res waitstop: %d, why: %08x\n", res, status.why);
/*
* Restore the registers and continue the process:
*/
res = devctl (fd, DCMD_PROC_SETGREG, &saved_registers, sizeof (saved_registers), 0);
memset(&run, 0, sizeof (run));
run.flags |= _DEBUG_RUN_CLRFLT;
res = devctl (fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
printf ("res run: %d\n", res);
close (fd);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment