zoukankan      html  css  js  c++  java
  • 手脱PESpin壳【06.exe】

    1.查壳

    2.LoradPE工具检查

    一方面可以用LoradPE工具查看重定位,另一方面也可获取一些详细信息

    3.查找OEP

    ①未发现pushad
    开始未发现pushad,进行单步步入,很快就能找到pushad
    ②使用ESP定律
    这里要注意如果是有守护进程的话,需要使用【Crtl+G】,在输入框中输入“CreateMutexA”,点击“OK”,解除双进程守护。我们在函数末尾的Retn 0xC处下断点,因为壳会判断这个函数的头部是否有断点。
    发现程序运行起来了,可以确定程序有反硬件断点,而反硬件断点是在异常处理中进行,所以要查看异常处理。
    ③开启异常处理
    点击“选项”,选择“调试选项”,去掉框中所有勾选。
    ④插件忽略异常
    右键导航栏单击“StrongOD”单击“Options”,出现图中界面,取消框中勾选,单击Save。
    ⑤异常断点
    第一次异常0043864A F3:AE repe scas byte ptr es:[edi]//内存访问异常,[0043864D]
    第二次异常0043884A F6F3 div bl//整数除0异常,[00438863]
    第三次异常0043AFC3 FB sti//特权指令,[0043AF42]
    第四次异常是在第三次异常的位置,[0043AF77]
    第五次异常0043AF87 D7 xlat byte ptr ds:[ebx+al]//内存访问异常,[0043AF92]
    第六次异常00438C00 8918 mov dword ptr ds:[eax],ebx//内存访问异常,[00438863]
    ⑥确定反调试位置
    将③开启异常处理和④插件忽略异常中去除的勾选重新勾上,在OD下侧有一个搜索窗口,再其中输入dd XXXXXXXX,就会在数据窗口出现地址,这时在其上下“硬件执行断定”,如果在反硬件断点的前面,就会成功下断,如果是在反硬件断点的后面,就会完成执行(注:每测试完一个异常就重新开始一次)
    次数执行点结果
    第一次异常0043864D
    成功命中
    第二次异常
    00438863
    成功命中
    第三次异常
    0043AF42
    成功命中
    第四次异常
    0043AF77
    程序执行
    第五次异常
    0043AF92
    程序执行
    第六次异常
    00438863
    程序执行
    由表中很明显看出程序在第三次还能中断异常,而在第四次异常的位置会无法中断,所以推出反硬件断点就在第三次和第四次之间,而地址就在0043AF42到0043AF77之间,大胆假设将其中的部分关于寄存器的值nop掉(注:我们只是为人不让寄存器中的值发生修改,所以,关于跳转返回的值应当保留下来,否则程序将无法跳转,提前结束程序)
    右键选择“复制到可执行文件”,在新窗口中右键”保存全部修改“,这是关闭OD,选择不保存,用OD打开新生成的文件,在第三次异常和第四次异常重新下断,发现两次异常都生效
    ⑦再次查找OEP
    用查壳工具选择插件“通用壳OEP查询”记录地址为00409486
    使用⑥确定反调试位置方法下OEP断点,F9运行两次,成功找到OEP位置

    4.查看IAT表(43CFCD=IAT被加密之一)

    向下进行单步步过到第一个call的位置,这里就是IAT表,右键单击“数据窗口跟随”选择“”内存地址“,可以很明显发现数值部分标红,很明显被加密了
    右键单击“可执行模块”,可以很明显发现部分模块被加密,部分模块未加密

    5.脱壳信息查找

    记录之前找得的信息:
    作用地址
    异常处理函数的入口点43AF42
    OEP409486
    IAT被加密的一个地址43CFCD
    删除之前所下的所有断点,重启OD,在上表地址下断点(注:将异常处理函数中的反硬件断点函数NOP掉),然后运行,在这个期间会多次命中43CFCD的断点,到写入假地址的时候停下
    ①第一次命中,写入了一个字节,字节数太少,不用看
    ②第二次命中,写入了四个字节,可以确定这是在给IAT表做修改,这个写入IAT表的地址为:43918C
    在此处下软断点,启用RUN跟踪,进行查看,发现寄存器窗口有函数名跳过,可以确认IAT
    我们已经知道函数名必然是在76打头段,我们将RUN跟踪的结果复制到TXT文本中,然后通过查找EAX=76进行逐个查找(注:由于操作流程,从后向前遍历,将会更容易找到),找到疑似的后,将前面的地址复制,在OD中,使用快捷键【Ctrl+G】,快速跳转至代码段,向下单步一次,查看寄存器,判断是否已到返回正确函数位置,由下图可以看到,返回正确函数地址:438F9F

    6.编写脱壳脚本

    设置断点地址:

    地址作用
    100409486OEP
    20043AF59函数内反硬件断点的位置
    3438F9F返回正确函数地址的位置
    443918C写入IAT的位置
    脚本思路:
    硬件断点下好后,首先命中反硬件断点的位置,填充0x1A个nop,去掉反断点,再通过返回正确函数地址的位置获取正确导入表IAT函数并保存,从写入IAT的位置,覆盖壳加密的IAT,完成后,跳转OEP,开始dump操作
    脚本实现:
    MOV dwSEHAddr,0043AF59
    MOV dwGetProcAddress,438F9F
    MOV dwWriteIAT,43918C
    MOV dwOEP,00409486
    MOV dwEAX,0
    
    //清除断点
    BPHWCALL//硬件断点
    BPMC//内存断点
    //异常处理函数,清除硬件断点的位置
    BPHWS dwSEHAddr,"x"
    //下断点
    BPHWS dwGetProcAddress,"x"//GetProcAddress后面,保存EAX
    BPHWS dwWriteIAT,"x"//填充IAT后面,将保存的EAX写入到[EDI]
    //在OEP处下硬件执行断点
    BPHWS dwOEP,"x"//OEP,弹出信息框,成功到达OEP
    LOOP0:
      RUN
      CMP eip,dwSEHAddr
      JNZ LOOP0  
      FILL dwSEHAddr,1A,90
    
    LOOP1:
      RUN  
      CMP eip,dwGetProcAddress  
      JNZ JMP1  
      MOV dwEAX,eax  
      JMP LOOP1
    
    JMP1:
        CMP eip,dwWriteIAT
        JNZ JMP2
        MOV [edi],dwEAX
        JMP LOOP1
    
    JMP2:
        CMP eip,dwOEP
        JNZ LOOP1
        MSG "成功到达OEP!!!"
    脚本运行:
    在这里就可以开始脱壳了
    7.修复IAT
    我们用Import REC修复IAT,发现无法修复
    我们可以很明显看出修复后的IAT表还有问题
    转换成“Hex/ASCII”显示后,可以看到每个函数地址后都多了个00,所以我们才看到隔4个地址有1个函数。
    Process ID----->所要脱壳的程序进程ID,可在任务管理器中查看,因为ID是十进制,所以取消勾选Hex
    Code Start----->代码起始于地址
    Code End------->代码终止于地址
    New IAT VA----->新的IAT偏移

    使用工具【通用导入表修复工具】进行修复导入表
    跟踪到新IAT表地址,可以看到完好的导入表
    完成脱壳








  • 相关阅读:
    图文讲解ImageView的ScaleType
    android问题总结:
    芯片介绍
    js正则表达式中/=s*".*?"/g表示什么意思?
    fidder配置 https设置 手机客户端
    JAVAAndroid 多线程实现方式及并发与同步
    多线程之问题总结
    html_学习地址
    java保留小数后两位的四种写法
    Glide 加载部分圆角图片
  • 原文地址:https://www.cnblogs.com/HOPEAMOR/p/11992063.html
Copyright © 2011-2022 走看看