【问题标题】:How to read a process' memory using code compiled with g++?如何使用用 g++ 编译的代码读取进程的内存?
【发布时间】:2020-05-17 15:06:01
【问题描述】:

我想读取notepad.exe的进程内存并在其中找到字符串Hello World!(在记事本窗口中输入)。

我想使用g++.exe,而不是cl.exe,因为尝试弄清楚如何设置正确的环境变量以便能够从命令行而不是从 Visual 内部使用它太麻烦了工作室。还有其他原因,但问题是我需要使用g++.exe

尝试编译以下代码会出现以下错误(我知道代码即使运行也不会按原样执行任何操作。但这是第一步):

wstring 未在此范围内声明

szModName 未在此范围内声明

预计;wstrModContain 之前

wstrModContain 未在此范围内声明

string 尚未声明

#include <windows.h>
#include <psapi.h>

HMODULE GetModule();

int main() {
    return 0;
}

HMODULE GetModule() {
    HMODULE hMods[1024];
    HWND hWnd = FindWindowA(0, "Untitled - Notepad");
    DWORD pID;
    GetWindowThreadProcessId(hWnd, &pID);
    HANDLE pHandle = OpenProcess(PROCESS_VM_READ, FALSE, pID);
    DWORD cbNeeded;
    unsigned int i;
    if (EnumProcessModules(pHandle, hMods, sizeof(hMods), &cbNeeded)) {
        for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
            wstring szModName[MAX_PATH];
            if (GetModuleFileNameEx(pHandle, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) {
                TCHAR* wstrModName = szModName;
                wstring wstrModContain = "notepad.exe";
                if (wstrModName.find(wstrModContain) != string::npos) {
                    CloseHandle(pHandle);
                    return hMods[i];
                }
            }
        }
    }
    return nullptr;
}

【问题讨论】:

  • 请提取并提供minimal reproducible example。此外,其中一些错误非常基本,我还建议您拿起一本关于 C++ 的书。
  • 如果您使用的是windows.h,那么我确实会使用visual studio,而不是GCC,因为linux 工具链显然不支持windows api。您是否尝试过实际制作 Visual Studio 解决方案和项目来编译您的 exe,而不是直接调用 cl.exe?
  • 您可能想查看x64dbg 的源代码,它是Windows 的开源调试器。它读取进程内存。
  • 要记住的一个很好的注意事项是,我相信您应该将您的程序编译成与目标进程相同的位。 (64bit or 32bit)。我一直在研究一个类似的问题:stackoverflow.com/questions/61777539/…如果你有兴趣。
  • 希望对您有所帮助!如果您设法找到正确的顶部地址,请随时 fork 我的项目并提出改进建议!

标签: c++ readprocessmemory


【解决方案1】:

这是一个比我上一个更好的答案,因为上一个只搜索可执行映像,它只包含 .exe 文件中的内容,而不是动态内存。

编译:g++ filename.cpp -lpsapi

#includes 的顺序很重要; &lt;Windows.h&gt; 必须在 &lt;psapi.h&gt; 之前。

#include <Windows.h>
#include <psapi.h>
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    DWORD pID;
    HWND hwnd = FindWindowA(NULL, "Untitled - Notepad"); // the window title

    if (!hwnd)
        std::cout << "FindWindowA Error: " << GetLastError() << std::endl;

    if (!GetWindowThreadProcessId(hwnd, &pID))
        std::cout << "GetWindowThreadProcessId Error: " << GetLastError() << std::endl;

    HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    if (!pHandle)
        std::cout << "OpenProcess Error:" << GetLastError() << std::endl;

    unsigned char *p = NULL;
    MEMORY_BASIC_INFORMATION info;

    for (p = NULL; VirtualQueryEx(pHandle, p, &info, sizeof(info)) == sizeof(info); p += info.RegionSize) {
        std::vector<char> buffer;

        if (info.State == MEM_COMMIT && (info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE)) {
            SIZE_T bytes_read;
            buffer.resize(info.RegionSize);
            ReadProcessMemory(pHandle, p, &buffer[0], info.RegionSize, &bytes_read);
            buffer.resize(bytes_read);

            for (int i = 0; i < buffer.size(); i++) {
                char value = buffer.at(i);
                std::cout << value;
            }
        }
    }
}

有趣的是,我的最后一个答案因称 cmets “愚蠢”而被删除。没有帮助、错误、傲慢的评论没有回答问题,但它们本身并没有被删除。

【讨论】:

  • 如果您仍然对此感兴趣,可以转到我的github 并添加我的不和谐,以便我们一起工作。
猜你喜欢
  • 2013-10-28
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
相关资源
最近更新 更多