我有一个游戏代码(来自ioquake3项目),用于编译游戏中的二进制文件(qvm系统)的一部分。现在,可以通过加载此操作的以前保存的二进制文件(使用任何文件更改预防措施)来加速它。以编程方式替换二进制文件的非常小的部分的正确方法是什么?
但是,保存在这些二进制文件中的函数指针并不是通过会话持久化的。
什么是正确的方式来改变那些在飞行中? (考虑在主应用程序中有一个汇编程序和汇编程序)
我有一个游戏代码(来自ioquake3项目),用于编译游戏中的二进制文件(qvm系统)的一部分。现在,可以通过加载此操作的以前保存的二进制文件(使用任何文件更改预防措施)来加速它。以编程方式替换二进制文件的非常小的部分的正确方法是什么?
但是,保存在这些二进制文件中的函数指针并不是通过会话持久化的。
什么是正确的方式来改变那些在飞行中? (考虑在主应用程序中有一个汇编程序和汇编程序)
这几乎是可执行文件的普通加载程序所做的。他们通常通过存储地址表的方式来工作,这些地方有对地址的引用,这些地址需要根据文件的加载位置进行更改。通常,它们在每个位置存储相对地址,因此要加载文件,您需要查看表并将基本加载地址添加到每个地址处的内容,然后将该结果加载到映像中,并将其加载到内存中。
传递相关函数指针表作为参数。或者,您可以使用生成的代码依赖于相对于代码,位置固定的数据区域。我记得当我搞这个东西的时候,我会设置一个读/写/执行内存页面,使用前半部分生成代码,后半部分用于数据。代码一旦得到控制,就会这样:
call l
l:
pop eax ; eax has the current eip
and eax, 0fffff000h ;round down to the page size, 4K AKA 0x1000
add eax, 800h ;now eax points at the data area
...等等。
对于大规模生成的代码,您可能希望将其存储为完整的DLL并使用系统提供的重定位和地址修复服务。
什么操作系统?答案可能是操作系统特定的。 – 2010-03-07 03:44:05
我知道你想编辑二进制文件,但我不太确定你的问题的其余部分。为什么指针首先改变?你怎么知道在不重新编译的情况下做出什么改变?也许我错过了一些东西,但我完全不明白你的问题。 – zdav 2010-03-07 03:56:57