inline hook是通过修改函数执行指令来达到挂钩的。比如A要调用B,但人为地修改执行流程导致A调用了C,C在完成了自己的功能后,返回B再执行。
修改这段指令前首先要获取修改权限
由于要修改的代码位于PE文件的代码段,而PE文件载入内存时默认代码段的权限为“可执行,只读”。通过函数VirtualProtect 修改这段代码所在内存空间的权限(保护属性)。
 VirtualProtect函数原型:
BOOL VirtualProtect(  
  LPVOID lpAddress,  //基地址:内存起始位置,也就是要修改代码的地址
  DWORD dwSize,  //    长度  :要修改多少个字节的属性,此处为一条jmp指令的长度5字节
  DWORD flNewProtect,  //    新保护属性  :修改后的内存保护属性,此处为64代表“可执行可写”。
  PDWORD lpflOldProtect  //    旧保护属性:原始的内存保护属性
);  
 代码实现:
//dwTemp保存旧保护属性。便于hook后续恢复原状
DWORD dwOldProtect , dwTemp; //修改为可读可写可执行
if(VirtualProtect(add , 5 , 64 , &dwOldProtect)){
//jmp to fake_add
}
//恢复为修改前的属性
VirtualProtect(add , 5 , dwOldProtect , &dwTemp);
以上实现修改add函数附近的5个字节码权限为为可读可写(flNewProtect设置为PAGE_EXECUTE_READWRITE(0x40)即64)
定位原函数地址时,可以像本例通过函数名(例如 LPVOID originFunction = MessageBoxA),或者如果该函数是存在在一个DLL并且已声明公开,则可以通过GetProcAddress( 功能是检索指定的动态链接库(DLL)中的输出库函数地址)函数来获取函数的地址。
比如要获取kernel32.dll里面的WriteProcessMemory函数:
LPVOID lpvWriteProcessMemory = GetProcAddress(GetModuleHandle("kernel32.dll") , "WriteProcessMemory");
权限修改好后就可以改写代码了,通过WriteProcessMemory将add函数开始部分改写为:jmp <fake_add的函数地址>,此处的jmp为短跳转,注意位移量为相对偏移
JMP 的 3 种类型
1. 短跳转(Short Jmp,只能跳转到256字节的范围内),对应机器码:EB
2. 近跳转(Near Jmp,可跳至同一段范围内的地址),对应机器码:E9
3. 远跳转(Far Jmp,可跳至任意地址),对应机器码: EA
短跳转 和 近跳转 指令中包含的操作数都是相对于(E)IP的偏移
远跳转指令中包含的是目标的绝对地址。
计算jmp位移量
jmp指令占5字节,执行该指令后,IP先加5,然后在加上jmp指令的位移量
所以 新函数的地址– 待修改函数的地址 – 5 = 位移量
RVA = fake_add - add - 5;
知道了地址可以开始改写内存写入jmp指令了,
//写入该段内存
if(WriteProcessMemory(currentProcessHandle , originAdd , shellCode , 5 , &dwWritten) && dwWritten == 5){
MessageBoxA(NULL , "Write Hook Success !" , "Hook add" , 0);
}
函数原型:
BOOL WriteProcessMemory(
HANDLE hProcess,//所写入的进程句柄
LPVOID lpBaseAddress,//写入内存的基地址
LPVOID lpBuffer,//待写入数据的地址
DWORD nSize,   //写入长度(字节)
LPDWORD lpNumberOfBytesWritten
);
//返回值非0为成功
运行效果
点击确定后
 
 
 
 
参考资料:

最新文章

  1. 新版 itextsharp pdf code
  2. java基础知识(三)java关键字
  3. web前端基础篇⑨
  4. 关于IE8及其以下的IE版本不支持getElementsByClassName
  5. 获取文本文件的第N行内容
  6. 读Windows编程
  7. Linq的延迟
  8. 详解ExplosionField的使用,实现View的粉碎效果
  9. Git 、CVS、SVN比较
  10. 用bootstrap结合php搭建MIS系统框架【转载】
  11. Cocos3.0测试版发布(中文)
  12. c#图像处理入门
  13. 使用SndPlaySound从内存中播放WAV
  14. Struts 上下文
  15. Hibernate SQLQuery 原生SQL 查询及返回结果集处理-1
  16. JAVA有哪些数据类型?基本数据类型各占多少个字节
  17. Spark编程指南分享
  18. 【CF1119E】Pavel and Triangles
  19. 初试Django的缓存系统
  20. 利用 T-sql 的从句 for xml path(&#39;&#39;) 实现多行合并到一行, 并带有分隔符

热门文章

  1. PHP中的数据库连接持久化
  2. 网络协议之:WebSocket的消息格式
  3. Docker系列(22)- DockerFile指令说明并构建自己的centos
  4. Centos 7 设置 SFTP
  5. 不使用插件的ajax 上传文件
  6. [转载20131024]Nginx服务器漏洞的利用和修复方法
  7. Python代码阅读(第8篇):列表元素逻辑判断
  8. 踩坑系列《五》 Incorrect datetime value: 时间添加失败原因
  9. Go语言之结构体与方法
  10. redis 5.0.12 install