A preserved archive of the Logical Gamers community forums, 2009-2025. The original threads and posts, served read-only. Registration, posting and private messages are gone for good.

Reading memory values out of a process

1.4k views · started by Chad ·
#1
Reading memory values out of a process
So I was poking around with how to manipulate memory processes today, because I have never done so, and I found it quite fun.
I made a Spider Solitaire 'bot' that would just up the score and what not. Easy enough however, every time the game closes and re-opens, the score memory address changes, meaning I have to go back through Cheat Engine to grab the address values to put it back into my program. I was wondering if there was a possible way to read the address values without having to, so say, make a move to have the score adjust just so you could pin the address value for the score.

A better example would be of you playing a shooting game and you want infinite ammo so you whip open Cheat Engine and you do the whole, "Okay I have 100 Shots in the clip " *scan for 100* *shoot one bullet* *next scan for 99* so on and so forth until you get the address for the amount of ammunition you have then lock it in place that you have 99999 + bullets in your magazine.

I've searched and I can't find anything on how to scan each address for a specific value? I don't want to have the program wait to scan and try to find a deduction in the value because that just seems incredibly tedious.
#2
I believe you need to use pointers. If so you can find some tutorials and getting them on youtube or the cheat engine forums.
#3
Stapled wrote:
I believe you need to use pointers. If so you can find some tutorials and getting them on youtube or the cheat engine forums.


Pointers? A little vague don't you think?

Can you be more specific than that? Or do you not have personal knowledge or experience of OP's question?

I do agree though that CEF has a lot of info about memory and such regarding this topic. But he was asking for help from this site.
#4
I've dug around and a lot of people have been mentioning something having to do with the Base Address but I don't know what else to do with it?
#5
Pointers? A little vague don't you think?

Can you be more specific than that? Or do you not have personal knowledge or experience of OP's question?

I do agree though that CEF has a lot of info about memory and such on this topic. But he was asking for help from this site.


I've only messed around with memory edits once and I ran into the same problem as Chad and quit. If you find the pointer and the offset, from what I know, the value will be the address.
#6
Unfortunately I personally can't help you on this topic as I currently have limited knowledge of low level programming aspects and memory.

But I can tell you that this isn't really something you can delve straight in to. You need to know a bit about this subject and what it entails.

I suppose a good start would be learning a lower level language like C (and perhaps accompany that by learning about things like Assembly). Stack Overflow is a better place to ask this question. Very few people here actually know a lot about these kinds of things.
#7
When I try to get the base address all I hit is, "A 32 bit processes cannot access modules of a 64 bit process." which just makes me want to put a hole through my monitor.
#8
Chad wrote:
When I try to get the base address all I hit is, "A 32 bit processes cannot access modules of a 64 bit process." which just makes me want to put a hole through my monitor.


To me that error seems like it stems from an incompatibility in memory/OS architecture.

Are you running a 32-bit (x86) or 62-bit (x64) machine? What is the program you're trying to read memory from?
#9
Chad wrote:
When I try to get the base address all I hit is, "A 32 bit processes cannot access modules of a 64 bit process." which just makes me want to put a hole through my monitor.


When you click "find out what accesses this address"?
#10
That is the error that is thrown.

System.ComponentModel.Win32Exception was unhandled
Message=A 32 bit processes cannot access modules of a 64 bit process.
Source=System
ErrorCode=-2147467259
NativeErrorCode=299
StackTrace:
at System.Diagnostics.NtProcessManager.GetModuleInfos(Int32 processId, Boolean firstModuleOnly)
at System.Diagnostics.NtProcessManager.GetFirstModuleInfo(Int32 processId)
at System.Diagnostics.Process.get_MainModule()
at ConsoleApplication1.Program.Main(String[] args) in C:\Users\Chad\documents\visual studio 2010\Projects\Memory Reading and writing\Memory Reading and writing\Program.cs:line 35
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
#11
If you can give me an example of your current source or something, I might be able to help you. I run into stuff like this while making trainers and reverse engineering games and stuff
#12
Right.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using ProcessMemoryReaderLib;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ProcessMemoryReader process_reader = new ProcessMemoryReader();

try
{
Process[] hook_process_snap = Process.GetProcessesByName("SpiderSolitaire");
Process hook_process = new Process();

if (hook_process_snap[0].ProcessName == "SpiderSolitaire")
{
Console.WriteLine("Process has been found and hooked.");
hook_process = hook_process_snap[0];

process_reader.ReadProcess = hook_process;
process_reader.OpenProcess();

Console.WriteLine(hook_process.MainModule.BaseAddress);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

Console.ReadLine();
}
}
}
[/0][/0]


