C++ 程序如何通过ReadProcessMemory从内存中读取自己的图像?

C++ 程序如何通过ReadProcessMemory从内存中读取自己的图像?,c++,winapi,C++,Winapi,我正在尝试制作一个可执行文件,它可以使用windows的ReadProcessMemoryapi从内存中读取自身 然后,我将使用它来计算可执行文件的校验和 这是我的代码: #define PSAPI_VERSION 1 #include <string> #include <windows.h> #include <tchar.h> #include <stdio.h> #include <psapi.h> #include <W

我正在尝试制作一个可执行文件,它可以使用windows的ReadProcessMemoryapi从内存中读取自身

然后,我将使用它来计算可执行文件的校验和

这是我的代码:

#define PSAPI_VERSION 1
#include <string>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>
#include <Wincrypt.h>

#define BUFSIZE 1024
#define MD5LEN  16

// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
#pragma comment(lib, "psapi.lib")


int main(void)
{

    HWND hMyProcess = (HWND)(GetCurrentProcess());
    HMODULE hModule = (HMODULE)GetModuleHandle(NULL);
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
    MODULEINFO moduleInfo;
    if(hModule != NULL && hMyProcess != NULL){
        // if (GetModuleInformation())
        GetModuleBaseName(hMyProcess, hModule, szProcessName, MAX_PATH);
        printf("%s\n", szProcessName);
        if (GetModuleInformation(hMyProcess, hModule, &moduleInfo, sizeof(moduleInfo))){
            printf("lpBaseOfDLL : %x\n", moduleInfo.lpBaseOfDll);
            printf("Entry Point : %x\n", moduleInfo.EntryPoint);
            printf("SizeOfImage : %x\n", moduleInfo.SizeOfImage);
        }
    }
    // Till here working fine, problem lies below

    // read process memory
    TCHAR *hexEXE;
    SIZE_T *lpNumberOfBytesRead;
    if(ReadProcessMemory(hMyProcess, moduleInfo.lpBaseOfDll,
        hexEXE, moduleInfo.SizeOfImage, 0)){
        //printf("%s\n", hexEXE);
        printf("Read memory\n");
        printf("%d \n",strlen(hexEXE));
    }

    // will be implemented later, taken from --> https://msdn.microsoft.com/en-us/library/aa382380(VS.85).aspx
    DWORD dwStatus = 0;
    BOOL bResult = FALSE;
    HCRYPTPROV hProv = 0;
    HCRYPTHASH hHash = 0;

    /*if (!CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT)){
        dwStatus = GetLastError();
        printf("CryptAcquireContext failed: %d\n", dwStatus);
        //CloseHandle(hFile);
        return dwStatus;
    }

    if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)){
        dwStatus = GetLastError();
        printf("CryptAcquireContext failed: %d\n", dwStatus);
        //CloseHandle(hFile);
        CryptReleaseContext(hProv, 0);
        return dwStatus;
    }*/



    return 0;
}
定义PSAPI第1版 #包括 #包括 #包括 #包括 #包括 #包括 #定义bufsize1024 #定义MD5LEN 16 //为确保符号的正确分辨率,请将Psapi.lib添加到TARGETLIBS #pragma注释(lib,“psapi.lib”) 内部主(空) { HWND hMyProcess=(HWND)(GetCurrentProcess()); HMODULE HMODULE=(HMODULE)GetModuleHandle(NULL); TCHAR szProcessName[MAX_PATH]=文本(“”); MODULEINFO MODULEINFO; if(hModule!=NULL&&hMyProcess!=NULL){ //if(GetModuleInformation()) GetModuleBaseName(hMyProcess,hModule,szProcessName,MAX_PATH); printf(“%s\n”,szProcessName); if(获取模块信息(hMyProcess、hModule和moduleInfo、sizeof(moduleInfo))){ printf(“lpbaseofdl:%x\n”,moduleInfo.lpbaseofdl); printf(“入口点:%x\n”,moduleInfo.EntryPoint); printf(“SizeOfImage:%x\n”,moduleInfo.SizeOfImage); } } //在这里工作正常之前,问题就在下面 //读取进程存储器 TCHAR*hexex; 大小*lpNumberOfBytesRead; if(ReadProcessMemory,hMyProcess,moduleInfo.lpBaseOfDell, hexEXE,moduleInfo.SizeOfImage,0)){ //printf(“%s\n”,hexex); printf(“读取内存\n”); printf(“%d\n”,strlen(hexEXE)); } //将在以后实施,取自-->https://msdn.microsoft.com/en-us/library/aa382380(第85节) DWORD dwStatus=0; BOOL-bResult=FALSE; HCRYPTPROV hProv=0; HCRYPTHASH hHash=0; /*if(!CryptAcquireContext(&hProv,NULL,NULL,PROV\u RSA\u FULL,CRYPT\u VERIFYCONTEXT)){ dwStatus=GetLastError(); printf(“CryptAcquireContext失败:%d\n”,dwStatus); //闭合手柄(hFile); 返回状态; } if(!CryptCreateHash(hProv、CALG_MD5、0、0和hHash)){ dwStatus=GetLastError(); printf(“CryptAcquireContext失败:%d\n”,dwStatus); //闭合手柄(hFile); CryptReleaseContext(hProv,0); 返回状态; }*/ 返回0; } 问题: 我无法读取自己进程的内存,这是我第一次使用WinAPI,因此可能是我以错误的方式使用了该函数

程序挂起,显示“Windows遇到了一些问题…”

可能的错误原因:
我认为我之前获取的进程句柄(hMyProcess)没有所需的权限(process\u VM\u READ),如何验证它,如果没有,如何获得正确的权限

很抱歉进行了这么长时间的讨论,但我通过将代码更改为而不是使用ReadProcessMemory直接通过for循环在内存上迭代来运行它,如下所示:

 long *baseAddress = (long *)moduleInfo.lpBaseOfDll;
    printf("%d %x\n",baseAddress, baseAddress);
    for (int i = 0; i < moduleInfo.SizeOfImage; ++i){
        long *addressToRead = baseAddress+i;
        printf("%x : %x\n", addressToRead, *addressToRead);
    }
long*baseAddress=(long*)moduleInfo.lpbaseofdl;
printf(“%d%x\n”,基地址,基地址);
对于(int i=0;i
以下是输出:

进一步思考
然而,我不明白为什么我不能使用ReadProcessMemory

获得它,为什么在2018年使用MD5?有没有更好的建议,尽管这不是主要的问题,但这是一个关于gtg的试验it@RbMm对不起,我不明白你的意思,目的是从内存中读取它自己,然后计算它的校验和,为了检测调试器,我知道有一些方法可以绕过它,也有一些更好的方法可以检查它,但如果您能帮忙的话,我想实现这一点,谢谢。您不需要使用
ReadProcessMemory
。你可以直接读取内存,就像你读取任何内存一样。@hemo这就是东西的工作原理-你可以从stackoverflow复制粘贴很多东西,但是你不能在任何时候复制粘贴你想要的所有东西,就像你想解积分eq而不知道如何乘以两个数字一样任何人对此投了反对票,你能评论一下这有什么问题吗?我不知道如何正确地打印,但这不是我的问题(不是我的投票)。这可能不是你的问题,但至少有两个人认为文字图片是个坏主意。也就是说,“扩展讨论”也是纯问答网站上的一个危险信号。你似乎在回答这个问题。@DavidHeffernan我实际上不清楚一点,我认为如果有人回答会更好that@MSalters我拍下了文字的照片以使其清晰,没有任何意外