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
我知道这个问题已经被遗忘很久了,但是我遇到了同样的问题(使用相同的函数),除了这个问题之外,网上没有任何信息,然后我自己解决了,所以我在这里留下了我的解决方案。
简短回答
WriteProcessMemory的第二个参数的类型不是"指针"。我的意思是,官方上是这样规定的,但是外部无法将原始地址转换为"指针",因此最好把它视为"long"。因此,您的类型声明应该如下:
wm:types{ ret ="long",abi ="stdcall"; "pointer","long","pointer","long","pointer" }
详细回答
我一直在用ReadProcessMemory测试,因为我认为在写入某些东西之前,需要验证这些东西是否实际存在。因此,有一次我调用了ReadProcessMemory,它返回的缓冲区不是我要找的,但也不是空的。实际上,似乎有些东西被写到那里——ASCII字符串。不是文本,只是一些数字。但这足以让我相信数据确实来自于"某个地方"。
于是我拿到了Cheat Engine,打开了同一个进程,并搜索了这个字符串。你猜怎么着——它确实存在,但是地址完全错了。这让我相信地址被错误地指定了。试图找到一种方法从Lua数值生成"指针"对象之后,我放弃了,并改变了类型声明——毕竟,指针只是一个不同的解释整数。
在我对lua和alien的源代码进行调查后,我做了一些调查,并用调试器调试了相关的部分。结果是,错误的完整步骤如下:
- "pointer"关键字对字符串具有特殊的行为:如果您的"pointer"声明的参数实际上是Lua字符串,则会立即创建一个新缓冲区,将字符串复制到其中,并将其用作实际参数。
- Alien使用lua_isstring函数来实现这一点。
- lua_isstring不仅针对实际字符串返回"true",而且对数字也返回"true",因为它们可以自动转换为字符串。
- 结果,您的SCOREREF被转换为字符串,复制到新创建的缓冲区中,并将其地址作为void*传递给WriteProcessMemory。
- 由于大多数进程的布局在它们各自的地址空间中是相似的,因此这个void*往往巧合地与目标进程中的某个东西的地址重合。这就是为什么系统调用有时会成功,只是写入了一个完全错误的地方。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
翻译
看起来你的缓冲区只包含两个字节("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)
```