Created
April 28, 2015 14:10
-
-
Save s1341/8df970eec5450b5e36bf to your computer and use it in GitHub Desktop.
call_in_process
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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