usercall 调用约定表示这个函数用寄存器传参,hook 它就没那么方便,需要整一个包装函数。原理是很简单的,下面给个例子,一看就懂:

说明一下我这里用的是 tramp hook 技术,或者叫“蹦床”hook,其实和普通inline hook也没什么区别,封装了一下而已。

//int* __usercall AccessEntInfoList@<eax>(int a1@<ecx>, int a2@<ebx>, int a3@<esi>)
int* __cdecl HookedAccessEntInfoList(int a1, int a2, int a3)
{EntInfoList = a1 + 0x188;__asm{leavepopfdpopadpop ecxpop ebxpop esijmp OldAccessEntInfoList}return 0; // 不会执行
}// hook __usercall 这种函数需要包装一下
__declspec(naked) void WrapperHookedAccessEntInfoList()
{__asm{push esipush ebxpush ecxpushadpushfdjmp HookedAccessEntInfoList}
}typedef int* (__cdecl *tAccessEntInfoList)(int a1, int a2, int a3);
tAccessEntInfoList OldAccessEntInfoList = NULL; // 蹦床
// hook client.dll + 204660 to get the ent info list
OldAccessEntInfoList = (tAccessEntInfoList)Internal::HookFunction((uintptr_t)hClientDll + (uintptr_t)0x204660, 6, (uintptr_t)WrapperHookedAccessEntInfoList);

我有一个 AccessEntInfoList 函数,他用了3个寄存器传参,不是标准的调用约定,于是我就写一个裸函数 WrapperHookedAccessEntInfoList,将这三个寄存器push到栈里,保存其他寄存器,然后 jmp 到 HookedAccessEntInfoList。

HookedAccessEntInfoList 可以按正常函数的方式编程,定义局部变量都是可以的,返回的时候要先恢复寄存器,然后依次将栈里的值弹回给寄存器,然后执行被替换的代码。

hook 用到的工具函数:

BOOL Internal::InlineHook(uintptr_t AddressToHook, size_t nByte, uintptr_t NewAddress)
{#ifdef _WIN64InterlockedCompareExchange128return FALSE;
#elseif (nByte < 5 || nByte > 8){return FALSE;}// 把原始的8字节拷贝过来BYTE Replace[8] = { 0 };memcpy(Replace, (BYTE*)AddressToHook, 8);Replace[0] = 0xE9;DWORD RelativeAddress = NewAddress - AddressToHook - 5;memcpy(Replace + 1, &RelativeAddress, 4);// 要 patch nByte 个字节,前5字节是JMP,其余是 NOPfor (size_t i = 5; i < nByte; i++){Replace[i] = 0x90;}AtomicWrite64(AddressToHook, *(LONG64*)Replace);return TRUE;
#endif
}BOOL Internal::Nop(uintptr_t BeginAddress, size_t nByte)
{return Internal::InlineHook(BeginAddress, 5, BeginAddress + nByte);
}uintptr_t Internal::HookFunction(uintptr_t FunctionToHook, size_t nByte, uintptr_t NewFunction)
{#ifdef _WIN64   return 0;
#elseif (nByte < 5 || nByte > 8) return 0;// Create the gateway (len + 5 for the overwritten bytes + the jmp)uintptr_t gateway = (uintptr_t)VirtualAlloc(0, nByte + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);// Put the bytes that will be overwritten in the gatewaymemcpy((void*)gateway, (void*)FunctionToHook, nByte);// Get the gateway to destination addyuintptr_t gateJmpAddy = FunctionToHook - gateway - 5;// Add the jmp opcode to the end of the gateway*(BYTE*)(gateway + nByte) = (BYTE)0xE9;// Add the address to the jmp*(uintptr_t*)(gateway + nByte + 1) = gateJmpAddy;if (Internal::InlineHook((uintptr_t)FunctionToHook, nByte, (uintptr_t)NewFunction)){return gateway;}else return 0;
#endif
}void Internal::UnhookFunction(uintptr_t FunctionToUnhook, size_t nByte, uintptr_t Gateway)
{#ifdef _WIN64   return 0;
#elseBYTE BytesToReplace[8] = { 0 };Internal::Read(FunctionToUnhook, TRUE, BytesToReplace, 8);BYTE OriginalBytes[8] = { 0 };Internal::Read(Gateway, TRUE, OriginalBytes, nByte);memcpy(BytesToReplace, OriginalBytes, nByte);AtomicWrite64(FunctionToUnhook, *(LONG64*)BytesToReplace);VirtualFree((LPVOID)Gateway, 0, MEM_RELEASE);
#endif
}

