简单学习花指令

花指令(junk code)是一种专门用来迷惑反编译器的指令片段,这些指令片段不会影响程序的原有功能,但会使得反汇编器的结果出现偏差,从而使破解者分析失败。比较经典的花指令技巧有利用 jmp 、call、ret 指令改变执行流,从而使得反汇编器解析出与运行时不相符的错误代码。

花指令用于加大静态分析的难度,破坏反编译的分析,造成异常。

分类:

可执行花指令:会被执行,但是没有任何意义的代码,执行前后不会改变寄存器的值,同时会被反汇编器识别。

不可执行花指令:不会运行,但是会使反汇编得到一些错误代码

常见花指令

jmp(E9)花指令:这是一类跳转花指令

这类花指令往往会实现永真或永假总之一定会跳转的情况,实现垃圾代码不运行。

先将0x00401D92转化为数据

然后将0x00401D94处的数据转换成代码,再把0x00401D92,0x00401D93处的数据nop掉即可

E9是jmp指令对应的机器码,当反汇编器读取到E9时,接着会往下读取四个字节的数据作为跳转地址的偏移,所以才会看到错误的汇编代码。即把cmp该条指令代码错误识别为数据。

该花指令编写方式

__asm { 
    _emit 075h    #jmp $+4//075h是jnz的机器码
        _emit 2h
        _emit 0E9h
        _emit 0EDh
    }

这段汇编再具体分析的话就是,075h 2h这两个字节码导致跳转到075h偏移4的位置,这一步是为了绕过我们编写的垃圾代码0E9和0ED,但是线性分析就会导致0E9被反编译成正常指令引发不正常,实际运行上0E9根本没有运行。

在此基础上,为了更好的混淆,常采用多层跳转。

MP Label1
  Db thunkcode1
Label1:
  ……
  JMP Label2
  Db thunkcode2
Label2:
  ……
JMP Label1
  Db thunkcode1
Label2:
  ……
  JMP Label3
  Db thunkcode3
Label1:
  …….
  JMP Label2
  Db thunkcode2
Label3:

call&ret构造花指令

__asm {
         call LABEL9;
         _emit 0x83;
     LABEL9:
         add dword ptr ss : [esp] , 8;
         ret;
         __emit 0xF3;
     }

代码中的esp存储的就是函数返回地址,对[esp]+8,就是函数的返回地址+8,正好盖过代码中的函数指令和垃圾数据。这个和上面的jmp差不多。

自定义花指令

_asm
    {
        call LABEL9;
        _emit 0xE8;
        _emit 0x01;
        _emit 0x00;
        _emit 0x00;
        _emit 0x00;
​
     LABEL9:
        push eax;
        push ebx;
        lea  eax, dword ptr ds : [ebp - 0x0];
        #将ebp的地址存放于eax        
​
        add dword ptr ss : [eax-0x50] , 26;
        #该地址存放的值正好是函数返回值,
        #不过该地址并不固定,根据调试所得。
         #加26正好可以跳到下面的mov指令,该值也是调试计算所得
​
        pop eax;
        pop ebx;
        pop eax;
        jmp eax;
        _emit 0xE8;
        _emit 0x03;
        _emit 0x00;
        _emit 0x00;
        _emit 0x00;
        mov eax,dword ptr ss:[esp-8];
        #将原本的eax值返回eax寄存器
    }

IDC脚本去花示例

#include <idc.idc>
static main() 
{
    auto x,FBin,ProcRange;
    FBin = "E8 0A 00 00 00 E8 EB 0C 00 00 E8 F6 FF FF FF";
    //目标 = "E8 0A tel:00 00 00 90 EB 0C tel:90 90 90 90 90 90 90";
    //花指令1的特征码
    for (x = FindBinary(MinEA(),0x03,FBin);x != BADADDR;x = FindBinary(x,0x03,FBin))
    {
            x=x+5; //返回的x是第一个E8的地址,
                  //加上5是第二个E8的地址
            PatchByte (x,0x90);//nop掉
            x = x + 3; //00
            PatchByte (x,0x90);
            x++;  //00 E8
            PatchWord (x,0x9090);
            x =x + 2 ; //F6 FF FF FF
            PatchDword(x,0x90909090);
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值