-
Notifications
You must be signed in to change notification settings - Fork 0
/
gamecommon.cpp
86 lines (69 loc) · 2.17 KB
/
gamecommon.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "gamecommon.h"
GameCommon::GameCommon(QObject *parent) : QObject(parent)
, m_processHandle(nullptr)
{
}
/**
* @brief 获取进程句柄
*
* @param[in] className 游戏类名
* @param[in] windowName 游戏窗口名称
*
* @return 进程句柄
*/
void GameCommon::getProcessHandle(LPCSTR className,LPCSTR windowName)
{
HWND windowHandle = FindWindowA(className,windowName);
if (!windowHandle)
{
throw RuntimeException("获取窗口句柄失败,游戏是否已启动?");
}
DWORD processId = 0;
GetWindowThreadProcessId(windowHandle,&processId);
if (!processId)
{
throw RuntimeException("获取窗口进程标识失败!");
}
m_processHandle = OpenProcess(PROCESS_ALL_ACCESS,false,processId);
if (!m_processHandle)
{
throw RuntimeException("打开进程句柄失败!");
}
}
/**
* @brief 获取模块基址
*
* @param[in] moduleNameS 模块名称
*
* @return 模块基址
*/
int GameCommon::getModuleBaseAddress(const QString &moduleNameS)
{
// 模块信息的字节数
DWORD cbNeeded;
// 加载的模块句柄的数组
HMODULE hModules[1024];
// 检索指定进程中满足指定筛选条件的每个模块的句柄,只检索 32 位的
EnumProcessModulesEx(m_processHandle, hModules, sizeof(hModules), &cbNeeded, LIST_MODULES_32BIT) ?: throw RuntimeException("检索进程模块句柄失败!");
// 模块基址
int moduleBaseAddress = 0;
// 模块数量
int moduleCount = cbNeeded / sizeof(HMODULE);
// 遍历每个加载的模块
for (int i = 0; i < moduleCount; i++)
{
TCHAR moduleName[MAX_PATH];
// 获取模块的文件名
if (GetModuleBaseName(m_processHandle, hModules[i], moduleName, sizeof(moduleName) / sizeof(TCHAR)))
{
// 转换为宽字符串
QString moduleNameQt = QString::fromWCharArray(moduleName);
// 检查模块名是否匹配,不区分大小写
if (moduleNameQt.compare(moduleNameS, Qt::CaseInsensitive) == 0) {
moduleBaseAddress = (DWORD_PTR)hModules[i];
break;
}
}
}
return moduleBaseAddress;
}