花指令的模式识别以及处理

前言:

花指令的出现主要是防止软件被反编译,加大逆向分析的难度,在一些代码中插入一些脏字节

为啥我要写呢,因为面试的时候也碰到了,虽然我都答出来了,但是特意过来记个笔记2333

一.花指令的分类

1. 可执行的花指令

之前在西电的ctf上,就碰到一题,只是为了混淆视听而已,实际上根本不会执行,

加大你静态分析的难度,那题是在源码级上搞,还有那种在汇编级上push一下

,再pop一下,这种看似没什么用的操作同理

2. 不可执行的花指令

这里要总结几种汇编层面上的花指令模式,很大程度是因为ida无法联系上下文233

1.jx+jnx

这个就不用多说了吧,很常见的一种花指令了,这里jnz实际上是fake的,因为jz这个指令,让ida

认为jz下面的是另外一个分支,所以这里去除,就是将jnz下面包括jnz 全c了,然后把loc_402669+1

的字节码全给nop了,f5就管用了

2. call pop / add esp

 

 这里call指令,其实本质就是jmp&push 下一条指令的地址,但是这里其实就是一个jmp指令

所以 push这条指令是多余的,需要add esp,4 调整堆栈,但是ida会默认把call 后面的那个地址

当成一个函数。

3. stx/jx

 

clc是清除EFlags寄存器的carry位的标志,而jnb是根据cf==0时跳转的,然而jnb这个分支指令,ida

又将后面的部分认作成了另外的分支,interesting。

4.jmp xxx红色

 

 

这也是一种非常常见的花指令的,其实这里很明显就有问题,因为虚拟地址怎么可能有那么大对吧,

我们来看一下花指令源代码,

 

 实际是e9在搞鬼,ida会默认将e9后面的4个字节当成地址,只要nop掉就好了

5. 多重跳转的

 

 这里也是,仔细分析下逻辑发现其实这一大段根本没用,就离谱,单纯恶心反编译器的,我们可以使用idapython

来进行去花,而且当花指令很多的时候,idapython的自动化会很有用

二.利用idapython去除第5点花指令

def nop(addr,endaddr):
    while(addr<endaddr):
        PatchByte(addr,0x90)
        addr+=1
def undefine(addr,endaddr):
    while addr<endaddr:
        MakeUnkn(addr,0)
        addr+=1
def dejunkcode(addr,endaddr):
    while addr<endaddr:
        MakeCode(addr)
        # 匹配模版
        if GetMnem(addr)=='jmp' and GetOperandValue(addr,0)==addr+5 and Byte(addr+2)==0x12:
            next=addr+10
            nop(addr,next)
            addr=next
            continue
        addr+=ItemSize(addr)
            

里面使用到的ida函数解析

MakeCode(ea) #分析代码区,相当于ida快捷键C
ItemSize(ea) #获取指令或数据长度
GetMnem(ea) #得到addr地址的操作码
GetOperandValue(ea,n) #返回指令的操作数的被解析过的值
PatchByte(ea, value) #修改程序字节
Byte(ea) #将地址解释为Byte
MakeUnkn(ea,0) #MakeCode的反过程,相当于ida快捷键U
MakeFunction(ea,end) #将有begin到end的指令转换成一个函数。如果end被指定为BADADDR(-1),IDA会尝试通过定位函数的返回指令,来自动确定该函数的结束地址

idapython的参考api链接:

https://www.bbsmax.com/A/x9J27Lgg56/

 

posted @ 2020-12-14 22:12  YenKoc  阅读(1930)  评论(0编辑  收藏  举报