逆向分析之花指令2

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">一、概述</span>

“jmp/call/ret+垃圾数据”这样的花指令已经是相当“老掉牙”了,OD的插件对付它们基本是“秒杀”,所以本文想说点“有点创意”的花指令,至少能对付OD的插件。

 

二、创意的核心

[2.1]花指令因何被发现

“jmp/call/ret+垃圾数据”的方法之所以容易被检测,原因是“意图太明显”,具体说任何一种检测手段,都是基于以下两点:

①检测跳转结构的固定形态特征,当然这不是绝对的,如果检测机制没能预见到这种形态特征,此点可以忽略,本文后边会提到一些这样的情况。

 

②用可靠的方法直接证明,垃圾数据部分在任何情况下都不会被执行。应该说该点是对“不可执行花指令”的无敌检测手段,然而却难在“可靠”二字上,目前已知的实践,只是做到“可供参考”的程度。

[2.2]创意的策略

通过[2.1]的分析,我们知道要想编写“有创意的花指令”,火力应集中在①上,因此我们通过以下策略对抗:

①      采用新的固定结构,许多插件还没有检测,比如下文提到的xor-cmp的结构。

②      采用“伪条件跳转”替代“强制跳转”

 

三、一步一步学创意

[3.1]一次幼稚的实践——互补条件跳转

首先,我们来尝试一种用“伪条件跳转”替代“强制跳转”的方法,称作“互补条件跳转法”,即用两个互补的条件跳转指令替代一个强制跳转指令。比如,用jz和jnz跳转到同一地址,和一个jmp是等价的。

举例:

……

  Jz Label

  Jnz Label

  Db thunkcode;垃圾数据

Label:

  ……

除了jz和jnz,还有许多互补跳转指令,如表1。

    经过测试,只有一少部分OD插件没能识别这类花指令,究其原因还是这种方法形态太过固定,一旦形态特征广为人知,检测就相当容易。

[3.2]上面方法的改进版——用随机值获得确定性标志位

上面的方面采用两个互补的条件跳转还是明显,连普通程序都不会使用。所以,我们应该试图只用一个条件跳转。具体方法是这样的:

通过某些隐蔽的手法,使得某个标志位有确定性的值,然后利用这个确定值,进行确定性条件跳转。比如下面的手法

Xor reg,value1

Cmp reg,value1

Jnz Label

Db thunkcode

Label:

  ……

该手法的优点是,无论value为何值,经过了xor reg,value1和cmp reg,value这两句指令,,ZF位一定不会置位,所以jnz一定跳转。该方法有相当多的变体,该方法的核心是使用随机值,使得某标志位有确定性值。

经过测试,OD的大部分插件都不能检测,这类花指令变种较多,插件编写容易遗漏或者未预见到某些形态,但是这种方法的形态特征还是相对固定的,只是某些还未广泛熟知,但随着时间推移,该方法的效力会越来越弱。

[3.3]利用API返回确定值

大部分API函数的返回值是不确定的,只要有方法使得API返回确定值,那么后面接续的条件跳转,就是等价的。比如说CreateFile返回文件句柄,句柄可能是任意值且有不确定性,然而我们可以使得函数CreateFile返回值是确定的。

1)            令CreateFile返回错误码,比如故意向CreateFile传入错误参数,还可以使用类似inc esp,使得堆栈不4字节对齐,即使传入正确参数,也会返回错误码。

2)            由于句柄值实际上是句柄表索引,所以CreatFile返回的正确句柄值都是4的倍数,我们把句柄值取4的模,得0是一定的。

类似的方法可以说是数不胜数,所以OD的插件想通过检测固定形态的方法,是无法穷举的。所以实际检测结果我不必说了吧。

四.如何去除花指令

对于花指令的去除方法,最好的方式就是通过自己来识别把垃圾的指令NOP掉,例如下面这个程序,首先我们浏览的时候可能会出现这种情况。


需要从分析中选择从模块中删除分析 ,就会出现汇编引擎分析的汇编代码


从上面的代码中可以看到反编译出来的汇编代码很奇怪,而且在F8单步运行的时候,会出现代码变化的情况,这只能说明在程序执行的时候是按照正常的指令来执行,但是在静态分析的时候,由于垃圾的指令的干扰,会出现莫名其妙的指令。根据前面对常用花指令的了解,机器码0xE8会解析为call指令,0xE9会解析为jmp指令等。从以上汇编可以看出,此程序利用的垃圾指令方式,是

<span style="font-size:14px;">push ecx
push edx
push ebx
xor ebx,ebx
je short 地址
db E8h
pop ebx
pop edx
pop ecx</span>
其实以上做的无意义的动作,但是这里解析的时候就没有把数据与指令区分开,导致解析出错误的指令。这里当我们把0xE9改成0x90也就是nop掉之后,可以看到正常的指令了。



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值