禁止将此文章提及的代码和技术用于违法违规用途, 违者后果自负
Github仓库
mypower是我用 C++ 仿制 scanmem 而来的。但是 mypower 包含了更多高级功能:
一、支持指针引用扫描。这个算是核心功能了,可以分析指针的引用路径。例如,我们扫描出了堆里的血量的指针,然后就可以用这个功能扫描出某个内存区域(通常是.bss或者.data)到血量的一系列指针和偏移量。假如是手机大型游戏,扫描起来会比较慢,这时则可以抓镜像到电脑端,用多核心电脑搭配内置的OpemMP支持进行多线程扫描。
二、支持导出内存镜像。这个可以在手机导出镜像然后拖到电脑上加载做静态分析。
三、命令交互支持数学表达式。这样方便做简单的计算。不需要计算器来回倒腾。
四、可扫描 Unity3D 对象,也可以一键分析指针的类和实例名,也支持字符串内容解析。
目标进程源码
首先运行目标进程,输出如下:
接着运行 mypower ,用 findps 命令查找目标进程。
接着在搜索到的进程列表界面按ESC
进入列表模式,选中进程后按 Enter 即可附加这个进程。也可以用命令 attach -p pid
手动附加,
附加进程后,就可以用扫描命令扫描内存了。这里作为例子我们扫描32位整数scan -i =300
。这行命令意识是扫描精确扫描32位整数300
。如果要扫描大于300的32位整数可以运行scan -i >300
运行扫描命令的结果
很多结果明显是不对的,我们可以过滤一下,因为这时目标进程的内容300变成299了,所以我们输入命令filter <300
把小于300的找出来。
这时结果,很显然[heap]
这一行就是我们的要找的东西。
最后我们尝试一下搜索 world 变量的地址
--mask 是内存块掩码,比如我们要搜索0x563db53396d0, 那么这个指针所处的内存块就是0x563db5339400(0x563db53396d0 & 0xFFFFFFFFFFFFFC00), 然后内存里每8个字节当作一个指针然后(指针 & 0xFFFFFFFFFFFFFC00) == 0x563db5339400的时候,程序就认为找到了对地址0x563db53396d0的引用。接着这个引用指针就会到做下一个目标地址进行下一轮搜索,直到这个指针落在指定的范围内。
--depth-max 意思是最多搜索多少级指针
--offset-max 意思是每级指针的最大偏移量
--result-max 是结构达到这个数量后停止扫描
0x563db339b000 0x563db339c000 是内存区域范围,比如给的是exe的bss段或data段,就是搜索全局变量到目标指针的引用路径。当搜索到落在这个区域的结果时,视为成功。
0x563db53396d0 是目标地址
就这样我们找到了全局变量world
的地址。
这个程序一直都是我自用的,开发理念就是能用就行,各方面都比较简陋,希望大家多多包含。
#include <iostream>
#include <memory>
#include <vector>
struct
Actor {
int32_t hp;
};
struct
World {
std::vector<Actor> actors;
};
std::unique_ptr<World> world;
int
main(
int
argc,
char
*argv[])
{
world.reset(
new
World);
std::cout <<
".bss "
<< (
void
*)&world << std::endl;
world->actors.push_back({});
world->actors.at(0).hp = 300;
while
(1) {
std::cout <<
"hp "
<< world->actors.at(0).hp << std::endl;
getchar
();
world->actors.at(0).hp -= 1;
}
return
0;
}
#include <iostream>
#include <memory>
#include <vector>
struct
Actor {
int32_t hp;
};
struct
World {
std::vector<Actor> actors;
};
std::unique_ptr<World> world;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2024-11-16 13:02
被vrolife编辑
,原因: 添加声明