ACProtect Professional 1.3C 主程序脱壳(2)(图)

4. dump
    根据脱US UnpackMe的经验,不能在false OEP处dump,此时BSS section中许多数据已经初始化了。最好在第一句(push ebp)就dump。可是那个push ebp离false OEP很远L。
    
    Packer EP的初始化环境:
    
    
    
    
    
    
    先看看发出第1个call的壳代码:
    
    
    可以看到(跟一下可以证实),在call入原程序空间前,最后的异常是div 0。用现在的OllyDbg脚本(跟到737B63),停下后修改异常拦截选项:
    
    
    试试能否拦截异常找到合适的dump位置。当前OllyScript脚本停下时的环境:
    
    
    
    栈中为pushad的结果。
     第7次div 0异常时:
    
    
    
    
    注意ebp的值已经入栈了。Pushad的结果,对应寄存器值为:
    esp = 12FFC0 (原来为12FFC4)
    ebp = 12FFC0 = esp (原来为12FFF0)
    看看BSS section:
    
    
    
    
    全为0,就在这里dump。如果需要仔细跟stolen code,也可以从这里入手(可以从脚本停下的第6次div 0异常处理后开始)。
    
    先用4D9DE4为OEP。
    
    
    
    用LoadPE查看节表:
    
    
    先把CODE的Vsize和Rsize加大,以避免修复stolen codes时空间不够。
    
    
    
    重新跟到false OEP(4D9E37)。重建输入表。
    
    
    
    用了Add new section,会不会有问题(好象有篇脱文里提到过这个)? 先这样处理。
    用IDA编译dumped_.exe,结果不错。
    现在剩下stolen code和replaced code。
    5. 修复stolen code
    
    既然不打算仔细跟,就只有猜了。对执行第1个call以前的stolen code进行猜测,应该是安全的。后面的4次call需要仔细看看。
    
    1) call 406EDC
    
    在IDA中看dumped_.exe的结果:
    
    
    先执行脚本,停下后只勾选div 0异常。直到73A9AF。经过一番遮遮掩掩的代码:
    
    
    在call前的寄存器:
    
    
    堆栈:
    
    
    call完后,下面的pushad为分界线,标识stolen code的结束。所以到这里的stolen code为(对于不确定的,可以在Packer EP修改寄存器值,到这里核对):
     Call完后,pushad前的环境:
    
    
    
    
    2) call 46261C
    
    
    
    
    
    到这里的stolen code:
    从这里开始,不能图省事了。要追出全部的stolen code,必须跟(必须确保上一次pushad和下一次popad时的环境一致,才不会丢代码)。先试直接拦截div 0异常,注意后面是否有popad。如果两次的环境不一致,则必须单步跟L。
    
    另外,追stolen code不是一次完成的,所以有些图中寄存器和堆栈中的数据对不上,不必管它。
    
    3) 0073BC47
    
    
    4) 0073C558
    
    
    5) 第1次call 462634
    
    
    这个函数有2个参数L。
    
    
    
    这是最后一次后面存在popad的div 0异常。看看是如何回到原程序的。
    在73D872忽略所有异常,对code section下内存访问断点。中间在kernel32中有一次内存访问异常。
    
    
    
    最后一次div ebx在73DBE1。单步跟到这里:
    
    
    73DE38破坏前面代码。
    
    
    
    至此修复所有stolen codes,将前面的6部分和fasle OEP的2个call合在一起。