PLT hook笔记
1. hook技术概述
hook技术是一种拦截用户函数调用的技术。通过hook技术可以实现统计用户对某些函数的调用次数,对函数注入新的功能的目标。在Linux平台,Hook技术可以分成用户和内核两个层面,每个类比中都存在不同的hook技术。本文主要介绍针对动态链接技术的PLT hook。
2. 代码实例

其次编写我们的main.c 该函数实现了将要替换strcmp函数的my_strcmp,和使hook生效的hook函数。代码的具体细节
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <inttypes.h>
#include <execinfo.h>
#include <sys/user.h>
#include <sys/mman.h>
#include "passwd.h" #define PAGE_SHIFT 12
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1)) #define __AC(X,Y) (X##Y)
#define _AC(X,Y) __AC(X,Y) #define PAGE_START(addr) ((addr) & PAGE_MASK)
#define PAGE_END(addr) (PAGE_START(addr) + PAGE_SIZE) int my_strcmp(const char *s1, const char *s2)
{
return ;
} uintptr_t get_base_addr(char *libname)
{
FILE *fp;
char line[];
//char base_addr[1024];
uintptr_t base_addr = ; if (NULL == (fp = fopen("/proc/self/maps", "r"))) {
perror("open err");
return -;
} while (NULL != fgets(line, sizeof(line), fp)) {
if (NULL != strstr(line, libname)) {
sscanf(line, "%"PRIxPTR"-%*lx %*4s 00000000", &base_addr);
printf("line2:%s, base_addr:%"PRIxPTR"\n", line, base_addr);
break;
}
}
fclose(fp); return base_addr;
} void hook() {
uintptr_t base_addr;
uintptr_t addr;
//1. get the base addr of libpasswd.so
base_addr = get_base_addr("libpasswd");
if ( == base_addr) return;
addr = base_addr + 0x201020;
//2. add the write permisson
mprotect((void *)PAGE_START(addr), PAGE_SIZE, PROT_READ|PROT_WRITE);
//3. replace our hook func my_strcmp
*(void **)addr = my_strcmp;
//4. clear the cache
__builtin___clear_cache((void *)PAGE_START(addr),
(void *)PAGE_END(addr));
} int main()
{
hook();
check_is_authenticated("abcd");
return ;
}

在将libpasswd.so放置到/usr/lib/目录中之后,使用以下命令编译main.c
运行之后我们 可以看到验证结果始终是正确的,说明我们对于libpasswd.so中的strcmp函数的Hook已经生效。
怎么样,是不是很神奇呀!下面我们就来看看plt hook到底是怎么实现的。
3. PLT hook原理

以上就是第一次调用strcmp函数的流程,可以看出开销还是不小的。在后续的调用中,首先还是跳转到strcmp的plt条目中,然后执行jmpq *0x200aaa(%rip)指令,不同的是这是strcmp对应的GOT条目已经被写入了strcmp的运行时地址,所以这条jmp指令直接将程序的执行跳转到strcmp函数中。那么是不是只要在strcmp对应的GOT条目中写入我们自己的函数的地址,就可以将控制跳转到自己实现的函数中了嘛。本着这样的思路我们来看看开始时的代码。
4. 代码分析
- 第一步我们要获取libpasswd在进程中的首地址,时刻记住我们拦截的是动态库中的函数,将来要替换的GOT[strcmp]也属于libpasswd。
第二步就是获取libpasswd中调用strcmp对应的GOT条目的地址,为什么是addr = base_addr + 0x201020呢?我们回到上文的libpasswd的plt段,可以看到strcmp的plt条目的第一条指令已经写出了相应的GOT条目的地址就是0x201020。又因为我们拦截的动态库的strcmp函数,所以必须加上libpasswd在main中的首地址。

