Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

to write new value into game memory address


  • Please log in to reply
16 replies to this topic
mlracing
  • Members
  • 42 posts
  • Last active: Oct 31 2009 02:17 AM
  • Joined: 12 Jul 2009
i searched the forum about writing memory, but none script works for me. so i ask the question again.

assuming i want to write value
"AA 06 00 00 88 02 00 00 00 F9 FF FF 00 00 00 05 00 00"
into address "005374c0"
of the game process "abcde.exe"
by pressing the key "Y"

how should i write the script, and what extra AHK or DLL library do i need?
my system is WinXP and the game use OpenGL graphic interface.

this can be done with other game cheat software, but i like to use AHK because it's customizable and i can have multiple functions for a single hotkey.

engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005
please post links to the code you tried, or show some code you tried, and tell us /what/ didn't work.

Just 'None of them worked' doesn't help us, since we don't know what you tried.

WriteProcessMemory would be my search term.

mlracing
  • Members
  • 42 posts
  • Last active: Oct 31 2009 02:17 AM
  • Joined: 12 Jul 2009
i tried to adapt some scripts in these post, because i don't need to read the address or do any loop, so i have to modify the scripts. but so far i haven't got one working script.
for one certain thing, the WINGET function can't get the PID of the game process (maybe because it's full screen and it use OpenGL interface ? )

<!-- m -->http://www.autohotke... ... ry address<!-- m -->

<!-- m -->http://www.autohotke... ... ry address<!-- m -->

<!-- m -->http://www.autohotke... ... ry address<!-- m -->

<!-- m -->http://www.autohotke... ... ry address<!-- m -->

thanks!

engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005
getting the PID can be done if you have AHK start the game, or by using the Process command. the Window ID is gotten with WinGet.

mlracing
  • Members
  • 42 posts
  • Last active: Oct 31 2009 02:17 AM
  • Joined: 12 Jul 2009
among those several versions of scripts, which one is the best?

engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005
I haven't looked, and can't judge. I don't play games, so I have no need to test.

mlracing
  • Members
  • 42 posts
  • Last active: Oct 31 2009 02:17 AM
  • Joined: 12 Jul 2009
i tried to put together a script:
===========================
;winget, hTarget, PID, abcde.exe

Process, exist, abcde.exe
hTarget := %ErrorLevel%
msgbox ID is %ErrorLevel%
===========================
in here, if i use WINGET, "GetWindowThreadProcessId failed" will be prompt.
if i use PROCESS, EXIST command, an ID will be shown, but "GetWindowThreadProcessId failed" still will be prompt.



whole script:
=========================
#NoEnv
#Persistent
#SingleInstance force
#MaxThreads 10
#MaxThreadsPerHotkey 1
#MaxThreadsBuffer off
#HotkeyInterval 2000
#MaxHotkeysPerInterval 100
#KeyHistory 0
SetBatchLines, 40ms
ListLines off
SetControlDelay, 10
SetKeyDelay, 10
SetMouseDelay, 10
SetDefaultMouseSpeed, 0
SetTitleMatchmode, 2

$y::
{

;winget, hTarget, PID, abcde.exe

Process, exist, abcde.exe
hTarget := %ErrorLevel%
msgbox ID is %ErrorLevel%

TID := DllCall("GetWindowThreadProcessId", "int", hTarget, "UInt *", PID, "UInt")
if (ErrorLevel or !PID) 
{ 
   MsgBox GetWindowThreadProcessId failed. 
   Exit 
} 

ProcessHandle := DllCall("OpenProcess", "int", 2035711, "char", 0, "UInt", PID, "UInt")
if (ErrorLevel or !ProcessHandle) 
{ 
   MsgBox OpenProcess failed. 
   Exit 
}

VarSetCapacity(output, 18)
iret := DllCall("ReadProcessMemory", "UInt", ProcessHandle, "UInt", 0x5374c0, "Uint*", Output, "Uint", 18, "Uint *", 0)  
   if (ErrorLevel or !iret) 
   { 
      DllCall("CloseHandle", "int", ProcessHandle) 
      MsgBox ReadProcessMemory failed. 
      Exit 
   }
   msgbox, %output%

VarSetCapacity(input, 18)
input := AA 06 00 00 88 02 00 00 00 F9 FF FF 00 00 00 05 00 00
iret := DllCall("WriteProcessMemory", "UInt", ProcessHandle, "UInt", 0x5374c0, "Uint*", input, "Uint", 18, "Uint *", 0)
if (ErrorLevel or !iret) 
   { 
      DllCall("CloseHandle", "int", ProcessHandle) 
      MsgBox WriteProcessMemory failed. 
      Exit 
   }  
DllCall("CloseHandle", "int", ProcessHandle)
Exit
}

