尝试以编程方式取消引用指针以获取动态地址 c#

问题描述

我正在尝试获取名为攻击立方体的游戏的静态地址,以便我可以更好地了解内存等在 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,[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,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"));

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...