【问题标题】:Insufficient permission to read system memory读取系统内存的权限不足
【发布时间】:2020-11-07 19:25:26
【问题描述】:

我正在使用代码扫描程序内存,我使用代码扫描notepad.exe,程序可以毫无问题地扫描,但是当我想扫描某些系统进程时(例如:dwm.exe,注册表)我没有足够的权限,程序无法扫描,我该怎么办?我已经尝试过以管理员身份运行。

char* scanMemory(DWORD dwmPID)
{

    HANDLE process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, dwmPID);
    if (process)
    {
        SYSTEM_INFO si;
        GetSystemInfo(&si);
        MEMORY_BASIC_INFORMATION info;
        std::vector<char> chunk;
        char* p = 0;

        while (p < si.lpMaximumApplicationAddress)
        {
            if (VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info))
            {
                p = (char*)info.BaseAddress;
                chunk.resize(info.RegionSize);
                SIZE_T bytesRead;
                if (ReadProcessMemory(process, p, &chunk[0], info.RegionSize, &bytesRead))
                {
                    for (size_t i = 0; i < (bytesRead - 4); ++i)
                    {

                        if (memcmp(".exe", &chunk[i], 4) == 0)
                        {
                            cout << "Found";
                            system("PAUSE");
                        }

                    }
                }
                p += info.RegionSize;
            }
        }
    }
    return 0;
}

【问题讨论】:

  • 根据 winapi 上的文档“要读取的整个区域必须可访问,如果不可访问,则功能失败。”也许这就是你的理由。并非所有内存都可以被外部进程读取。想象一下可能导致的问题。 :)
  • 但是一个叫做进程黑客2的程序可以读取进程dwm.exe的内存,我只是不知道我如何才能拥有进程黑客2的相同权限
  • 当你运行hacker 2时,系统会停止并请求管理权限吗?
  • 是的......但是,我的程序也使用管理员运行
  • 除了以管理员权限运行程序外,您还需要在打开远程进程的句柄之前使用 SE_DEBUG_NAME 权限显式调整进程的令牌。这使得除了少数关键系统进程之外的所有远程进程都可以完全访问内存。有许多代码 sn-ps 说明了如何执行此操作。在您最喜欢的搜索引擎中查询“SE_DEBUG_NAME 提升权限”

标签: c++ winapi memory


【解决方案1】:

重要的系统进程受到保护,首先您应该使用 SeDebugPrivelage 提升权限:

bool SetDebugPrivilege()
{
    HANDLE hToken{ nullptr };
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
        return false;

    TOKEN_PRIVILEGES TokenPrivileges{};
    TokenPrivileges.PrivilegeCount = 1;
    TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!LookupPrivilegeValueA(nullptr, "SeDebugPrivilege", &TokenPrivileges.Privileges[0].Luid))
    {
        CloseHandle(hToken);
        return false;
    }

    if (AdjustTokenPrivileges(hToken, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr) != ERROR_SUCCESS)
    {
        CloseHandle(hToken);
        return false;
    }

    CloseHandle(hToken);
    return true;
}

如果这不起作用,您可以尝试从具有更高权限的进程中劫持/复制句柄/令牌。您可以通过查看this source code了解如何从用户模式枚举进程句柄并劫持它们

由于受保护的进程,您也可能没有对所有进程的完全访问权限。

受保护的进程资源:

【讨论】:

  • 第一:我喜欢 GH 论坛,第二:这很有效,但是,当chunk.resize(info.RegionSize); 程序崩溃并且错误是:MemoryReadTest.exe 中 0x768C43D2 中的未处理异常:Microsoft C++ 异常:std: :bad_alloc 在内存位置 0x0019F640。发生
  • @DeathZ 使用向量是多余的,不需要调整大小,只需创建一个大小为 regionSize 的动态缓冲区。您不能 RPM 或 Memcpy 进入向量的地址,这不是容器的工作方式
【解决方案2】:
猜你喜欢
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多