zoukankan      html  css  js  c++  java
  • PESpin加密壳分析

    转载自https://www.cnblogs.com/KIDofot/p/8641385.html

    KIDofot大神

    手工脱壳之 PESpin加密壳【SHE链硬件反调试】【IAT重定向】【混淆+花指令】

    阅读目录(Content)

    回到顶部

    一、工具及壳介绍

    使用工具:Ollydbg,PEID,ImportREC,LoadPE,IDA,Universal Import Fixer,OllySubScript

    此篇是加密壳的第二篇,更详细的步骤和思考,请查看第一篇:手工脱壳之 未知加密壳 【IAT加密+混淆+花指令】

    PESpin壳:

    回到顶部

    二、脱壳之寻找OEP

    1、硬件断点失效

    尝试ESP定律,但硬件断点未断下。

    (原因其实是壳做了反调试,后面部分介绍)

    2、采用API断点+单步跟踪

    API下断:

    壳导入了LoadLibrary 和 GetProAddress,可以从API下手。

    按照经验来说,跟踪GDI32.dll的基地址。因为其它DLL,如kernel32.dll取出的函数,壳有可能用于自己的代码而非修复IAT。

    跟踪GDI32的基地址。多观察寄存器窗口堆栈窗口

    DLL导出表:

    DLL INT:

    DLL IAT:

    DLL 序号表:

    通过RVA取得函数名:

    跟踪字符串,接下来可能有字符串循环。

    函数名 首个字节跟0x53比。0x53 == ' S '。

    而且每次的值都不一样。可见是取对应字母开头的函数名。

    查看首个H开头的函数名,下条件断点。

    字符串在减少,疑似于计算哈希值,

    预判:根据上一篇加密壳的经验,这样的循环可能跟哈希加密,IAT加密有关。

    预操作:记录从DLL IAT取出函数地址的 指令地址 和 存放进exe IAT 指令的地址。

    3、确定目标

    确定循环的判断临界点,跳出循环,跟踪最后的结果。

    3.1、API Address

    目标1:寻取出DLL IAT的函数地址。

    字符串循环条件临界点:

    跳出循环,疑似哈希值。

    交换寄存器。

    的确是进行哈希值比较。

    在条件成立的下一条指令下断点。

    跟踪哈希值,得到取函数地址的指令地址

    取DLL IAT函数地址的指令地址 :

    记录下一条指令地址:0x438F9F

    3.2、Put EXE IAT

    目标2:寻 把DLL IAT函数地址 存放进 exe IAT 的指令地址。

    此处还不知道exe IAT的位置,所以只能跟踪函数地址EAX了。

    多观察带方括号 MOV [xxx], xxx 之类的指令。

    代码中做了大量的混淆和花指令,如下,纯粹无意义的指令,干扰分析。

    (混淆和花指令具体见后面部分)

    记录PESpin壳特征:

    【跳过0043933E循环到00439340】

    0043933E 73 F6 JNB SHORT 06.00439336 00439340 8A47 FF MOV AL,BYTE PTR DS:[EDI-0x1]

    记录壳的一些操作:

    取API函数前部分字节,并判断。

    对取出的字节 做一些操作。

    最终拷贝进指定地址,数据窗口跟随反汇编看出点端倪。

    推测壳是在 IAT引用真正API调用 之间增加代码屏障,还是带混淆的屏障。

    这样做顺便可以对IAT进行加密,阻止ImportREC解析。

    3.3、IAT加密

    流程:偷取函数前部分字节,申请空间,制造混淆代码块。

    CALL(IAT引用) ->> 内存代码(混淆) -->> API

    以下跟踪证明推测正确:

    再逐步取出字节。

    构造混淆,IAT引用CALL进来就是这个样子。

    【00439079要实现】

    跳到0043910F.0043910F的地方被花指令挡住了,所以在00439109按1.

    00439079 0F84 90000000 JE 06.0043910F

    1564839729869

    观察内存空间首地址0x200000。推测可能准备填入exe IAT。

    因为混淆和花指令,很多仔细分析都会做无用功,不知哪条真那条假。所以要确定目标,定点分析。

    存进IAT指令:

    存进exe IAT 指令的地址:

    记录下一条指令地址:0x43918C

    3.4、IAT重定向

    现在,存在IAT的位置的是 申请出来的内存地址,内存的地址 –>> API的地址。

    查看数据窗口,仔细一看你会发现,IAT被重定向了

    API的地址用0隔开,这明显不是IAT结构,是壳自己建立的IAT,ImportREC无法解析。

    3.5、IAT重定向解决方案:
    1. 用OD脚本修复内存地址为真正API地址

    2. 用Universal Import Fixer重建IAT

    3. 接着用ImportREC重建导入表。

    3.6、OEP

    接下来就是跳出修复IAT的循环,找到OEP了。

    多注意 比较指令 和 远跳。

    找OEP的过程,感觉就是在"花"海里遨游~~.....

    跨区段远跳,一般是跳到OEP。

    OEP:

    记录OEP地址:0x409486

    3.7、记录分支

    查看调用模块:

    IAT引用,有些加密,有些未加密。

    可见在壳修复IAT时,有些函数地址并没有做相关加密处理,直接放回去了。

    这就意味着在存进exe IAT 的循环中,多了一条分支,这像是有意扰乱分析者的脚步。

    找一块地址密集的地方,在首部,下硬件断点,跟踪分析出分支位置。

    此处存进exe IAT的指令地址跟上一处的不同,地址正好可以做为分支的条件判断。

    记录分支指令:

    跳过call下一条指令地址: 0x439101

    回到顶部

    四、快速定位OEP

    特征码搜索:

    在壳解密TEXT段后,可以按各个版本的编译器的OEP特征码,进行逐个搜索。

    如:

    VC++的OEP特征码:

    55 8B EC 6A FF

    如果做了OEP特征偷取,可以针对某一条OEP相关指令,对内存进行暴力搜索。

    回到顶部

    五、 SEH异常链反调试

    壳操作:利用SEH异常链清理硬件断点,进行反调试。

    很多情况下,要么就硬件断点断不下,要么就断下的位置不正确。

    怀疑硬件断点被清除了。

    按经验,首先推测在异常处理里进行反调试。

    OD取消忽略异常。

    Shift+F9 忽略异常运行,总共触发9处异常,列出首几处。

    第三处第四处断在了同一个地方,但异常处理函数不同。

    方案:通过在后方异常点 设置硬件断点,来判断前方异常点的异常处理 是否做了反调试。

    逐个排查,确定是第3个异常点,清理了硬件断点。

    查看异常处理函数,可以在反调试函数前下硬件执行断点。

    这里为了进行更好的分析,在此处Dump下来,采用IDA分析。

    的确是对Dr1、2、3、4清理为零了,并且对Dr6、7进行了操作。

    反反调试:编写OD脚本时,下硬件断点在此函数,并去掉反调试指令。

    记录地址:0x43AF59,NOP掉字节0x1A。

    回到顶部

    六、OD脚本及修复

    //清除所有硬件断点

    BPHWC

    //清除所有软件断点

    BC

    //清除所有内存断点

    BPMC

      

    //IAT地址

    VAR IATAddress

      

    //OEP断点

    BPHWS 409486,"x"

    //取IAT指令

    BPHWS 438F9F,"x"

    //存IAT指令

    BPHWS 43918C,"x"

    //硬件反调试代码

    BPHWS 43AF59,"x"

      

    _LOOP:


    RUN


    //去掉硬件反调试代码

    cmp eip,43AF59

    JNZ _Sign1

    fill 43AF59,1A,90

    //清除反调试硬件断点

    BPHWC 43AF59


    _Sign1:

      
    //取IAT判断

    CMP eip,438F9F

    JNZ _Sign2

      
    MOV IATAddress,eax

      
    _Sign2:

      

    //分支判断

    CMP eip,439101

    JNZ _Sign3

    //不作操作

    BPHWS 43AF59,"x"


    _Sign3:

      

    //存IAT的地方

    CMP eip,43918C

    JNZ _Sign4

      
    MOV [edi],IATAddress


    _Sign4:


    //OEP

    CMP eip,409486

    JNZ _LOOP

      

    MSG "到达OEP"

    OD脚本修复加密:

    使用Universal Import Fixer 重定向修复IAT表:

    从上面的壳代码的运行地址可以看出,壳的代码是运行在最后一个区段的,可以推断最后一个区段是壳的区段。

    当Dump下来的时候,最后一个区段就没用了,所以可以重定向到此区段。

    再用ODDump,ImportREC新建导入表:

    回到顶部

    七、脱壳成功

    回到顶部

    八、混淆花指令

    分析经验:

    混淆:无意义的垃圾指令,干扰分析,干扰反汇编引擎,使指令产生多种解释。

    花指令:无意义的大量跳转,干扰分析。

    花指令块:无意义跳转。

    跳转指令被截断。

    混淆让反汇编出错。

    下硬件读写断点,会难确定上一条是什么指令。

    混淆使同样意思的指令被肢解成多条。

    一个混淆和花指令结合的循环,就是上面的字符串处理循环。

    通过STC设置进位标志 和 CMC进位标志求补 控制跳转,花指令。

    个人总结:

    附件:

    PESpin加密壳

    KID

  • 相关阅读:
    WPS项目编号问题
    Allegro转换PADS终极篇(转载)
    Allegro16.3约束设置 (转载)
    转:浮点数在计算机中存储方式
    转:十进制小数转化为二进制小数
    变量的存储类别 内部函数和外部函数
    关于Nios II的启动分析(转载)
    Allegro学习(http://www.asmyword.com/forum.php?mod=forumdisplay&fid=86)
    cf1113 C. Sasha and a Bit of Relax
    D. Jongmah cf1110
  • 原文地址:https://www.cnblogs.com/ltyandy/p/11296454.html
Copyright © 2011-2022 走看看