Lua Alien模块 - 使用WriteProcessMemory函数出现问题,对类型(unit32)不确定

require "alien"

--我正在尝试编辑Win7上“Mahjong”游戏中的地址
local SCOREREF = 0x0744D554
--这应该能让我完全访问进程
local ACCESS = 0x001F0FFF
--这是我的Mahjong窗口的进程ID
local PID = 1136

--打开进程的函数
local op = alien.Kernel32.OpenProcess
op:types{ ret = "pointer", abi = "stdcall"; "int", "int", "int"}

--写入进程内存的函数
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))
--如果成功,打印1;如果失败,打印0

这是我的代码。我甚至不确定是否正确设置了类型。

我完全迷失了方向,需要一些指导。我真希望有更多关于alien的在线帮助/文档,它让我伤透了脑筋。

让我完全困惑的是,“WriteProcessMemory”有时会成功完成(尽管据我所知它什么也没做),有时也会无法成功完成。正如我所说,我的脑袋疼痛不已。

感谢任何帮助。

原文链接 https://stackoverflow.com/questions/2571848

点赞
stackoverflow用户189205
stackoverflow用户189205

翻译

看起来你的缓冲区只包含两个字节("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)

markdown

It looks like your buffer contains only 2 bytes ("99"), but you specify 4 bytes in the call to WriteProcessMemory.

If your intention was to write the 32-bit value `99` into memory (as a number, not an ASCII string), you can use:

alien.buffer("\99\0\0\0")


You can convert arbitrary integers to string representations using `alien.struct.pack`:

require "alien.struct" s = alien.struct.pack('i', 99) buf = alien.buffer(s)

```

2010-04-03 17:17:34
stackoverflow用户10191364
stackoverflow用户10191364

我知道这个问题已经被遗忘很久了,但是我遇到了同样的问题(使用相同的函数),除了这个问题之外,网上没有任何信息,然后我自己解决了,所以我在这里留下了我的解决方案。

简短回答

WriteProcessMemory的第二个参数的类型不是"指针"。我的意思是,官方上是这样规定的,但是外部无法将原始地址转换为"指针",因此最好把它视为"long"。因此,您的类型声明应该如下:

wm:types{ ret ="long",abi ="stdcall"; "pointer""long""pointer""long""pointer" }

详细回答

我一直在用ReadProcessMemory测试,因为我认为在写入某些东西之前,需要验证这些东西是否实际存在。因此,有一次我调用了ReadProcessMemory,它返回的缓冲区不是我要找的,但也不是空的。实际上,似乎有些东西被写到那里——ASCII字符串。不是文本,只是一些数字。但这足以让我相信数据确实来自于"某个地方"。

于是我拿到了Cheat Engine,打开了同一个进程,并搜索了这个字符串。你猜怎么着——它确实存在,但是地址完全错了。这让我相信地址被错误地指定了。试图找到一种方法从Lua数值生成"指针"对象之后,我放弃了,并改变了类型声明——毕竟,指针只是一个不同的解释整数。

在我对lua和alien的源代码进行调查后,我做了一些调查,并用调试器调试了相关的部分。结果是,错误的完整步骤如下:

  1. "pointer"关键字对字符串具有特殊的行为:如果您的"pointer"声明的参数实际上是Lua字符串,则会立即创建一个新缓冲区,将字符串复制到其中,并将其用作实际参数。
  2. Alien使用lua_isstring函数来实现这一点。
  3. lua_isstring不仅针对实际字符串返回"true",而且对数字也返回"true",因为它们可以自动转换为字符串。
  4. 结果,您的SCOREREF被转换为字符串,复制到新创建的缓冲区中,并将其地址作为void*传递给WriteProcessMemory。
  5. 由于大多数进程的布局在它们各自的地址空间中是相似的,因此这个void*往往巧合地与目标进程中的某个东西的地址重合。这就是为什么系统调用有时会成功,只是写入了一个完全错误的地方。
2018-08-07 11:52:29