x64 InlineHook 黑魔法

网上x64 InlineHook资料挺少的,我翻阅文章找到个不错的x64 InlineHook方法,在此整理成笔记如有错误欢迎指正。

为什么不能用X86 的HOOK方式?

像32位JMP跳转只需要5字节即可,但是在64位进程中情况确截然不同。

32位进程寻址能力为4字节,而64位进程寻址能力变成了8字节,然而64位汇编中所有的跳转直接寻址只支持4字节。

原理:jmp + rip 进行寻址6字节方式跳转

在64位程序中. 可以使用rip寄存器了. 而32位不可以.32位下想要改变 eip的值. 无非就是 jmp + call才可以改变.64位可以使用下面

;其核心方法类似
jmp qword ptr [rip] ;//机器码0xFF 0x25 0x00 0x00 0x00 0x00

在上面可以看到他有固定的机器码,0xFF,0x25.而后面的内容都是0他就会自动定位到rip也就是下一句的地址,那么我们就可以来构造,0xFF,0x25,0x00,0x00,0x00,0x00.把这个0x00 4字节替换成我们的一块空内存地址,然后再空内存地址里面写入8字节地址(目标地址)就能实现一个远跳转了,下面是jmp rip的整个流程。

偏移 = 临时地址x - 源地址 - 6
0xFF 0x25 偏移(4字节)
临时地址x(内容) = 目标地址
;比32位HOOK 多出了一个临时地址x而已,其他目的地址,源地址都差不多所以可以构造Inline Hook

只不过我们不能直接把目标函数地址写到rip里面,需要一系列手段来计算出来,大概分下面几个步骤:

  • 找一块空的内存(或者全局变量)
  • 计算偏移:空的内存地址 - 需要HOOK处位置地址 - 6
  • 修改需要HOOK位置处的汇编代码jmp qword ptr [] //6字节
  • 将空的内存处写入字节码,(你的HOOK函数地址)//8字节

手动InlineHook

知道原理后我们就可以来构造了,一共分这4个东西。

  • 临时地址x
  • 计算偏移
  • 源地址(内容 )= jmp + rip + 偏移
  • 临时地址x(内容) = 目标地址

临时地址x(找一块空内存)

打开x64dbg 然后随便载入一个64位程序,接着ctrl+b输入很多0然后点击确定,跳转到0的地址处,然后记下地址0x00007FF7094B7674

计算偏移

我们先找到我们想要hook的地址,这里随便这一个就假如是下面这位置吧,然后记一下地址0x00007FF7094B63DE

计算偏移:0x00007FF7094B7674 - 0x00007FF7094B63DE - 6= 0x1290,记下偏移。

源地址(内容 )= jmp + rip + 偏移(HOOK代码)

修改成如下格式jmp qword ptr [rip +x]的格式,注意你不能直接汇编改[偏移],要不然会变成下面这种情况。

改成这样子是不对的,起不到任何效果。

我们说过我们是要改rip,而改rip有固定机器码,所以我们得根据上面讲过的0xFF 0x25的方式来修改我们的rip。

改为后他会自动变成jmp qword ptr ds:[0x7FF7094B7674],而这个0x7FF7094B7674就是我们之前找的空内存的地址。

临时地址x(内容) = 目标地址

最后一步才是真正的改rip,也就是利用rip [0+x]的寻址方式,x处的地址机器码要改成我们想要把之前HOOK处的函数改成自己想要让他执行处地址的。

废话不多说,我们先随便找一处想让程序跳到的地址0x00007FF7094B644E,我们想让程序知道到hook处的地方后直接跳到pop rbp这位置。

ctrl +g 跳转到空内存的地址处0x7FF7094B7674

修改二进制,改成0x00007FF7094B644E这个地址(想让hook处的地方跳到这里的地址),注意大小端转换

最终效果

当我们点击hook处的地方,从这个流程图箭头处我们就能看到效果,他会直接jmp到我们想要改变他流程后的地址,即pop rbp

代码InlineHook

例子说明

这里来下一个demo,大概程序运行后会把本来的my_func函数内容替换成fake_func函数内容来测试HOOK效果。

int fake_func()
{
MessageBox(NULL, L"fake function!", NULL, NULL);
return 0;
} int my_func()
{
MessageBox(NULL, L"Hello,World!", NULL, NULL);
return 1;
}

构造InlineHook

Inline HOOK代码的构造

临时地址x = 自己定义一个全局变量x
源地址 = my_func
目标地址 = fake_func
偏移 = 临时地址x - 源地址 - 6
HOOK代码 = 0xFF 0x25 偏移(4字节)
临时地址x(地址处内容) = 目标地址(8字节)

Inline HOOK代码

DWORD64 tmpx = 0;
void x64_InlineHook(DWORD64 qwHookAddr, LPVOID pFuncAddr)
{
//1.将HOOK处的位置改为 jmp qword ptr [rip + x]的方式
DWORD Offset = (DWORD64)&tmpx - qwHookAddr - 6;
byte hook_code[6] = { 0xFF, 0x25 };
*(DWORD*)(hook_code + 2) = Offset;
WriteProcessMemory((void*)-1, (void*)qwHookAddr, hook_code, sizeof(hook_code), NULL); //2.将目标地址写到临时地址x(字节码)
byte dest_address_opcode[8] = { 0 };
*(DWORD64*)dest_address_opcode = (DWORD64)pFuncAddr;
WriteProcessMemory((void*)-1, (void*)&tmpx, dest_address_opcode, sizeof(dest_address_opcode), NULL); //3.完成
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
x64_InlineHook((DWORD64)&my_func, fake_func); //测试Inline HOOK
my_func();
}

