转自看雪帖子:http://bbs.pediy.com/showthread.php?p=1216957
求人不如求己阿,已经解决啦!现在放出被注入的SO源码(至于如何注入并查找目标函数,自己去看看古河大哥的libinject);
源码主要分为两块:
1.用于初始化trampoline和实现自己函数的libservice.cpp
2.用于实现trampoline的shellcode.s
/* libservice.cpp */
#include <sys/ptrace.h>
#include <asm/user.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 <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <pthread.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>
#include <android/log.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <elf.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/input.h>
#include "../common/Log.h"
#define LOG_TAG "Service"
typedef void (*fun_XXXX)(void);
extern uint32_t _hijack, _o_code_0, _o_code_1, _addr_o_code_2, _addr_hook_proc, _n_code_0, _n_code_1;
extern "C" void XXXX_stub() {
LOGI("[+] XXXX() is called");
}
/* 根据古河大哥的libject,init函数将会在inject的时候被调到,这里我们传入被hook函数的地址 */
extern "C" int init(void *arg) {
unsigned int original_XXXX_addr = (unsigned int)arg;
void* page_start = (void *)(((long)&_hijack / PAGE_SIZE) * PAGE_SIZE);
if(-1 == mprotect((void *)page_start, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC) {
LOGE("mprotect failed(%d)", errno );
return -1;
}
page_start = (void *)(((long)g_original_XXXX / PAGE_SIZE) * PAGE_SIZE);
if(-1 == mprotect((void *)page_start, PAGE_SIZE * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) {
LOGE("mprotect failed(%d)", errno );
return -1;
}
_o_code_0 = *((unsigned int*)g_original_XXXX); //从被hook函数处读取第一条原始指令
_o_code_1 = *((unsigned int*)g_original_XXXX + 1); //从被hook函数处读取第二条原始指令
_addr_o_code_2 = (unsigned int)((unsigned int*)g_original_XXXX + 2); //hook函数第三条指令地址
_addr_hook_proc = (unsigned int)XXXX_stub; //设置自己函数的地址
_n_code_1 = (unsigned int)&_hijack;
memcpy((void *)g_original_XXXX, (void *)&_n_code_0, 2 * sizeof(unsigned int)); //将新的两条指令写入到被hook函数的头两条指令处
return 0;
}
/* shellcode.s */
.global _hijack
.global _o_code_0
.global _o_code_1
.global _addr_o_code_2
.global _addr_hook_proc
.global _n_code_0
.global _n_code_1
.data
_hijack:
stmdb sp!, {r0-r11,lr} @将需要保护的寄存器(r0-r11,lr)压栈
ldr r3, _addr_hook_proc @将自己的函数地址装载到寄存器r3
blx r3 @调用自己的函数
ldmia sp!, {r0-r11, lr} @恢复寄存器(r0-r11,lr)
_o_code_0:
.word 0x11111111 @执行被hook函数的第一条原始指令(需要在程序中初始化)
_o_code_1:
.word 0x11111111 @执行被hook函数的第二条原始指令(需要在程序中初始化)
ldr pc, _addr_o_code_2 @跳转到被hook函数的第三条原始指令处继续执行
_addr_o_code_2:
.word 0x11111111 @用于保存被hook函数的第三条原始指令的地址(需要在程序中初始化)
_addr_hook_proc:
.word 0x11111111 @用于保存自己函数的地址(需要在程序中初始化)
_n_code_0:
ldr pc, _n_code_1 @该指令需要被写入被hook函数的第一条指令处,这条指令后就会立即跳转到_hijack处了
_n_code_1:
.word 0x11111111 @用于保存trampoline的起始地址,需要被写入被hook函数的第二条指令处(需要在程序中初始化)
.space 0x900, 0
.end
已知问题:
如果被HOOK函数的头两条指令存在相对寻址指令的话,就会有问题。
参考文献:
1.http://bbs.pediy.com/showthread.php?t=72728
2.http://bbs.routerclub.com/blog-681-7706.html
3.http://blog.dbgtech.net/blog/?p=51