我正在尝试制作一个程序,将值500存储到计算器应用程序中MR(内存恢复)按钮的计算器内存地址中。 我知道这个整数的地址是 “calc.exe”+00073320 + 0 + C
如果我使用像作弊引擎这样的程序,我可以获取我正在运行的calculator.exe实例的当前地址,并以这种方式写入它。但是,由于这不是静态地址,我需要一种获取模块基址的方法。
我尝试使用此GetModuleBase函数(请参阅下面的代码)来获取calc.exe的基地址,但我的问题是我无法获取基址。该函数始终返回0而不是正确的地址。
我调试了它,发现在GetModuleBase函数中,它甚至没有循环遍历while循环,因为bModule从Module32First函数返回0。
#include <tchar.h>
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <Psapi.h>
#include <wchar.h>
#pragma comment( lib, "psapi" )
using namespace std;
DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId)
{
MODULEENTRY32 lpModuleEntry = {0};
HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );
if(!hSnapShot)
return NULL;
lpModuleEntry.dwSize = sizeof(lpModuleEntry);
BOOL bModule = Module32First( hSnapShot, &lpModuleEntry );
while(bModule)
{
if(!strcmp( lpModuleEntry.szModule, lpModuleName ) )
{
CloseHandle( hSnapShot );
return (DWORD)lpModuleEntry.modBaseAddr;
}
bModule = Module32Next( hSnapShot, &lpModuleEntry );
}
CloseHandle( hSnapShot );
return NULL;
}
int main() {
HWND hWnd = FindWindow(0, "Calculator");
DWORD BaseAddr;
if(hWnd == 0){
MessageBox(0, "Error cannot find window.", "Error", MB_OK|MB_ICONERROR);
} else {
DWORD proccess_ID;
GetWindowThreadProcessId(hWnd, &proccess_ID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proccess_ID);
if(!hProcess){
MessageBox(0, "Could not open the process!", "Error!", MB_OK|MB_ICONERROR);
} else {
int newdata = 500;
BaseAddr = GetModuleBase("calc.exe",proccess_ID);
//GetModuleBase is always returning 0, so I am not getting the correct base address
DWORD newdatasize = sizeof(newdata);
if(WriteProcessMemory(hProcess, (LPVOID)0x002413FC, &newdata, newdatasize, NULL)){
cout << "Memory successfully written." << endl;
} else {
cout << "Memory failed to write." << endl;
}
CloseHandle(hProcess);
}
}
return 0;
}
总结:我无法使用我的GetModuleBase函数获取正确的基址,我需要弄清楚我做错了什么,以便我可以获得“calc.exe”进程的正确基址。
答案 0 :(得分:4)
你应该阅读这样的模块:
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
//You don't have to use this function if you don't want to..
int strcompare(const char* One, const char* Two, bool CaseSensitive)
{
#if defined _WIN32 || defined _WIN64
return CaseSensitive ? strcmp(One, Two) : _stricmp(One, Two);
#else
return CaseSensitive ? strcmp(One, Two) : strcasecmp(One, Two);
#endif
}
//You read module information like this..
MODULEENTRY32 GetModuleInfo(std::uint32_t ProcessID, const char* ModuleName)
{
void* hSnap = nullptr;
MODULEENTRY32 Mod32 = {0};
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)) == INVALID_HANDLE_VALUE)
return Mod32;
Mod32.dwSize = sizeof(MODULEENTRY32);
while (Module32Next(hSnap, &Mod32))
{
if (!strcompare(ModuleName, Mod32.szModule, false))
{
CloseHandle(hSnap);
return Mod32;
}
}
CloseHandle(hSnap);
return {0};
}
int main()
{
//Change the process ID below..
BYTE* BaseAddr = GetModuleInfo(5172, "calc.exe").modBaseAddr;
std::cout<<"BASE ADDRESS: "<<(void*)BaseAddr<<"\n";
return 0;
}
编辑:经过进一步调查后,我发现Visual Studio正在为x32平台进行编译,但calc.exe是一个x64进程..
要使Visual Studio为x64编译,您需要执行以下操作:
然后单击并从以下下拉菜单中选择“新建”:
接下来在下面的下拉菜单中,选择x64:
保存设置并重建项目,它应该可以工作..