PEspin v1.3 public主程序脱壳 之一

PEspin1.3主程序iat修复和到达OEP脚本

/////////////////////////////////////////////////////////
//PEspin v1.3 public Unpack Script                     //
//Tools:Ollydbg v1.1\OllScript v0.92                   //
//System:windows xpsp1                                 //
//by fxyang  tcfxyang·126.com                         //
//2005.7.24                                            //
/////////////////////////////////////////////////////////


dbh

var addrs

//获得函数RtlGetLastWin32Error的地址,因为壳用这个函数的返回值判断是不是子进程。
gpa "GetProcAddress", "kernel32.dll"
bp  $RESULT
eob getapi
run

getapi:
bc $RESULT
rtu
sto
gpa "RtlGetLastWin32Error", "ntdll.dll"
BPRM  $RESULT,ff
eob goadd
run

goadd:
eob setjump
run

setjump:
bc $RESULT
rtu

//返回到壳中

mov eax,0b7

//直接赋值给EAX,骗过壳

sto
//处理第一个异常
///////////////////////////////////////////////////////
//00415AB6    58                POP EAX
//00415AB7    2BD2              SUB EDX,EDX
//00415AB9    BB BAE74D02       MOV EBX,24DE7BA
//00415ABE    81EB 86E74D02     SUB EBX,24DE786
//00415AC4    F7E3              MUL EBX
//00415AC6    81CB FE12F40E     OR EBX,0EF412FE
//00415ACC    8D8428 B40291ED   LEA EAX,DWORD PTR DS:[EAX+EBP+ED9102B4]
//00415AD3    2D 179B50ED       SUB EAX,ED509B17
//00415AD8    FFE0              JMP EAX                ; PESpin.00415AF1

//00415AF1    F1                INT1                   <--子进程中需要父进程解码的异常
//00415AF2    E8 1C030000       CALL PESpin.00415E13
////////////////////////////////////////////////////////

find eip, #FFE0#                 //查找 JMP EAX 代码
bp $RESULT
eob seteip
run

//父进程的解码就是把子进程的EIP修改到正确的地方
seteip:
bc $RESULT
sto
add eip,1f             //修改eip

//下面用函数来定位第二个异常

gpa "VirtualFree", "kernel32.dll"
BPRM $RESULT,01
mov addrs,3
eob seteip1
esto

seteip1:
//pause
dec addrs
cmp addrs,0
je seteip2
esto

seteip2:
bc $RESULT
gpa "VirtualProtect", "kernel32.dll"
BPRM $RESULT,01
eob temp0
esto

temp0:
bc $RESULT
rtu


//同上第二个异常处理,这是个子进程能自己处理的异常
//这个异常会把代码的流程修改到正确的地方,相当于jump
////////////////////////////////////////////////
//004147C2    005A 8B         ADD BYTE PTR DS:[EDX-75],BL
//004147C5    1255 52         ADC DL,BYTE PTR SS:[EBP+52]
//004147C8    64:FF33         PUSH DWORD PTR FS:[EBX]
//004147CB    64:8923         MOV DWORD PTR FS:[EBX],ESP
//004147CE    68 F3AA9090     PUSH 9090AAF3
//004147D3    FFE7            JMP EDI

//00400158    BE 5F014000     MOV ESI,PESpin.0040015F
//0040015D    8F06            POP DWORD PTR DS:[ESI]
//0040015F    0000            ADD BYTE PTR DS:[EAX],AL  <--异常
////////////////////////////////////////////////

find eip, #FFE7#
bp $RESULT
eob tempbuf
esto

tempbuf:
sto
sto
gpa "GetTickCount", "kernel32.dll"
BPRM $RESULT,01
eob temp1
esto

//第三个异常,需要父进程解码的异常
//////////////////////////////////////////////
//0041638A    F1              INT1         <--第三个异常
//0041638B    87DF            XCHG EDI,EBX
//0041638D    57              PUSH EDI
//0041638E    C3              RETN
//////////////////////////////////////////////

