收藏首页
您所在的位置:首页 > 完美国际sf > 正文

完美国际游戏主程序封包和解包教程

作者:admin 来源: 日期:2017-5-18 10:59:12 人气:51 加入收藏 标签:

有的补丁是用MoleBox封的包,这个软件很多使用方法也就不介绍了也不复杂

以下是在看雪论坛上找到的关于脱壳的文章希望对大家有用




【文章标题】: MoleBox 脱壳的一些总结

【文章作者】: CCDebuger

【软件名称】: Ultra Video Converter

【下载地址】: http://www.zxmedia.com/ultra_videoconverter.exe

【作者声明】: 无他,仅是自己调试时的一些记录,方便查阅而已

--------------------------------------------------------------------------------

【详细过程】

论坛上写MoleBox脱壳教程的已经有不少了,大家应该知道MoleBox会加密输入表。我看了几个MoleBox加的壳和MoleBox的主程序,发现这个壳还是挺有意思的。只要你找好关键点,可以 dump 出来一个完整的未加壳前的程序,MoleBox的那个加密输入表的功能根本没用。这篇文章只是我自己的一个调试记录,只是为了方便自己查阅。大家可以参考一下。OK,现在进入正题。


一、主程序脱壳


在 OD 中忽略所有异常,载入程序:


00470B53 > E8 00000000 CALL Ultra_Vi.00470B58 ; OD载入后停在这

00470B58 60 PUSHAD

00470B59 E8 4F000000 CALL Ultra_Vi.00470BAD ; F8到这里的时候在命令行中输入hr esp


完成上面的操作后,直接按 F9,会断在这里:


00470731 58 POP EAX ; 断在这里

00470732 58 POP EAX

00470733 FFD0 CALL EAX ; 这里F7进去就是OEP


我们到 00470733 地址处时按 F7 进去,就到 OEP 了:


0042304E 55 PUSH EBP ; OEP

0042304F 8BEC MOV EBP,ESP

00423051 6A FF PUSH -1

00423053 68 90A74200 PUSH Ultra_Vi.0042A790

00423058 68 B8314200 PUSH Ultra_Vi.004231B8 ; JMP 到 msvcrt._except_handler3

0042305D 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]

00423063 50 PUSH EAX

00423064 64:8925 0000000>MOV DWORD PTR FS:[0],ESP

0042306B 83EC 68 SUB ESP,68

0042306E 53 PUSH EBX

0042306F 56 PUSH ESI

00423070 57 PUSH EDI

00423071 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP

00423074 33DB XOR EBX,EBX

00423076 895D FC MOV DWORD PTR SS:[EBP-4],EBX

00423079 6A 02 PUSH 2

0042307B FF15 38764200 CALL DWORD PTR DS:[427638] ; msvcrt.__set_app_type


看 OEP 开始的代码就知道这是个典型的 VC 程序。记住 OEP 的 RVA = 0042304E - 00400000 = 2304E。随便找个 API 调用,如 0042307B 处的这句。左键选择这句,按鼠标右键,选择弹出菜单 数据窗口中跟随->内存地址。现在在数据窗口中按CTR+G转到427638(这样做主要是为了便于OD记住这个地址),重新启动程序,在数据窗口中转到我们上次记住的地址,设内存写入断点。在数据窗口中按右键切换一下视图,选择长型->地址,这样便于观察。经过几次中断后,数据窗口中会看到这样的内容:


00427624 73DC067B MFC42.#952_??_afxSOCK@@3UAFX_SOCK_CALL@@A@@YAXXZ

00427628 73DCC3C8 MFC42.#3716_?GetRuntimeClass@CSliderCtrl@@UBEPAUCRuntimeClass@@XZ

0042762C 73D8ACCE MFC42.#541_??0CStringArray@@QAE@XZ

00427630 00000000

00427634 77C1EE2F msvcrt._controlfp

00427638 0002E8E4

0042763C 0002E8D6

00427640 0002E8C6

00427644 0002E8B6

00427648 0002E8A2

0042764C 0002E896

00427650 0002F52C

