能力值:
( LV4,RANK:50 )
|
-
-
2 楼
这和COM接口的实现有关系,实际上牵涉到了COM的一个重要概念,即COM对象如何重用的。已经很久没有碰过COM了,凭印象说说。
一般而言,你一开始有一个接口IA,实现了一些feature,不久之后,你觉得需要扩充,COM的推荐做法是实现IA2接口,来实现新的feature,那么在IA2中你如何获得老的功能?有包容和聚合2种方法,前者是把IA的接口全都实现一遍,后者是直接返回一个IA接口给你。但无论是哪种方法,客户都需要从IA2获得IA接口,因为接口ID不同。
所以,对于你的问题,我想,即使你获得了最新的DDraw接口,你要想调用老的方法,还是要取得老的DDraw接口。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
有道理,如果是这样的话,修改起来难度就太大了。毕竟是用反汇编的办法去做,得一个个去人肉调用点,然后逐个修改。。
有时候觉得反汇编修改软件不是什么高技术的活,完全是超重体力劳动,让人扛不住。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
初步试验结果是不行,有些函数能正常调用,有些不行。。杯具
比如call [ecx+54],在游戏本来call的是SetDisplayMode,但改用DDraw7后,就变成SetDisplayMode2了,两个函数形参个数都不一样,直接崩溃。。
|
能力值:
( LV4,RANK:50 )
|
-
-
5 楼
ecx是this指针,它的第一个成员应该是虚表指针,所以应该是 Call [[ecx]+54]
hook SetdisplayMode这个虚函数指针,然后你的hook函数加入不同的调用参数:调用SetdisplayMode2
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
我用的简单的笨办法,就是修改[ecx+54]的值,使它从指向SetDisplayMode2,变为指向原来的SetDisplayMode。这样在SICE中发现调用正常,call完以后屏幕也确实改变了。但跑到后面还是仍然出错,什么图形系统无法初始化。。
这要一个个去跟踪是哪个DD函数失败了,体力消耗真得太大。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
完全错了,我高兴得过早,根本就错得。哎。。。算了。闭关
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
完全错了,大错特错。。
|
能力值:
( LV11,RANK:188 )
|
-
-
9 楼
哈,我恰好也有一个非常喜欢的老游戏,有前人大牛做的程序,我只是修改补充新功能的。我们的实现方式是这样的,
ddraw5的接口完全一样的实现一遍,那些类的接口,也弄成一样的。返回的那个指针,其实就是自己的这个和原ddraw5接口完全一致的假类的地址,游戏调用的就不会出差错。而具体那些函数里怎么执行,其实是直接调用自己这个ddraw类初始化时Create的那个新的系统的DDraw对象的指针,来执行对应的函数的。
但我其实是一个DX白痴,最近在异想天开想把DplayX做手脚,来实现配合服务端做网络穿透的功能,两个思路,一是个ddraw类似的wapper,二是做Dplay支持的那种联网方式扩充,也就是Service Providers。
|
能力值:
( LV3,RANK:20 )
|
-
-
10 楼
1.首先获得接口指针lpDD
DirectDrawCreateEx函数的第二个参数就是
2.VTable(虚表)的首地址是: *(lpDD->lpVTable) 得到虚表的首地址后就可以通过偏移得到DDraw中所有函数的地址.比如SetCooperativeLevel可以用这个首地址加上80来获得
反汇编窗口中:
mov eax, dword ptr [lpDD]
mov ecx, dword ptr [eax]
这个ecx就是 *(lpDD->lpVTable) 也就是上图中的 737137C0,call [ecx+54] 就是在调用 SetDisplayMode 函数,注意这里的54是16进制,转化成10进制就是84
3.虚表反正就是一个函数地址组成的数组,想挂接哪个函数就把相应的地址替换掉就可以了.那些函数的的顺序是固定的,好像就是MSDN里面列出来的顺序
|
|
|