inline hook __usercall 函数相关推荐

  1. C语言playsoundw函数,使用inline hook实现修改PC微信通知铃声-哥哥微信来了

    本帖最后由 bester 于 2020-2-15 01:20 编辑 原贴:https://www.52pojie.cn/thread-1103441-1-1.html 最近频繁刷某音刷到哥哥微信来了的 ...

  2. 一种注册表沙箱的思路、实现——Hook Nt函数

    Nt函数是在Ring3层最底层的函数了,选择此类函数进行Hook,是为了提高绕过门槛.我的Hook方案使用的是微软的Detours.(转载请指明出处) Detours的Hook和反Hook的写入如下: ...

  3. Inline Hook

    @author: dlive IAT Hook时如果要钩取的API不在IAT中(LoadLibrary后调用),则无法使用该技术.而Inline Hook不存在这个限制. 0x01 Inline Ho ...

  4. WIN32 Inline HOOK

    Inline hook 和CE里面的代码注入很像(应该是一个东西),这个技术的原理是,修改汇编指令,让某个指令跳转到我们定义的函数,然后在函数内完成被替换的指令,然后再跳转回去.在我们定义的函数内,我 ...

  5. inline hook学习

    vs2013编译 //inline hook 实际上就是指 通过改变目标函数头部的代码来使改变后的代码跳转至我们自己设置的一个函数里,产生hook.#include <windows.h> ...

  6. Windows驱动开发学习笔记(六)—— Inline HOOK

    Windows驱动开发学习笔记(六)-- Inline HOOK SSDT HOOK Inline Hook 挂钩 执行流程 脱钩 实验一:3环 Inline Hook 实验二:0环 Inline H ...

  7. Windows内核实验005 Inline Hook

    文章目录 准备工作 寻找Inline Hook的返回地址 编写代码 动态变化的返回地址 JmpTargetAddr Inline Hook基本框架 示例代码 实战HOOK KiTrap01 无需计算偏 ...

  8. Android inline hook手记

    2019独角兽企业重金招聘Python工程师标准>>> 许久没搞安全方面的东西了.最近有些时间看了看android下面的开发,看去看来总是想往内深入,结果又往Native和内核挖过去 ...

  9. Ring3下Inline Hook API

    用CreateFile为例子,讲解一下Ring3下的Inline Hook API,基本原理很简单 1.获取CreateFile函数的地址 2.读取CreateFile函数的前8个字节 3.将Crea ...

最新文章

  1. 2021年春季学期-信号与系统-第十次作业参考答案-第二小题
  2. 2019昆明计算机会议,计算机 | ACSAC 2019等国际会议信息6条
  3. 【SGU】SGU每日练1·Little shop of flowers【DP】
  4. Meta http-equiv 大全
  5. Hibernate查询技术(2)
  6. CentOS[linux]操作系统的安装手册
  7. 算法复习——带修改莫队(bzoj2453)
  8. asp.net 数据绑定 使用eval 时候报 “字符文本中的字符太多” 问题解决
  9. FL Studio20.8中文完整版本覆盖升级更新说明介绍v20.8.3
  10. BI前端展示工具评估
  11. C++ ../ ./的区别
  12. Xshell 6, 7 已过期的解决方案
  13. mysql-connector-java-8.0.26.jar MySQLJDBC下载
  14. Firemonkey
  15. Win10 封装报错处理
  16. 解决win10系统安装ch341驱动程序显示“预安装成功”的一个方法
  17. 阿里云loT物联网学习
  18. 制作Nine-Patch图片
  19. 表格说超链接危害计算机怎么办,win10系统excel表格中的超链接打不开提示“由于本机限制”的处理教程...
  20. 360插件化方案RePlugin学习笔记-外置插件

热门文章

  1. vbsedit无法创建空文档_如何用Python快速优雅的批量修改Word文档样式?
  2. ML:MLOps系列讲解之《端到端 ML工作流生命周期》解读
  3. AI:2020年6月22日北京智源大会演讲分享之09:00-09:50 全体大会《AI精度与隐私的博弈》
  4. ETH:Windows搭建ETH(区块链技术)利用Web端和小程序端两种方式调用ETH上的SC智能合约
  5. ML之Hash_EditDistance:基于输入图片哈希化(均值哈希+差值哈希)即8*8个元素的单向vector利用编辑距离算法进行判别
  6. CV之IS:计算机视觉之图像分割(Image Segmentation)/语义分割算法的简介、使用方法、案例应用之详细攻略
  7. pyhanlp 提取关键词、自动摘要
  8. 蓝桥杯_算法训练_最小乘积(基本型)
  9. 如何将你拍摄的照片转换成全景图及六面体(PTGui)
  10. JAVA 解析xml字符串