游戏辅助原理基址与动态地址
游戏辅助原理——基址与动态地址
版权声明:
在前面一节课我们已经实现了游戏的阳光值修改,并且也写出了程序,现在我们重新打开游戏,再启动我们写的程序,并进行修改:
我们发现,修改失败!这是为什么呢?难道我们的阳光的内存地址发生了变化?
我们打开工具,再次进行寻找:
我们重新寻找后,发现现在的阳光内存地址为:171A2578,而我们之前所找到的地址是:20194DC8。看来我们的阳光地址已经发生了变化,那这到底是为什么呢?
这里,一些C/C++比较好的同学和有过游戏开发经验可能已经推断出来了,其实这就是我们C/C++语言通常用到的一个做法:动态内存分配。
我们把游戏的阳光值当作C语言的一个变量,可以简单的理解为:int n_sunshine;那么这个游戏的经过编译后,这个变量的地址在以下几种情况下是会发生变化的:
1.作为局部变量的时候。
2.n_sunshine在某个结构体(或者类)里面,而这个结构体或者类的内存是动态分配的。
当其作为全局变量时,程序编译的时候已经分配好了全局数据区的地址,所以里面的数据地址是不会变得。简单点来说,动态分配就是在运行时分配的,具体怎么分配,由操作系统决定,而全局变量的地址,是编译时就确定的,所以是不会变的。
那么,阳光值到底是怎样的一个情况呢。对于游戏的开发,一般都是面向对象的,所以我们可以推测阳光值这个变量应该在某个类的示例指针里面,类的示例指针在运行时进行动态内存的分配,为其分配内存。为了阐述这个过程,我用简单的代码的表示:
class Game_Info{
int n_Sunshine;
//阳光值
....
//其它成员
}
Game_Info *Game_Info_PvZ;
int main()
{
Game_Info_PvZ =
new Game_Info;
return
0;
}
在代码中,我定义了一个类Game_Info,并定义了这个类的示例指针Game_Info_PvZ。这个指针变量的地址,是存在全局数据区的,地址并不会随运行改变。在主函数中,我们为这个实例指针动态分配了内存,这句代码是在运行中执行的,所以所分配的内存的地址是不定的,所以阳光值的地址也是不定的。
到这里,我们就可以解释为什么我们每次找的阳光地址都发生了改变了 。我们这里提出两个概念:基址和动态地址。对于这里的基址,我们可以理解成在全局数据区的数据的地址,它的地址是不会发生改变的。对于动态地址,则是我们程序在运行时动态分配的地址,它的地址是不会发生改变的。
<script>
(function(){
function setArticleH(btnReadmore,posi){
var winH = $(window).height();
var articleBox = $("div.article_content");
var artH = articleBox.height();
if(artH > winH*posi){
articleBox.css({
'height':winH*posi+'px',
'overflow':'hidden'
})
btnReadmore.click(function(){
if(typeof window.localStorage === "object" && typeof window.csdn.anonymousUserLimit === "object"){
if(!window.csdn.anonymousUserLimit.judgment()){
window.csdn.anonymousUserLimit.Jumplogin();
return false;
}else if(!currentUserName){
window.csdn.anonymousUserLimit.updata();
}
}
articleBox.removeAttr("style");
$(this).parent().remove();
})
}else{
btnReadmore.parent().remove();
}
}
var btnReadmore = $("#btn-readmore");
if(btnReadmore.length>0){
if(currentUserName){
setArticleH(btnReadmore,3);
}else{
setArticleH(btnReadmore,1.2);
}
}
})()
</script>
</article>
优秀博主: