Hmily 发表于 2009-3-18 14:08

PECompact 2.x Unpacker Script 0.2

By:CCDebuger


脚本功能:
一、支持 PECompact 2.x 加壳的 EXE 或 DLL。
二、自动生成前缀“UN_ + 原始文件名”的脱壳文件。
三、自动分离区段,分离后的区段名称按序数递增(1、2、3、…),最后一个区段“CanBeDel”是原来壳的,如果你想删掉它,请移动输出表(若有)并用 DT_FixRes dump 资源以备修正原程序资源。
四、自动填写 OEP、IAT RVA 及大小、重定位表 RVA 及 大小,基本上脱出来的文件不需修改就可以直接运行。



/*
Script written by CCDebuger
Script   : PECompact 2.x Unpacker
版本   : v0.2
日期   : 15-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 tmp3
var OrgCode
var jumpflag
var ProcName
var ResetImageBase
var VirtualAlloc
var section
var SecName
var SecBase
var SecNum
var IATRVA
var IATSize
var RelocRVA
var RelocSize
var AllocVA
var AllocVATemp
var AllocVAReal
var VirtualFree
var imgbase
var signVA
var modsize
var dllreloc
var oep
var oeprva
var apiloc
var unpackname

msgyn "为保证脚本能正确运行,请忽略所有异常。本脚本只能用于 PECompact 2.x 版本加壳的 EXE 或 DLL"
cmp $RESULT, 0
je exit
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,     //获取 PE 签名的偏移
add tmp1, imgbase         //tmp1=签名 VA
mov signVA, tmp1
gpi PROCESSNAME
mov ProcName, $RESULT
gpi EXEFILENAME
//设 VirtualAlloc 断点,返回到相关位置

gpa "VirtualAlloc", "kernel32.dll"
mov VirtualAlloc, $RESULT
bp VirtualAlloc
alloc 1000
mov AllocVA, $RESULT
mov AllocVATemp, AllocVA
mov AllocVAReal, AllocVA + 400      //用来保存区段的实际大小

VirtualAlloc_Next:
esto
rtu

/*
查找命令序列:
00AB10BD    8B3B            MOV EDI,DWORD PTR DS:               ; 各个区段的 RVA 地址送EDI
00AB10BF    03FA            ADD EDI,EDX                              ; 区段RVA+基址
00AB10C1    8B4B 08         MOV ECX,DWORD PTR DS:             ; 区段大小送ECX
00AB10C4    8BC1            MOV EAX,ECX                              ; 这里设断
*/
find eip, #03FA8B4B088BC1#
mov section, $RESULT
cmp section, 0
je VirtualAlloc_Next
add section, 5
bp section
bc VirtualAlloc
lc
eob logsection
esto

logsection:
mov tmp1, edi
sub tmp1, imgbase
log tmp1, "区段 RVA = "
mov tmp2, ecx
mov , tmp1
add AllocVAReal, 4
mov , tmp2
add AllocVAReal, 4
div tmp2, 1000
mul tmp2, 1000
add tmp2, 1000
log tmp2, "区段大小 = "
mov , tmp1
add AllocVA, 4
mov , tmp2
add AllocVA, 4
rtr

bc section
cob
log "区段 RVA = 001000"   //加上最开始的那个段
mov , 1000
mov tmp1,
sub tmp1, 1000
add AllocVA, 4
mov , tmp1
log tmp1, "区段大小 = "
mov tmp1, AllocVA

FixSectionSize:
cmp AllocVATemp, tmp1 - 4
je continue
mov tmp2,     //区段大小
mov tmp3,     //下一个区段 RVA
sub tmp3,     //两个区段间的大小
sub tmp1, 8      //下一个区段大小
cmp tmp3, tmp2      //实际大小与获取的大小比较
jb FixSecSize
jmp FixSectionSize

FixSecSize:
mov , tmp3
jmp FixSectionSize

continue:
sto

isdll:
mov tmp1, , 2//DLL 特征值
cmp tmp1, 1
je dll
mov tmp2,     //重定位表RVA
cmp tmp2, 0
jne dll
eval "UN_{ProcName}.exe"
mov unpackname, $RESULT
jmp findIAT

