尝试以编程方式取消引用指针以获取动态地址 c#
Trying to dereference pointers programmatically to get the dynamic address c#
我正在尝试获取名为 assault cube 的游戏的静态地址,以便我可以更好地了解内存等在 c# 中的工作原理,但我被困在了一个部分。如上所示,我需要添加“ac_client.exe”和 0x10F4F4。我这样做是因为“ac_client.exe”是 0x400000,所以我只是将十六进制值加在一起。这给了我 0x50F4F4;然后我需要取消引用我卡住的地方。我已经尝试了很多不同的方法并进行了搜索,但是在 c# 中没有太多关于它的信息。我确实得到了一些代码工作,我假设取消引用它但是当我将取消引用的部分添加到 0x150 的偏移量时,我没有得到相同的动态地址。因此它不起作用,因为它没有指向任何地方。
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}");
}
上面的代码有效,但没有提供我正在寻找的输出。
我搜索了很多地方,有关于如何获取静态地址的视频,他们只是说“现在你每次都可以获取动态地址”,但实际上并没有展示如何去做。
这些只是允许您获取静态地址的导入
[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;
}
下面的代码是您将如何使用它
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"));
我正在尝试获取名为 assault cube 的游戏的静态地址,以便我可以更好地了解内存等在 c# 中的工作原理,但我被困在了一个部分。如上所示,我需要添加“ac_client.exe”和 0x10F4F4。我这样做是因为“ac_client.exe”是 0x400000,所以我只是将十六进制值加在一起。这给了我 0x50F4F4;然后我需要取消引用我卡住的地方。我已经尝试了很多不同的方法并进行了搜索,但是在 c# 中没有太多关于它的信息。我确实得到了一些代码工作,我假设取消引用它但是当我将取消引用的部分添加到 0x150 的偏移量时,我没有得到相同的动态地址。因此它不起作用,因为它没有指向任何地方。
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}");
}
上面的代码有效,但没有提供我正在寻找的输出。 我搜索了很多地方,有关于如何获取静态地址的视频,他们只是说“现在你每次都可以获取动态地址”,但实际上并没有展示如何去做。
这些只是允许您获取静态地址的导入
[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;
}
下面的代码是您将如何使用它
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"));