2
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有时会成功完成(尽管据我所知,它什么都不做),有时也会无法成功完成。正如我所说,我的大脑很痛。

任何帮助表示赞赏。

4

2 回答 2

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)
于 2010-04-03T17:17:34.870 回答
0

我知道这个问题早就被遗忘了,但是我遇到了同样的问题(具有相同的功能),除了这个问题,网上什么都没有,然后我自己解决了,所以我把我的解决方案留在这里。

简短的回答

WriteProcessMemory 的第二个参数的类型不是“指针”。我的意思是,正式地它是,但外星人不能将原始地址投射到“指针”,所以你最好假装它是一个“长”。所以你的类型声明应该看起来像

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

长答案

我一直在玩 ReadProcessMemory,因为我认为在写东西之前你需要验证这个东西确实存在。所以有一次我调用了 ReadProcessMemory,它返回了一个不是我想要的缓冲区,但它也不是空的。事实上,那里似乎写了一些东西——比如一个 ASCII 字符串。不过,不是文字,只是一些数字。但这足以让我相信数据实际上来自某个地方

所以我抓住了作弊引擎,打开了相同的进程并搜索了这个字符串。你猜怎么着——它确实在那里,但地址完全错误。这使我相信地址指定错误。在试图找到一种从 Lua 数字生成“指针”对象的方法之后,我放弃并更改了类型声明——毕竟,指针只是一个不同解释的整数。

毕竟,我做了一些调查,包括阅读 lua 和外星人的源代码,并使用调试器逐步完成相关部分。事实证明,错误的完整演练如下:

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