如何找基址,原理是什么
CE (cheat engine)修改数值来作弊是一种很大众化的游戏作弊方式了。
尤其是CE设计的很人性化,几乎不需要任何专业知识就能用。
但是有一个问题就是,每次开游戏或者有什么变化,就要重新找内存地址。
小时候没学过编程,但是经常在网上逛,看别人怎么作弊。经常有人提到“基址”这个词。它就是用来解决上面那个问题的关键。如何找基址是写作弊器的核心部分。
有很多教人怎么找基址的教程,基本上都是一步一步,很详细的教怎么做,但是都没有讲为什么。
(废话。。受众都是小时候的我那样的,不懂编程,就想着作弊爽一把的人,讲了原理也看不懂,直接讲怎么做就行了)
现在我是正儿八经程序员了,再回过头看如何找基址,大概知道原理是什么了。
一般来说,先要找到一个内存地址,比如说你通过不断增大减小金钱,用CE搜,搜出来了代表金钱的内存地址。这个地址我们称之为 目标地址 (我瞎起的名字)。 目标地址是会变化的,每次重开游戏,甚至换个角色,换个地图,都有可能变。
所以它的可用性不强。我们需要的是一个稳定的访问方式,这个东西就是基址。
让我们从写游戏的程序员角度来思考,程序里面需要一个地方放金钱。
假设这个游戏是C/C++写的。(一般来说都是这样的,就算不是,一般来说其他语言的底层细节和C是类似的)
最简单的情况:
比如说一个非常简单的小游戏,可能它的金钱直接就是个全局变量。因为这是一个C/C++写的游戏,全局变量的位置应该是固定的。当一个程序被加载后,其映像地址被确定,比如说现在的windows,可执行文件的加载地址一般是 (囧,忘了)。 然后该全局变量就在相对于这个映像地址的某个偏移处,这个偏移是固定的。这种情况,我们在CE搜到的直接就是不变的地址了。
如果是另一种情况:
假设这个游戏有一堆全局变量,写游戏的程序员看着这一堆全局变量很发愁。他决定把代码重构一下。把所有的全局变量整合到一个结构体里面,比如说原来是 血,蓝,金钱 都直接裸体放在全局。现在搞了一个struct,把血,蓝,金钱,都弄到结构体里面,当成员。然后全局放一个这个struct的实例。这样的话,因为这个实例是全局的,它的地址不变,然后金钱在struct内的偏移不变,所以目标地址还是可以直接当基址用。
但是如果更进一步:
假如这个struct太大了,程序员决定把它动态分配,也就是说现在全局放了一个指针,指针指向了一片动态分配出来的内存,放着这个struct。现在我们可以知道,指针是全局的,它的地址不变,但是它的内容是变化的(因为是动态分配的),所以我们搜到的目标地址就是变化的了。但是如果我们每次都先找到指针(指针是全局的,它的地址固定),再找指针指向的位置,得到struct,然后金钱在相对于这个struct的固定偏移处,这样一个迂回的方式,就可以保证每次都取到正确金钱地址了。
基本上其他的都是上面这种指针式的扩展了:
比如说某游戏采用了 一关一关的 数据结构。每关都会重新搞一块儿内存,但是金钱在这块内存的固定偏移处。这样的话,我们需要找到一个东西指向 关卡 ,然后再加一个固定的偏移。
再组合一下,可能金钱不在这个关卡结构的固定偏移处,可能关卡内部一个指针,指向一个角色,然后金钱在这个角色的固定偏移处。这就是两重指针。
当然也可能更复杂。但是总是可以找到一个方式来寻找到目标地址。
可以这样想,游戏本身肯定需要一个方式来访问金钱。这个方式就是 指针 和 固定地址、固定偏移 的组合。
并且这个方式是固定的。既然如此,我们就可以用同样的方式来访问金钱。
(一个相关的问题。以前想过,如果游戏本身加入了随机因素,那么访问方式就不是固定的了。会不会导致我们找不到基址。想了想应该不会。所谓随机,如何随机呢。举个例子,某游戏,在开启时产生一个随机数,然后在一个数组的该随机数偏移处存放金钱。这样我们可以找到存放这个随机数的基址,然后找到存放数组位置的基址,组合起来其实还是 指针和固定地址、固定偏移的组合。只不过这个固定地址(也就是这个随机数)的获得,也需要搞一遍基址。)
原理就是这样。
对照网上的教程,给出一些小时候不明白的地方的解释。
一般来说CE找到目标地址以后,教程里会用CE找,访问此地址的代码。然后找出来一堆。从里面以某种方式选中一项,查看其反汇编。举个例子,假如说金钱放在0x00000018, 然后我们找到的相关反汇编是这样的
mov eax,[0x00001234]
mov ebx, [eax+4] 这条执行完毕后ebx=0x00000010
add [ebx+8],9 金钱增加9
这里我们就可以看到目标地址0x00000018是怎么来的。 首先访问 0x00001234,得到一个数值,把这个数值+4,当成一个地址,访问这个地址得到一个数值,这个数值是0x00000010。 后面我们发现,把它加8得到目标地址,把目标地址的内容加9,也就是金钱增加9.
可以这样想(这是一个猜测),0x00001234是一个全局指针的地址(注意,这个地址是固定的),这个指针指向关卡的数据结构,访问0x1234得到这个指针的内容,也就是关卡的首地址。关卡首地址+4处存放了一个指针。这个指针指向了一个角色的数据结构。访问这个指针得到其内容,也就是角色的首地址。再角色内部+8处存放着金钱。
这样我们就知道 基址是 [[0x00001234]+4]+8 ,这个基址的内容就是金钱,这个基址本身就是金钱的地址。
当然这里是我编的例子,一般来说反汇编出来不会这么紧凑的写着所有关键代码。很有可能我们只能看到
add [ebx+8], 9 ebx=0x00000010
然后周围都是无关代码。
这时候教程做法是在CE里再搜 0x00000010。
为什么要这样呢,我们的目的是找 这个 0x00000010是怎么来的。
这时候我们会在CE里看到很多地方都存放有0x00000010,以某种方式找到其中一项,查看谁访问了它,再找反汇编。
这时候我们有可能看到
mov ebx, [eax+4] 这条执行完毕后ebx=0x00000010, eax=0x00004321
这就是0x00000010怎么来的。是访问 eax +4 得来的, eax=0x00004321,然后再看0x00004321怎么来的。
先搜,再看谁访问,我们又找到了
mov eax,[0x00001234] eax=0x00004321
这就是0x00004321怎么来的,是访问 0x00001234得来的。这个0x00001234哪来的?。。它就是个固定值
所以这样我们就找到了基址。
但是这样有一个很大的缺点。如果像我编的那个很紧凑的例子一样,我们一次性看到了所有相关代码,那自然好。可是如果不是这样(基本上都是这样)。我们就要看某些值是从哪来的。但是关键点就在于,我们是用CE搜的相关值,用CE查的相关代码,谁也不知道是不是驴头不对马嘴,有可能找到的不是同一套访问方式的中间代码和中间值。 这是很有几率的。不过一般来说大量值和中间代码都是类似的,比如说寄存器从eax换成了ecx,但是访问方式还是不变。这就是这个不严谨方式几乎总是能成功的一大部分原因。
(后记:多用了几次以后发现,OD查反汇编虽然理论上来说是最准的,但太费事了,万一某一条线 路上跟丢了简直崩盘,还会时不时用一个不知道哪里赋值的寄存器的值,真累。。有时候还是直接CE强搜比较方便。)
另外一个要提醒的是,有的复杂情况可能中间的+4 +8偏移不是固定值,而是 +ecx 这种变量。然后还要查这个ecx哪来的。
知道了上面这种方式的原理和缺点,就可以知道,上面这种方式完全没必要。最好还是找到目标地址后,看谁访问了,然后直接转到反汇编,看整个上下文,这样保证总是对的。比如说用CE查到目标地址,然后用OD开开,下访问断点,然后看访问的这个东西,如何访问的,就能直接找到一整套的访问方式。
然后就是看反汇编了。找到底如何访问的。
这些内容就没必要说了,看各人功力了
另外,之前我们找到的基址是[[0x00001234]+4]+8,我们的猜测是 0x00001234指向关卡,关卡+4是角色,角色+8是金钱
那我们就可以去试一试,看一看,说不定角色+12是血,+16是蓝呢?
说不定关卡+8是关卡名呢?
另外说一句,一般字符串是C字符串。也就是说是一个指针,指向一个char型数组,以0结尾,查看的时候要注意。
如何找基址,原理是什么相关推荐
- ce查找人物基址_关于CE找基址的一些基础概念
本文纯粹是和想学习这方面知识的新手做简单的技术讨论(咱也算和软件逆向工程沾边了). 作为一个文科生,"基址"到底是个什么东西,这个概念我就折腾了很久,做培训的老师们不会详细讲,网上 ...
- CS起源pointermap找基址+工具函数测试
这是我的爱好,但我不会用这些技术做越界的事情,希望您也是. 这是我的爱好,但我不会用这些技术做越界的事情,希望您也是. 这是我的爱好,但我不会用这些技术做越界的事情,希望您也是. 一.MemHackL ...
- C/C++植物大战僵尸之CE找基址+修改器制作(基础版)
思路: 每个程序打开后他们的数据的内存地址都会改变,但他们的静态基址和偏移不会变 关于获取的是静态基址,所以就算是关闭了游戏,再开启动,地址也是不变的也可以修改 所以我们用CE找到他的静态地址和偏移地 ...
- 网摘-按键精灵屏幕找色原理分析
一.数据提取 位图其实可以看成是一个由象素组成的矩阵,找图找色可以看成是象素值的比对.很多新手在设计这类的程序时喜欢使用TBitmap.Canvas.Pixels属性,这个属性其实是对API函数Get ...
- c语言如何找到进程基址,从0开始学模拟挂(一)--找内存基址,包含原理 _ 脚本
PS:12楼的兄弟,不能回到选择人物画面,那你就换个地图试试,也可以请看下篇,找内存基址方法(二), 有人问怎么自动加血,我板凳帖子里不是有了,读取血内存地址的代码了吗? 把那份代码,你用两次,第一次 ...
- 从0开始学模拟挂(一)--找内存基址,包含原理 _ 脚本..._按键精灵论坛
PS:12楼的兄弟,不能回到选择人物画面,那你就换个地图试试,也可以请看下篇,找内存基址方法(二),页面 有人问怎么自动加血,我板凳帖子里不是有了,读取血内存地址的代码了吗? 把那份代码,你用两次,第 ...
- 使用CE找天龙八部基址(图解)毛头小伙制作
使用CE找天龙八部基址(图解)毛头小伙制作 这几天很无聊,刚学会用CE找基址,就拿天龙试下,还真行.在网上很难找到天龙的外挂程序,谁有写好的易代码给偶一个,在这里先谢了. 下面开始了,不明白的地方可以 ...
- 关于FPS透视原理的研究(一)
关于FPS透视原理的研究(一) 方向一GDI绘制 1.CE找基址,人物X,Y,Z鼠标X,Y 这里我选择获取模块句柄的方式为跨进程访问 还有一种为注入方法用到GetModuleHandle 读取数据并在 ...
- 【大数据】大数据思维的十大核心原理
感谢博主,转自:https://blog.csdn.net/supermapsupport/article/details/78741774 一.数据核心原理 从"流程"核心转变为 ...
最新文章
- ERROR: Failed to resolve: com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.46
- 解决list-style-type属性失效
- 继续C#开发or转做产品
- Dubbo环境搭建-管理控制台dubbo-admin实现服务监控
- 数据结构整理中。。。
- python函数:基础函数调用整理
- 获取php服务器ip地址,PHP获取客户端和服务器IP地址
- python基础—字典
- gpio mysql_GPIO控制LED
- 临时设置mysql数据库最大连接数,重启后需重新设置
- vue实现垂直无限滑动日历组件
- wpdec函数_小波包分解常用函数
- 用java做考试管理系统,考试管理系统的开发实现(Java+Web)
- 为公寓运营商提供SaaS管理系统,寓小二获贝壳找房5000万元A轮融资...
- mysql最大整数类型_MySQL教程19-整数类型
- 单片机c语言有没有跳转指令,51单片机跳转指令
- 微信小程序项目从app.js中获取数据
- Android尺子布局和自定义TextView
- ShareSDK Android 第三方平台分享参数说明
- 安搭Share:如果说格局决定人生,那么什么决定格局
热门文章
- GPT解读(论文 + TensorFlow实现)
- Java Thread的使用类
- signature=e260e08d0d5973d18c37cc596c51cae8,女性不妊症領域におけるレーザー手術の現況...
- 软件赋能 数智转型 GBASE南大通用亮相南京软博会
- python中map函数定义及使用方法、技巧
- 消费积分与顾客忠诚计划
- 面试题64. 求1+2+…+n(C++)
- 让android程序根据重力感应旋转屏幕(支持4个方向旋转)
- 微信小程序中引用vant组件库
- annotate标注解释