Android Inline hook跳转部分代码

转自看雪帖子: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 

你可能感兴趣的:(Android Inline hook跳转部分代码)