[Moderator's note: please use code tags.]

engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005
Since you are getting the PID directly, you don't need to convert it from a window ID to a PID.

Process, exist, abcde.exe
PID := %ErrorLevel%
msgbox ID is %PID%

ProcessHandle := DllCall("OpenProcess", "int", 2035711, "char", 0, "UInt", PID, "UInt")
if (ErrorLevel or !ProcessHandle) 
{ 
   MsgBox OpenProcess failed. 
   Exit 
}

;...


mlracing
  • Members
  • 42 posts
  • Last active: Oct 31 2009 02:17 AM
  • Joined: 12 Jul 2009
WOW, you reply so fast! :O

but it still doesn't work.
if i am not runing abcde.exe, it will prompt ID is 0.
if i am runing abcde.exe, it will prompt ID is (blank).

then prompt "OpenProcess failed" either way.

mlracing
  • Members
  • 42 posts
  • Last active: Oct 31 2009 02:17 AM
  • Joined: 12 Jul 2009
even if i put

process, exist, sndrec32.exe

it still prompt ID is (blank) . it has nothing to do with weather it is a DX game or in windows GUI.

engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005
I didn't notice your other error in the copy/paste

PID := ErrorLevel
;or 
PID = %ErrorLevel%


mlracing
  • Members
  • 42 posts
  • Last active: Oct 31 2009 02:17 AM
  • Joined: 12 Jul 2009
thanks, now i can write something into memory.
but it doesn't write the right value or doesn't write to the right address.
in CheatEngine, the address is shown as 005374c0, and value is [array of 18 bytes], such as
AA 06 00 00 88 02 00 00 00 F9 FF FF 00 00 00 05 00 00

in my script, i write 0x5374c0 , and
input := AA 06 00 00 88 02 00 00 00 F9 FF FF 00 00 00 05 00 00
or
input :=AA0600008802000000F9FFFF000000050000 (without spaces)
either works correctly.
in CheatEngine, i see the value is not right. why?

VxE
  • Moderators
  • 3622 posts
  • Last active: Dec 24 2015 02:21 AM
  • Joined: 07 Oct 2006
You'll need to convert the hex into the proper data type (string ?) before you try to write it into the process's memory. After setting the variable's capacity, use NumPut() to insert the numerical value represented by each pair of hex digits into the variable.

engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005
that is not something I am able to answer. Please tell us what Cheatengine thinks you changed it to.

Try digging into another program's memory space (like a AHK exe you write just for this test.

for example, Make a AHK exe that has a few msgboxes on hotkeys. Then have cheatengine change the text of the message boxes. Then see if you can do the same with an AHK script.

my guess is that you are writing chars into the memory when you should be writing bytes.
input := Chr(0xAA) Chr(0x06) Chr(0x00) .....

AHK might not like the Chr(0x00), so you might have to do something like
VarSetCapacity(input, 18, 0)  ;make it 18 bytes and fill with zeros
NumPut(0xAA, input, 0, "Char")
NumPut(0x06, input, 1, "Char")
NumPut(0x88, input, 4, "Char")
;...


mlracing
  • Members
  • 42 posts
  • Last active: Oct 31 2009 02:17 AM
  • Joined: 12 Jul 2009
thanks!
i just realized i can't input 18 bytes as a whole. so i cut it into 4 bytes and convert the hex value, now the script can work correctly!
AHK rocks!