zoukankan      html  css  js  c++  java
  • 第19章:寻找UPack OEP

    PE头在进程装载的时候使用格式比较固定,从中找到需要的信息后不必过多关注,只需要找到还原后的节区体即可。

    从文件中的EntryPoint找到进程入口:

    占用不需要的元素,其在节区如下区域中插入代码:

    蓝色框中是可选头所占区域,其余的到16F多余的区域

    这条命令将ESI所指的区域中的27个Dword大小的数据移动到EDI所指的地址中(即F0~16F),即将解码代码释放出来,以供后面执行:

    红色框中是第一个节区头部分数据(前五个Dword元素),前面是利用SizeOfOptionalHeader增加出来的区域。

    而EDI所指的地方恰好是PE文件的最后部分,并且这个区域是第二节区所处的位置:

    下一条指令将两个Word元素(NumberOfRelocations/LineNumbers)压入栈。

    然后用400H填充后面1C00个Dword,一直填充到1026DC处(已经快把第二节区[102700]填充满了)。

    后面的解码中,首先会反复使用一个函数,大概会看到两种解码方式:

    1.对几个变量进行计算,通过adc指令,在循环体中通过对AX寄存器进行反复的计算,得到值,写入EDI寄存器中。

    2.通过rep movsb 指令,对一块区域进行解码。

    这一区域的代码是两种解码方式最开始都会用到的,通过对函数返回的Flag值进行判断,从而选择了解码方式。

    首先看看Decryption()函数,参数通过EDX传入:

    首先需要明确一点 EBX 在程序的运行过程是一个固定的值,不会改变,即:0101FEC4

    [EBX] , [EBX-4] , [EBX+4],这三个变量(分别命名为A,B,C)与解码密切相关。

    1.将变量 A 与传入的变量EDX相乘,然后除以1000H,放在EAX中。

    2.由变量 B (地址,即指针) 寻址找到数据,进行字节转置。

    3. [B] - C 的值与变量 A 进行对比

    (1)若小于 A则不跳转 , A = EAX,[EDX] += (800 - [EDX]) / 20H) , 通常[EDX] <= 400H 。

    (2)跳转后:C += EAX , B -= EAX , [EDX] -=  [EDX] / 20H .然后置CF位为1。

    4.对比AL寄存器是否为0,若为0,则 B++, C /= 3000H , A /= 3000H 。

    执行返回。

    总结一下这个函数的功能:通过对几个变量的计算,解密出值写入内存,并设置了CF位,后面会用到。

    先看第一种解码方式,即不跳转的方式,代表没有置CF位为1,前面计算出来的值小于变量A

     对EAX寄存器进行一系列的操作,如果ECX != 0 就进入循环,通过adc 指令,实现解码:

    将AL寄存器写入EDI中,EDI会从第二节区0101Fxxx开始一直写到节区后面[ESI+34]即1014B5A为止。

    当然有时候也会写前面的数据。

    第二种解码方式是在第一个地方跳转:

    这当中有一个执行了Decryption()函数,且执行了stc指令都会跳转。

    若执行到最后的jmp,则会最后跳转,然后将EAX中的值写入[EDI]:

    若没有执行jmp就跳转了则他们经过一系列对EAX的计算,最后都会到:

    逐渐填充:

    重建IAT

    出循环后会进入第一个循环,从01001000H开始比较,一字节一字节的寻找,直到 [EDI] + 18 == 00  or  x1.

    第二个循环继续寻找,直到 [EDI] + 18 ==  x1. 第三个循环是循环132次。

    总结一下:一共循环133次,每次都要满足  [EDI] + 18 ==  x1 。

    然后从栈中获取LoadLibrary() 以及 GetProcAddress()的地址,然后先调用LoadLibrary() ,将需要的库载入。

    然后通过GetProcAddress()函数依次将获得到的函数地址写入EDI所指向的地址。

    ret 返回时就到了正常notepad程序入口。

    这篇文章写的杂乱没有头绪,是因为没有真正懂得它的解压缩算法是怎么执行的,只是看出了一个大概的流程。

  • 相关阅读:
    Oracle中查询表中数据的上次更新时间
    数据库分区 分库 分表 分片(转)
    beanFactory和factoryBean的区别(转)
    TCP三次握手形象理解
    深拷贝,浅拷贝(转)
    真的要去做
    '庞然大物'是怎么来的?为何有的技术明明看了很多遍依然不能很好的理解
    java6大原则之单一职责原则,里式替换原则
    状态不好记录一下
    java继承,多态
  • 原文地址:https://www.cnblogs.com/Rev-omi/p/13326320.html
Copyright © 2011-2022 走看看