dll:
eval "UN_{ProcName}.dll"
mov unpackname, $RESULT
/*查找命令序列:
00950D08    56            PUSH ESI
00950D09    E8 30030000   CALL 0095103E
00950D0E    56            PUSH ESI
00950D0F    E8 45020000   CALL 00950F59    ;后面的内容
00950D14    56            PUSH ESI
00950D15    E8 45010000   CALL 00950E5F
00950D1A    90            NOP
*/
find eip, #56E8????????56E8????????90#
mov tmp2, $RESULT

Next_Reloc:
/*
查找命令序列:
MOV EAX,DWORD PTR DS:
MOV EBX,DWORD PTR DS:
CMP EAX,EBX
JE SHORT 00AB0C12
*/
find eip, #8B47??8B5F??3BC374??#
mov dllreloc, $RESULT
cmp dllreloc, 0
je findIAT
mov tmp1, dllreloc + 08
bp tmp1
esto
bc
mov jumpflag, ebx
sub jumpflag, eax
opcode tmp1
mov OrgCode, $RESULT_1
mov , #9090#
add dllreloc, 0D
bp dllreloc
esto
bc
log esi, "重定位表 RVA = "
mov RelocRVA, esi
mov tmp3, AllocVAReal

GetRelocSize:
cmp RelocRVA,
je FindRelocSize
sub tmp3, 8
jmp GetRelocSize

FindRelocSize:
mov RelocSize,
log RelocSize, "重定位表大小 = "

/*
查找命令序列:
JMP SHORT 00AB0BC9
POP ESI
POP EDI
POP EBX
LEAVE
RETN 4
以上命令序列就是处理重定位表函数的返回部分
*/
find eip, #EB??5E5F5BC9C2????#
add $RESULT, 2
bp $RESULT
cmp jumpflag, 0
je MustJump
cmp tmp2,0
jne RunToRelocRet

MustJump:
mov , 0EB, 1

RunToRelocRet:
mov ResetImageBase, tmp2
esto
bc
eval "{OrgCode}"
asm tmp1, $RESULT
mov , 074, 1
rtr
sto

findIAT:
find eip, #8B4E??85C90F84#
mov tmp1, $RESULT
add tmp1, 3
bp tmp1
esto
bc
mov IATRVA, ecx
cmp IATRVA, 0
je FindOEP
log IATRVA, "输入表 RVA = "
mov tmp1, imgbase
add tmp1, IATRVA
//根据 IAT 表以 5 个字段组成,最后以 20 个 0 字节组成的特性来搜索
find tmp1, #0000000000000000000000000000000000000000#
mov IATSize, $RESULT
sub IATSize, tmp1
add IATSize, 015
log IATSize, "输入表大小 = "

/*
查找命令序列:
MOV DWORD PTR DS:,EAX
MOV DWORD PTR DS:,EAX
即处理输入表的部分。
*/
find eip, #89068902#
mov iatloc, $RESULT
cmp iatloc,0
je exit
asm iatloc, "mov eax,"
add iatloc, $RESULT
asm iatloc, "mov dword ptr ,eax"
bp iatloc
esto
bc iatloc
rtr
sto
find eip, #485E5F5BC9C2????#   //在返回地址上设断
add $RESULT, 5
bp $RESULT
esto
bc
asm iatloc, "mov dword ptr ,eax"
sub iatloc, $RESULT
asm iatloc, "mov dword ptr ,eax"

FindOEP:
gpa "VirtualFree", "kernel32.dll"
mov VirtualFree, $RESULT
BP VirtualFree

nextoep:
esto
rtu
rtr
sto
find eip, #5A5E5F595B5DFFE0#
mov oep, $RESULT
cmp oep, 0
je nextoep
bc VirtualFree
add oep, 6
bp oep
esto
sti
bc
mov oeprva, eip
sub oeprva, imgbase
log oeprva, "OEP RVA = "
cmt eip, "这就是 OEP 了"
mov , 1000    //文件对齐设为1000
mov , 1000    //头部大小设为1000
mov tmp1, 0
mov tmp1, , 2 //区段数目
mov SecBase, signVA
add SecBase, 0F8         //第一个区段
cmp tmp1, 0
je lab1
fill SecBase, 200, 0
mov tmp2, AllocVA + 4
sub tmp2, AllocVATemp
div tmp2, 8
mov SecNum, tmp2
mov tmp2, 1
mov tmp4, SecNum