最终运行程序的效果

x64 InlineHook 黑魔法的更多相关文章

  1. C# inline-hook / api-hook

    我查阅了一下相关C#方面的资料,却没有发现有提供过关于api-hook方面的资 料包括应用库由此本人编写一套inline-hook的库用于支持x64.x86上的基于在 clr的公共语言,如: c#.c ...

  2. Win64 驱动内核编程-23.Ring0 InLineHook 和UnHook

    Ring0 InLineHook 和UnHook 如果是要在R0里hook,作者的建议是InLine HOOK,毕竟SSDT HOOK 和 SHADOW SSDT HOOK比较麻烦,不好修改.目前R3 ...

  3. HOOK技术之SSDT hook(x86/x64)

    x86 SSDT Hook 32位下进行SSDT Hook比较简单,通过修改SSDT表中需要hook的系统服务为自己的函数,在自己的函数中进行过滤判断达到hook的目的. 获取KeServiceDes ...

  4. X86和X86_64和X64有什么区别?

    x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称为&qu ...

  5. VisualStudio 2015 开启IIS Express可以调试X64项目

    现在项目开发时总有时需要在X64下开发,这样我们就需要IIS Express中调试.不要总是放在IIS中,在Attach这样好慢.   如果不设置直接调试X64的程序,我们有可能会受到以下类似的错误 ...

  6. Win7(x64)升级到Win10

    北京时间7月29日零点起,微软正式开始向包含中国在内的全球用户推送Windows 10正式版安装包,Win7.Win8正版用户从29日零点起就可以免费升级到Win 10. 如果你的C盘里边有“$Win ...

  7. 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY

    转载自: 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY Navicat Premium(数据库管理工具 ...

  8. 在Ubuntu X64上编译Hadoop

    在之前的文章中介绍了如何直接在Ubuntu中安装Hadoop.但是对于64位的Ubuntu来说,官方给出的Hadoop包是32位的,运行时会得到警告: WARN util.NativeCodeLoad ...

  9. win7(x64)下安装cocos2d并编译安卓项目

    好吧,不为啥,就是如题. win7 x64 脑袋内存比较小,说不定明儿就忘了,今天记录一下. 没有什么经验,所有步骤基本都是百度出来的,这里边操作边记录,为了保护原创作者,这里我都附上我查找的链接. ...

随机推荐

  1. PHP中的数据库连接持久化

    数据库的优化是我们做web开发的重中之重,甚至很多情况下其实我们是在面向数据库编程.当然,用户的一切操作.行为都是以数据的形式保存下来的.在这其中,数据库的连接创建过程有没有什么可以优化的内容呢?答案 ...

  2. Jmeter系列(10)- Linux环境安装之Jmeter下载配置

    step-1下载 我是之前windows有,就直接copy到Linux系统了 step-2Jmter放到local目录 mv apache-jmeter-5.2.1 /usr/local/ step- ...

  3. CF891B-Gluttony【构造】

    正题 题目链接:https://www.luogu.com.cn/problem/CF891B 题目大意 给出\(n\)个数字互不相同的一个序列\(a\),求它的一个排列\(b\),使得选出任意一个\ ...

  4. AT2305-[AGC010D]Decrementing【博弈论】

    正题 题目链接:https://www.luogu.com.cn/problem/AT2305 题目大意 \(n\)个数字两个人进行博弈,每个人的操作为 选择一个大于1的数字减一 之后所有数字除以所有 ...

  5. P7717-「EZEC-10」序列【Trie】

    正题 题目链接:https://www.luogu.com.cn/problem/P7717 题目大意 求有多少个长度为\(n\)的序列\(a\)满足,都在\([0,k]\)的范围内且满足\(m\)个 ...

  6. 深入浅出WPF-02.WPF系列目录

    WPF系列目录 2. XAML认识 3. XAML语法 4. x名称空间详解 5. 控件与布局 6. 绑定Binding-01 6. 绑定Binding-02 6. 绑定Binding-03 7. 属 ...

  7. 初步认识HCIA,什么是计算机网络,拓扑,网络的发展,交换机,路由器,IP,光纤,带宽,广播,ARP......

    HCIA ---- 华为认证初级网络工程师 云技术 --- 云存储 云计算 计算机技术 : ​ --- 抽象语言 -- 电线号的转换 抽象语言 -- 编码 ---- 应用层 编码 --- 二进制 -- ...

  8. spark性能优化(一)

    本文内容说明 初始化配置给rdd和dataframe带来的影响 repartition的相关说明 cache&persist的相关说明 性能优化的说明建议以及实例 配置说明 spark:2.4 ...

  9. 2020.11.6-vj补题

    A - A CodeForces - 136A 题解:按输入的顺序输出对应的下标即可,定义一个数组,将输入的作为下标,下标为值,最后依次输出即可: #include<bits/stdc++.h& ...

  10. 【Java虚拟机9】类加载器之命名空间详解

    前言 前面介绍类加载器的时候,介绍了一下命名空间这个概念.今天就通过一个例子,来详细了解一下[类加载器的命名空间].然后通过这个例子,我们可以总结一下双亲委托模型的好处与优点. 例1(不删除class ...