概述

对于android的so文件的hook根据ELF文件特性分为:Got表hook、Sym表hook和inline hook等。
全局符号表(GOT表)hook,它是通过解析SO文件,将待hook函数在got表的地址替换为自己函数的入口地址,这样目标进程每次调用待hook函数时,实际上是执行了我们自己的函数。

Androd so注入和函数Hook(基于got表)的步骤:

1.ptrace附加目标pid进程;
2.在目标pid进程中,查找内存空间(用于存放被注入的so文件的路径和so中被调用的函数的名称或者shellcode);
3.调用目标pid进程中的dlopen、dlsym等函数,用于加载so文件实现Android so的注入和函数的Hook;
4.释放附加的目标pid进程和卸载注入的so文件。

具体代码实现

以下以fopen函数进行got hook为例。

//获取模块地址功能实现
void* getModuleBase(pid_t pid, const char* module_name){FILE* fp;long address = 0;char* pch;char filename[32];char line[1024];// 格式化字符串得到 "/proc/pid/maps"if(pid < 0){snprintf(filename, sizeof(filename), "/proc/self/maps");}else{snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);}// 打开文件/proc/pid/maps,获取指定pid进程加载的内存模块信息fp = fopen(filename, "r");if(fp != NULL){// 每次一行,读取文件 /proc/pid/maps中内容while(fgets(line, sizeof(line), fp)){// 查找指定的so模块if(strstr(line, module_name)){// 分割字符串pch = strtok(line, "-");// 字符串转长整形address = strtoul(pch, NULL, 16);}break;}}}fclose(fp);return (void*)address;
}

//hook fopen进行实现
//(libxxxx.so文件是ELF32文件)
#define LIBPATH "/data/app-lib/com.xxxx/libxxxx.so"int hookFopen(){// 获取目标pid中"/data/app-lib/com.xxxx/libxxxx.so"模块的加载地址void* base_addr = getModuleBase(getpid(), LIBPATH );// 保存Hook目标函数的原始调用地址old_fopen = fopen;int fd;// 用open打开内存模块文件"/data/app-lib/com.xxxx/libxxxx.so"fd = open(LIB_PATH, O_RDONLY);if(-1 == fd){return -1;}// elf32文件的文件头结构体Elf32_EhdrElf32_Ehdr ehdr;// 读取elf32格式的文件"/data/app-lib/com.xxxx/libxxxx.so"的文件头信息read(fd, &ehdr, sizeof(Elf32_Ehdr));// elf32文件中节区表信息结构的文件偏移unsigned long shdr_addr = ehdr.e_shoff;// elf32文件中节区表信息结构的数量int shnum = ehdr.e_shnum;// elf32文件中每个节区表信息结构中的单个信息结构的大小(描述每个节区的信息的结构体的大小)int shent_size = ehdr.e_shentsize;// elf32文件节区表中每个节区的名称存放的节区名称字符串表,在节区表中的序号indexunsigned long stridx = ehdr.e_shstrndx;Elf32_Shdr shdr;lseek(fd, shdr_addr + stridx * shent_size, SEEK_SET);// 读取elf32文件中的描述每个节区的信息的结构体(这里是保存elf32文件的每个节区的名称字符串的)read(fd, &shdr, shent_size);// 为保存elf32文件的所有的节区的名称字符串申请内存空间char * string_table = (char *)malloc(shdr.sh_size);// 定位到具体存放elf32文件的所有的节区的名称字符串的文件偏移处lseek(fd, shdr.sh_offset, SEEK_SET);read(fd, string_table, shdr.sh_size);lseek(fd, shdr_addr, SEEK_SET);int i;uint32_t out_addr = 0;uint32_t out_size = 0;uint32_t got_item = 0;int32_t got_found = 0;// 循环遍历elf32文件的节区表(描述每个节区的信息的结构体)for(i = 0; i<shnum; i++){// 依次读取节区表中每个描述节区的信息的结构体read(fd, &shdr, shent_size);// 判断当前节区描述结构体描述的节区是否是SHT_PROGBITS类型//类型为SHT_PROGBITS的.got节区包含全局偏移表if(shdr.sh_type == SHT_PROGBITS){// 获取节区的名称字符串在保存所有节区的名称字符串段.shstrtab中的序号int name_idx = shdr.sh_name;// 判断节区的名称是否为".got.plt"或者".got"if(strcmp(&(string_table[name_idx]), ".got.plt") == 0|| strcmp(&(string_table[name_idx]), ".got") == 0){// 获取节区".got"或者".got.plt"在内存中实际数据存放地址out_addr = base_addr + shdr.sh_addr;// 获取节区".got"或者".got.plt"的大小out_size = shdr.sh_size;int j = 0;// 遍历节区".got"或者".got.plt"获取保存的全局的函数调用地址for(j = 0; j<out_size; j += 4){// 获取节区".got"或者".got.plt"中的单个函数的调用地址got_item = *(uint32_t*)(out_addr + j);// 判断节区".got"或者".got.plt"中函数调用地址是否是将要被Hook的目标函数地址if(got_item == old_fopen){got_found = 1;// 获取当前内存分页的大小uint32_t page_size = getpagesize();// 获取内存分页的起始地址(需要内存对齐)uint32_t entry_page_start = (out_addr + j) & (~(page_size - 1));// 修改内存属性为可读可写可执行if(mprotect((uint32_t*)entry_page_start, page_size, PROT_READ | PROT_WRITE | PROT_EXEC) == -1){return -1;}// Hook的函数,是我们自己定义的函数got_item = new_fopen;// 进行恢复内存属性为可读可执行if(mprotect((uint32_t*)entry_page_start, page_size, PROT_READ | PROT_EXEC) == -1){return -1;}break;// 目标函数的调用地址已经被Hook了}else if(got_item == new_fopen){break;}}// 对目标函数HOOk成功,跳出循环if(got_found)break;}}}free(string_table);close(fd);
}

