Reserve系列题目浅析(一)

0x00 花指令(Junk code)的介绍

  所谓花指令,人如其名,它就是一些混淆人们视线的指令,一般就是混在正常指令,正常运行时是永远不会运行到的代码块,但是当你去反汇编它是,因为反编译器不会是判断,会导致反编译出来的代码永远不正确,进而使得反汇编过程不能够如期进行。
例如如下的程序中:

#include <iostream.h>
#include <windows.h>
void main()
{
    _asm
    {
            jmp l2
        _EMIT 0x1//这里就是花指令
        _EMIT 0x2//这里就是花指令
        _EMIT 0x3//这里就是花指令
        _EMIT 0x4//这里就是花指令
l2:
        mov eax,0x11111111
    }
}


  反编译器在反编译的时候不会像我们人一样去理解jmp和l2之间的指令是永远不会执行到的,所以在反编译的时候就把这段乱七八糟的代码作为正常的指令了,而这样的反编译会影响mov eax,0x11111111这个指令的正确识别,所以导致在OD中以上代码不会正确显示。

0x01 花指令的设置

  设置花指令有两种方式,一是使用jmp指令,另外一个就是使用call指令配合ret指令。

  使用jmp指令的方法不用多说了,上面的示例程序就是能很好地说明了,这里就着重介绍一下第二种方法。因为call指令相当于是两个指令,先将自身所在位置的下一条指令的地址压入栈中,然后再跳转到call函数执行的地方,而ret则是跳转到已经压入堆栈的地址,使之往下运行。这样的话就能使用这两条指令组合来完成jmp指令的目的。

  下面介绍一下具体的加花指令的流程:

  (1) 先是call一个地址,然后在里面写一些无用的垃圾汇编代码,但是要记得所写的代码的字节数;

  (2) 再者就是在call里面的一些设置,先是pop出压入的地址,把这个地址减去刚刚代码字节数再push进堆栈里然后就是ret就好了
还有推荐一篇尝试自己手动加花指令的文章,可以去看看,链接如下:
      http://www.pediy.com/kssd/pediy09/pediy09-324.htm

0x02 如何去除花指令

  既然都知道花指令的原理了,那当然需要知道如何才能去除他咯,毕竟我们要不仅要能够运行一个程序,还要去reserve它。

  去除花指令也有两种方式,一种是手动的去除,另一种是使用工具。手动肯定是费时费力的活,但是感觉还是有必要去学习的,毕竟不是什么地方都有工具来供我们使用的。而手动去除花指令的方法也是多种多样,这里就分享一个别人的小技巧:当发现jmp或者call的地址在OD中没显示的话,就把jmp或者call指令的下一个指令nop掉吧,肯定是花指令,如果还没有显示的话就继续nop下一条,直到显示的指令和执行的指令一致。然后使用工具的话,就是对应的一些插件,使用就不多说了。

0x03 实力搞一波事情(其实是看了别人的writeup)

  下面就来用事实说话。
首先是测试程序,然后侦壳,使用peid和die都没发现,但是却在使用OD调试时发现还是有壳的,看人家的writeup上用的一个ExeinfoPe的软件能查出壳,但是也看不出是什么壳。既然知道有壳,就脱吧,这并不是什么难的壳,简单的单步跟踪或者堆栈平衡都行,找到OEP使用OllyDump脱了就好。

  下面就是花指令的事了,使用ODA查看了发现有好多处,如下:

  然后先定位到判断函数然后对相关函数去花,先是在MessageBoxW处下断,但是并没有在这里断下。再是就是CreatThread,下断,输入伪码回车,断在这了。在0x4044FF下断跟进线程函数sub_4044FF,发现只是call了一个函数,地址是0x403894,跟进发现花指令,这里的大概分为两种:

  (1)这里使用了CLC指令之后,用JNB指令跳转到0x4038A8,所以在0x4038A7处nop掉即可。这是第一种花指令,使用的较多。


  (2)这种是在函数4038D8里(下一行)对esp进行重新计算,并通过RETN返回真确的地址。如上,返回的正确地址为4038DCE。所以只需将4038DD处改为0x90(nop)即可。这一片去完就能看到sub_403894函数了。

  上面就是去除花指令的过程,下面的就是简单地一个算法,经过分析得到flag是:codebywidesoft。