er1cw00 / ElfHook

ElfHooK, reference with boyliang's AllHookInOne project, fix bugs, support android 5/6/7 and aarch64

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

0x01 Brief About ElfHook

  ElfHook的代码参考boyliang的AllHookInOne

  • .dynmaic节中没有DT_HAST,使用DT_GNU_HASH的情况下.

  • 计算动态库加载的base_addr是错误的,应该使用bias_addr来计算出ehdr、phdr和shdr之外的所有地址。

  • 替换函数时,修改page的读写权限时,在SEAndroid上PROT_EXEC和PROT_WRITE同时设置可能会导致异常,

  • 在dlopen返回时,通过返回值获得动态库加载的base_addr

  • elfhook 支持 aarch64 (arm64-v8a),soinfo的处理暂不支持

  • android 6以下系统使用/proc/self/maps来检索进程内动态库,android 7以上使用soinfo_list

ref:

 AllHookInOne : [https://github.com/boyliang/AllHookInOne.git]

 AllHookInOne说明 : [http://bbs.pediy.com/showthread.php?p=1328038]

 bionic : [https://android.googlesource.com/platform/bionic]

0x02 How To Build

Export android ndk path

export -p PATH=$PATH:$ANDROID_NDK

Build

./build.sh arm // 构建arm32 target

./build.sh arm64 // 构建arm64 target

./build.sh both // 构建arm32和arm64 targets

0x03 How To Use

elf_file用于解析文件形式的elf文件, elf_module用于解析加载到内存中的elf文件, elf_hooker 封装linker中解析出来的私有方法和对象,例如dlopen_ext、soinfo_list等

3.1 elf_hooker接口

  • bool elf_hooker::load()

elf_hooker初始化,解析出linker中在hook过程中需要使用到的变量和方法的地址。

  • void elf_hooker::dump_module_list()

打印在android 6以下版本,使用/proc/self/maps中解析出来当前已经加载的所有动态库的名字和基地址

  • void elf_hooker::dump_soinfo_list()

打印在android 7以上版本,soinfo_list链表中所有soinfo对象的动态库文件路径和内存中的基地址

  • void elf_hooker::set_prehook_cb( prehook_cb ):

设置回调函数,用于检查该动态库是否hook

bool prehook_cb(const char* module_name);

参数:

module_name: 动态库路径

返回值:

true: 可以hook

false: 不需要hook

  • void elf_hooker::hook_all_modules(struct elf_rebinds * rebinds)

劫持elf_hooker中解析出来当前已加载所有动态库

struct elf_rebinds {
    const char * func_name;
    void * pfn_new;
    void ** ppfn_old;
};

 func_name: 要劫持的函数名.

 pfn_new: 新函数地址

 ppfn_old: 返回的劫持前原函数地址, ppfn_old非空

3.2 elf_module接口

  • elf_module::elf_module(ElfW(Addr) base_addr, const char* module_name)

elf_module构造函数,传入elf内存基地址和文件路径作为参数,如果使用无参数的默认构造函数,则在调用get_segment_view前需要调用set_base_addr()和 set_module_name()设置基地址和路径。

  • bool elf_module::get_segment_view()

解析elf格式

  • bool elf_module:hook(const char * symbol, void * replace_func, void ** old_func);

劫持当前模块中的symbol函数,

  symbol: 要劫持的函数名.

  replace_func: 新函数地址

  old_func: 返回的劫持前原函数地址, old_func非空

About

ElfHooK, reference with boyliang's AllHookInOne project, fix bugs, support android 5/6/7 and aarch64


Languages

Language:C++ 89.2%Language:C 8.0%Language:CMake 1.4%Language:Shell 1.3%