And the class I am using is

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ProcessMemoryReaderLib
{
/// <summary>
/// ProcessMemoryReader is a class that enables direct reading a process memory
/// </summary>
class ProcessMemoryReaderApi
{
// constants information can be found in <winnt.h>
[flags]
public enum ProcessAccessType
{
PROCESS_TERMINATE = (0x0001),
PROCESS_CREATE_THREAD = (0x0002),
PROCESS_SET_SESSIONID = (0x0004),
PROCESS_VM_OPERATION = (0x0008),
PROCESS_VM_READ = (0x0010),
PROCESS_VM_WRITE = (0x0020),
PROCESS_DUP_HANDLE = (0x0040),
PROCESS_CREATE_PROCESS = (0x0080),
PROCESS_SET_QUOTA = (0x0100),
PROCESS_SET_INFORMATION = (0x0200),
PROCESS_QUERY_INFORMATION = (0x0400)
}

// function declarations are found in the MSDN and in <winbase.h>

// HANDLE OpenProcess(
// DWORD dwDesiredAccess, // access flag
// BOOL bInheritHandle, // handle inheritance option
// DWORD dwProcessId // process identifier
// );
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);

// BOOL CloseHandle(
// HANDLE hObject // handle to object
// );
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hObject);

// BOOL ReadProcessMemory(
// HANDLE hProcess, // handle to the process
// LPCVOID lpBaseAddress, // base of memory area
// LPVOID lpBuffer, // data buffer
// SIZE_T nSize, // number of bytes to read
// SIZE_T * lpNumberOfBytesRead // number of bytes read
// );
[DllImport("kernel32.dll")]
public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,[In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);

// BOOL WriteProcessMemory(
// HANDLE hProcess, // handle to process
// LPVOID lpBaseAddress, // base of memory area
// LPCVOID lpBuffer, // data buffer
// SIZE_T nSize, // count of bytes to write
// SIZE_T * lpNumberOfBytesWritten // count of bytes written
// );
[DllImport("kernel32.dll")]
public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,[In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);


}

public class ProcessMemoryReader
{

public ProcessMemoryReader()
{
}

/// <summary>
/// Process from which to read
/// </summary>
public Process ReadProcess
{
get
{
return m_ReadProcess;
}
set
{
m_ReadProcess = value;
}
}

private Process m_ReadProcess = null;

private IntPtr m_hProcess = IntPtr.Zero;

public void OpenProcess()
{
// m_hProcess = ProcessMemoryReaderApi.OpenProcess(ProcessMemoryReaderApi.PROCESS_VM_READ, 1, (uint)m_ReadProcess.Id);
ProcessMemoryReaderApi.ProcessAccessType access;
access = ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_READ
| ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_WRITE
| ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_OPERATION;
m_hProcess = ProcessMemoryReaderApi.OpenProcess((uint)access, 1, (uint)m_ReadProcess.Id);
}

public void CloseHandle()
{
int iRetValue;
iRetValue = ProcessMemoryReaderApi.CloseHandle(m_hProcess);
if (iRetValue == 0)
throw new Exception("CloseHandle failed");
}

public byte[] ReadProcessMemory(IntPtr MemoryAddress, uint bytesToRead, out int bytesRead)
{
byte[] buffer = new byte[bytestoread];

IntPtr ptrBytesRead;
ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess,MemoryAddress,buffer ,bytesToRead,out ptrBytesRead);

bytesRead = ptrBytesRead.ToInt32();

return buffer;
}

public void WriteProcessMemory(IntPtr MemoryAddress, byte[] bytesToWrite ,out int bytesWritten)
{
IntPtr ptrBytesWritten;
ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess,MemoryAddress,bytesToWrite,(uint)bytesToWrite.Length,out ptrBytesWritten);

bytesWritten = ptrBytesWritten.ToInt32();
}




}
}
[/bytestoread][/flags]
#14
Thanks however, I already know how to read and write. My current problem is grabbing the base value to calculate the other values because of how they change every time the program is launched. I can't grab the base value because of the reason stated above.

And I'm doing this in C#.

EDIT:

I tried grabbing Notepads base address and it worked. I'm assuming it's the game that's causing the problems.
#15
It seems like you're trying to read a 64-bit process' memory with a library that only supports 32-bit addressing.
Quick look at your process memory accessing library:
[DllImport("kernel32.dll")]


You need to find a library that can read 64-bit process' memory. Your library seems to only support 32-bit addressing, thus your error:
A 32 bit processes cannot access modules of a 64 bit process.
#16
Many thanks Riddle! :D