【问题标题】:C++ Write to a process with protected memoryC ++写入具有受保护内存的进程
【发布时间】:2020-01-10 08:36:45
【问题描述】:

所以我决定开始进行内存编辑,以便能够为游戏制作更多工具。看到游戏已经通过使用作弊引擎和或任何其他内存编辑软件修补了网络版本的作弊,我决定尝试自己制作一个内存编辑工具,但使用 NoxPlayer,这是一个 Android 模拟器,因为他们有没有在手机上打补丁但是没有人知道这个方法。

无论如何,我之前遇到过这种类型的问题,作弊引擎本身在 Nox 上编辑内存,因为内存很可能受到保护。但是,在作弊引擎中进行了一些设置更改后,我就能够在模拟器上编辑游戏内的内存了。

问题在于我的 C++ 应用程序,它可以从抓取的地址中读取内存,但无法将内存写入地址。

所以我想知道是否有人可以帮助我找到一种解决方案,以便能够通过模拟器中的受保护内存来更改值?

(也会在下面提供我当前代码的一部分,即使那里可能不需要)。

private: System::Void backgroundWorker3_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {
        button1->Text = "Stop Spoofing";
        string ac;
        MarshalString(sid->Text, ac); // made a function to convert system string to std string
        stringstream stream(ac);
        stream >> value; // setting value to write to memory
        HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
        while (true)
        {
            if (backgroundWorker3->CancellationPending == true)
            {
                e->Cancel = true;
                break;
            }
            else
            {
                if (DoesTxtExist())
                {
                    for (int i(0); i < address.size(); ++i)
                    {
                        WriteProcessMemory(handle, (LPVOID)address[i], &value, sizeof(value), 0);
                        ReadProcessMemory(handle, (PBYTE*)address[i], &readTest, sizeof(int), 0);
                    }
                    label1->Text = L"Spoofing ID: "+readTest.ToString()+" "+value.ToString();
                    // was doing something like this to check if the values changed, but of course they didn't.
                }
            }
        }
    }

【问题讨论】:

    标签: c++ memory c++-cli protection


    【解决方案1】:

    在写尝试之前使用VirtualProtectEx() 将内存保护更改为可写。使用 PROCESS_ALL_ACCESS 打开句柄不会自动使整个进程内存可写。

    【讨论】:

    • 不幸的是,这对我不起作用。虽然我确实觉得我可能做错了,所以我会为您提供我的代码的屏幕截图,以便您可以帮助我更多。 prntscr.com/mm6i3p/direct(或者如果这不起作用:prntscr.com/mm6i3p
    • 这些函数返回什么?你检查过他们的错误报告吗?此外,您不需要为每个字节调用 VirtualProtectEx(),它适用于页面。
    • 我没有看到任何要知道的错误,但基本上仍然在我的程序中,当它读取数据时它仍然是相同的,这是活动时的程序截图prntscr.com/mm6oqc。但同样,该值在游戏中不会改变。也许 Nox 模拟器保护得太好了?
    【解决方案2】:

    您必须以管理员身份运行。您可能还需要 SeDebugPrivilege 令牌权限。

    您可以使用清单文件将您的应用设置为需要管理员模式。

    您可以从pinvoke.net 使用此函数设置SeDebugPrivilege

    Public Class AdjPriv()
    {
    
    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
    internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
    ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
    
    [DllImport("kernel32.dll", ExactSpelling = true)]
    internal static extern IntPtr GetCurrentProcess();
    
    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
    internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr
    phtok);
    
    [DllImport("advapi32.dll", SetLastError = true)]
    internal static extern bool LookupPrivilegeValue(string host, string name,
    ref long pluid);
    
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct TokPriv1Luid
    {
        public int Count;
        public long Luid;
        public int Attr;
    }
    
    internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
    internal const int TOKEN_QUERY = 0x00000008;
    internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
    internal const string SE_TIME_ZONE_NAMETEXT = "SeTimeZonePrivilege"; //http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
    
    private bool SetPriv()
    {
        try
        {
        bool retVal;
        TokPriv1Luid tp;
        IntPtr hproc = GetCurrentProcess();
        IntPtr htok = IntPtr.Zero;
        retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
        tp.Count = 1;
        tp.Luid = 0;
        tp.Attr = SE_PRIVILEGE_ENABLED;
        retVal = LookupPrivilegeValue(null, SE_TIME_ZONE_NAMETEXT, ref tp.Luid);
        retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
        return retVal;
        }
        catch (Exception ex)
        {
        throw;
        return false;
        }
    
    }
    

    }

    一旦这两个事情都解决了,如果您试图覆盖任何代码,它将位于模块的代码部分中,该部分将具有执行权限但没有写入权限。

    要获得写入权限,您必须在要修改的内存位置调用 VirtualProtectEx()。我没有为此的 C# sn-p,但我基本上有一个 WriteProcessMemory 的包装器,它在之前和之后调用 VirtualProtectEx() 看起来像这样

    void PatchEx(HANDLE hProc, char* dst, char* src, const intptr_t size)
    {
        DWORD oldprotect;
        VirtualProtectEx(hProc, dst, size, PAGE_EXECUTE_READWRITE, &oldprotect);
        WriteProcessMemory(hProc, dst, src, size, nullptr);
        VirtualProtectEx(hProc, dst, size, oldprotect, &oldprotect);
    }
    

    我想你可以很容易地重新创建一个 C#。然后任何时候你想写入内存,使用这个函数来确保页面内存保护常量设置正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 2010-12-27
      • 2012-07-30
      • 1970-01-01
      • 2012-04-26
      • 2010-11-29
      相关资源
      最近更新 更多