ARM下的injectso
2013-03-19 14:56
811 查看
https://bitbucket.org/tewilove/injectso/src/41afcf79b9c4/injectso.c
#include <errno.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <dlfcn.h> #include <unistd.h> #include <sys/types.h> #include <sys/ptrace.h> #if !defined(__ANDROID__) || (!defined(__arm__) && !defined(__thumb__)) #error "ARM Android only!" #endif static void die(int ln) { char temp[256]; snprintf(temp, sizeof(temp), "failed at %d: %s\n", ln, strerror(errno)); fprintf(stderr, temp); exit(-1); } static void usage(FILE *fp, const char *self) { fprintf(fp, "Usage:\n"); fprintf(fp, "%s <pid> <so>\n", self); } static void* get_module_base_addr(pid_t pid, const char* name) { FILE *fp; char path[32]; long addr = -1; char buffer[1024]; char *temp; if (pid == -1) snprintf(path, sizeof(path), "/proc/self/maps"); else snprintf(path, sizeof(path), "/proc/%d/maps", pid); fp = fopen(path, "r"); if (!fp) return (void *)(-1); while (fgets(buffer, sizeof(buffer), fp)) { if (strstr(buffer, name)) { temp = strtok(buffer, "-"); addr = strtoul(temp, NULL, 16); if(addr == 0x8000) { addr = 0; } break; } } fclose(fp); return (void*) addr; } static void *find_my_dlopen() { void *handle = dlopen("libdl.so", RTLD_NOW); if (!handle) die(__LINE__); void *symbol = dlsym(handle, "dlopen"); if (!symbol) die(__LINE__); return symbol; } static int find_symbol_offset(pid_t pid, const char *ref) { void *mine = get_module_base_addr(-1, ref); if (!mine) return -1; void *theirs = get_module_base_addr(pid, ref); if (!theirs) return -1; return (int)(mine) - (int)(theirs); } static void *find_foreign_dlopen(pid_t pid, void *my_dlopen) { int offset = find_symbol_offset(pid, "/system/bin/linker"); if (offset == -1) offset = find_symbol_offset(pid, "/system/lib/libc.so"); if (offset == -1) die(__LINE__); int result = (int) my_dlopen + offset; return (void *) result; } // memcpy like static void ptrace_peek(pid_t pid, void* dest, const void* src, size_t n) { int i; long *d = (long *) dest, *s = (long *) src; n /= sizeof(long); for (i = 0; i < n; i++) { d[i] = ptrace(PTRACE_PEEKTEXT, pid, s + i, NULL); if (errno) die(__LINE__); } } static void ptrace_poke(pid_t pid, void* dest, const void* src, size_t n) { int i; long *d = (long *) dest, *s = (long *) src; for (i = 0; i < n / sizeof(long); i++) { if (ptrace(PTRACE_POKETEXT, pid, d + i, (void *) s[i]) == -1) { die(__LINE__); } } } static int injectso(pid_t pid, const char *so) { void *p_dlopen = NULL; void *my_dlopen, *foreign_dlopen; int err, status, len; char old_stack[512], new_stack[512]; struct pt_regs old_regs, new_regs; my_dlopen = find_my_dlopen(); printf("my dlopen = %p\n", my_dlopen); foreign_dlopen = find_foreign_dlopen(pid, my_dlopen); printf("foreign dlopen = %p\n", foreign_dlopen); printf("attaching...\n"); err = ptrace(PTRACE_ATTACH, pid, NULL, NULL); if (err < 0) die(__LINE__); if (waitpid(pid, &status, 0) < 0) die(__LINE__); printf("getting regs...\n"); err = ptrace(PTRACE_GETREGS, pid, NULL, &old_regs); if (err < 0) die(__LINE__); printf("pc=%08x, sp=%08x, lr=%08x, cpsr=%08x\n", old_regs.ARM_pc, old_regs.ARM_sp, old_regs.ARM_lr, old_regs.ARM_cpsr); printf("reading foreign stack...\n"); ptrace_peek(pid, old_stack, (void *) old_regs.ARM_sp, sizeof(old_stack)); len = strlen(so); memset(new_stack, 0, sizeof(new_stack)); memcpy(new_stack, so, len); memcpy(&new_regs, &old_regs, sizeof(struct pt_regs)); printf("writing foreign stack...\n"); ptrace_poke(pid, (void *) old_regs.ARM_sp, new_stack, sizeof(new_stack)); // = psz_path new_regs.ARM_r0 = old_regs.ARM_sp; new_regs.ARM_r1 = RTLD_NOW; new_regs.ARM_sp += sizeof(new_stack); // trigger a SIGE*** after cont new_regs.ARM_lr = 0; new_regs.ARM_pc = (long) foreign_dlopen; if (new_regs.ARM_pc & 1) new_regs.ARM_cpsr |= PSR_T_BIT; else new_regs.ARM_cpsr &= ~PSR_T_BIT; printf("setting regs...\n"); err = ptrace(PTRACE_SETREGS, pid, NULL, &new_regs); if (err < 0) die(__LINE__); printf("resuming...\n"); err = ptrace(PTRACE_CONT, pid, NULL, NULL); if (err < 0) die(__LINE__); if (waitpid(pid, &status, 0) < 0) die(__LINE__); printf("restoring foreign stack...\n"); ptrace_poke(pid, (void *) old_regs.ARM_sp, old_stack, sizeof(old_stack)); printf("restoring old regs...\n"); err = ptrace(PTRACE_SETREGS, pid, NULL, &old_regs); if (err < 0) die(__LINE__); err = ptrace(PTRACE_DETACH, pid, NULL, NULL); if (err < 0) die(__LINE__); return 0; } int main(int argc, char *argv[]) { if (argc != 3) { usage(stderr, argv[0]); exit(-1); } pid_t pid = strtoul(argv[1], NULL, 10); return injectso(pid, argv[2]); } |
相关文章推荐
- ARM的三种中断调试方法介绍
- Make ARM cross compiler tool chain using crosstool-ng
- [ARM学习]ARM指令集详解(超…
- 【iCore1S 双核心板_FPGA】例程十二:基于单口RAM的ARM+FPGA数据存取实验
- arm成功移植sqlite经验
- nfs:server 172.168.1.22 not responding,still trying问题解决方法 平台为RealARM 210平台
- R0-R37它是Arm 寄存器,那是,CPU内部。和GPIO注册所有外设。换句话说,要是arm的cpu,它包含了其他芯片公司将有R0-R37,和GPIO寄存器只有一个特定的芯片。
- 移植 Nginx+PHP(FastCGI) 到 ARM Linux (二)
- ARM VIC控制器 --- 6410
- ARM交叉编译boost 1.54.0
- ARM 汇编指令集
- <arm开发版>arm开发板触摸屏坐标的获取
- 双核处理器ARM+DSP如何实现协同工作
- ARM上裸奔的跑马灯程序
- eclipse 远程图形化调试嵌入式linux c arm(beaglebone black),解决常见调试问题
- Azure Powershell使用已有特殊化非托管磁盘创建ARM虚拟机
- Emacs+GDB远程调试ARM-LINUX程序
- 在QEMU上用Busybox模拟ARM的文件系统
- ARM架构解析
- 三星S5P6818ARM工控主板,ARM Cortex-A53架构