00427654 0002E87C

00427658 0002E874

0042765C 0002E866


可见00427638下面的都没被填充,而上面已经填入了API函数的实际地址了。重来,在上面填充过地址的地方重设内存断点,直到输入表部分都显示为这样的:


00427638 0002E8E4

0042763C 0002E8D6

00427640 0002E8C6

00427644 0002E8B6

00427648 0002E8A2


现在就可以dump了。用16进制工具打开dump后的文件,推荐用 010Editor。先定位到输入表所在区段,查找 ASCII 字串“.dll”,看看找到的地方,比如看到了 KERNEL32.dll。记下 KERNEL32.dll 的开始地址,逆序转换一下(可以用 Hpmbcalc Hex Calculator 来转换),再在输入表所在段中搜索 KERNEL32.dll 开始地址的逆序字串,一般只会找到一个地方。根据 IAT 的结构,名称在第四个字段,往前再数12个字节就是这个 DLL 调用信息开始的地方。再根据 IAT 最后以20个0结束,就可以确定输入表的开始地址和大小了。把我们找到的 OEP 和 IAT 信息用 PE 编辑工具填入 dump 后的文件就可以了。

--------------------------------------------------------------------------------------------------

上面说的是一种跟踪加壳程序处理输入表比较通用的方法。对于 MoleBox,为了得到完好的输入表,可以 BP VirtualProtect 设断点。这也分两种情况:


1、MoleBoxPro_2.6.1.2387主程序脱壳例子


先到MoleBox壳的EP,设断 BP VirtualProtect,中断两次后返回,来到下面的地方:


0043AB9D FF15 AC774400 CALL DWORD PTR DS:[4477AC] ; kernel32.VirtualProtect

0043ABA3 8B15 84764400 MOV EDX,DWORD PTR DS:[447684] ; [00447684]=00CD1F00,地址00CD1F00中就是OEP

0043ABA9 8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18]

0043ABAC 0342 08 ADD EAX,DWORD PTR DS:[EDX+8] ; [00CD1F08]=00027B00,输入表的RVA。这里直接dump文件

0043ABAF 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX

0043ABB2 C705 14794400 0>MOV DWORD PTR DS:[447914],0

0043ABBC 6A 00 PUSH 0

0043ABBE 68 246C4400 PUSH mbox2w.00446C24 ; ASCII "EXECUTABLE"

0043ABC3 8B0D 10794400 MOV ECX,DWORD PTR DS:[447910] ; mbox2w.00400108

0043ABC9 51 PUSH ECX

0043ABCA 8B55 E8 MOV EDX,DWORD PTR SS:[EBP-18]

0043ABCD 52 PUSH EDX

0043ABCE 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C]

0043ABD1 50 PUSH EAX

0043ABD2 E8 E9FAFFFF CALL mbox2w.0043A6C0

0043ABD7 83C4 14 ADD ESP,14

0043ABDA E8 B30F0000 CALL mbox2w.0043BB92

0043ABDF 25 FF000000 AND EAX,0FF

0043ABE4 85C0 TEST EAX,EAX

0043ABE6 74 15 JE SHORT mbox2w.0043ABFD

0043ABE8 E8 B60F0000 CALL mbox2w.0043BBA3

0043ABED 25 FF000000 AND EAX,0FF

0043ABF2 85C0 TEST EAX,EAX

0043ABF4 74 02 JE SHORT mbox2w.0043ABF8

0043ABF6 ^ EB F0 JMP SHORT mbox2w.0043ABE8

0043ABF8 E8 950F0000 CALL mbox2w.0043BB92

0043ABFD 68 846C4400 PUSH mbox2w.00446C84 ; ASCII "imm32.dll"

0043AC02 FF15 18774400 CALL DWORD PTR DS:[447718] ; kernel32.GetModuleHandleA

0043AC08 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX

0043AC0B 837D E4 00 CMP DWORD PTR SS:[EBP-1C],0

0043AC0F 74 0E JE SHORT mbox2w.0043AC1F

