转移指令原理和Inline Hook
转移指令原理和Inline Hook
转移指令
可以修改IP,或同时可以修改CS和IP的指令统称为:转移指令
8086CPU
的转移行为
有以下几类:
- 只修改IP时,称为段内转移,比如:jmp ax。
- 同时修改CS和IP时,称为段间转移,比如:jmp 1000:0。
由于转移指令对IP的修改范围
不同,段内转移又分为:短转移和近转移。
- 短转移IP的修改范围为-128~127(0xFF)
- 近转移IP的修改范围为-32768~32767(0xFFFF)
8086CPU
的转移指令
分为以下几类:
- 无条件转移指令(jmp)
- 条件转移指令(jnz jz..)
- 循环指令(loop)
- 过程
- 中断(int)
操作符offset
操作符offset是伪指令,在汇编语言中由编译器处理的符号,它的功能是取得标号的偏移地址
jmp指令
jmp为无条件转移指令,可以只修改IP,也可以同时修改CS和IP。
jmp指令要给出两种信息:
- (1) 转移的目的地址
- (2) 转移的距离(段间转移、段内短转移、段内近转移)
jmp short 标号
jmp near ptr 标号
jcxz 标号
loop 标号 等几种汇编指令,它们对 IP的修改是根据转移目的地址和转移起始地址之间的位移来进行的。在它们对应的机器码中不包含转移的目的地址,而包含的是到目的地址的位移距离。
根据位移进行转移的jmp指令
jmp short 标号
(段内短转移)
指令“jmp short 标号
”的功能为(IP)=(IP)+8位位移
,转到标号处执行指令
- 8位位移 = "标号"处的地址 - jmp指令后的第一个字节的地址;
- short指明此处的位移为8位位移动;
- 8位位移的范围为(-128~127),用补码表示。 也就是最大一个字节(0xFF)
- 8位位移由编译程序在编译时算出
编译后标号被翻译成了位移。
CPU不需要这个目的地址就可以实现对IP的修改。这里是依据位移进行转移。
jmp short s指令的读取和执行过程如下:
- (1) (CS)=076C,(IP)=0000,执行完
mov ax,0
后CS:IP指向了EB 03
(jmp short s机器码); - (2) 读取指令码
EB 03
进入指令缓冲器; - (3) (IP) = (IP) + 所读取指令的长度 = (IP) + 2 = 5,CS:IP指向了add ax,1;
- (4) CPU执行指令缓冲器中的指令
EB 03
; - (5) 指令执行后
IP+位移
=(IP) + 3 = 8,CS:IP(076C:0008) 指向->inc ax
插播HOOK知识
这里插播点X86
平台下的hook知识,看到这里我们已经知道了我们可以通过修改ip的方式来让代码跳到想要的地方执行代码。
Inline Hook
inline hook是一种通过修改机器码的方式来实现hook的技术。
在没有学汇编知识前,我们可能对Hook这种技术感到很深奥,觉得这简直是一种黑魔法,凭什么他就能把正常函数替换成我们自己的假函数。
Inline Hook 原理
当我们学习了王爽老师的汇编知识后,才明白原来在底层,CPU是根据ip寄存器来控制我们要执行的指令处的。
而学习了《王爽汇编第9章转移指令的原理》后,了解了可以通过jmp指令来修改ip寄存器,目前我们已经学习了短转移的使用,这已经足够用来学HOOK了。
打开OD载入程序,然后找到执行demo函数的汇编代码处,再利用我们今天刚学的短转移知识进行机器码的修改。
首先经过单步调试后,我找到了执行demo函数处的位置,我们先记下他下条指令的地址0x00481885
。
接着我们需要找到标号
处,也就是fake_demo
函数处,也记下地址0x004817D0
好了,最后的步骤就是改机器码,根据公式计算出位移:-181(0xFFFFFF4B)
最后来执行一遍:
Hook代码开发
在了解了Hook原理后,甚至我们用手动方式实现了HOOK后,就有了思路来代码开发了。
在此之前让我们先来认识两个函数WriteProcessMemory
、VirtualProtect
- WriteProcessMemory函数可以对进程的内存进行写入,这样我们就可以修改,写入机器码了。
- VirtualProtect函数可以更改虚拟内存中的访问保护,在Win32中代码段具有写保护,所以我们无法直接写入,可以利用此函数修改保护后再调用WriteProcessMemory修改和写入机器码。
/*************************************************
*功能:内联HOOK 函数,可以劫持函数的原本流程
*
*函数名:InlineHook
*参数:(原函数地址)、(fake函数地址)
*by: 《王爽汇编笔记》
************************************************/
void InlineHook(DWORD dwHookAddr, LPVOID pFunAddr)
{
BYTE jmpCode[5] = {0xE9};
//计算偏移
*(DWORD*)(&jmpCode[1]) = (DWORD)pFunAddr - dwHookAddr - 5;
// 保存以前的属性用于还原
DWORD OldProtext = 0;
DWORD dwWritten;
// 因为要往代码段写入数据,又因为代码段是不可写的,所以需要修改属性
VirtualProtect((LPVOID)dwHookAddr, 5, PAGE_EXECUTE_READWRITE, &OldProtext);
WriteProcessMemory(GetCurrentProcess(), (FARPROC)dwHookAddr, jmpCode, 5, &dwWritten);
VirtualProtect((LPVOID)dwHookAddr, 5, OldProtext, &OldProtext);
}
int main()
{
//故意让程序暂停
getchar();
//执行函数
InlineHook((DWORD)&demo, &fake_demo);
demo();
}
转移的目的地址在指令中的jmp指令
jmp far ptr 标号
(远转移、段间转移)
- (CS) = 标号所在段的段地址;
- (IP) = 标号所在段中的偏移地址。
- far ptr 指明了指令用标号的
段地址 和 偏移地址
修改CS和IP
。
在Win32
中的远转移
可以跳到其他DLL的空间,其中关键的机器码是0xFF25
+ 目标地址
转移地址在寄存器或内存中的jmp指令
jmp 16位寄存器
功能:IP=(16位寄存器)[段内转移]
转移地址在内存中的jmp指令有两周格式:
- jmp word ptr [...] (段内转移)
- jmp dword ptr [...] (段间转移)
功能:从内存单元地址处开始存放着两个字,高地址
出的字是转移目的段地址
,低地址
处是转移目的偏移地址
。
1:(CS) = (内存单元地址+2)
2:(IP) = (内存单元地址)
jcxz指令和loop指令
jcxz指令
jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移
,而不是目的地址
。对IP的修改范围都为-128~127(0xff)。
指令格式:jcxz 标号
(如果cx=0
,则转移到标号处执行。)
当(cx) = 0时,(IP) = (IP) + 8位位移
- 8位位移 = "标号" 处的地址 - jcxz指令后的第一个字节的地址;
- 8位位移的范围为-128~127,用补码表示;
- 8位位移由编译程序在编译时算出。
当(cx)!=0时,程序向下执行什么都不做!
loop指令
loop指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移
,而不是目的地址。
对IP的修改范围都为-128~127(0xFF)。
指令格式:loop 标号
((cx) = (cx) - 1,如果(cx) ≠ 0
,转移到标号处执行)。
(cx) = (cx) - 1;如果 (cx) != 0,(IP) = (IP) + 8位位移。
- 8位位移 = ""标号""处的地址 - loop指令后的第一个字节的地址;
- 8位位移的范围为-128~127,用补码表示;
- 8位位移由编译程序在编译时算出。
如果(cx)= 0,什么也不做(程序向下执行)。
几种跳转指令和对应的机器码
注:(Win32 x86架构下)
机器码 | 指令 | 解释 |
---|---|---|
0xE8 | CALL | 后面的四个字节是地址 (近转移) |
0xE9 | JMP | 后面的四个字节是偏移 (近转移) |
0xEB | JMP | 后面的二个字节是偏移 (近转移 8086) |
0xFF15 | CALL | 后面的四个字节是存放地址的地址 (远转移) |
0xFF25 | JMP | 后面的四个字节是存放地址的地址 (远转移) |
0x68 | PUSH | 后面的四个字节入栈 |
0x6A | PUSH | 后面的一个字节入栈 |
参考文献:
https://www.cnblogs.com/Archimedes/p/14823218.html inline hook原理和实现
https://blog.csdn.net/wzsy/article/details/17163589 几种跳转指令和对应的机器码
https://blog.csdn.net/qq_39654127/article/details/88698911 王爽《汇编语言》笔记(详细)
《王爽汇编第四版 第9章》
转移指令原理和Inline Hook的更多相关文章
- android inline hook
最近终于沉下心来对着书把hook跟注入方面的代码敲了一遍,打算写几个博客把它们记录下来. 第一次介绍一下我感觉难度最大的inline hook,实现代码参考了腾讯GAD的游戏安全入门. inline ...
- Inline Hook
@author: dlive IAT Hook时如果要钩取的API不在IAT中(LoadLibrary后调用),则无法使用该技术.而Inline Hook不存在这个限制. 0x01 Inline Ho ...
- INLINE HOOK过简单驱动保护的理论知识和大概思路
这里的简单驱动保护就是简单的HOOK掉内核API的现象 找到被HOOK的函数的当前地址在此地址处先修改页面保护属性然后写入5个字节.5个字节就是一个简单的JMP指令.这里说一下JMP指令,如下: 00 ...
- x86平台inline hook原理和实现
概念 inline hook是一种通过修改机器码的方式来实现hook的技术. 原理 对于正常执行的程序,它的函数调用流程大概是这样的: 0x1000地址的call指令执行后跳转到0x3000地址处执行 ...
- Android Hook框架adbi的分析(2)--- inline Hook的实现
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/74452308 一. Android Hook框架adbi源码中inline Hoo ...
- Android Hook框架adbi的分析(3)---编译和inline Hook实践
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/75200800 一.序言 在前面的博客中,已经分析过了Android Hook框架a ...
- iOS开发UI篇—程序启动原理和UIApplication
iOS开发UI篇—程序启动原理和UIApplication 一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就 ...
- 对付ring0 inline hook
对付ring0 inline hook的基本思路是这样的,自己写一个替换的内核函数,以NtOpenProcess为例,就是MyNtOpenProcess.然后修改SSDT表,让系统服务进入自己的函数M ...
- iOS开发UI篇—程序启动原理和UIApplication1
iOS开发UI篇—程序启动原理和UIApplication 一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就 ...
随机推荐
- 【PHP数据结构】线性查找与二分查找
欢迎来到查找的世界,在学习完各种数据结构之后,总算走到了这一步,不知道大家有什么感想呢?反正我是边学边忘,现在让我去说说图的那几个算法还是在蒙圈的状态中.不过学习嘛,就是一步一步的来,暂时搞不懂的东西 ...
- 如何创建 Office LTSC 2021 VL(批量许可)版本的安装 ISO
Office LTSC 2021 发布 2021 年 9 月 16 日,微软正式发布了支持 Office 2021 的部署工具(Office Deployment Tool),这意味着 Office ...
- Java基础系列(28)- 方法的定义和调用
方法的定义 Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法: 修饰符 返回值类型 方法名(参数类型 参数名){ -- 方法体 -- retu ...
- SonarScanner扫描Maven项目使用说明
最近在学习使用sonar扫描代码,已经成功扫描python项目,而扫描java代码不成功. 在网上找到的扫描java项目文章,经过尝试之后也没有成功. 本人自己研究了sonar官方的使用说明文章,将其 ...
- 『GoLang』包
可见性规则 在Go语言中,标识符必须以一个大写字母开头,这样才可以被外部包的代码所使用,这被称为导出.标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的.但是包名不管 ...
- P3306-[SDOI2013]随机数生成器【BSGS】
正题 题目链接:https://www.luogu.com.cn/problem/P3306 题目大意 给出一个\(p,a,b,x_1,t\),有\(x_i=ax_{i-1}+b\) 求一个最小的\( ...
- Superedge的新特性和未来之路
作者 王冬,腾讯云高级研发工程师,专注于Kubernetes.容器等云原生领域,SuperEdge 核心开发人员,现负责腾讯云边缘容器TKE Edge私有化相关工作. 背景 2021年9月27号,,在 ...
- SpringCloud升级之路2020.0.x版-25.OpenFeign简介与使用
本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent OpenFeign 的由来和实现思路 在微服务系统中,我们经常会进行 RPC 调用.在 S ...
- bash是什么?
bash shell就是一个bash程序 --解释器,启动器 --解释器: 用户交互输入 如vim 文本文件输入 脚本本质: !/bin/bash !/usr/bin/python 读取方 ...
- 独家对话阿里云函数计算负责人不瞋:你所不知道的 Serverless
作者 | 杨丽 出品 | 雷锋网产业组 "Serverless 其实离我们并没有那么遥远". 如果你是一名互联网研发人员,那么极有可能了解并应用过 Serverless 这套技术体 ...