这是一个内存修改工具,好象是一个中华儿女写的。
它自带咯一个图形界面前端,叫做GameConqueror,在MagicLinux上面会运行出错,所以本座就只用它的命令行程序scanmem咯。
为咯研究这个工具的用法,本座写咯一个尽可能简单的试验程序作为操作目标。
试验程序是这样的:
这个窗口类MemTest有一个成员变量Number,界面上有Set和Read两个按钮。当点击Set时,会把它左侧那个旋转框的数值赋值给Number。当点击Read时,会把Number的值显示在它左侧的旋转框中。
试验步骤:
1.使用Set按钮将内部的Number值设置成1988.
2.使用Read按钮读取内部的Number值,此时左边两个旋转框都显示1988.
3.使用scanmem找到MemTest进程内部的那个Number的地址。在这一步中需要多次手动操作MemTest程序的Set按钮,使内部Number的值发生变化,以让scanmem能够过滤出该变量的真正内存地址。
4.使用scanmem来将程序内部的那个Number修改成1900.
5.使用Read按钮读取内部的Number值,此时下面一个旋转框应该显示1900.如果是这样,就表示内存修改成功咯。
另外还要有一个常识,就是像MemTest::Number这样的成员变量是储存在进程的栈里的。
开始做了。
运行起MemTest程序,Set一次,Read一次,这个时候两个旋转框显示1988,并且内部的那个Number的值也是1988了。
使用系统监视器查出MemTest进程的进程号,scanmem需要知道目标进程的进程号。这里查到的是10176:
下面开始使用scanmem。
在终端中直接启动scanmem:
使用pid命令告诉它要干进程号为10176的进程:
它直接打开/proc下的对应文件,发现这个进程的内存映射中有21个区域。
使用lregions列出这些区域的信息,这些命令都可以只打开头,再按Tab键让scanmem自动补全的:
最后一个编号为20的区域是进程的栈空间,它才是本座关心的。
把其它区域删除,这里的删除不是指将它们从进程的内存寻址空间里卸载,而是指让scanmem无视它们的存在。因为某些区域是不允许scanmem操作的,即使是简单的读操作也不行,会引起scanmem崩溃。可能那些低地址是内核占用的吧。
删除区域的操作使用dregion命令,参数是要删除的区域的编号,也可以在编号前面带上感叹号表示删除除该区域以外的其它区域。这里本座删除除20以外的其它区域:
然后就是真正进行匹配工作咯,要找到本座想要从外部修改的那个变量的内存地址。这个过程中要使用scanmem提供的那些逻辑判断功能。想知道有哪些判断功能,可执行help命令。在用判断功能查找内存位置之前一定要先执行snapshot命令做一下内存快照,不然直接使用判断命令查找内存时会因为没有有效的快照而崩溃。
判断工具有动态的和静态的,这次查找过程中本座用咯动态的“-”和静态的“<”,实际上只用“-”也可以。
首先快照一下,snapshot:
从截图来看,scanmem应当是自动执行咯一次“=”判断,=表示的是匹配所有未变动过其值的地址。在这种情况下,整个内存区域都被判断成匹配咯。
现在,去MemTest界面上去动一下,把原来1988的值又设置成1987,这样做是为咯让本座要查找的目标内存地址的值减小1.把Set左边旋转框的值改成1987,再按Set:
这个时候内存中的Number就变成1987了,比上次快照时减小咯1.
使用scanmem的“-”命令匹配一下,执行“- 1”:
现在的匹配数变成283咯,还要继续过滤。
这个时候,如果想看一下有哪些内存位置被匹配的话,可用list命令。
用list命令列出被匹配的内存位置的信息:
好多。
继续过滤。本座已知要找的内存位置的值是1987,使用“<”命令过滤出小于1988的位置,“< 1988”:
匹配位置减少到158个咯。
又在MemTest窗口中操作,把1987变成1986,再又匹配一下数值减少咯1的位置。
再要匹配数值又减少咯1的位置时,直接“- 1”即可,scanmem会直接与上个匹配发生时的情况作比较:
只能说是狠幸运,这次执行“- 1”命令直接就过滤到只剩下一个位置咯,scanmem报告说已经确认位置咯。
再list看一下细节:
果然它的值就是那个1986吧。
然后使用write命令把那个内存地址的值改成1900.这里直接用快捷的set命令也可以。
执行“write i32 bfa8dcc4 1900”,表示将内存地址bfa8dcc4的值改写成32位整数1900:
这个时候MemTest进程里面的Number值应当就变成1900咯。到窗口上去按一下Read按钮确认一下:
值确实变成1900了。
这里本座是有意写咯一个简单至极的程序来进行测试的,并且运气也狠好,只三条命令就匹配到咯要找的位置。如果是实际使用中的大程序,就需要反复多次进行过滤才能找到最终的内存位置咯。
GNU/Linux用户用的大部分软件都是开源的,不满意的地方自己去改源代码即可,不过现在也有一些闭源的软件咯,这个时候如果想要改变程序的行为(一般是在游戏中作弊)就可以用scanmem咯。
本座突然想着,要是有那么一天,本座狠无聊的话,狠想试试把一个进程内存中的代码段用汇编代码直接替换掉,就这样生生地完全改变一个运行中的进程的行为。那是要多蛋疼才会去做的事啊,而且如果真的实现咯的话,本座也可以进一步考虑用一块磁铁在硬盘上摩擦出一个苍井空作品咯。
HxLauncher: Launch Android applications by voice commands