use*_*103 2 c++ winapi visual-c++
我最近一直在玩内存读取/编辑,遇到了一个问题,我认为这是由于 64 位应用程序引起的,我也尝试在 64 位下编译。我在 32 位应用程序中使用此脚本没有任何问题,但是当我在 Solitaire 上尝试此操作时,它无法获取基地址,从而无法计算出正确的偏移量等。这是脚本:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
using namespace std;
DWORD dwGetModuleBaseAddress(DWORD dwProcessID, TCHAR *lpszModuleName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
DWORD dwModuleBaseAddress = 0;
if (hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry32 = { 0 };
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &ModuleEntry32))
{
do
{
if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0)
{
dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &ModuleEntry32));
}
CloseHandle(hSnapshot);
}
return dwModuleBaseAddress;
}
int main()
{
DWORD address = 0xBAFA8;
HWND hwnd = FindWindow(0, L"Solitaire");
DWORD pid;
int data = 0;
int newData = 0;
if (hwnd)
{
GetWindowThreadProcessId(hwnd, &pid);
HANDLE phandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if (phandle)
{
DWORD base = dwGetModuleBaseAddress(pid, L"Solitaire.exe");
cout << "Base: " << (void*)base << endl;
ReadProcessMemory(phandle, (LPCVOID)(base + address), &data, sizeof(data), 0);
}
else {
cout << "Couldnt get handle" << endl;
}
}
else {
cout << "Couldn't find window" << endl;
}
cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题可能是我使用的函数使用 MODULE32,但是我尝试了其他函数(使用 EnumModules),但仍然无法返回地址。
有什么想法如何获取 64 位应用程序的基地址或让此脚本工作吗?
谢谢
小智 6
那么你的代码永远不会成功工作,因为你谈论的是 64 位,但你使用 DWORD 作为基地址!Solitare可能有一个 32 位地址,但你不能保证这一点,而且你永远不应该假设它。
这个功能有效。它只需要相关进程的进程 ID,并且假设您需要该进程的基地址。即不是它的 DLL 之一。如果您不想要拥有进程,那么您需要moduleArray使用类似的方法进行迭代for (int i=0; i<moduleCount; i++ ) { // do something with moduleArray[i] },然后检查模块文件名。
如果您只想要启动进程(可执行文件),您可以假设它是数组中的第一个元素。
DWORD_PTR GetProcessBaseAddress( DWORD processID )
{
DWORD_PTR baseAddress = 0;
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
HMODULE *moduleArray;
LPBYTE moduleArrayBytes;
DWORD bytesRequired;
if ( processHandle )
{
if ( EnumProcessModules( processHandle, NULL, 0, &bytesRequired ) )
{
if ( bytesRequired )
{
moduleArrayBytes = (LPBYTE)LocalAlloc( LPTR, bytesRequired );
if ( moduleArrayBytes )
{
unsigned int moduleCount;
moduleCount = bytesRequired / sizeof( HMODULE );
moduleArray = (HMODULE *)moduleArrayBytes;
if ( EnumProcessModules( processHandle, moduleArray, bytesRequired, &bytesRequired ) )
{
baseAddress = (DWORD_PTR)moduleArray[0];
}
LocalFree( moduleArrayBytes );
}
}
}
CloseHandle( processHandle );
}
return baseAddress;
}
Run Code Online (Sandbox Code Playgroud)