今天下午在调试某射击软件的时候,想实现无限子弹(子弹数量不限且不换弹夹功能)
CE中通过变量查询很容易就实现了
然后我们按F5 找到谁访问了这个地址 并搜索这个地址 找到基地址+偏移的地址 cshell_x64+0x272EE18+2D4,根据这个地址我们就能进行代码编写从而读写对应的数据
但是我想很多同学都和我一样会疑惑,为什么不能直接搜索6DFF1934这个子弹数量的地址 去 找到 基地址+偏移的结果 而要舍近求远 搜索谁访问了这个地址 再根据CE猜测的地址搜索结果 再加上偏移呢?
查阅了一下午的相关文档,这里跟大家做一个分享
- 当你看到
xxx.dll + 0xXXXX
这种形式,一般表示 “xxx.dll
在进程中的基地址 + 固定偏移”。这是针对模块(DLL/EXE)本身的映像 或者 其全局变量区 才成立的。 - 而你想调试的变量所处的
6DEF1934
往往是堆上或者动态分配的内存,并不在xxx.dll
的映像区(有的甚至在0x00xxxxx
或者0x1Fxxxxx
之类的地址段)。 - 因此,单纯搜
6DEF1934
并不会告诉你它“属于xxx.dll + 某偏移
”,因为它根本就不在xxx.dll
映像的区间。 - 而CE 指针扫描过程就是:
- 先观察哪些代码“访问”了
要调试的内存的地址(假设是A1)
,推断出在内存中可能有个指针假设是A2
正在存A1
。 - 再根据该指针
A2
的地址和上下文,看看A2
是否又被别的指针A3
所存储。 - 一路回溯,直到找到一个“基址 + 偏移”的形式(比如
xxx.dll+0xABCDE
)里存了A3
。
- 先观察哪些代码“访问”了
- 这样才能最终得到一个相对稳定且固定的寻址方式:
xxx.dll + offset
→ 取出指针A3
→ 再加偏移 → 得到A2
→ 再加偏移 → 得到A1
→ 最终读到你的变量。 - 这也是多级指针搜索(Pointer Scan)的原理:并不是
A1
本身永远固定,而是通过一连串指针解引用找回去,找到可以用模块基址或全局区做起点的那根“根指针”。
以上,就是为什么我们CE搜索地址的时候要一步步地去分析 搜索的原因所在,整理的一点点小内容,希望跟遇到类似困惑的同学分享。