0043AC11 68 846C4400 PUSH mbox2w.00446C84 ; ASCII "imm32.dll"

0043AC16 8B4D E4 MOV ECX,DWORD PTR SS:[EBP-1C]

0043AC19 51 PUSH ECX

0043AC1A E8 31000000 CALL mbox2w.0043AC50

0043AC1F 68 746C4400 PUSH mbox2w.00446C74 ; ASCII "oleoaut32.dll"

0043AC24 FF15 18774400 CALL DWORD PTR DS:[447718] ; kernel32.GetModuleHandleA

0043AC2A 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX

0043AC2D 837D F0 00 CMP DWORD PTR SS:[EBP-10],0

0043AC31 74 0E JE SHORT mbox2w.0043AC41

0043AC33 68 646C4400 PUSH mbox2w.00446C64 ; ASCII "oleaout32.dll"


2、极品时刻表的例子


如果未发现与上面代码类似的内容,可以结合堆栈来看。比如极品时刻表,Delphi 程序,里面是aspack的壳。BP VirtualProtect第一次断下来的时候看堆栈:


0012FDB8 004F621C /CALL 到 VirtualProtect 来自 JPSKB061.004F6216

0012FDBC 004E9F5C |Address = JPSKB061.004E9F5C

0012FDC0 00000004 |Size = 4

0012FDC4 00000004 |NewProtect = PAGE_READWRITE

0012FDC8 0012FDCC \pOldProtect = 0012FDCC

0012FDCC 00000000

0012FDD0 003D20EC

0012FDD4 005021B8 JPSKB061.005021B8

0012FDD8 00000000

0012FDDC /0012FE30

0012FDE0 |004F5AA6 返回到 JPSKB061.004F5AA6 来自 JPSKB061.004F61D0

0012FDE4 |004E9F5C JPSKB061.004E9F5C

0012FDE8 |00501B44 ASCII "EXECUTABLE"

0012FDEC |004E9F6C ASCII "kernel32.dll"

0012FDF0 |00000001

0012FDF4 |00000000

0012FDF8 |00000000

0012FDFC |0045AB2C JPSKB061.0045AB2C

0012FE00 |00501B4E JPSKB061.00501B4E

0012FE04 |00501B4E JPSKB061.00501B4E

0012FE08 |C1CC0928

0012FE0C |39ADD078

0012FE10 |004E9F79 JPSKB061.004E9F79

0012FE14 |004E9F6C ASCII "kernel32.dll"

0012FE18 |004E9F5C JPSKB061.004E9F5C

0012FE1C |004E9F6C ASCII "kernel32.dll"

0012FE20 |7C800000 kernel32.7C800000

0012FE24 |FA46F001

0012FE28 |004E9F5C JPSKB061.004E9F5C

0012FE2C |00000000

0012FE30 ]0012FE74

0012FE34 |004F5C54 返回到 JPSKB061.004F5C54 来自 JPSKB061.004F58A0 ;右键选择这里,在反汇编窗口中跟随

0012FE38 |004E9FAC JPSKB061.004E9FAC

0012FE3C |00400000 ASCII "MZP"

0012FE40 |00400100 ASCII "PE"

0012FE44 |00501B44 ASCII "EXECUTABLE"

0012FE48 |00000000

0012FE4C |00000001

0012FE50 |00000000

0012FE54 |00000001

0012FE58 |00000000

0012FE5C |004EF564 ASCII ".adata"

0012FE60 |003D0000

0012FE64 |00400000 ASCII "MZP"

0012FE68 |0000000A

0012FE6C |004E9FAC JPSKB061.004E9FAC

0012FE70 |0000000A

0012FE74 ]0012FF94

0012FE78 |004EFF6B 返回到 JPSKB061.004EFF6B 来自 JPSKB061.004F5B10

0012FE7C |7C930738 ntdll.7C930738


在堆栈中的第二个返回上右键选择反汇编窗口中跟随,会来到这样的地方:


004F5C16 E8 65000000 CALL JPSKB061.004F5C80

004F5C1B ^ E9 4DFFFFFF JMP JPSKB061.004F5B6D

