require "alien"
--the address im trying to edit in the Mahjong game on Win7
local SCOREREF = 0x0744D554
--this should give me full access to the process
local ACCESS = 0x001F0FFF
--this is my process ID for my open window of Mahjong
local PID = 1136
--function to open proc
local op = alien.Kernel32.OpenProcess
op:types{ ret = "pointer", abi = "stdcall"; "int", "int", "int"}
--function to write to proc mem
local wm = alien.Kernel32.WriteProcessMemory
wm:types{ ret = "long", abi = "stdcall"; "pointer", "pointer", "pointer", "long", "pointer" }
local pRef = op(ACCESS, true, PID)
local buf = alien.buffer("99")
-- ptr,uint32,byte arr (no idea what to make this),int, ptr
print( wm( pRef, SCOREREF, buf, 4, nil))
--prints 1 if success, 0 if failed
这就是我的代码。我甚至不确定我是否正确设置了类型。
我完全迷失了,需要一些指导。我真的希望有更多关于外星人的在线帮助/文档,它让我的可怜的大脑感到困惑。
令我感到非常困惑的是, WriteProcessMemory 有时会成功完成(虽然根据我的知识它什么都不做),有时也无法成功完成。正如我所说,我的大脑疼。
任何帮助表示感谢。
答案 0 :(得分:0)
看起来你的缓冲区只包含2个字节(“99”),但你在WriteProcessMemory的调用中指定了4个字节。
如果您打算将32位值99
写入内存(作为数字,而不是ASCII字符串),则可以使用:
alien.buffer("\99\0\0\0")
您可以使用alien.struct.pack
将任意整数转换为字符串表示形式:
require "alien.struct"
s = alien.struct.pack('i', 99)
buf = alien.buffer(s)
答案 1 :(得分:0)
我知道这个问题早已被遗忘,但是我遇到了相同的问题(具有相同的功能),除了这个问题,网络上什么都没有,然后我自己解决了,所以我要离开解决方案在这里。
缩短答案
WriteProcessMemory的 second 参数的类型不是“指针”。我的意思是,正式地说是这样,但是外星人不能将原始地址强制转换为“指针”,因此您最好假装它是“长”字。所以您的类型声明应该像
wm:types{ ret = "long", abi = "stdcall"; "pointer", "long", "pointer", "long", "pointer" }
长答案
我一直在玩ReadProcessMemory,因为我发现在编写某些内容之前,您需要验证该内容是否确实存在。因此,有一次我调用ReadProcessMemory,它返回的缓冲区不是我想要的,但也不是空的。实际上,似乎在其中写入了一些内容-如ASCII字符串。但是不是文本,只是一些数字。但这足以说服我数据实际上来自某处。
于是,我抓住了作弊引擎,打开了相同的进程,并搜索了这个字符串。猜猜是什么-它实际上在那里,但是地址完全错误。这使我相信地址指定有误。在尝试找到一种从Lua编号生成“指针”对象的方法之后,我放弃了并更改了类型声明-毕竟,指针只是一个不同解释的整数。
毕竟,我做了一些调查,包括阅读lua和Alien的源代码,并使用调试器逐步调试相关部分。事实证明,该错误的完整演练如下:
- “ pointer”关键字对字符串具有特殊的行为:如果声明了“ pointer”的参数实际上是Lua字符串,则会立即创建一个新的缓冲区,将字符串复制到那里,并将其用作真实参数。
- Alien使用lua_isstring函数来实现此目的
- lua_isstring不仅为实际字符串返回“ true”,还为数字返回“ true”,因为它们可以自动转换为字符串。
- 结果,您的SCOREREF被转换为字符串,被复制到新创建的缓冲区中,并且THAT的地址作为void *传递到WriteProcessMemory中。
- 由于大多数进程在它们各自的地址空间中的布局相似,因此该void *经常与目标进程中某物或另一物的地址重合。这就是为什么系统调用有时成功,而只是将其写入完全错误的地方的原因。