Я знаю, что этот вопрос давно забыт, но я столкнулся с той же проблемой (с той же функцией), и в Интернете не было ничего, кроме этого вопроса, и затем я решил его сам, поэтому я оставляю свое решение здесь.
КОРОТКИЙ ОТВЕТ
Тип второго аргумента WriteProcessMemory не является «указателем». Я имею в виду, что официально это так, но пришелец не может привести необработанный адрес к «указателю», так что лучше сделать вид, что он «длинный». Так что ваше объявление типов должно выглядеть как
wm:types{ ret = "long", abi = "stdcall"; "pointer", "long", "pointer", "long", "pointer" }
ДОЛГО ОТВЕТ
Я играл с ReadProcessMemory, так как я подумал, что перед тем, как что-то писать, нужно убедиться, что это действительно существует. Итак, однажды я вызвал ReadProcessMemory, и он вернул буфер, который не был тем, что я искал, но он также не был пустым. На самом деле, казалось, что-то там было написано - например, строка ASCII. Не текст, а только цифры. Но этого было достаточно, чтобы убедить меня, что данные на самом деле пришли из где-то .
Итак, я взял Cheat Engine, открыл тот же процесс и запустил поиск по этой строке. И угадайте, что ... это действительно было там, но адрес был совершенно неверным. Это привело меня к мысли, что адрес указан неверно. После попытки найти способ создания объекта «указателя» из числа Lua я отказался и изменил объявление типов - в конце концов, указатель - это просто целое число, интерпретируемое по-другому.
После всего этого я провел некоторое расследование, в том числе прочитал источники как lua и alien, так и прошел соответствующие части с помощью отладчика. Оказывается, полное прохождение ошибки выглядит следующим образом:
- Ключевое слово указателя имеет специальное поведение для строк: если ваш аргумент, объявленный указателем, фактически является строкой Lua, то новый буфер создается мгновенно, строка копируется туда и используется в качестве реального аргумента. .
- Alien использует функцию lua_isstring для реализации этого
- lua_isstring возвращает true не только для реальных строк, но и для чисел, поскольку они автоматически конвертируются в строки.
- В результате ваш SCOREREF превращается в строку, копируется во вновь созданный буфер, и адрес THAT передается в WriteProcessMemory как пустота *.
- Поскольку схемы большинства процессов в соответствующих им адресных пространствах похожи, эта пустота * чаще всего совпадает с адресом того или иного объекта в целевом процессе. Вот почему системный вызов иногда завершается успешно, он просто записывает в совершенно неправильное место.