android的got表HOOK实现相关推荐

  1. Android so导入表,Android so注入(inject)和Hook技术学习(二)——Got表hook之导入表hook...

    全局符号表(GOT表)hook实际是通过解析SO文件,将待hook函数在got表的地址替换为自己函数的入口地址,这样目标进程每次调用待hook函数时,实际上是执行了我们自己的函数. GOT表其实包含了 ...

  2. 【Android 插件化】Hook 插件化框架总结 ( 插件包管理 | Hook Activity 启动流程 | Hook 插件包资源加载 ) ★★★

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  3. 【Android 插件化】Hook 插件化框架 ( 使用 Hook 方式替换插件 Activity 的 mResources 成员变量 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  4. 【Android 插件化】Hook 插件化框架 ( 从源码角度分析加载资源流程 | Hook 点选择 | 资源冲突解决方案 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  5. 【Android 插件化】Hook 插件化框架 ( 加载插件包资源 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  6. 【Android 插件化】Hook 插件化框架 ( 反射工具类 | 反射常用操作整理 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  7. 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  8. 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | AMS 启动前使用动态代理替换掉插件 Activity 类 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  9. 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 反射获取 IActivityManager 对象 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  10. 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

最新文章

  1. ISA Server***检测及配置
  2. ClassPool CtClass浅析
  3. 使用Magicodes.SwaggerUI快速配置SwaggerUI以及设置API分组
  4. 二分查找(一次查找多个相同的值)
  5. JDK 9中不推荐使用Java的Observer和Observable
  6. Windows Live Messenger 2011,离线安装、多开、去广告……
  7. 小熊派折叠开发板Docker编译烧录安装HAP
  8. 第二节:使用反射构建动态可扩展应用程序
  9. liunux中的 【ifconfig】 命令 查看系统IP。
  10. 汇桔网与分众传媒正式达成全面深度战略资本合作
  11. wepy集成colorui 样式框架
  12. de4dot命令 v2.0.3.3405 破解命令
  13. matlab 求obb,obb包围盒代码
  14. 计算机一级考试试题在线操作,计算机一级考试题库操作题
  15. 以程序员的方式解决武汉公积金用户注册页面无法点击下一步问题
  16. thrift文件服务器,Thrift功能和使用
  17. 【概率论与数理统计】1.4 条件概率
  18. 电商打折套路分析 —— Python数据分析练习
  19. 解读《Superhuman AI for multiplayer poker》
  20. 一代版本一代神,加密行业在新局势下充满机遇也面临挑战

热门文章

  1. 《基因突变》学习笔记
  2. 阿里云服务器安全组授权对象ip设置
  3. linux多个网卡丢包,linux系统双网卡绑定及丢包问题
  4. IPwe区块链智能池利用AI来处理专利分析
  5. 达梦数据库(DM8)初次使用及DCA考试体会
  6. latex添加代码注释_在代码中添加注释:好的,坏的和丑陋的。
  7. 关于破解邮箱的一点心得
  8. Excel大家来找茬,两列数据对比找出不同数据
  9. 打印当前html页面 有背景,word打印时页面背景颜色怎么去掉
  10. mysql的number范围_数据库number类型精度实用分析