美文网首页
esp脱壳+文件大小自校验

esp脱壳+文件大小自校验

作者: 看点书 | 来源:发表于2018-05-24 20:02 被阅读0次

    步骤如下

    1.查壳
    由图可见,显然有壳

    image

    2.找oep(ESP定律)

    程序加载进OD,F8单步运行,右边寄存器窗口发现只有esp的值在变,符合ESP定律。
    在寄存器位置右键,点击HW-break下硬件断点。然后F9运行到断点处,到达跳转到oep 的前一步,单步运行,遇到如下图:右键分析点击在模块中删除分析,即得到OEP.在oep处右键用ollydump脱壳当前进程。复制当前oep.

    image
    image

    3.脱壳(LordPE)

    在lordPE中打开样本程序,选中右键纠正镜像大小,再右键完全脱壳。


    image

    4.修复导入表(ImportREC)

    在ImportREC中打开目标进程即样本进程,然后右边选项中输入之前在OD中选中的OEP,点击IAT自动搜索,然后点击获取导入表。

    image

    5.文件大小自检

    脱壳以后双击没得反应,可能是有文件大小自检校验,脱壳后的程序载入OD,在GetFileSize函数下断点,在插件中选API断点设置工具->常用API断点。选中文件类的GetFileSize.然后F9运行程序,到断点处停下,在堆栈中右键反汇编跟随,找到调用这个函数的位置,然后下断点,把刚刚的那个断点删除。在断点后发现是几个cmp ,很明显是比较文件大小,故而把这两个cmp右键二进制->用nop填充。然后复制到可执行文件,保存文件。再次点击程序,发现正常运行。


    image image image

    **
    注:esp 定律**

    ESP定律算是我们在脱壳当中最常使用的方法之一,也特别适合像我一样的新手!而今天文章说的是ESP脱壳的原理和分析!只有知道原理了,我们的技术才能走得列远!

    一.准备知识
    在我们开始讨论ESP定律之前,说些简单的汇编知识。

    1.call

    这个命令是访问子程序的一个汇编基本指令。也许你说,这个我早就知道了!别急请继续看完。call真正的意义是什么呢?我们可以这样来理解:

    1.向堆栈中压入下一行程序的地址;
    2.JMP到call的子程序地址处。

    例如:

    代码:

    00401029.E8 DA240A00 call 004A3508
    0040102E.5A pop edx

    在执行了00401029以后,程序会将0040102E压入堆栈,然后JMP到004A3508地址处!

    2.RETN

    与call对应的就是RETN了。对于RETN我们可以这样来理解:

    1.将当前的ESP中指向的地址出栈;

    2.JMP到这个地址。

    这个就完成了一次调用子程序的过程。在这里关键的地方是:如果我们要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在RETN这条指令之前,ESP指向的是我们压入栈中的地址。这也就是著名的“堆栈平衡”原理!

    3.狭义ESP定律

    ESP定律的原理就是“堆栈平衡”原理。

    让我们来到程序的入口处看看吧!

    1.这个是加了ASPACK壳的入口时各个寄存器的值!

    代码:

    EAX 00000000

    ECX 0012FFB0

    EDX 7FFE0304 //堆栈值

    EBX 7FFDF000 //堆栈值

    ESP 0012FFC4

    EBP 0012FFF0

    ESI 77F57D70 ntdll.77F57D70

    EDI 77F944A8 ntdll.77F944A8

    EIP 0040D000 ASPACK.<ModuleEntryPoint>

    2.这个是ASPACK壳JMP到OEP后的寄存器的值!

    代码:

    EAX 004010CC ASPACK.004010CC

    ECX 0012FFB0

    EDX 7FFE0304 //堆栈值

    EBX 7FFDF000 //堆栈值

    ESP 0012FFC4

    EBP 0012FFF0

    ESI 77F57D70 ntdll.77F57D70

    EDI 77F944A8 ntdll.77F944A8

    EIP 004010CC ASPACK.004010CC

    呵呵~是不是除了EIP不同以外,eax保存当前OEP值,其他都一模一样啊!

    为什么会这样呢?我们来看看

    0040D000 A> 60 pushad //注意这里ESP=0012FFC4

    0040D001 E8 00000000 call ASPACK.0040D006 //ESP=0012FFA4

    PUSHAD就是把所有寄存器压栈!我们在到壳的最后看看:

    代码:

    0040D558 61 popad //ESP=0012FFA4

    0040D559 75 08 jnz short ASPACK.0040D563 //注意这里ESP=0012FFC4

    也就是说当我们对ESP的0012FFA4下硬件访问断点之后。当程序要通过堆栈访问这些值,从而恢复原来寄存器的值,准备跳向苦苦寻觅的OEP的时候,OD帮助我们中断下来。

    小结:我们可以把壳假设为一个子程序,当壳把代码解压前和解压后,他必须要做的是遵循堆栈平衡的原理。

    因为大家对ESP理解各有异同,但是,大同小异!一般理解可以为:

    1、在命令行下断hr esp-4(此时的ESP就是OD载入后当前显示的值)

    2、hr ESP(关键标志下一行代码所指示的ESP值(单步通过))

    相关文章

      网友评论

          本文标题:esp脱壳+文件大小自校验

          本文链接:https://www.haomeiwen.com/subject/pjqejftx.html