经过一翻周折,UPX这个简单的壳,我却么有搞定!_!.不得不难过了:(
一直心情很糟糕,么有办法静下来做东西了.好长时间么来看雪了,今天碰到个很简单的UPX壳,我竟然么有搞定.
天哪~~~~,我是何等的渺小.一直想给看雪带点好东西,但是我依然么有拿的出手的东西.因为我已经很久么有
好好打开OD和IDA看过.最多是随手打开随手关掉.
最近玩游戏,碰到了个东西,它有个英文名字GameGuard,不知道大家听说过么,好象它便是大名顶顶的NP,关于NP
我会再以后的文章中说明,当然是旧版本,做为研究无所谓新旧,为了看雪也为了我和大家,我选择了旧版本.
今天和大家探讨的是GameGuard.des的脱壳问题,因为PEID告诉我说是未知,我来个深度扫描竟然是UPX,
和我开了个天大的玩笑.
我很熟练的OD,不到10秒,不!是5秒,一个断点,两下F8,于是我到了OEP,LOAD直接DUMP发现竟然是4KB,我晕了.....
直接拿WINHEX,从内存提出来LOADPE重建搞定.发现这样的脱壳不完美首先运行不起来.而且后来修复后,运行,
发现也不正常,于是我用UPX -D么想到提示:
//-----------------------------------------------------------------------------------------------
E:\软件加密解密\脱壳工具\UPX\upx303w>upx -d gameguard.des
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2008
UPX 3.03w Markus Oberhumer, Laszlo Molnar & John Reiser Apr 27th 2008
File size Ratio Format Name
-------------------- ------ ----------- -----------
upx: gameguard.des: CantUnpackException: file is modified/hacked/protected; take
care!!!
Unpacked 0 files.
//----------------------------------------------------------------------------------------------
对上面的提示只能是汗颜了.一到咱看雪,搜索一下!发现有个UPXFIX很好玩.点一下修复,竟然告诉我不是UPX
壳,到底那个说的对呢??我们来看看入口:
//----------------------------------------------------------------------------------------------
00422AF0 > 31FF xor edi, edi
00422AF2 74 06 je short 00422AFA
00422AF4 61 popad
00422AF5 - E9 4A4D5030 jmp 30927844
00422AFA 5A pop edx
00422AFB BA 7D000000 mov edx, 7D
00422B00 807C24 08 01 cmp byte ptr [esp+8], 1
00422B05 E9 00000000 jmp 00422B0A
00422B0A 60 pushad
00422B0B BE 00504100 mov esi, 00415000
00422B10 31FF xor edi, edi
00422B12 74 06 je short 00422B1A
00422B14 61 popad
00422B15 - E9 4A4D5030 jmp 30927864
00422B1A 8DBE 00C0FEFF lea edi, dword ptr [esi+FFFEC000]
00422B20 31C9 xor ecx, ecx
00422B22 74 06 je short 00422B2A
00422B24 61 popad
00422B25 - E9 4A4D5030 jmp 30927874
//-----------------------------------------------------------------------------------------------
大家看看是不是UPX,但是和UPX脱壳方法很是一样.估计是被修改过的UPX了.管它呢~~~好好看看.
1:
//-----------------------------------------------------------------------------------------------
00422AF0 > 31FF xor edi, edi ; edi =0
00422AF2 74 06 je short 00422AFA ; if edi == 0 ->jmp
00422AF4 61 popad
00422AF5 - E9 4A4D5030 jmp 30927844
00422AFA 5A pop edx ; save edx
00422AFB BA 7D000000 mov edx, 7D ; edx = 7D
00422B00 807C24 08 01 cmp byte ptr [esp+8], 1 ; ????
00422B05 E9 00000000 jmp 00422B0A
00422B0A 60 pushad
00422B0B BE 00504100 mov esi, 00415000 ; esi = 00415000
00422B10 31FF xor edi, edi ; edi = 0
00422B12 74 06 je short 00422B1A ; if edi ==0 ->jmp
00422B14 61 popad
00422B15 - E9 4A4D5030 jmp 30927864
00422B1A 8DBE 00C0FEFF lea edi, dword ptr [esi+FFFEC000] ; edi = esi - 14000
00422B20 31C9 xor ecx, ecx ; ecx =0
00422B22 74 06 je short 00422B2A ; if ecx ==0 ->jmp
00422B24 61 popad
00422B25 - E9 4A4D5030 jmp 30927874
2:需要说明的是ADC是与CF相加
//--------------------------------------------------------------------------------------------
00422B78 61 popad
00422B79 57 push edi
00422B7A 83CD FF or ebp, FFFFFFFF ; ebp = -1
00422B7D EB 0B jmp short 00422B8A
00422B7F 90 nop
00422B80 8A06 mov al, byte ptr [esi] ; get byte
00422B82 46 inc esi
00422B83 8807 mov byte ptr [edi], al ; set .code address 将计算后的结果保
存到代码段.
00422B85 47 inc edi
00422B86 01DB add ebx, ebx ; ebx + ebx
00422B88 75 07 jnz short 00422B91 ; ebx + ebx != 0 ->jmp
00422B8A 8B1E mov ebx, dword ptr [esi] ; ESI = .rdata address
00422B8C 83EE FC sub esi, -4 ; esi =esi -4
00422B8F 11DB adc ebx, ebx ; ebx + ebx
00422B91 ^ 72 ED jb short 00422B80
00422B93 B8 01000000 mov eax, 1 ; eax =1
00422B98 01DB add ebx, ebx ; ebx + ebx
00422B9A 75 07 jnz short 00422BA3 ; ebx + ebx != 0 ->jmp
00422B9C 8B1E mov ebx, dword ptr [esi]
00422B9E 83EE FC sub esi, -4 ; esi = esi -4
00422BA1 11DB adc ebx, ebx ; ebx+ebx
00422BA3 11C0 adc eax, eax ; eax + eax
00422BA5 01DB add ebx, ebx ; ebx + ebx
00422BA7 ^ 73 EF jnb short 00422B98
00422BA9 75 09 jnz short 00422BB4
00422BAB 8B1E mov ebx, dword ptr [esi]
00422BAD 83EE FC sub esi, -4
00422BB0 11DB adc ebx, ebx
00422BB2 ^ 73 E4 jnb short 00422B98
00422BB4 31C9 xor ecx, ecx ; ecx = 0
00422BB6 83E8 03 sub eax, 3 ; eax -= 3
00422BB9 72 0D jb short 00422BC8
00422BBB C1E0 08 shl eax, 8 ; eax << 8
00422BBE 8A06 mov al, byte ptr [esi]
00422BC0 46 inc esi ; esi ++
00422BC1 83F0 FF xor eax, FFFFFFFF ; eax ^= -1
00422BC4 74 74 je short 00422C3A ; if eax = 0 -> jmp
00422BC6 89C5 mov ebp, eax ; ebp = eax
00422BC8 01DB add ebx, ebx ; ebx +ebx
00422BCA 75 07 jnz short 00422BD3 ; !=0 ->jmp
00422BCC 8B1E mov ebx, dword ptr [esi]
00422BCE 83EE FC sub esi, -4 ; esi -4
00422BD1 11DB adc ebx, ebx ; ebx+ebx
00422BD3 11C9 adc ecx, ecx ; ecx +ecx
00422BD5 01DB add ebx, ebx
00422BD7 75 07 jnz short 00422BE0
00422BD9 8B1E mov ebx, dword ptr [esi]
00422BDB 83EE FC sub esi, -4 ; esi -4
00422BDE 11DB adc ebx, ebx ; ebx +ebx
00422BE0 11C9 adc ecx, ecx ; ecx +ecx
00422BE2 75 20 jnz short 00422C04 ; ecx != 0->jmp
00422BE4 41 inc ecx ; ecx ++
00422BE5 01DB add ebx, ebx ; ebx+ebx
00422BE7 75 07 jnz short 00422BF0
00422BE9 8B1E mov ebx, dword ptr [esi]
00422BEB 83EE FC sub esi, -4 ; esi -4
00422BEE 11DB adc ebx, ebx ; ebx+ebx
00422BF0 11C9 adc ecx, ecx ; ecx+ecx
00422BF2 01DB add ebx, ebx ; ebx+ebx
00422BF4 ^ 73 EF jnb short 00422BE5
00422BF6 75 09 jnz short 00422C01
00422BF8 8B1E mov ebx, dword ptr [esi]
00422BFA 83EE FC sub esi, -4 ; esi -4
00422BFD 11DB adc ebx, ebx ; ebx+ebx
00422BFF ^ 73 E4 jnb short 00422BE5
00422C01 83C1 02 add ecx, 2 ; ecx += 2
00422C04 81FD 00F3FFFF cmp ebp, -0D00 ; 比较EBP是否为-0D00
00422C0A 83D1 01 adc ecx, 1 ; ecx+cf +1
00422C0D 8D142F lea edx, dword ptr [edi+ebp] ; 代码段计算当前地址+EBP
00422C0D 8D142F lea edx, dword ptr [edi+ebp]
00422C10 83FD FC cmp ebp, -4 ; ?-4
00422C13 76 0F jbe short 00422C24 ; 如果小于-4 不执行,否则就执行下面
00422C15 8A02 mov al, byte ptr [edx] ; 计算后的代码地址
00422C17 42 inc edx ; edx ++
00422C18 8807 mov byte ptr [edi], al ; 保存到当前地址
00422C1A 47 inc edi ; 指针+1
00422C1B 49 dec ecx ; 循环计数-1
00422C1C ^ 75 F7 jnz short 00422C15 ; 不为0就继续循环,实际就是COPY
00422C1E ^ E9 63FFFFFF jmp 00422B86
3:
//--------------------------------------------------------------------------------------------
00422C24 8B02 mov eax, dword ptr [edx] ; edx = code address
00422C26 83C2 04 add edx, 4 ; edx += 4
00422C29 8907 mov dword ptr [edi], eax ; edi =code address
00422C2B 83C7 04 add edi, 4 ; edi += 4
00422C2E 83E9 04 sub ecx, 4 ; ecx -= 4
00422C31 ^ 77 F1 ja short 00422C24 ; ecx > 0 ->loop
00422C33 01CF add edi, ecx ; edi += ecx
经过上面三段后,代码已经被解开了,现在需要做什么呢?我们来看看就知道了,毕竟我还在看.可以看到的是,前面的代码
计算不是很难的,如果两段一样的代码它就直接复制一下了.估计应该是API了吧.
4:
//-------------------------------------------------------------------------------------------
00422C3A 5E pop esi
00422C3B 89F7 mov edi, esi ; esi = code begin address
00422C3D B9 37060000 mov ecx, 637 ; ecx = 637
00422C42 8A07 mov al, byte ptr [edi] ; edi = code address
00422C44 47 inc edi ; edi ++
00422C45 2C E8 sub al, 0E8 ; al - e8
00422C47 3C 01 cmp al, 1 ; al > 1 ->loop
00422C49 ^ 77 F7 ja short 00422C42 ; 寻找是CALL或JMP指令
00422C4B 803F 07 cmp byte ptr [edi], 7 ; [edi] ? 7
00422C4E ^ 75 F2 jnz short 00422C42 ; !=7 ->jmp
00422C50 8B07 mov eax, dword ptr [edi] ; call xxxx read xxxx->eax
00422C52 8A5F 04 mov bl, byte ptr [edi+4] ; [edi + 4] ->bl
00422C55 66:C1E8 08 shr ax, 8 ; ax >> 8
00422C59 C1C0 10 rol eax, 10 ; eax ROL 10
00422C5C 86C4 xchg ah, al
00422C5E 29F8 sub eax, edi ; eax -edi
00422C60 80EB E8 sub bl, 0E8 ; bl -e8
00422C63 01F0 add eax, esi ; eax + esi
00422C65 8907 mov dword ptr [edi], eax ; eax ->call xxxx write xxxx
00422C67 83C7 05 add edi, 5 ; edi + 5
00422C6A 89D8 mov eax, ebx ; eax =ebx
00422C6C ^ E2 D9 loopd short 00422C47 ; 计算地址修改CALL和JMP
5:
//--------------------------------------------------------------------------------------------------
00422C6E 8DBE 00000200 lea edi, dword ptr [esi+20000] ; esi + 20000 esi = code begin
; address 到了输入表函数名部分
00422C74 8B07 mov eax, dword ptr [edi] ; eax = [edi]
00422C76 09C0 or eax, eax
00422C78 74 45 je short 00422CBF ; eax = 0 -> jmp
00422C7A 8B5F 04 mov ebx, dword ptr [edi+4]
00422C7D 8D8430 602B0200 lea eax, dword ptr [eax+esi+22B60] ; dll name address
00422C84 01F3 add ebx, esi
00422C86 50 push eax ; dll name
00422C87 83C7 08 add edi, 8
00422C8A FF96 D82B0200 call dword ptr [esi+22BD8] ; load dll
00422C90 95 xchg eax, ebp
00422C91 8A07 mov al, byte ptr [edi]
00422C93 47 inc edi ; edi ++
00422C94 08C0 or al, al ; al | al
00422C96 ^ 74 DC je short 00422C74
00422C98 89F9 mov ecx, edi ; edi = fun address
00422C9A 79 07 jns short 00422CA3
00422C9C 0FB707 movzx eax, word ptr [edi]
00422C9F 47 inc edi
00422CA3 57 push edi ; edi = fun name
00422CA4 48 dec eax ; eax --
00422CA5 F2:AE repne scas byte ptr es:[edi]
00422CA7 55 push ebp ; dll HANDLE
00422CA8 FF96 DC2B0200 call dword ptr [esi+22BDC]
00422CAE 09C0 or eax, eax
00422CB0 74 07 je short 00422CB9
00422CB2 8903 mov dword ptr [ebx], eax ; ebx = IAT address
00422CB4 83C3 04 add ebx, 4
00422CB7 ^ EB D8 jmp short 00422C91 ; 循环处理函数
上面的代码是依次加载DLL,并获得输入表的函数地址,组建IAT表.下面就回到了OEP.
上面已经基本上分析了算法汇编.总体上来讲就是先解密代码段,再休整CALL和JMP,再就是组建IAT表等了.
//比较好的是,我无意中往下拉了一下,看到了一个EXE头,我想应该是原来的文件头,这样再写脱壳工具的时候
//是十分有用的.我很高兴^_^
004219ED 00 00 00 00 00 00 50 45 00 00 4C 01 04 00 AF BD ......PE..L.
004219FD F6 42 00 00 00 00 00 00 00 00 E0 00 0F 01 0B 01 ........?
00421A0D 06 00 00 40 01 00 00 C0 00 00 00 00 00 00 C7 BB ..@..?.....腔
从它的工作流程来讲,现在已经到了OEP,和UPX来说应该是基本一致的,我还么有研究出到底是因为什么UPX -D无法
脱壳,只有自己写个专版脱壳机了.
么什么技术性的文章,发出来给大家们笑笑,也算是给大家一个乐子,我本来就很白菜,而且进步有慢.高人们就看看
喜欢的就收下吧,不喜欢的就闪了就是了.千万别开口XXXX,我最近很受不了,前段时间也好点了,最近,实在是很差.
说不定以后很少发文章了,大家都支持一下吧~~~~~~~~
先发出来给大家新鲜一下,我整理一下就写个静态脱壳工具,真的最讨厌的就是GameGuard和StarForce.后者已经被
我整的差不多了,就前着还在继续,GameGuard好笑的是,千万别用OD直接调试,不然一下子屏幕黑掉,然后听到硬盘
磁头"仓"的一声,落在了你的扇面上,么关系的按一下电源键就可以重新开启.经过测试,么有无法开启电脑的现象.
后来我用了VC直接挂着调试,很有意思的是,在VC调试的时候GameGuard一直保持更新.N久后么反应,于是我关掉NP
再关掉VC还是N久的更新状态,不更新只显示连接成功.....!_! .我还以为掉线了,打开游戏主页,结果游戏主页打
不开,再问朋友是否能打开,结果朋友打的开,于是我想IP被封了.后来挂了个网站代理,很顺利的打开了主页.
所以结论就是调试NP是会被封IP的........朋友们一定要注意撒~~~~~~~~~~~~~~~!!!!
-By EasyStudy
2008.08.23 凌晨
- 标 题:深入伪UPX分析之一汇编分析
- 作 者:menting
- 时 间:2008-08-23 10:54
- 链 接:http://bbs.pediy.com/showthread.php?t=71248