last:
cmp AllocVATemp, AllocVA - 4
je SetLastSec
itoa tmp2
mov SecName, $RESULT
mov , SecName      //区段名称
mov ,     //VirtualSize
mov ,     //SizeOfRawData
sub AllocVA, 4            //指向区段偏移
mov ,     //VirtualAddress
mov ,     //PointerToRawData
mov , 0E00000E0   //设置区段属性
sub AllocVA, 4            //指向下一个区段大小
add tmp2, 1
add SecBase, 28            //指向一个区段
mov tmp3,       //下一个区段的偏移地址
mov tmp1, tmp3
sub tmp3,       //两个区段相减
cmp tmp3,       //判断两个区段间的大小是否相符
je last
sub tmp3,       //取新区段的大小
sub tmp1, tmp3            //取新区段的偏移 RVA
itoa tmp2
mov SecName, $RESULT
mov , SecName      //区段名称
mov , tmp3    //VirtualSize
mov , tmp3    //SizeOfRawData
mov , tmp1    //VirtualAddress
mov , tmp1    //PointerToRawData
mov , 0E00000E0   //设置区段属性
add SecNum, 1
add tmp2, 1
add SecBase, 28            //指向一个区段
jmp last

SetLastSec:
itoa tmp2
mov SecName, $RESULT
mov , SecName      //区段名称
mov ,     //VirtualSize
mov ,     //SizeOfRawData
sub AllocVA, 4            //指向区段偏移
mov ,     //VirtualAddress
mov ,     //PointerToRawData
mov , 0E00000E0   //设置区段属性
add SecNum,1
add SecBase, 28            //指向一个区段
mov SecName, "CanBeDel"
mov tmp1, modsize
mov tmp2,       //原程序最后一个区段的大小
add tmp2,       //加上最后一个区段的偏移,得到新区段的偏移 RVA
sub tmp1, tmp2            //最后一个区段的大小

mov , SecName      //区段名称
mov , tmp1    //VirtualSize
mov , tmp1    //SizeOfRawData
mov , tmp2    //VirtualAddress
mov , tmp2    //PointerToRawData
mov , 0E00000E0   //设置区段属性
mov , SecNum, 2   //设置区段数目


lab1:
free AllocVATemp, 1000
mov , oeprva      //填写 OEP
mov , IATRVA    //输入表 RVA 地址
mov , IATSize    //输入表大小
mov , RelocRVA    //重定位表 RVA 地址
mov , RelocSize    //重定位表大小
cmp ResetImageBase, 0
je dumpproc
mov ,imgbase    //更改镜像基址

dumpproc:
dm imgbase, modsize, unpackname
msg "已经到 OEP 了。程序已 dump 后另存为 UN_+原文件名。OEP 、输入表、重定位(若有)都已修正,区段都已重建。若要优化大小,请查看输出表及资源是否在最后那个“CanBeDel”段中,若在,请重建输出表及资源后再删除最后的那个“CanBeDel”段。"

exit:
ret

errorver:
msg "运行此脚本需要 ODbgScript 1.65 或更高的版本,您的版本过低,请更新 ODbgScript 后再试。"
ret

evilangel 发表于 2009-3-18 14:48

:lol    昨天在看雪看到CC发的了用几个试炼壳试试   :)

i9420 发表于 2009-3-18 14:55

PECompact
现在貌似用这个加壳都被当病毒处理了。

我加了记事本测试。居然很多把她当病毒。

nbqj0001 发表于 2009-3-18 20:16

我东西:lol

nbqj0001 发表于 2009-3-18 20:18

我东西
:(

kiss4 发表于 2009-3-21 12:54

哈哈``感谢。正好有个,可以试下。

nbqj0001 发表于 2009-3-21 18:45

:loveliness:我东西

baxianhua 发表于 2011-4-3 02:03

正需要 谢谢分享 支持

stl88083365 发表于 2011-4-24 22:18

支持一下
!!!!

sgf20212 发表于 2011-8-13 10:58

不错 就是在找你
页: [1] 2 3
查看完整版本: PECompact 2.x Unpacker Script 0.2