004F5C20 8B15 08255000 MOV EDX,DWORD PTR DS:[502508] ; 放OEP的地方

004F5C26 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]

004F5C29 0342 08 ADD EAX,DWORD PTR DS:[EDX+8]

004F5C2C 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX

004F5C2F C705 38275000 0>MOV DWORD PTR DS:[502738],0

004F5C39 6A 00 PUSH 0

004F5C3B 68 441B5000 PUSH JPSKB061.00501B44 ; EXECUTABLE

004F5C40 8B0D 34275000 MOV ECX,DWORD PTR DS:[502734] ; JPSKB061.00400100

004F5C46 51 PUSH ECX

004F5C47 8B55 F0 MOV EDX,DWORD PTR SS:[EBP-10]

004F5C4A 52 PUSH EDX

004F5C4B 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]

004F5C4E 50 PUSH EAX

004F5C4F E8 4CFCFFFF CALL JPSKB061.004F58A0

004F5C54 83C4 14 ADD ESP,14 ; 返回到这里

004F5C57 68 841B5000 PUSH JPSKB061.00501B84 ; imm32.dll

004F5C5C FF15 9C255000 CALL DWORD PTR DS:[50259C] ; kernel32.GetModuleHandleA

004F5C62 8945 EC MOV DWORD PTR SS:[EBP-14],EAX

004F5C65 837D EC 00 CMP DWORD PTR SS:[EBP-14],0

004F5C69 74 0E JE SHORT JPSKB061.004F5C79

004F5C6B 68 841B5000 PUSH JPSKB061.00501B84 ; imm32.dll

004F5C70 8B4D EC MOV ECX,DWORD PTR SS:[EBP-14]

004F5C73 51 PUSH ECX

004F5C74 E8 F7010000 CALL JPSKB061.004F5E70

004F5C79 8BE5 MOV ESP,EBP

004F5C7B 5D POP EBP

004F5C7C C3 RETN


004F5C20就是我们要找的地方。


对上面的第二种情况,根据上面看到的代码,也可以尝试搜索命令序列:


MOV EAX,DWORD PTR SS:[EBP-10]

ADD EAX,DWORD PTR DS:[EDX+8]

MOV DWORD PTR SS:[EBP-8],EAX


如极品时刻表,搜索以上命令序列时,会找到这样的地方:


004F5C16 E8 65000000 CALL JPSKB061.004F5C80

004F5C1B ^ E9 4DFFFFFF JMP JPSKB061.004F5B6D

004F5C20 8B15 08255000 MOV EDX,DWORD PTR DS:[502508]

004F5C26 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10] ; 找到的地方

004F5C29 0342 08 ADD EAX,DWORD PTR DS:[EDX+8]

004F5C2C 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX

004F5C2F C705 38275000 0>MOV DWORD PTR DS:[502738],0

004F5C39 6A 00 PUSH 0

004F5C3B 68 441B5000 PUSH JPSKB061.00501B44 ; EXECUTABLE

004F5C40 8B0D 34275000 MOV ECX,DWORD PTR DS:[502734] ; JPSKB061.00400100

004F5C46 51 PUSH ECX

004F5C47 8B55 F0 MOV EDX,DWORD PTR SS:[EBP-10]

004F5C4A 52 PUSH EDX

004F5C4B 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]

004F5C4E 50 PUSH EAX

004F5C4F E8 4CFCFFFF CALL JPSKB061.004F58A0

004F5C54 83C4 14 ADD ESP,14

004F5C57 68 841B5000 PUSH JPSKB061.00501B84 ; imm32.dll

004F5C5C FF15 9C255000 CALL DWORD PTR DS:[50259C] ; kernel32.GetModuleHandleA

004F5C62 8945 EC MOV DWORD PTR SS:[EBP-14],EAX

004F5C65 837D EC 00 CMP DWORD PTR SS:[EBP-14],0

004F5C69 74 0E JE SHORT JPSKB061.004F5C79

004F5C6B 68 841B5000 PUSH JPSKB061.00501B84 ; imm32.dll

