void ptrace_attach(int pid) { regs_t regs; int status = 0; if (ptrace(PTRACE_ATTACH, pid, NULL, NULL ) < 0) { perror("ptrace_attach"); exit(-1); } status = ptrace_wait_for_signal(pid, SIGSTOP); LOGD("ptrace_wait_for_signal: %d %d\n", __LINE__, status); //waitpid(pid, NULL, WUNTRACED); ptrace_readreg(pid, ®s); memcpy(&oldregs, ®s, sizeof(regs)); ptrace_dump_regs(&oldregs, "old regs"); #ifdef ANDROID #ifdef THUMB regs.ARM_pc = 0x11; regs.ARM_cpsr |=0x30; #else regs.ARM_pc= 0; #endif #else regs.rip = 0; #endif ptrace_writereg(pid, ®s); ptrace_cont(pid); LOGD("waiting.. sigal...\n"); status = ptrace_wait_for_signal(pid, SIGSEGV); LOGD("ptrace_wait_for_signal2: %d %d\n", __LINE__, status); }
int ptrace_mymath_add(pid_t pid, long mymath_add_addr, int a, int b) { #ifdef ANDROID regs_t regs; //int stat; ptrace_readreg(pid, ®s); ptrace_dump_regs(®s, "before call to ptrace_mymath_add\n"); #ifdef THUMB regs.ARM_lr = 1; #else regs.ARM_lr= 0; #endif regs.ARM_r0= a; regs.ARM_r1= b; regs.ARM_pc= mymath_add_addr; ptrace_writereg(pid, ®s); ptrace_cont(pid); ptrace_wait_for_signal(pid, SIGSEGV); ptrace_readreg(pid, ®s); ptrace_dump_regs(®s, "before return ptrace_mymath_add\n"); return regs.ARM_r0; #endif }
void *ptrace_dlsym(pid_t pid, void *handle, const char *symbol) { #ifdef ANDROID regs_t regs; //int stat; ptrace_readreg(pid, ®s); ptrace_dump_regs(®s, "before call to ptrace_dlsym\n"); #ifdef THUMB regs.ARM_lr = 1; #else regs.ARM_lr= 0; #endif regs.ARM_r0= (long)handle; regs.ARM_r1= (long)ptrace_push(pid,®s, (void*)symbol,strlen(symbol)+1); regs.ARM_pc= ldl.l_dlsym; ptrace_writereg(pid, ®s); ptrace_cont(pid); ptrace_wait_for_signal(pid, SIGSEGV); ptrace_readreg(pid, ®s); ptrace_dump_regs(®s, "before return ptrace_dlsym\n"); return (void*) regs.ARM_r0; #endif }
void *ptrace_dlopen(pid_t pid, const char *filename, int flag) { #ifdef ANDROID regs_t regs; //int stat; ptrace_readreg(pid, ®s); ptrace_dump_regs(®s, "before call to ptrace_dlopen\n"); #ifdef THUMB regs.ARM_lr = 1; #else regs.ARM_lr= 0; #endif regs.ARM_r0= (long)ptrace_push(pid,®s, (void*)filename,strlen(filename)+1); regs.ARM_r1= flag; regs.ARM_pc= ldl.l_dlopen; ptrace_writereg(pid, ®s); ptrace_cont(pid); ptrace_wait_for_signal(pid, SIGSEGV); ptrace_readreg(pid, ®s); ptrace_dump_regs(®s, "before return ptrace_call\n"); return (void*) regs.ARM_r0; #endif }
void call_shit(struct elf_info *einfo) { unsigned long addr2 = 0; unsigned long rel_addr = find_sym_in_rel(einfo, "math_shit"); regs_t regs; ptrace_read(einfo->pid, rel_addr, &addr2, sizeof(long)); printf("math_shit rel addr\t %lx\n", rel_addr); printf("addr2 is \t %lx\n", addr2); ptrace_readreg(einfo->pid, ®s); ptrace_dump_regs(®s,"before call to call_shit\n"); #ifdef THUMB regs.ARM_lr = 1; #else regs.ARM_lr = 0; #endif regs.ARM_r0 = 5; regs.ARM_r1 = 6; regs.ARM_r2 = 7; regs.ARM_r3 = 8; { int a5 = 9; ptrace_push(einfo->pid, ®s, &a5, 4); ptrace_push(einfo->pid, ®s, &a5, 4); ptrace_push(einfo->pid, ®s, &a5, 4); ptrace_push(einfo->pid, ®s, &a5, 4); ptrace_push(einfo->pid, ®s, &a5, 4); ptrace_push(einfo->pid, ®s, &a5, 4); ptrace_push(einfo->pid, ®s, &a5, 4); ptrace_push(einfo->pid, ®s, &a5, 4); ptrace_push(einfo->pid, ®s, &a5, 4); a5 = 10; ptrace_push(einfo->pid, ®s, &a5, 4); } regs.ARM_pc = addr2; ptrace_writereg(einfo->pid, ®s); ptrace_cont(einfo->pid); printf("done %d\n", ptrace_wait_for_signal(einfo->pid,SIGSEGV)); ptrace_readreg(einfo->pid, ®s); ptrace_dump_regs(®s,"before return call_shit\n"); }
int ptrace_call(int pid, long proc, int argc, ptrace_arg *argv) { int i = 0; #define ARGS_MAX 64 regs_t regs; ptrace_readreg(pid, ®s); ptrace_dump_regs(®s, "before ptrace_call\n"); /*prepare stacks*/ for (i = 0; i < argc; i++) { ptrace_arg *arg = &argv[i]; if (arg->type == PAT_STR) { arg->_stackid = ptrace_push(pid, ®s, arg->s, strlen(arg->s) + 1); } else if (arg->type == PAT_MEM) { //LOGD("push data %p to stack[%d] :%d \n", arg->mem.addr, stackcnt, *((int*)arg->mem.addr)); arg->_stackid = ptrace_push(pid, ®s, arg->mem.addr, arg->mem.size); } } for (i = 0; (i < 4) && (i < argc); i++) { ptrace_arg *arg = &argv[i]; if (arg->type == PAT_INT) { regs.uregs[i] = arg->i; } else if (arg->type == PAT_STR) { regs.uregs[i] = arg->_stackid; } else if (arg->type == PAT_MEM) { regs.uregs[i] = arg->_stackid; } else { LOGD("unkonwn arg type\n"); } } for (i = argc - 1; i >= 4; i--) { ptrace_arg *arg = &argv[i]; if (arg->type == PAT_INT) { ptrace_push(pid, ®s, &arg->i, sizeof(int)); } else if (arg->type == PAT_STR) { ptrace_push(pid, ®s, &arg->_stackid, sizeof(unsigned long)); } else if (arg->type == PAT_MEM) { ptrace_push(pid, ®s, &arg->_stackid, sizeof(unsigned long)); } else { LOGD("unkonwn arg type\n"); } } #ifdef THUMB regs.ARM_lr = 1; #else regs.ARM_lr= 0; #endif regs.ARM_pc= proc; ptrace_writereg(pid, ®s); ptrace_cont(pid); ptrace_wait_for_signal(pid, SIGSEGV); ptrace_readreg(pid, ®s); ptrace_dump_regs(®s, "before return ptrace_call\n"); //sync memory for (i = 0; i < argc; i++) { ptrace_arg *arg = &argv[i]; if (arg->type == PAT_STR) { } else if (arg->type == PAT_MEM) { ptrace_read(pid, arg->_stackid, arg->mem.addr, arg->mem.size); } } return regs.ARM_r0; }