C ++:读取另一个进程的内存

时间:2013-10-26 11:30:16

标签: c++ winapi memory

我想要一个允许我读取另一个进程的内存的函数。 我在想这样的事情(伪代码):

staticAddress = 0x026E0DC4
processId = GetProcessIdByName(processName)
processHandle = GetProcessHandle(processId)
processBaseAddress = GetBaseAddress(processHandle)
addressToRead = processBaseAddress+staticAddress
readValueAsInt = ReadMemoryInt(processHandle, addressToRead)
readValueAsFloat = ReadMemoryFloat(processHandle, addressToRead)
readValueAsString = ReadMemoryString(processHandle, addressToRead)

这甚至可能吗? 这是我到目前为止所得到的:

#include <Windows.h>
#include <conio.h>
#include <tlhelp32.h>
#include <string>
#include <psapi.h>
#pragma comment( lib, "psapi" )

int GetProcessId(char* ProcName) {
    PROCESSENTRY32 pe32;
    HANDLE hSnapshot = NULL;
    pe32.dwSize = sizeof( PROCESSENTRY32 );
    hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

    if( Process32First( hSnapshot, &pe32 ) ) {
        do {
            if( strcmp( pe32.szExeFile, ProcName ) == 0 )
                break;
        } while( Process32Next( hSnapshot, &pe32 ) );
    }

    if( hSnapshot != INVALID_HANDLE_VALUE )
        CloseHandle( hSnapshot );

    return pe32.th32ProcessID;  
}

int GetModuleBase(HANDLE processHandle, string &sModuleName) 
{ 
   HMODULE *hModules; 
   char szBuf[50]; 
   DWORD cModules; 
   DWORD dwBase = -1; 
   //------ 

   EnumProcessModules(processHandle, hModules, 0, &cModules); 
   hModules = new HMODULE[cModules/sizeof(HMODULE)]; 

   if(EnumProcessModules(processHandle, hModules, cModules/sizeof(HMODULE), &cModules)) { 
      for(int i = 0; i < cModules/sizeof(HMODULE); i++) { 
         if(GetModuleBaseName(processHandle, hModules[i], szBuf, sizeof(szBuf))) { 
            if(sModuleName.compare(szBuf) == 0) { 
               dwBase = (DWORD)hModules[i]; 
               break; 
            } 
         } 
      } 
   } 

   delete[] hModules; 

   return dwBase; 
}


int ReadMemoryInt(HANDLE processHandle, LPCVOID address) {
    //LPVOID buffer = ??;
    //SIZE_T size = ??;
    SIZE_T NumberOfBytesToRead = 4; //??
    ReadProcessMemory(processHandle, address, buffer, size, NumberOfBytesToRead)
    return buffer; //??
}

int ReadMemoryFloat(HANDLE processHandle, LPCVOID address) {
    //LPVOID buffer = ??;
    //SIZE_T size = ??;
    SIZE_T NumberOfBytesToRead = 8; //??
    ReadProcessMemory(processHandle, address, buffer, size, NumberOfBytesToRead)
    return buffer; //??
}

int ReadMemoryString(HANDLE processHandle, LPCVOID address) {
    //LPVOID buffer = ??;
    //SIZE_T size = ??;
    SIZE_T NumberOfBytesToRead = 999; //??
    ReadProcessMemory(processHandle, address, buffer, size, NumberOfBytesToRead)
    return buffer; //??
}

int main()
{
    //read an integer from "Program.exe"+0x05D8A3C4
    int address = 0x05D8A3C4;
    char* processName = "Program.exe";
    int processId = GetProcessId(processName);
    HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, processId);
    int processBaseAddress = GetModuleBase(processHandle, (string)"Program.exe";
    LPCVOID actualAddress = processBaseAddress+address;
    int readValue = ReadMemory(processHandle, actualAddress);
    std::cout << readValue << std::endl;
    CloseHandle(processHandle);
    return 0;
}

正如您在代码中看到的那样,问题我不确定ReadProcessMemory的“缓冲区”和“大小”参数。如果有人能帮助我解决这个问题,我真的很感激。

2 个答案:

答案 0 :(得分:6)

以下是ReadMemoryInt()功能的示例:

int ReadMemoryInt(HANDLE processHandle, LPCVOID address) {
    int buffer = 0;
    SIZE_T NumberOfBytesToRead = sizeof(buffer); //this is equal to 4
    SIZE_T NumberOfBytesActuallyRead;
    BOOL err = ReadProcessMemory(processHandle, address, &buffer, NumberOfBytesToRead, &NumberOfBytesActuallyRead);
    if (err || NumberOfBytesActuallyRead != NumberOfBytesToRead)
      /*an error occured*/ ;
    return buffer; 
}

&表示传递变量的地址而不是其值。

ReadMemoryString()你无法知道你需要阅读的实际大小,你可以读取一个大块(大小为999)或读取许多小块,直到你得到一个包含\ 0。

如果你想知道它是否有效,你可以在调试器中启动它,看看你期望的值是否会被返回。

答案 1 :(得分:2)

https://github.com/T-vK/Memory-Hacking-Class
这是一个非常简单的课程,可以做到这一切,甚至更多 这是一个包含它支持的所有方法的列表:

GetProcessId()
GetModuleBase()
SetPrivilege()
GetDebugPrivileges()
ReadInt()
GetPointerAddress()
ReadPointerInt()
ReadFloat()
ReadPointerFloat()
ReadText()
ReadPointerText()

使用示例:

#include "Memory.hpp"
using std::string;

int main() {
    char* TARGET_PROCESS_NAME = "League of Legends.exe";

    int GAME_VERSION_MODULE_OFFSET = 0x2A1D738; // [Base address of 'League of Legends.exe']+0x2A1D738 (address of a string containing a version number)

    Memory Memory;
    Memory.GetDebugPrivileges();
    int processId = Memory.GetProcessId(TARGET_PROCESS_NAME);
    HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, processId);

    int baseAddress = Memory.GetModuleBase(processHandle, (string)TARGET_PROCESS_NAME);

    int gameVersionAddress = baseAddress + GAME_VERSION_MODULE_OFFSET;

    string gameVersion = Memory.ReadText(processHandle, gameVersionAddress);

    std::cout << "Game version: " << gameVersionAddress << std::endl;

    cin.get();
    return 0;
}

如果你想知道,是的,我是作者。