android so 注入,Android中的so注入(inject)和挂钩(hook)

本文介绍了一种适用于Android x86和arm平台的SO注入与挂钩技术,通过ptrace函数实现了跨平台代码。主要内容包括:1) 分别针对arm和i386平台的函数调用实现;2) 使用mmap、dlopen、dlsym等函数进行远程过程调用;3) 示例展示了如何注入并替换系统进程中eglSwapBuffers函数。
摘要由CSDN通过智能技术生成

对于Android for arm上的so注入(inject)和挂钩(hook),网上已有牛人给出了代码-libinject(http://bbs.pediy.com/showthread.php?t=141355)。由于实现中的ptrace函数是依赖于平台的,所以不经改动只能用于arm平台。本文将之扩展了一下,使它能够通用于Android的x86和arm平台。Arm平台部分基本重用了libinject中的代码,其中因为汇编不好移植且容易出错,所以把shellcode.s用ptrace_call替换掉了,另外保留了mmap,用来传字符串参数,当然也可以通过栈来传,但栈里和其它东西混一起,一弄不好就会隔儿了,所以还是保险点好。最后注意设备要root。

首先创建目录及文件:

jni

inject.c

Android.mk

Application.mk

inject.c:

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#if defined(__i386__)

#define pt_regs         user_regs_struct

#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 <

constchar*libc_path ="/system/lib/libc.so";

constchar*linker_path ="/system/bin/linker";

intptrace_readdata(pid_t pid,  uint8_t *src, uint8_t *buf,size_tsize)

{

uint32_t i, j, remain;

uint8_t *laddr;

unionu {

longval;

charchars[sizeof(long)];

} d;

j = size / 4;

remain = size % 4;

laddr = buf;

for(i = 0; i 

d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);

memcpy(laddr, d.chars, 4);

src += 4;

laddr += 4;

}

if(remain > 0) {

d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);

memcpy(laddr, d.chars, remain);

}

return0;

}

intptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data,size_tsize)

{

uint32_t i, j, remain;

uint8_t *laddr;

unionu {

longval;

charchars[sizeof(long)];

} d;

j = size / 4;

remain = size % 4;

laddr = data;

for(i = 0; i 

memcpy(d.chars, laddr, 4);

ptrace(PTRACE_POKETEXT, pid, dest, d.val);

dest  += 4;

laddr += 4;

}

if(remain > 0) {

d.val = ptrace(PTRACE_PEEKTEXT, pid, dest, 0);

for(i = 0; i 

d.chars[i] = *laddr ++;

}

ptrace(PTRACE_POKETEXT, pid, dest, d.val);

}

return0;

}

#if defined(__arm__)

intptrace_call(pid_t pid, uint32_t addr,long*params, uint32_t num_params,structpt_regs* regs)

{

uint32_t i;

for(i = 0; i 

regs->uregs[i] = params[i];

}

//

// push remained params onto stack

//

if(i 

regs->ARM_sp -= (num_params - i) * sizeof(long) ;

ptrace_writedata(pid, (void*)regs->ARM_sp, (uint8_t *)&params[i], (num_params - i) *sizeof(long));

}

regs->ARM_pc = addr;

if(regs->ARM_pc & 1) {

/* thumb */

regs->ARM_pc &= (~1u);

regs->ARM_cpsr |= CPSR_T_MASK;

} else{

/* arm */

regs->ARM_cpsr &= ~CPSR_T_MASK;

}

regs->ARM_lr = 0;

if(ptrace_setregs(pid, regs) == -1

|| ptrace_continue(pid) == -1) {

printf("error\n");

return-1;

}

intstat = 0;

waitpid(pid, &stat, WUNTRACED);

while(stat != 0xb7f) {

if(ptrace_continue(pid) == -1) {

printf("error\n");

return-1;

}

waitpid(pid, &stat, WUNTRACED);

}

return0;

}

#elif defined(__i386__)

longptrace_call(pid_t pid, uint32_t addr,long*params, uint32_t num_params,structuser_regs_struct * regs)

{

regs->esp -= (num_params) * sizeof(long) ;

ptrace_writedata(pid, (void*)regs->esp, (uint8_t *)params, (num_params) *sizeof(long));

longtmp_addr = 0x00;

regs->esp -= sizeof(long);

ptrace_writedata(pid, regs->esp, (char*)&tmp_addr,sizeof(tmp_addr));

regs->eip = addr;

if(ptrace_setregs(pid, regs) == -1

|| ptrace_continue( pid) == -1) {

printf("error\n");

return-1;</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值