首页
社区
课程
招聘
[求助]可以修改游戏的DirectDraw对象吗?
发表于: 2011-8-28 19:22 6009

[求助]可以修改游戏的DirectDraw对象吗?

2011-8-28 19:22
6009
一个老游戏,我想加些新功能,这必须要用到新版的DDraw。但它用的是最老版本的DDraw对象。我想能不能修改它的DD对象创建函数,使它改为创建新版的DDraw7对象。
不知道这样会不会导致游戏无法运行,我觉得DDraw是向下兼容的,理论上似乎可行。游戏使用新版的IDirectDraw7接口,仍然可以调用老版本的DD函数吧。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
这和COM接口的实现有关系,实际上牵涉到了COM的一个重要概念,即COM对象如何重用的。已经很久没有碰过COM了,凭印象说说。

一般而言,你一开始有一个接口IA,实现了一些feature,不久之后,你觉得需要扩充,COM的推荐做法是实现IA2接口,来实现新的feature,那么在IA2中你如何获得老的功能?有包容和聚合2种方法,前者是把IA的接口全都实现一遍,后者是直接返回一个IA接口给你。但无论是哪种方法,客户都需要从IA2获得IA接口,因为接口ID不同。

所以,对于你的问题,我想,即使你获得了最新的DDraw接口,你要想调用老的方法,还是要取得老的DDraw接口。
2011-8-28 21:31
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
有道理,如果是这样的话,修改起来难度就太大了。毕竟是用反汇编的办法去做,得一个个去人肉调用点,然后逐个修改。。
有时候觉得反汇编修改软件不是什么高技术的活,完全是超重体力劳动,让人扛不住。
2011-8-28 21:46
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
初步试验结果是不行,有些函数能正常调用,有些不行。。杯具
比如call [ecx+54],在游戏本来call的是SetDisplayMode,但改用DDraw7后,就变成SetDisplayMode2了,两个函数形参个数都不一样,直接崩溃。。
2011-8-29 21:50
0
雪    币: 8753
活跃值: (5215)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
ecx是this指针,它的第一个成员应该是虚表指针,所以应该是 Call [[ecx]+54]
hook SetdisplayMode这个虚函数指针,然后你的hook函数加入不同的调用参数:调用SetdisplayMode2
2011-8-29 22:06
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我用的简单的笨办法,就是修改[ecx+54]的值,使它从指向SetDisplayMode2,变为指向原来的SetDisplayMode。这样在SICE中发现调用正常,call完以后屏幕也确实改变了。但跑到后面还是仍然出错,什么图形系统无法初始化。。
这要一个个去跟踪是哪个DD函数失败了,体力消耗真得太大。
2011-8-29 22:43
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
完全错了,我高兴得过早,根本就错得。哎。。。算了。闭关
2011-8-29 22:54
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
完全错了,大错特错。。
2011-8-29 23:19
0
雪    币: 242
活跃值: (468)
能力值: ( LV11,RANK:188 )
在线值:
发帖
回帖
粉丝
9
哈,我恰好也有一个非常喜欢的老游戏,有前人大牛做的程序,我只是修改补充新功能的。我们的实现方式是这样的,
ddraw5的接口完全一样的实现一遍,那些类的接口,也弄成一样的。返回的那个指针,其实就是自己的这个和原ddraw5接口完全一致的假类的地址,游戏调用的就不会出差错。而具体那些函数里怎么执行,其实是直接调用自己这个ddraw类初始化时Create的那个新的系统的DDraw对象的指针,来执行对应的函数的。
但我其实是一个DX白痴,最近在异想天开想把DplayX做手脚,来实现配合服务端做网络穿透的功能,两个思路,一是个ddraw类似的wapper,二是做Dplay支持的那种联网方式扩充,也就是Service Providers。
2011-8-30 09:03
0
雪    币: 14
活跃值: (28)
能力值: ( 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里面列出来的顺序
2011-8-31 20:02
0
游客
登录 | 注册 方可回帖
返回
//