• 花指令


    本文作者:sodme
    本文出处:http://blog.csdn.net/sodme
    声明:本文能够不经作者允许随意转载、复制、引用。但不论什么对本文的引用,均须注明本文的作者、出处以及本行声明信息。

    可能非常多人都听说过花指令,但限于平时的开发所限,可能较少接触到。日前,跟同事讨论了一些有关花指令的问题,现将自己的体会总结一下。

    这篇文章将讨论以下问题:

    一、什么是花指令?它的原理是什么?
    二、在什么地方使用花指令?怎样使用花指令?
    三、怎样识别花指令?怎样去除花指令?
    四、一些典型的花指令实例

    什么是花指令?当然不是"flower code",呵呵,实际上,把它依照“乱指令”来理解可能更贴切一些,它的真正英文名应该叫"thunkcode"吧(不确定,呵呵)。我们知道,汇编语言事实上就是机器指令的符号化,从某种程度上看,它仅仅是更easy理解一点的机器指令而已。每一条汇编语句,在汇编时,都会依据cpu特定的指令符号表将汇编指令翻译成二进制代码。而日常应用中,我们通过VC的IDE或其他如OD等反汇编、反编译软件也能够将一个二进制程序反汇编成汇编代码。机器的一般格式为:指令+数据。而反汇编的大致过程是:首先会确定指令開始的首地址,然后依据这个指令字推断是哪个汇编语句,然后再将后面的数据反汇编出来。由此,我们能够看到,在这一步的反汇编过程中存在漏洞:如果有人有益将错误的机器指令放在了错误的位置,那反汇编时,就有可能连同后面的数据一起错误地反汇编出来,这样,我们看到的就可能是一个错误的反汇编代码。这就是“花指令”,简而言之,花指令是利用了反汇编时单纯依据机器指令字来决定反汇编结果的漏洞

    先举个样例(记为A代码段):
       jz    label
       jnz  label
       db thunkcode
    label:

    以上是一个相当简单的花指令块,当中thunkcode是由应用者自己随便写的机器指令字,当然,你写的这个机器指令字不能是单字节指令(比方nop, clr,等),否则,你的花指字就相当于白加了。那么,你要怎样来使用这段代码呢?

    如果我们待加密的代码块例如以下(记为B代码段):
       mov ax, 8
       xor ax, 77
       ...

    我们如果这B代码段是我们的加密算法所在的代码段,如今我们想要对B代码段进行保护,能够直接将A花指令块加到mov指令之前,形如:
       jz    label
       jnz  label
       db thunkcode
    label:
       mov ax, 8
       xor ax, 77
       ...

    当中,对于thunkcode,在实际使用时,能够使用不论什么一个多字节指令的机器指令字来取代,这样就会欺骗反汇编软件将它连同后面的mov指令的前边某一部分反汇编成一个多字节指令。这样,我们的目的也就达到了。

    由上能够看到,使用了花指令的地方,一般都会出现这样的现象:一个跳转指令,跳转到了某条语句的中间位置,而不是这条语句的開始位置。每当出现这样的情况时,我们就能够断定,这里出现了花指令。

    显然地,破解它的办法,就是在那个跳转到的目的地址之前将中间的代码所有nop掉。

    当然,为了加强难度,我们能够将若干个花指令结合起来使用。比方:
       jz    label
       jnz  label
       db thunkcode
    label:
       jz    label2
       jnz  label2
       db thunkcode
    lable2
       mov ax, 8
       xor ax, 77
       ...

    也当然,针对这样的情况的破解仅仅要一层层解开它就可以:我们能够先破解到以label为首字节的指令出现为止,然后再依据新的结果,破解到以label2为首字节的指令出现为止,尽管这样麻烦点,但还是不难的。

    可是,如果把以下的这段代码再同其他花指令结合起来使用,可能就更复杂了:
       call    label_1 
       db        thunkcode 
       jmp        label_2 
       db        thunkcode
    label_1:   
       pop        eax 
       jmp        label_3 
       db        thunkcode,thunkcode,thunkcode
    label_3:   
       inc        eax 
       jmp      label_4 
       db        thunkcode,thunkcode,thunkcode
    label_4:   
       jmp        eax 
       db        thunkcode
    label_2:   
       ....


    这里另一段:
       call label_1
       db  thunkcode,thunkcode
       jmp  label_4
    label_1: 
       pop  eax
       jmp  label_2
       db  thunkcode,thunkcode
    label_2: 
       add  eax,2
       jmp  label_3
       db  thunkcode
    label_3: 
       push eax
       ret
       db  thunkcode
    label_4: ....
     
    为了加强难度,尽可能地用call和push实现间接跳转,当然,矛矛盾盾,仅仅是时间长点而已,世上没有绝对安全的系统。
    <以上代码来源于看雪的"软件加密技术内幕"一书>
  • 相关阅读:
    基于fpga uart学习笔记
    sublime text3 verilog代码编写高级操作篇
    做一个高尚的fpga调参侠
    彩色MT9V034摄像头 Bayer转rgb FPGA实现
    最新 Xilinx vivado IP许可申请
    基于fpga的256m的SDRAM控制器
    如何调用数据链接属性的对话框
    ASP.NET中动态生成验证码的一则方法
    为什么IIS的应用池回收设置默认为1740分钟
    使用SmtpClient发送邮件
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3823278.html
Copyright © 2020-2023  润新知