实现Android arm64(aarch64)中的so注入(inject) ,并且兼容x86和arm。如果没有搞错,这是国内外第一份公开的arm64注入的针对性完整资料~~
代码基于 ariesjzj 的 《Android中的so注入(inject)和挂钩(hook) - For both x86 and arm 》,增加了对arm64的支持。(目前已经开始有64位安卓手机)
同样,代码由jni中以下三个文件构成。 inject.c
Android.mk
Application.mk
其中Android.mk一样,Application.mk中
APP_ABI := arm64-v8a
inject.c如下:
#include <stdio.h>
#include <stdlib.h>
#include <asm/user.h>
#include <asm/ptrace.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <elf.h>
#include <android/log.h>
#include <sys/uio.h>
#if defined(__i386__)
#define pt_regs user_regs_struct
#elif defined(__aarch64__)
#define pt_regs user_pt_regs
#define uregs regs
#define ARM_pc pc
#define ARM_sp sp
#define ARM_cpsr pstate
#define ARM_lr regs[30]
#define ARM_r0 regs[0]
#define PTRACE_GETREGS PTRACE_GETREGSET
#define PTRACE_SETREGS PTRACE_SETREGSET
#endif
#define ENABLE_DEBUG 1
#if ENABLE_DEBUG
#define LOG_TAG "INJECT"
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, fmt, ##args)
#define DEBUG_PRINT(format,args...) \
LOGD(format, ##args)
#else
#define DEBUG_PRINT(format,args...)
#endif
#define CPSR_T_MASK ( 1u << 5 )
#if defined(__aarch64__)
const char *libc_path = "/system/lib64/libc.so";
const char *linker_path = "/system/bin/linker64";
#else
const char *libc_path = "/system/lib/libc.so";
const char *linker_path = "/system/bin/linker";
#endif
int ptrace_readdata(pid_t pid, uint8_t *src, uint8_t *buf, size_t size)
{
long i, j, remain;
uint8_t *laddr;
size_t bytes_width = sizeof(long);
union u {
long val;
char chars[bytes_width];
} d;
j = size / bytes_width;
remain = size % bytes_width;
laddr = buf;
for (i = 0; i < j; i ++) {
d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);
memcpy(laddr, d.chars, bytes_width);
src += bytes_width;
laddr += bytes_width;
}
if (remain > 0) {
d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);
memcpy(laddr, d.chars, remain);
}
return 0;
}
int ptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data, size_t size)
{
long i, j, remain;
uint8_t *laddr;
size_t bytes_width = sizeof(long);
union u {
long val;
char chars[bytes_width];
} d;
j = size / bytes_width;
remain = size % bytes_width;
laddr = data;
for (i