zoukankan      html  css  js  c++  java
  • pediy未知加密壳分析

    转载https://www.cnblogs.com/KIDofot/p/8641380.html#_labelTop

    KIDofot大神

    手工脱壳之 未知IAT加密壳 【IAT加密+混淆+花指令】【哈希加密】【OD脚本】

    阅读目录(Content)

    一、工具及壳介绍

    使用工具:Ollydbg,PEID,ImportREC,LoadPE,OllySubScript

    未知IAT加密壳:

    回到顶部

    二、初步脱壳

    尝试用ESP定律。

    疑似OEP,VC6.0特征

    进第一个CALL查看

    确认是OEP。

    OEP地址 = 47148b,RVA = 7148b

    导入表函数信息出了问题。

    查看IAT引用。

    IAT表被加密。所以ImproREC才检测失败。

    回到顶部

    三、解析IAT加密方式

    先API方面考虑。

    壳修复exe IAT时,需要调用相关API,用LoadPE查看壳的导入表信息。

    可见,推测,LoadLibrary 和 GetProAddress 是 隐藏调用 或 自我实现的。

    采取硬件断点的方式:

    在被加密的IAT表的最顶端,下硬件断点。

    首次断下,执行代码是在内存地址上,说明壳是在自己申请的内存上执行代码的。

    回溯分析函数。

    进一步分析,确认是memcoy

    查看memcoy参数,数据窗口跟随,发现是壳首次调用解密TEXT段

    改换在memcpy下断点,第二次断下。

    第二次断下,是往IAT填RVA。

    接下来断下的每一次,是往IAT填内存地址,内存地址数据窗口跟随。

    IAT引用的顺序是这样的:

    CALL à 壳的内存代码 à 真正的API

    所以壳是在中间加了一层内存代码,并且内存代码里包含混淆花指令。

    回到顶部

    三、锁定IAT加密点

    在memcpy进RVA后,依旧在IAT首部下硬件断点。

    得知壳进行内存的操作后,顺便在API下断,VirtualAlloc

    记录一下,一共申请了三次内存。

    在硬件断点断下的地方。

    由于汇编中掺杂着混淆和花指令,(具体见最后部分)。

    确定目标:在壳修复IAT过程,寻 取出的函数地址 和 475000(往IAT填的内存地址)。

    操作:多观察寄存器窗口 和 堆栈窗口

    在当前指令下硬件断点,并开始单步步入(混淆代码的CALL F8会跑飞)

    记录异样:

    DLL基地址

    查看地址,是遍历时的RVA

    出现字符串,并在代码循环中逐步减少,疑似DLL INT取得的函数名。

    查看地址,确认是。

    按经验,在壳中,比较函数名的汇编代码有两种规律:

    壳调用比较函数:在字符串完整或全没时,跟踪到返回指令,回溯分析函数和函数周围的函数调用。

    壳采用比较循环:纯代码循环比较字符串。找到字符串比较条件的临界点,一般下一条是条件跳转指令,跳出循环。

    由于代码是混淆过的,跳来跳出乱跳,很明显是属于比较循环。

    比较字符串,如果采用rep的方式的话,结果一般会设置标志位跳转,再返回布尔值。

    上面是TEST AL, AL,判断字符串是否结尾。壳可能进行长度记录,或是对整个字符串进行了特殊操作。

    当比较结束时,跟踪结果,寻找函数地址 。

    发现壳是对函数名进行哈希加密,并拿哈希值与 要寻函数的哈希值比较,来锁定函数。

    下条件断点,当匹配正确后,下一步应该就是从DLL IAT取函数地址了

    取出的函数地址:。

    为后面OD脚本做准备:

    跳过CALL,需在下一条指令下硬件断点:

    记录下一条指令地址:0x002E08D5,RVA = 08D5

    接下来找 把函数地址放进exe IAT的指令,观察475000开始的地址。

    中间经过memcpy,应该是把内存代码往刚申请的内存上填,然后把内存地址赋给IAT。

    寻到IAT的地址:

    然后就是把内存地址IAT地址上填了

    为后面OD脚本做准备:

    跳过CALL,需在下一条指令下硬件断点:

    记录下一条指令地址:0x2E1A36,RVA =1A36

    由于壳代码是在申请出来的内存上执行的,需要确定内存基址,就需要确定申请内存的指令。

    寻到申请内存的指令:

    为后面OD脚本做准备:

    记录下一条指令地址:0x47A381。

    回到顶部

    四、OD脚本

    前面的准备材料:

    OEP 地址 = 0x47148b

    得到申请内存地址:0x47A381

    取IAT指令地址RVA:08D5

    存IAT指令地址RVA:1A36

    OD脚本:

    //清除所有硬件断点

    BPHWC

    //清除所有软件断点

    BC

    //清除所有内存断点

    BPMC


    //壳申请内存基地址

    VAR BaseAddress

    //IAT地址

    VAR IATAddress

      
    //得到申请内存基地址指令

    BPHWS 47A381,"x"

    //OEP断点

    BPHWS 47148b,"x"


    _LOOP:

    RUN

      
    //内存基地址判断

    CMP eip,47A381

    JNZ _Sign1

      
    MOV BaseAddress,eax


    //取IAT指令

    BPHWS BaseAddress+1A36,"x"

    //存IAT指令

    BPHWS BaseAddress+08D5,"x"

      
    _Sign1:


    //取IAT判断

    CMP eip,BaseAddress+1A36

    JNZ _Sign2


    MOV IATAddress,eax


    _Sign2:


    //存IAT的地方

    CMP eip,BaseAddress+8D5

    JNZ _Sign3


    MOV [edx],IATAddress


    _Sign3:

      
    //OEP

    CMP eip,47148b

    JNZ _LOOP


    MSG "到达OEP"

    再次Dump,成功解析。

    成功运行。

    回到顶部

    五、混淆和花指令

    代码中出现很多这样的指令:

    call xxx

    xxx   LEA ESP,DWORD PTR SS:[ESP+0x4]

    实际上等价于jmp   xxx

    很多地方都是 混淆和花指令结合:

    有关混淆和花指令详细,可以参考下一篇,下一个壳采用了大量的花指令和混淆:

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

    个人总结:

    附件:

    未知加密壳

    KID

  • 相关阅读:
    证券交易买进卖出手续费公式
    iOS学习之 plist文件的读写
    蓝桥杯——基础练习之字母图形
    SNMP协议具体解释
    Android开发框架SmartAndroid2.0 强劲框架
    隐藏快捷方式扩展名(.lnk)
    Filter及FilterChain的使用具体解释
    uva 1393
    深入浅出Windows BATCH
    科大讯飞2014公布会看点二:智能语音装进车载车机!
  • 原文地址:https://www.cnblogs.com/ltyandy/p/11291236.html
Copyright © 2011-2022 走看看