temp1:
rtu
bp 0041638A
eob seteip3
esto


//父进程的解码就是把子进程的EIP修改到正确的地方
seteip3:
bc 0041638A
add eip,2c               //<--修改eip
//pause
sto

//下面到了iat处理的地方了,由于壳把comctl32.dll和comdlg32.dll中的函数
//不做加密处理,给修复iat带来了方便,就是把比较这两个函数的地方修改就行了
//////////////////////////////////////////
//00412E11    0FB700          MOVZX EAX,WORD PTR DS:[EAX]
//00412E14    C1E0 02         SHL EAX,2
//00412E17    0385 063A4000   ADD EAX,DWORD PTR SS:[EBP+403A06]
//00412E1D    8B00            MOV EAX,DWORD PTR DS:[EAX]
//00412E1F    0385 FE394000   ADD EAX,DWORD PTR SS:[EBP+4039FE] <--这里直接计算出正确的iat函数地址
//00412E25    EB 10           JMP SHORT PESpin.00412E37
//////////////////////////////////////////
gpa "LoadLibraryA", "kernel32.dll"
BPRM $RESULT,01
eob setiat
esto

setiat:
rtu
bpmc
bp 00412E3F
eob setiat1
esto

//比较第一地址
///////////////////////////////////////////////
//00412E37    8BBD F2394000   MOV EDI,DWORD PTR SS:[EBP+4039F2]
//00412E3D    3BC7            CMP EAX,EDI
//00412E3F    76 35           JBE SHORT PESpin.00412E76  这里
///////////////////////////////////////////////


setiat1:
bc 00412E3F
mov [eip],#EB#   //修改为jmp
bp 004137E6
eob setiat2
esto

//第二个关键的地址,这个跳转根据dll计算出不同的处理地址,跟踪发现comctl32.dll
//的地址是0041384A ,修改这个的代码为:JMP  0041384A
//////////////////////////////////////////////
//004137E6   /FF6424 FC       JMP DWORD PTR SS:[ESP-4]       ; PESpin.0041384A  这个地址由于dll不同
//////////////////////////////////////////////
setiat2:
//pause
bc 004137E6
mov [eip],#EB62#    //修改为JMP  0041384A
//pause
bp 00412FB9
eob setiat3
esto

//第三个关键比较地址,比较标志,修改为jmp
//////////////////////////////////////////////
//00412FB5    807F FF EA      CMP BYTE PTR DS:[EDI-1],0EA              //标志
//00412FB9  ^ 75 90           JNZ SHORT PESpin.00412F4B                // jmp
//////////////////////////////////////////////
setiat3:
//pause
bc 00412FB9
mov [eip],#EB#       //修改为jmp
bp 0041398B
eob settime
esto

settime:
//pause
bp 00413AA1
eob getOEP
esto