3. 因为我们要写入目标进程的数据段,所以必须给相应的页增加写权限,这里使用mprotect函数来调整相应页的权限。
void hook() {
uintptr_t base_addr;
uintptr_t addr;
//1. get the base addr of libpasswd.so
base_addr = get_base_addr("libpasswd");
if ( == base_addr) return;
addr = base_addr + 0x201020;
//2. add the write permisson
mprotect((void *)PAGE_START(addr), PAGE_SIZE, PROT_READ|PROT_WRITE);
//3. replace our hook func my_strcmp
*(void **)addr = my_strcmp;
//4. clear the cache
__builtin___clear_cache((void *)PAGE_START(addr),
(void *)PAGE_END(addr));
}
参考
PLT hook笔记的更多相关文章
- Linux Hook 笔记
相信很多人对"Hook"都不会陌生,其中文翻译为"钩子".在编程中, 钩子表示一个可以允许编程者插入自定义程序的地方,通常是打包好的程序中提供的接口. 比如,我 ...
- hook笔记①
汇编中push 0x*** retn表示跳转到某个地址继续执行 取消hook时会在多线程环境中可能被检测 去掉函数框架可以规避寄存器cpu前后状态监测 #pragma comment(linker,& ...
- hook笔记②
- 基于Android的ELF PLT/GOT符号和重定向过程ELF Hook实现(by 低端农业代码 2014.10.27)
介绍 技术原因写这篇文章,有两种: 一个是在大多数在线叙述性说明发现PLT/GOT第二十符号重定向过程定向x86的,例<Redirecting functions in shared ELF l ...
- 基于Android的ELF PLT/GOT符号重定向过程及ELF Hook实现(by 低端码农 2014.10.27)
引言 写这篇技术文的原因,主要有两个: 其一是发现网上大部分描写叙述PLT/GOT符号重定向过程的文章都是针对x86的.比方<Redirecting functions in shared EL ...
- 羽夏笔记——Hook攻防基础
写在前面 本笔记是由本人独自整理出来的,图片来源于网络.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你 ...
- 孙鑫MFC学习笔记20:Hook编程
1.HOOK拦截消息,设置越后的钩子优先级越高(钩子队列)2.SetWindowHookEx设置钩子 如果thread identifier为0或其他进程创建的线程,回调函数需要在动态链接库中声 ...
- CI框架源码阅读笔记6 扩展钩子 Hook.php
CI框架允许你在不修改系统核心代码的基础上添加或者更改系统的核心功能(如重写缓存.输出等).例如,在系统开启hook的条件下(config.php中$config['enable_hooks'] = ...
- 我的Hook学习笔记
关于Hook 一.基本概念: 钩子(Hook),是Windows消息处理机制的一个平台,应用程序能够在上面设置子程以监视指定窗体的某种消息,并且所监视的窗体能够是其它进程所创建的.当消息到达后,在目标 ...
随机推荐
- 【神经网络与深度学习】Caffe Model Zoo许多训练好的caffemodel
Caffe Model Zoo 许多的研究者和工程师已经创建了Caffe模型,用于不同的任务,使用各种种类的框架和数据.这些模型被学习和应用到许多问题上,从简单的回归到大规模的视觉分类,到Siames ...
- Web Components的概念和用法
参考链接:https://developer.mozilla.org/zh-CN/docs/Web/Web_Components
- jmeter-ERROR o.a.j.p.j.c.DataSourceElement: JDBC data source already defined for: 报错原因
转载自:https://www.cnblogs.com/zhangfeivip/p/9450403.html Jmeter 多个threadgroup 中的配置元件会一次性进行初始化 例如3个th ...
- JAVA文件类工具
FileUtil package cn.jiangzeyin.util.file; import org.springframework.util.Assert; import java.io.*; ...
- MySQL性能优化(五):分表
原文:MySQL性能优化(五):分表 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/vbi ...
- 深入理解hadoop之机架感知
深入理解hadoop之机架感知 机架感知 hadoop的replication为3,机架感知的策略为: 第一个block副本放在和client所在的datanode里(如果client不在集群范围内, ...
- 上海的Costco,谈谈你的理解和感受
众所周知,Costco在上海第一天开业,由于人流量过大,一度暂停营业.我觉得Costco的成功在于不走寻常路,换位思考(站在用户.厂商角度看问题),下面几点是我觉得它做得比较独特的地方: 1. Cos ...
- npm操作命令
查看所有高级的npm moudles npm list --depth= 查看所有全局安装的模块 npm list --depth= -global 查找npm全局安装模块路径 npm config ...
- BLOB和CLOB
mysql各数据类型及字节长度一览表: 数据类型 字节长度 范围或用法 Bit 1 无符号[0,255],有符号[-128,127],天缘博客备注:BIT和BOOL布尔型都占用1字节 TinyInt ...
- MySQL单机上多实例安装
首先安装mysql,不要启动MySQL,先配置vim /etc/my.cnf.[mysqld_multi]mysqld = /usr/bin/mysqld_safemysqladmin = /usr/ ...