前段时间没事写的 Aspack 脱壳脚本,支持最新的 2.2 版。脚本功能是自动修复 OEP、IAT、TLS(若有),自动 dump,dump 出来的程序应该就可以直接运行。如果有附加数据的话,可能要你自己添加。脚本支持 EXE 和 DLL,大概类似于脱壳机。
代码:
/* Script written by CCDebuger Script : Aspack 2.x Unpacker 版本 : v0.1 日期 : 24-03-2009 调试环境 : OllyDbg 1.1, ODBGScript 1.65, WINXP, WIN2000 调试选项 : 设置 OllyDbg 忽略所有异常选项 工具 : OllyDbg, ODBGScript 1.65 感谢 : Oleh Yuschuk - author of OllyDbg SHaG - author of OllyScript hnhuqiong - author of ODbgScript Epsylon3 - author of ODbgScript */ var tmp1 var tmp2 var NewModSize var ExeName var DirName var NameStarAddr var SectionNum var SecName var SecBase var IATRVA var IATSize var RelocRVA var RelocSize var AllocVA var AllocVATemp var VirtualFree var imgbase var signVA var modsize var TLSRVA var OrgImageBase var oep var unpackname cmp $VERSION, "1.65" jb errorver bc bphwcall dbh GMI eip, MODULEBASE //get imagebase mov imgbase, $RESULT gmi eip, MODULESIZE mov modsize,$RESULT mov tmp1, [imgbase+3C] //获取 PE 签名的偏移 add tmp1, imgbase //tmp1=签名 VA mov signVA, tmp1 mov OrgImageBase, [signVA + 34] //原始的镜像基址 //gpi PROCESSNAME //mov ProcName, $RESULT gpi EXEFILENAME mov ExeName, $RESULT gpi CURRENTDIR mov DirName, $RESULT mov SectionNum, [signVA + 6], 1 //获取区段数目 mov [signVA + 3C], 1000 //文件对齐设为1000 mov [signVA + 54], 1000 //头部大小设为1000 alloc 1000 mov AllocVA, $RESULT mov [AllocVA], ExeName len ExeName mov tmp1, $RESULT len DirName mov tmp2, $RESULT sub tmp1, tmp2 mov NameStarAddr, tmp2 mov NameStarAddr, AllocVA + NameStarAddr READSTR [NameStarAddr], tmp1 mov unpackname, $RESULT eval "UN_{unpackname}" mov unpackname, $RESULT free AllocVA alloc 1000 mov AllocVA, $RESULT mov AllocVATemp, AllocVA //以下命令获取区段RVA地址及大小,并设置V.Size = R.Size mov SecBase, signVA + 0F8 mov tmp2, SectionNum GetSecInfo: mov SecSize, [SecBase + 08] //获取区段 V.Size mov [AllocVATemp + 4], SecSize //保存区段 V.Size mov [SecBase + 10], SecSize //R.Size = V.Size mov tmp1, [SecBase + 0C] //获取区段 RVA 地址 mov [SecBase + 14], tmp1 //V.Offset = R.Offset mov [AllocVATemp], tmp1 add SecBase, 28 //指向下一个区段 add AllocVATemp, 8 dec tmp2 cmp tmp2, 0 jne GetSecInfo /*查找以下命令序列: 00407015 BB EDFFFFFF MOV EBX,-13 0040701A 03DD ADD EBX,EBP 0040701C 81EB 00700000 SUB EBX,7000 */ find eip, #BBEDFFFFFF03DD81EB# mov tmp1, $RESULT add tmp1, 7 bp tmp1 esto bc tmp1 mov NewModSize, ebx sub NewModSize, imgbase //保存原始程序的镜像大小 //设 VirtualFree 断点,返回到相关位置 gpa "VirtualFree", "kernel32.dll" mov VirtualFree, $RESULT bp VirtualFree FindReloc: esto rtu /* 查找命令序列: 0040C1DA 2BD0 SUB EDX,EAX 0040C1DC 74 79 JE SHORT 0040C257 0040C1DE 8BC2 MOV EAX,EDX 0040C1E0 C1E8 10 SHR EAX,10 0040C1E3 33DB XOR EBX,EBX */ find eip, #2BD074??8BC2C1E8??33DB# mov tmp1, $RESULT cmp tmp1, 0 je FindReloc bc bp tmp1 esto bc lc //处理重定位 mov [tmp1 + 2], #9090#, 2 add tmp1, 11 bp tmp1 esto bc findop eip, #74# mov tmp1, $RESULT mov [tmp1], #EB#, 1 mov tmp2, esi mov RelocRVA, esi mov [signVA + 0A0], RelocRVA cmp tmp2, 0 je FixIAT log esi, "重定位表 RVA = " /* 查找以下内容: 0040C278 BE 00600000 MOV ESI,6000 0040C27D 8B95 22040000 MOV EDX,DWORD PTR SS:[EBP+422] 0040C283 03F2 ADD ESI,EDX */ FixIAT: find eip, #BE????????8B95????????03F2# mov tmp1, $RESULT bp tmp1 esto sto log esi, "输入表 RVA = " bc mov IATRVA, esi mov tmp2, esi add tmp2, imgbase //根据 IAT 表以 5 个字段组成,最后以 20 个 0 字节组成的特性来搜索 find tmp2, #0000000000000000000000000000000000000000# mov IATSize, $RESULT sub IATSize, tmp2 add IATSize, 15 log IATSize, "输入表大小 = " mov [signVA + 80], IATRVA //set IAT address mov [signVA + 84],IATSize //set IAT size /*查找以下内容: 0040C39A B8 143F0000 MOV EAX,3F14 0040C39F 50 PUSH EAX 0040C3A0 0385 22040000 ADD EAX,DWORD PTR SS:[EBP+422] 0040C3A6 59 POP ECX 0040C3A7 0BC9 OR ECX,ECX */ find eip, #B8????????500385????????59# mov tmp1, $RESULT mov tmp1, [tmp1 + 1] log tmp1, " OEP RVA = " mov oep, tmp1 mov [signVA + 28], oep //set OEP address TLS: mov TLSRVA,[signVA + 0C0] //TLS table address cmp TLSRVA, 0 je FixReloc1 mov AllocVATemp, AllocVA FindTLS: mov tmp1, [AllocVATemp + 8] //Next Section RVA address mov tmp2, [AllocVATemp] //previous Section RVA address add tmp1, imgbase mov tmp1, [tmp1] //Get next section context of start address add tmp2, OrgImageBase add AllocVATemp, 8 //Point to next section cmp tmp2, tmp1 jne FindTLS mov TLSRVA, [AllocVATemp] mov [signVA + 0C0], TLSRVA //Set TLS table RVA address mov [signVA + 0C4], 18, 1 //Set TLS table size FixReloc1: mov AllocVATemp, AllocVA cmp RelocRVA, 0 je SetRelocSize0 FixReloc: mov tmp1, [AllocVATemp] add AllocVATemp, 8 cmp tmp1, RelocRVA jne FixReloc add tmp1, imgbase find tmp1, #0000000000000000000000000000000000000000# mov RelocSize, $RESULT sub RelocSize, imgbase sub RelocSize, RelocRVA //add RelocSize, 4 mov [signVA + 0A4], RelocSize //set Reloc table size mov [signVA + 0F4], 0 //set Reserved = 0 /* FixSection: mov tmp2, 0 mov AllocVATemp, AllocVA lab1: mov tmp1, [AllocVATemp] add AllocVATemp, 8 inc tmp2 cmp tmp1, NewModSize jne lab1 dec tmp2 mov SectionNum, tmp2 //mul tmp2, 028 //mov tmp2, signVA + 0F8 + tmp2 //fill tmp2, 100, 0 mov [signVA + 6], SectionNum, 1 //set section number mov [signVA + 50], NewModSize //set SizeOfImage */ DumpFile: free AllocVA dm imgbase, modsize, unpackname msg "程序已 dump 后另存为 UN_+原文件名。OEP 、输入表、重定位、TLS 表(若有)都已修正,可直接运行脱壳后的程序。要优化的话,请重建资源后删除最后的两个垃圾区段。" exit: ret errorver: msg "运行此脚本需要 ODbgScript 1.65 或更高的版本,您的版本过低,请更新 ODbgScript 后再试。" ret SetRelocSize0: mov [signVA + 0A4], 0 //Reloc size = 0 jmp DumpFile