//快到OEP了,剩下的还需要修改代码中iat跳转表
////////////////////////////////////////////////////////
//0040A08C    EA 94C04000 FFE>JMP FAR EAFF:0040C094                    ; 远距跳转
//0040A093    88C0            MOV AL,AL
//0040A095    40              INC EAX
//0040A096    00FF            ADD BH,BH
//0040A098    EA 70C04000 FFE>JMP FAR EAFF:0040C070                    ; 远距跳转
//0040A09F  ^ 74 C0           JE SHORT PESpin.0040A061
//0040A0A1    40              INC EAX
//0040A0A2    00FF            ADD BH,BH
//0040A0A4    EA 84C04000 FFE>JMP FAR EAFF:0040C084                    ; 远距跳转
//0040A0AB    80C0 40         ADD AL,40
//0040A0AE    00FF            ADD BH,BH
//0040A0B0    EA 7CC04000 FFE>JMP FAR EAFF:0040C07C                    ; 远距跳转
//0040A0B7    54              PUSH ESP
//0040A0B8    C040 00 FF      ROL BYTE PTR DS:[EAX],0FF                ; 移动常数超出 1..31 的范围
//0040A0BC    EA 2CC04000 FFE>JMP FAR EAFF:0040C02C                    ; 远距跳转 1..31 的范围
//......
//......
//0040A1BE    EA 04C14000 FFE>JMP FAR EAFF:0040C104                    ; 远距跳转
//0040A1C5    00C1            ADD CL,AL
//0040A1C7    40              INC EAX
//0040A1C8    00FF            ADD BH,BH
//0040A1CA    EA D8C04000 FFF>JMP FAR FFFF:0040C0D8                    ; 远距跳转
//0040A1D1    25 00C04000     AND EAX,40C000
//0040A1D6  - FF25 04C04000   JMP DWORD PTR DS:[40C004]                ; COMCTL32.InitCommonControls
//0040A1DC  - FF25 08C04000   JMP DWORD PTR DS:[40C008]                ; COMCTL32.InitCommonControlsEx
//0040A1E2  - FF25 10C04000   JMP DWORD PTR DS:[40C010]                ; COMDLG32.GetOpenFileNameA
//0040A1E8    EA A8C04000 FFE>JMP FAR EAFF:0040C0A8                    ; 远距跳转
//0040A1EF    A4              MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
//0040A1F0    C040 00 FF      ROL BYTE PTR DS:[EAX],0FF                ; 移动常数超出 1..31 的范围
//0040A1F4    EA A0C04000 FFE>JMP FAR EAFF:0040C0A0                    ; 远距跳转
//0040A1FB    9C              PUSHFD
//0040A1FC    C040 00 FF      ROL BYTE PTR DS:[EAX],0FF                ; 移动常数超出 1..31 的范围
//0040A200    EA 18C04000 FFE>JMP FAR EAFF:0040C018                    ; 远距跳转
//0040A207    1C C0           SBB AL,0C0
//0040A209    40              INC EAX
//0040A20A    00FF            ADD BH,BH
//0040A20C    EA 20C04000 FFE>JMP FAR EAFF:0040C020                    ; 远距跳转

/////////////////////////////////////////////////////////////

getOEP:
bc 00413AA1
//pause
bp 0040A0A4
eob setiat4
esto

//到0040A0A4后在00900063处写入处理代码
//////////////////////////////////////////////////////////////
//00900063    60              PUSHAD
//00900064    9C              PUSHFD
//00900065    B8 8CA04000     MOV EAX,40A08C
//0090006A    8038 EA         CMP BYTE PTR DS:[EAX],0EA
//0090006D    75 16           JNZ SHORT 00900085
//0090006F    8B58 01         MOV EBX,DWORD PTR DS:[EAX+1]
//00900072    66:C700 FF25    MOV WORD PTR DS:[EAX],25FF
//00900077    8958 02         MOV DWORD PTR DS:[EAX+2],EBX
//0090007A    8D40 06         LEA EAX,DWORD PTR DS:[EAX+6]
//0090007D  ^ EB EB           JMP SHORT 0090006A
//0090007F    0000            ADD BYTE PTR DS:[EAX],AL
//00900081    0000            ADD BYTE PTR DS:[EAX],AL
//00900083    0000            ADD BYTE PTR DS:[EAX],AL
//00900085    40              INC EAX
//00900086    3D 15A24000     CMP EAX,40A215
//0090008B    7D 02           JGE SHORT 0090008F
//0090008D  ^ EB DB           JMP SHORT 0090006A
//0090008F    9D              POPFD
//00900090    61              POPAD
//00900091  - E9 0EA0B0FF     JMP PESpin.0040A0A4

/////////////////////////////////////////////////////////////////

setiat4:
bc 0040A0A4
mov [00900063],#609CB88CA040008038EA75168B580166C700FF258958028D4006EBEB000000000000403D15A240007D02EBDB9D61E90EA0B0FF90#
mov eip,00900063
bp 00900091
eob setOEP
run

setOEP:
bc 00900091
sto
msg "PEspin1.3主程序iat修复和到达OEP已完成!by fxyang"
ret
              fxyang
                       2005.7.24