花指令的原理,花指令的分析方法

在我们逆向分析的过程中,经常会受到花指令的干扰,今天我就来带领大家了解了解花指令。

一.花指令的原理

花指令是干扰反汇编引擎正常工作的指令片段,不影响程序本身的执行结果。
花指令可以干扰IDA等反汇编工具生成正确的汇编代码,CFG(控制流图),进一步干扰生成中间代码(IR)以及伪代码。对于只会用IDA F5功能进行逆向的人来说,简直就是致命杀手。

我们想要搞清楚花指令的原理,我们先来思考这样一个问题:假如有一个函数disAsm(addr),该函数可以对指定地址addr处反汇编一条指令,并将结果自动输出到屏幕,返回值是当前反汇编指令的长度。
那么我们就应该能写出这样的代码:

target=getFunctionAddress;
targetEnd=getFUnctionEnd(main);
currentAddr=target;
while(currentAddr<targetEnd){
	currentLen=disAsm(currentAddr);
	currentAddr+=currentLen;
}
  • 线性扫描:
    我们上述代码的实现方式,就叫做线性扫描
    线性扫描的特点:从入口开始,一次解析每一条指令,遇到分支指令不会递归进入分支。

  • 递归下降:
    当使用线性扫描时,比如遇到call或者jmp的时候,不会跳转到对应地址进行反汇编,而是反汇编call指令的下一条指令,这就会导致出现很多问题。
    递归下降分析当遇到分支指令时,会递归进入分支进行反汇编。

X86指令集的长度是不固定的,有一些指令很短,只有1个字节,有些指令比较长,可以达到5字节,指令长度不是固定的。如果通过巧妙的构造,引导反汇编引擎解析一条错误的指令,扰乱指令的长度,就能使反汇编引擎无法按照正常的指令长度一次解析邻接未解析的指令,最终使反汇编引擎输出错误的反汇编结果。

JMP指令字节码构成:E9(1字节),目标地址-当前地址-5(4字节)。

我们来看这样一段代码:

E9 00 00 00 00 JMP 0x005      //实际上没有跳转
0xcc     int 3
0xcc     int 3

这样的一段程序是正常的,但是我们来看看另一种情况:

E9 01 00 00 00 jmp 0x006
0xE9                ......
0x50                 push eax
0x53                 push ebx
0x5B                 pop ebx
B8 56 34 12 00       mov eax,0x123456

仔细分析上面这这段代码,如果反汇编引擎使用线性扫描,当反汇编引擎解析到E9的位置时,会将后面的4字节数据当作跳转的偏移来解释,导致程序反编译出错。

  • 间接跳转形式的花指令(在定长指令集如arm中比较常见)
    花指令

二.花指令分析方法:

调试观察法,使用动态调试观察指令的执行流:
花指令不会干扰正常代码:

  1. 花指令内部如果涉及到寄存器的使用,一般会将其保存在栈中,利用这个弱点,我们可以通过观察sp寄存器来判断花指令的入口和出口
  2. 大部分情况下,花指令可以直接使用相同长度的nop(0x90)替换。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shad0w-2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值