Lua Alien Module - Trouble using WriteProcessMemory function, unsure on types (unit32)
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 = al开发者_高级运维ien.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
So that is my code. I am not even sure if I have the types set correctly.
I am completely lost and need some guidance. I really wish there was more online help/documentation for alien, it confuses my poor brain.
What utterly baffles me is that it WriteProcessMemory will sometimes complete successfully (though it does nothing at all, to my knowledge) and will also sometimes fail to complete successfully. As I've stated, my brain hurts.
Any help appreciated.
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)
I know this question is long forgotten, but I ran into the same issue (with the same function), and there was nothing on the web except this question, and then I solved it myself, so I'm leaving my solution here.
SHORT ANSWER
The type of the second argument of WriteProcessMemory is not "pointer". I mean, officially it is, but alien cannot cast a raw address to a "pointer", so you are better off pretending it's a "long" instead. So your types declaration should look like
wm:types{ ret = "long", abi = "stdcall"; "pointer", "long", "pointer", "long", "pointer" }
LONG ANSWER
I was playing around with ReadProcessMemory, since I figured that before writing something you need to verify that this something actually exists. So one time I called ReadProcessMemory, and it returned a buffer that wasn't what I was looking for, but it wasn't empty either. In fact, it seemed something was written there - as in, an ASCII string. Not text, though, just some digits. But that was enough to convince me that the data actually came from somewhere.
So I grabbed Cheat Engine, opened the same process and ran a search for this string. And guess what - it actually was there, but the address was completely wrong. That led me to believe that the address is specified wrongly. After trying to find a way to generate a "pointer" object from a Lua number, I gave up and changed the types declaration - after all, a pointer is just a differently interpreted integer.
After all that, I did some investigating, including reading the sources of both lua and alien, and stepping through the relevant parts with a debugger. It turns out, the full walkthrough of the error is as follows:
- The "pointer" keyword has special behaviour for strings: if your "pointer"-declared argument is actually a Lua string, then a new buffer is instantly created, the string is copied there, and it is used as the real argument.
- Alien uses the lua_isstring function to implement this
- lua_isstring returns "true" not only for actual strings, but for numbers as well, since they are auto-convertible into strings.
- As a result, your SCOREREF is turned into a string, copied into a newly created buffer, and the address of THAT is passed into WriteProcessMemory as a void*.
- Since the layouts of most processes in their respective address spaces are similar, this void* more often than not happens to coincide with an address of some thing or another in the target process. That is why the system call sometimes succeedes, it just writes into a completely wrong place.
精彩评论