004F5C70 8B4D EC MOV ECX,DWORD PTR SS:[EBP-14]

004F5C73 51 PUSH ECX

004F5C74 E8 F7010000 CALL JPSKB061.004F5E70

004F5C79 8BE5 MOV ESP,EBP

004F5C7B 5D POP EBP

004F5C7C C3 RETN


总体看来,MoleBox解压程序前字串“EXECUTABLE”是个非常重要的标志,而在 VirtualProtect 函数上设断点,是个不错的选择。


二、捆绑文件


1、文件数目


要知道捆绑文件的数目,可以通过 BP GetFileTime 设断得到。以 Ultra Video Converter 为例,中断后取消断点Alt+F9返回:


00476C8C FF15 84364800 CALL DWORD PTR DS:[483684] ; kernel32.GetFileTime

00476C92 C745 AC 00000000 MOV DWORD PTR SS:[EBP-54],0 ; 返回到这里

00476C99 EB 09 JMP SHORT Ultra_Vi.00476CA4

00476C9B 8B4D AC MOV ECX,DWORD PTR SS:[EBP-54]

00476C9E 83C1 01 ADD ECX,1

00476CA1 894D AC MOV DWORD PTR SS:[EBP-54],ECX

00476CA4 8B55 AC MOV EDX,DWORD PTR SS:[EBP-54]

00476CA7 3B55 9C CMP EDX,DWORD PTR SS:[EBP-64] ; 这里[EBP-64]=1,就是捆绑文件的数目

00476CAA 0F83 E3000000 JNB Ultra_Vi.00476D93

00476CB0 8B45 AC MOV EAX,DWORD PTR SS:[EBP-54]

00476CB3 C1E0 04 SHL EAX,4

00476CB6 8B4D E0 MOV ECX,DWORD PTR SS:[EBP-20]

00476CB9 8B51 04 MOV EDX,DWORD PTR DS:[ECX+4]

00476CBC 8B4D DC MOV ECX,DWORD PTR SS:[EBP-24] ; [EBP-24]=003D2370,数据窗口中可以看到文件名

00476CBF 030C02 ADD ECX,DWORD PTR DS:[EDX+EAX]

00476CC2 8B55 AC MOV EDX,DWORD PTR SS:[EBP-54]

00476CC5 C1E2 04 SHL EDX,4


2、参与运行的可执行文件


对于参与运行的可执行文件,可以通过以下三个断点获取文件:


(1) BP CreateFileA,断下后看堆栈,根据堆栈显示信息改文件名(在 BP CreateFileA 之前,可以通过 BP GetCurrentProcessId 看到对捆绑文件更名的处理)。

(2) BP GetModuleHandleA,断下后取消断点(BP VirtualProtect 在对付捆绑文件时好像也很有功效,能得到OEP地址。有空再仔细研究)。

(3) 在参与执行的 DLL 代码段上设内存访问断点,到达OEP。


而在第二步时dump下来,文件的输入表都是未被填充过的。只要修正一下OEP,重定位表、输入表的RVA和大小,必要时修正一下基址,就OK了。


对于采用上面的第三步找OEP无效的文件,这时可以在上面的第一步后 BP GetSystemTimeAsFileTime,中断两次后ALT+F9返回(以下都以 MoleBoxPro_2.6.1.2387 主程序为例):


00436FE1 FF15 2C774400 CALL DWORD PTR DS:[44772C] ; kernel32.GetSystemTimeAsFileTime

00436FE7 8B45 C4 MOV EAX,DWORD PTR SS:[EBP-3C] ; 回到这里,[EBP-3C]中就是PE文件头

00436FEA 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]

00436FED 64:890D 00000000 MOV DWORD PTR FS:[0],ECX


数据窗口中显示如下:


00D30098 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ?......




这个就是所谓的把重要文件,也就是data文件夹里的文件封状到elementclient.exe里的软件了哦.



    本文网址:http://www.wmxiaoai.com/wanmei/html/wmgj/184.html
    读完这篇文章后,您心情如何?
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0