【RE】花指令

【RE】花指令花指令概念分享 花指令

大家好,欢迎来到IT知识分享网。

一、什么是花指令

1)定义

花指令又名垃圾代码、脏字节,英文名是junk code。花指令就是在不影响程序运行的情况下,往真实代码中插入一些垃圾代码,从而影响反汇编器的正常运行;或是起到干扰逆向分析人员的静态分析,增加分析难度和分析时间。

2)分类

花指令分为不可执行花指令、可执行花指令

可执行花指令 顾名思义,可以执行的花指令,这部分垃圾代码会在程序运行的时候执行,但是执行这些指令没有任何意义,并不会改变寄存器的值,同时反汇编器也可以正常的反汇编这些指令。目的是为了增加静态分析的难度,加大逆向分析人员的工作量。

不可执行花指令 不可以执行的花指令,这类花指令会使反编译器在反编译的时候出错,反汇编器可能错误的反汇编这些指令。根据反汇编的工作原理,只有花指令同正常指令的前几个字节被反汇编器识别成一组无用字节时,才能破坏反汇编的结果。因此,插入的花指令应当是一些不完整的指令,被插入的不完整指令可以是随机选择的。

为了能够有效迷惑反汇编器,同时又确保代码的正确运行,花指令必须满足两个基本特征,即:

  • 垃圾数据必须是某个合法指令的一部分。
  • 程序运行时,花指令必须位于实际不可执行的代码路径。
3)原理:反汇编算法的设计缺陷

常用的两类反汇编算法:

1.线性扫描算法:逐行反汇编(无法将数据和内容进行区分)

2.递归行进算法:按照代码可能的执行顺序进行反汇编程序。

通过构造必然条件或者互补条件,使得反汇编出错。

简单的花指令 0xe8是跳转指令,可以对线性扫描算法进行干扰,但是递归扫描算法可以正常分析。

【RE】花指令

两个跳转一个指向无效数据,一个指向正常数据来干扰递归扫描算法。

【RE】花指令

二、花指令实现

1.简单jmp

这是最简单的花指令。

这种jmp单次跳转只能骗过线性扫描算法,会被IDA识别(递归下降)。

__asm{ jmp label1 db junkcode label1: } 

【RE】花指令

2.多层跳转

本质上和简单跳转是一样的,只是加了几层跳转。显然无法干扰ida

start://花指令开始 jmp label1 DB junkcode label1: jmp label2 DB junkcode label2: jmp label3 DB junkcode label3 

【RE】花指令

和单次跳转一样,这种也会被IDA识别。

为了骗过IDA,我们将上面的花指令改写一下,

__asm { _emit 0xE8 _emit 0xFF //_emit 立即数:代表在这个位置插入一个数据,这里插入的是0xe8 } 

查看反汇编后的结果

【RE】花指令

可以看到IDA错误的识别loc_处的代码,成功的实现了花指令的目的。那么我们知道了如何构造,自然也就明白了如何去除,只需要将插入的立即数nop掉即可,点击0xe8和0xff,点击右键,选择patching->change byte

【RE】花指令

也可以使用一个idapython脚本添加一个快捷键,

from idaapi import * from idc import * def nopIt(): start = get_screen_ea() patch_byte(start,0x90) refresh_idaview_anyway() add_hotkey("ctrl-N",nopIt) 

这个快捷键可以将选中的地方直接nop掉。

3.jnx和jx条件跳转

利用jz和jnz的互补条件跳转指令来代替jmp。骗过OD

_asm{ jz label1 jnz label1 db junkcode label1: } 

【RE】花指令

 __asm { jz Label; jnz Label; _emit 0xC7; Label: 

【RE】花指令

这种混淆去除方式也很简单,特征也很明显,因为是近跳转,所以ida分析的时候会分析出jz或者jnz会跳转几个字节,这个时候我们就可得到垃圾数据的长度,将该长度字节的数据全部nop掉即可解混淆。

4.永真条件跳转

通过设置永真或者永假的,导致程序一定会执行,由于ida反汇编会优先反汇编接下去的部分(false分支)。也可以调用某些函数会返回确定值,来达到构造永真或永假条件。ida和OD都被骗过去了

__asm{ push ebx xor ebx,ebx test ebx,ebx jnz label1 jz label2 label1: _emit junkcode label2: pop ebx//需要恢复ebx寄存器 } __asm{ clc jnz label1: _emit junkcode label1: } 

【RE】花指令

确保一个支路永远跳转

在另一个不跳转的支路填充垃圾代码

 __asm { push ebx; xor ebx, ebx; test ebx, ebx; jnz LABEL7; jz LABEL8; LABEL7: _emit 0xC7; LABEL8: pop ebx; } 

【RE】花指令

先对ebx进行xor之后,再进行test比较,zf标志位肯定为1,就肯定执行jz LABEL8,也就是说中间0xC7永远不会执行。

解混淆的时候也需要稍加注意,需要分析一下哪里是哪里是真正会跳到的位置,然后将垃圾数据nop掉,本质上和前面几种没什么不同。

5.call&ret构造花指令

这里利用call和ret,在函数中修改返回地址,达到跳过thunkcode到正常流程的目的。可以干扰ida的正常识别

__asm{ call label1 _emit junkcode label1: add dword ptr ss:[esp],8//具体增加多少根据调试来 ret _emit junkcode } call指令:将下一条指令地址压入栈,再跳转执行 ret指令:将保存的地址取出,跳转执行 

【RE】花指令

6.汇编指令共用opcode

jmp的条指令是inc eax的第一个字节,inc eax和dec eax抵消影响。这种共用opcode确实比较麻烦

【RE】花指令

【RE】花指令

三、清除花指令

手动清除

找到所有的花指令,重新设置数据和代码地址。或者将花指令设置为nop(0x90)

【RE】花指令在0x401051设置为数据类型(快捷键D),在0x401052设置为代码类型(快捷键C)

【RE】花指令

这里用一个ida python脚本添加ALT+N快捷键来将指令的第一个字节设置为NOP

from idaapi import * from idc import * def nopIt(): start = get_screen_ea() patch_byte(start,0x90) refresh_idaview_anyway() add_hotkey("alt-N",nopIt) 

参考文章

CTF逆向Reverse 花指令介绍 and NSSCTF靶场入门题目复现_ctf 花指令-CSDN博客

【逆向学习】花指令的去除_去除花指令-CSDN博客

VMP常见花指令学习笔记1 – 哔哩哔哩 (bilibili.com)

逆向分析基础 — 花指令实现及清除_jmp花指令逆向-CSDN博客

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/122964.html

(0)
上一篇 2025-10-12 18:00
下一篇 2025-10-12 18:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信