GOT Hook的简单实现与原理
简述
有什么用?
通过hook全局符号表实现各种黑科技功能,比如我们可以hook open,write和read监控文件的IO读写,hook malloc,calloc,realloc 和 free统计分配了多少内存,内存是否被泄露,也可以对其他进程进行hook实现各种 黑科技功能(root),这种hook方式比较简单,只需更改表中符号地址即可,但只能hook导入函数。
ELF
ELF是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。
具体实现
1. 获取模块基址
Elf加载的地址是随机的我们只有在elf加载后才能获取到他的基址,下面有两种方式获取
通用:
我们可以读取 /proc/self/maps,对其进行解析,下面是maps文件的格式
address perms offset dev inode pathname00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon00651000-00652000 r--p 00051000 08:02 173521 /usr/bin/dbus-daemon00652000-00655000 rw-p 00052000 08:02 173521 /usr/bin/dbus-daemon00e03000-00e24000 rw-p 00000000 00:00 0 [heap]00e24000-011f7000 rw-p 00000000 00:00 0 [heap]...
Android 5.0 +:
通过翻阅 Linux 资料我们找到了 dl_iterate_phdr 函数
static int callback(struct dl_phdr_info *info, size_t size, void *data)
{..auto *pInfo = new struct dl_phdr_info(*info);if (strstr(pInfo->dlpi_name, "模块名")) {// pInfo->dlpi_addr便是我们的基地址..}
}extern "C" JNIEXPORT jstring JNICALL
Java_com_example1_gothook_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */) {...dl_iterate_phdr(&callback, nullptr);...
}
2. 获取Program_header_table
// dl_iterate_phdr
Elf32_Phdr *phdr = &(pInfo->dlpi_phdr[i]);//通用,读取Elf_Ehdrtypedef struct{unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; //文件的类型Elf32_Half e_machine; //体系结构Elf32_Word e_version; //文件的版本Elf32_Addr e_entry; //入口地址Elf32_Off e_phoff; //Program header tableElf32_Off e_shoff; //Section header tableElf32_Word e_flags;Elf32_Half e_ehsize;Elf32_Half e_phentsize;Elf32_Half e_phnum;Elf32_Half e_shentsize;Elf32_Half e_shnum;Elf32_Half e_shstrndx;
} Elf32_Ehdr;Elf_Ehdr *ehdr = (Elf_Ehdr *) base;
Elf32_Phdr *phdr = (Elf32_Phdr *)ehdr->e_phoff + base
3.获取DT_STRTAB,DT_JMPREL,DT_SYMTAB
我们对Program_header_table进行遍历获取 PT_DYNAMIC
通过 p_vaddr 获取Elf_Dyn
JMPREL
ELFStringTable
ELFSymolTable
for (int i = 0; i < pInfo->dlpi_phnum; ++i) {__u8 *str_table = nullptr;Elf_Rela *jmprel = nullptr;Elf_Sym *sym_table = nullptr;if (phdr->p_type == PT_DYNAMIC) {auto *dyn = (Elf_Dyn *) (phdr->p_vaddr + pInfo->dlpi_addr);int i1 = 1;while (dyn->d_tag) {if (dyn->d_tag == DT_STRTAB) { //是否DT_STRTABstr_table = (__u8 *) (dyn->d_un.d_ptr + pInfo->dlpi_addr);}if (dyn->d_tag == DT_JMPREL) { //是否DT_JMPRELjmprel = (Elf_Rela *) (dyn->d_un.d_ptr + pInfo->dlpi_addr);}if (dyn->d_tag == DT_SYMTAB) { //是否DT_SYMTABsym_table = (Elf_Sym *) (dyn->d_un.d_ptr + pInfo->dlpi_addr);}dyn = reinterpret_cast<Elf_Dyn *>(phdr->p_vaddr + pInfo->dlpi_addr +sizeof(Elf_Dyn) * i1++);}...}
}
4.进行Hook
查看strstr函数原型我们自己实现了一个用来替换的函数,每次调用strstr都会到我们自己的函数这里打印日志
Hook代码
if (jmprel && str_table && sym_table) {for (int j = 0; jmprel->r_info; ++j) { //遍历jmprelElfW(Word) sym = ELFW(R_SYM)(jmprel[j].r_info); //取符号下标char *name = (char *) (sym_table[sym].st_name + str_table); //从sym_table获取st_name在str_table的偏移if (strstr(name, "strstr")) { //需要hook的函数void *i2 = (void *) (jmprel[j].r_offset + pInfo->dlpi_addr); ElfW(Addr) page_start = PAGE_START(jmprel[j].r_offset + pInfo->dlpi_addr);mprotect((ElfW(Addr) *) page_start, PAGE_SIZE, PROT_WRITE | PROT_READ);//使用mprotect解除内存访问权限 https://man7.org/linux/man-pages/man2/mprotect.2.html*((ElfW(Addr) *) i2) = (ElfW(Addr)) myStrstr + jmprel[i].r_addend;//修改got表地址mprotect((ElfW(Addr) *) page_start, PAGE_SIZE, PROT_READ);//还原内存访问权限break;}}
宏定义如下
#define PAGE_SIZE 4096
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
#if defined(__LP64__)
#define ELFW(what) ELF64_ ## what#define Elf_Dyn Elf64_Dyn
#define Elf_Sym Elf64_Sym
#define Elf_Rela Elf64_Rela
#else
#define ELFW(what) ELF32_ ## what
#define Elf_Dyn Elf32_Dyn
#define Elf_Sym Elf32_Sym
#define Elf_Rela Elf32_Rela#endif#define ELF32_R_SYM(x) ((x) >> 8)
#define ELF32_R_TYPE(x) ((x) & 0xff)
#define ELF64_R_SYM(i) ((i) >> 32)
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
5.大功告成
我们每次调用strstr都会打印出两个的参数
extern "C" JNIEXPORT jstring JNICALL
Java_com_example1_gothook_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */) {dl_iterate_phdr(&callback, nullptr);strstr("test1", "test2"); //调用strstrreturn env->NewStringUTF(hello.c_str());
}hook_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */) {dl_iterate_phdr(&callback, nullptr);strstr("test1", "test2"); //调用strstrreturn env->NewStringUTF(hello.c_str());
}
代码下载:https://github.com/Mrack/GotHook
关注我的技术公众号
不定期分析各种技术文章
GOT Hook的简单实现与原理相关推荐
- JS函数简单的底层原理 -变量重复声明无效,隐式申明,变量提升,函数提升,以及堆栈内存的变化
JS函数简单的底层原理 (个人理解): 1. 已经使用var申明且赋值,若再次申明,则第二次申明(不赋值)无效. 2.在同一个作用域下,只要是发生了同名,且变量完成赋值,后者会覆盖前者.存在两个相同的 ...
- [EDA] 2.2 简单PLD结构原理-潘松版
2.2 简单PLD结构原理 知识点: 2.1 PLD概述 名称概念: PLD:Programmable Logic Device,可编程器件 PLD的分类:1.按集成度分,可分为简单PLD和复杂PLD ...
- pureMVC简单示例及其原理讲解四(Controller层)
本节将讲述pureMVC示例中的Controller层. Controller层有以下文件组成: AddUserCommand.as DeleteUserCommand.as ModelPrepCom ...
- Unity优化——简单AOI实现原理
声明:本文为个人笔记,用于学习研究使用非商用,内容为个人研究及综合整理所得,若有违规,请联系,违规必改. Unity网络--简单AOI实现原理 文章目录 Unity网络--简单AOI实现原理 一.开发 ...
- android hook技术教学视频,[科普向]hook技术简单介绍
首先 1. 这只是科普向,会介绍相关Hook技术及原理,但是不会给源码.源码请自行百度 2.请至少有一点Windows编程经验,知道系统API是什么...以免看科普内容给您带来不适 3.这里结合了一 ...
- API HOOK 金山词霸取词功能原理
本文由本人整理 1 屏幕抓词 屏幕抓词(或者叫动态翻译)是指随着鼠标的移动,软件能够随时获知屏幕上鼠标位置的单词或汉字,并翻译出来提示用户.它对於上网浏览.在线阅读外文文章等很有帮助作用,因此 ...
- promise是什么?简单分析promise原理
预备知识 回调函数 高级函数 发布-订阅模式 promise A+ 规范 promise是什么,能干什么 Promise是异步编程的一种解决方案,它可以解决异步回调地狱的问题,防止层层嵌套对程序代码带 ...
- 线程的3种实现方式并深入源码简单分析实现原理
前言 本文介绍下线程的3种实现方式并深入源码简单的阐述下原理 三种实现方式 Thread Runnable Callable&Future 深入源码简单刨析 Thread Thread类实现了 ...
- html轮播图原理,30_用js实现一个轮播图效果,简单说下原理
一.原理 将一些图片在一行中平铺,然后计算偏移量再利用定时器实现定时轮播. 步骤一:建立html基本布局 如下所示: 轮播图 1 2 3 4 5 < > 只有五张图片,却使用7张来轮播,这 ...
最新文章
- 小朋友你是否有很多问号?疫情期间不打游戏却在背ABC,百度翻译日活同比增长40%...
- wxWidgets:滚动Scrolling
- ImageLoader设置圆形图片
- java两个字符串前缀_java – 找到两个字符串的最长公共前缀
- 传统的6d位姿估计fangfa1_李飞飞团队最新论文:基于anchor关键点的类别级物体6D位姿跟踪...
- flex gallery / 产品展示
- Macaca基础原理解析
- mysql 存储时间 时间戳_具体场景下MySQL中用“时间戳”存储时间的问题
- JavaScript:split() 方法和join() 方法
- 安装java虚拟机_JAVA虚拟机的安装以及JAVA的环境配置
- python|cookie和session介绍——以12306验证码破解
- 关于CUDA,cuDNN,TF,CUDA驱动版本兼容问题
- 抽签助手|抽签助手2.8绿色免费版下载
- mac系统添加VSCode到右键菜单
- dataframe动态命名(读取不同文件并规律命名)
- win10安装红警运行出现FATALString Manager failed to initilaized properly
- excel离散度图表怎么算_excel离散数据表格-Excel 离散程度分析图表如何做
- “background-image:url(data:image”data类型的Url格式简介
- 【电商网站】将商品加入购物车代码
- 2022起重机司机(限桥式起重机)理论题库及答案