C ++写入具有受保护内存的进程

时间:2019-02-17 07:58:20

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

因此,我决定开始进行内存编辑,以便能够为游戏制作更多工具。看到游戏通过使用作弊引擎和任何其他内存编辑软件修补了作弊的网络版本,我决定尝试自己制作一个内存编辑工具,但要使用NoxPlayer(这是一个安卓模拟器)没有在移动设备上修补该方法,但没人知道该方法。

无论如何,我之前在作弊引擎本身遇到过这类问题,因为它最有可能受到保护,因此在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.
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

您必须以管理员身份运行。您可能还需要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#代码段,但是基本上我有一个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#。然后,无论何时要写入内存,都可以使用此功能来确保正确设置页面内存保护常量。