I'm trying to get the static address of a game called assault cube so I can get a better understanding of how memory and such works in c#, however I am stuck at one part. As seen above I need to add "ac_client.exe" and 0x10F4F4. This I have done as "ac_client.exe" is 0x400000 so I just added the hex values together. This gave me 0x50F4F4; I then need to dereference that which is where I get stuck. I've tried loads of different ways and searched about it but there isn't too much info about it in c#. I did get some code working which I'm assuming dereferenced it but when I added the dereferenced part to the offset of 0x150 I don't get the same dynamic address. Therefore it doesn't work as it doesn't point anywhere.
int BaseAddress = 0x400000 + 0x10F4F4;
unsafe
{
int* ptr = &BaseAddress;//this is what should defreference it
var FinalAddress = ptr + 0x150;
Console.WriteLine($"Final value is: {(long)FinalAddress:X}");
}
The code above works but doesn't give me the output I am looking for. I've searched many places and there are videos about how to get the static address and they just end on saying "now you can get the dynamic address each time" but don't actually show how to do it.
These are just imports which allows you to get static address
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processID);
[StructLayout(LayoutKind.Sequential)]
public struct PROCESSENTRY32
{
public uint dwSize;
public uint cntUsage;
public uint th32ProcessID;
public IntPtr th32DefaultHeapID;
public uint th32ModuleID;
public uint cntThreads;
public uint th32ParentProcessID;
public int pcPriClassBase;
public uint dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szExeFile;
};
//inner enum used only internally
[Flags]
public enum SnapshotFlags : uint
{
HeapList = 0x00000001,
Process = 0x00000002,
Thread = 0x00000004,
Module = 0x00000008,
Module32 = 0x00000010,
Inherit = 0x80000000,
All = 0x0000001F,
NoHeaps = 0x40000000
}
//inner struct used only internally
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [MarshalAs(UnmanagedType.AsAny)] object lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,[Out, MarshalAs(UnmanagedType.AsAny)] object lpBuffer,int dwSize,out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll")]
public static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll")]
public static extern bool Module32First(IntPtr hSnapshot, ref MODULEENTRY32 lpme);
[DllImport("kernel32.dll")]
public static extern bool Module32Next(IntPtr hSnapshot, ref MODULEENTRY32 lpme);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateToolhelp32Snapshot(SnapshotFlags dwFlags, int th32ProcessID);
public static IntPtr GetModuleBaseAddress(Process proc, string modName)
{
IntPtr addr = IntPtr.Zero;
foreach (ProcessModule m in proc.Modules)
{
if (m.ModuleName == modName)
{
addr = m.BaseAddress;
break; ;
}
}
return addr;
}
const int INVALID_HANDLE_VALUE = -1;
public static IntPtr GetModuleBaseAddress(int procID, string modName)
{
IntPtr modBaseAddr = IntPtr.Zero;
IntPtr hSnap = CreateToolhelp32Snapshot(SnapshotFlags.Module | SnapshotFlags.Module32, procID);
if (hSnap.ToInt64() != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry = new MODULEENTRY32();
modEntry.dwSize = (uint)Marshal.SizeOf(typeof(MODULEENTRY32));
if (Module32First(hSnap, ref modEntry))
{
do
{
if (modEntry.szModule.Equals(modName))
{
modBaseAddr = modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, ref modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
public static IntPtr FindDMAAddy(IntPtr hProc, IntPtr ptr, int[] offsetse)
{
var buffer = new byte[IntPtr.Size];
foreach (int i in offsetse)
{
ReadProcessMemory(hProc, ptr, buffer, buffer.Length, out var read);
ptr = (IntPtr.Size == 4)
? IntPtr.Add(new IntPtr(BitConverter.ToInt32(buffer, 0)), i)
: ptr = IntPtr.Add(new IntPtr(BitConverter.ToInt64(buffer, 0)), i);
}
return ptr;
}
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VirtualMemoryOperation = 0x00000008,
VirtualMemoryRead = 0x00000010,
VirtualMemoryWrite = 0x00000020,
DuplicateHandle = 0x00000040,
CreateProcess = 0x000000080,
SetQuota = 0x00000100,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x00001000,
Synchronize = 0x00100000
}
[StructLayout(LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct MODULEENTRY32
{
internal uint dwSize;
internal uint th32ModuleID;
internal uint th32ProcessID;
internal uint GlblcntUsage;
internal uint ProccntUsage;
internal IntPtr modBaseAddr;
internal uint modBaseSize;
internal IntPtr hModule;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
internal string szModule;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
internal string szExePath;
}
public static IntPtr GetModuleBaseAddress()
{
Process process = Process.GetProcessesByName("ac_client")[0];
var module = process.Modules.Cast<ProcessModule>().SingleOrDefault(m => string.Equals(m.ModuleName, "ac_client.exe", StringComparison.OrdinalIgnoreCase));
// Attempt to get the base address of the module - Return IntPtr.Zero if the module doesn't exist in the process
return module?.BaseAddress ?? IntPtr.Zero;
}
The code below is how you would use it
Process proc = Process.GetProcessesByName("ac_client")[0];
var hProc = MainFunctions.OpenProcess(MainFunctions.ProcessAccessFlags.All, false, proc.Id);
var modBase = MainFunctions.GetModuleBaseAddress(proc, "ac_client.exe");
var modBase2 = MainFunctions.GetModuleBaseAddress(proc.Id, "ac_client.exe");
var ammoAddr = MainFunctions.FindDMAAddy(hProc, (IntPtr)(modBase + 0xE56BC), new int[] { 0x0, 0x274 });
//put the offsets here and put the local offset next to modBase
Console.WriteLine("Last Error: " + Marshal.GetLastWin32Error());
Console.WriteLine("Ammo address " + "0x" + ammoAddr.ToString("X"));