-
-
[原创]家园2 vista win7兼容补丁
-
发表于:
2011-1-2 09:12
34114
-
最近心血来潮,想起了以前有个东西叫做家园2,随即下载下来准备回味一番。结果却在搜索中发现与vista和win7不兼容。
按照网上的方法左试右试发现还是没用,然后我愤怒了,打开了OD。
载入运行,发现问题在这里:
00400110 83EC 04 sub esp,4 <-执行时访问异常。
00400113 50 push eax
00400114 8B4424 08 mov eax,dword ptr ss:[esp+8]
00400118 894424 04 mov dword ptr ss:[esp+4],eax
0040011C 58 pop eax
0040011D 60 pushad
0040011E 8B4424 20 mov eax,dword ptr ss:[esp+20]
00400122 BA 0C094000 mov edx,offset Homeworld2.0040090C
00400127 33DB xor ebx,ebx
00400129 EB 14 jmp short Homeworld2.0040013F
0040012B 390413 cmp dword ptr ds:[edx+ebx],eax
0040012E 75 0C jne short Homeworld2.0040013C
00400130 8B4413 FC mov eax,dword ptr ds:[edx+ebx-4]
00400134 8B00 mov eax,dword ptr ds:[eax]
00400136 894424 20 mov dword ptr ss:[esp+20],eax
0040013A EB 09 jmp short Homeworld2.00400145
0040013C 83EB 08 sub ebx,8
0040013F 833C13 00 cmp dword ptr ds:[edx+ebx],0
00400143 ^ 75 E6 jne short Homeworld2.0040012B
00400145 61 popad
00400146 C3 retn
为什么会这样呢?我们首先想既然破解是这么发布的,所以它这段代码肯定不会有问题。然后结合网上说DEP的问题,我觉得它唯一的问题就是这段代码是写在了PE头部区域中造成的。
大家都知道在xp时代,PE头里面写的代码是可以无忧运行的,堆栈里面的同样也没有问题。但是这时候DEP出现了,不允许将数据区域作为代码执行,所以这个时候上面这些写在PE头里面的代码就无法运行了。
Address = 00400000
Size = 00001000 (4096.)
Owner = Homeworld2 00400000 (self)
Section =
Contains = PE header
Type = Img 01001002
Access = R
Initial access = RWE CopyOnWr
如上所写,我们看见PE头部区域被严格的保护成了只读模式,没有执行的权限。
这是我们就有思路了,我们可以将PE头改成RE(可执行可读),或者我们将上面那段代码搬迁到.text区段中。
很明确的说,结果是可行的,但是为什么我没用呢?这是因为伟大的win7_x64+OD2.0完全搜索不到API的名字……这使我感觉很悲剧=。=
--------------------------------------------------------我是纯洁的分割线---------------------------------------------------------
我们将这一小段代码搬迁到.text区段中的空白数,从00694A6A开始。然后仔细的阅读这一段代码我们发现它引用了0040090C这么一个地址,这里是是什么呢?结合代码,我们认为它应该是一个表。我们按Ascii dump模式看看:
00400638 006958D0 �Xi. ; <&memory.MemCRTFree>
0040063C 00422699 �&B. ; RETURN from Homeworld2.00400110 to Homeworld2.00422699
00400640 00695244 DRi. ; <&fileio.RamStream::Attach>
00400644 0041D41D �A. ; RETURN from Homeworld2.00400110 to Homeworld2.0041D41D
00400648 006958CC �Xi. ; <&memory.MemCRTAlloc>
0040064C 0041CDC4 ��A. ; RETURN from Homeworld2.00400110 to Homeworld2.0041CDC4
00400650 0069585C \Xi. ; <&msvcr70.wcslen>
00400654 0041C90C .�A. ; RETURN from Homeworld2.00400110 to Homeworld2.0041C90C
………………
004008F4 00404497 �D@. ; RETURN from Homeworld2.00400110 to Homeworld2.00404497
004008F8 006958CC �Xi. ; <&memory.MemCRTAlloc>
004008FC 00403940 @9@. ; RETURN from Homeworld2.00400110 to Homeworld2.00403940
00400900 00695F5C \_i. ; <&lua.lua_tonumber>
00400904 004035B1 �5@. ; RETURN from Homeworld2.00400110 to Homeworld2.004035B1
00400908 006958D0 �Xi. ; <&memory.MemCRTFree>
0040090C 00401DEB �@. ; RETURN from Homeworld2.00400110 to Homeworld2.00401DEB
这确实是一张表,那么我们就不用动了,因为查表的时候只有读的操作,这样是不会被和谐的。
然后新问题,我们还要将代码段中所有指向400110的call改过来。怎么办,例遍代码来找?太麻烦了。我们结合查表的代码来看这张表。很明显的以2个DWORD为一组,第一个DWORD为需要跳转到的API,第二个为返回的地址。
这样就简单了,我们写一小段代码取返回地址,然后计算一下调用的距离,然后写入一下就解决了。
或者,你可以更进一步的,将这些调用全部还原成call []的形式。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课