想必大家玩游戏都开过挂,无论单机或者联机游戏,如何最大程度的保护自己的游戏。
如果只是想简简单单的防御一下。
HANDLE shProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 sprocess = {sizeof(PROCESSENTRY32)};
// 遍历进程
while (Process32Next(shProcessSnap,&sprocess)){
string s_szExeFile = process.szExeFile; // char* 转 string
if(s_szExeFile == "QQ.exe") {
//操作
}
}
上述简简单单的例子,可以在游戏启动前,检测电脑所处环境,就跟玩绝地前,蓝洞的检测一样。
如果软件进程名称随机生成呢,那么可以查找他的软件信息
如上,检测厂商名称也是一种检测手段。
#pragma region 依赖
class FileVerInfo{
public:
string ProductName; // 产品名
string Comments; // 注释
string CompanyName; // 公司名
string LegalCopyright; // 合法版权
string FileDescription; // 文件描述
string FileVersion; // 文件版本
string ProductVersion; // 产品版本
string InternalName; // 内部名称
string LegalTrademarks; // 合法商标
string OriginalFilename; // 原文件名
string PrivateBuild; // 私人设置
string SpecialBuild; // 特殊设置
};
BOOL getFileVerInfo(char* fileFullPath,FileVerInfo &fvi){
// 获取文件版本信息大小
DWORD verInfoSize = GetFileVersionInfoSize(fileFullPath,0);
// 获取的版本信息大小为 0
if(!verInfoSize){cout << "GetFileVersionInfoSize failed." << endl;return FALSE;}
// 给文件版本信息分配内存
LPVOID p_verInfo = malloc(verInfoSize);
// 获取文件版本信息失败
if(!GetFileVersionInfo(
fileFullPath, // 文件全路径
0, // 保留
verInfoSize, // 缓冲区大小
p_verInfo // 接收文件版本信息的缓冲区指针
)){cout << "GetFileVersionInfo failed." << endl;return FALSE;}
// 检索指定的文件版本信息失败
char* p_verValue = NULL;
UINT verValueSize = 0;
if(!VerQueryValue(
p_verInfo, // 由 GetFileVersionInfo 获取到的指向文件版本信息缓冲区的指针
"\\VarFileInfo\\Translation", // 版本信息值,\VarFileInfo\Translation :
(LPVOID*)&p_verValue, // 接收版本信息
&verValueSize // 接收版本信息大小
)){cout << "VerQueryValue failed." << endl;return FALSE;}
// 判断中文还是英文
CString str_subBlock; // 版本信息值
CString str_translation; // 拼接后的值
CString str_temp; // 临时
str_temp.Format("000%x",*((unsigned short int *)p_verValue));
str_translation = str_temp.Right(4);
str_temp.Format("000%x",*((unsigned short int *)&p_verValue[2]));
str_translation += str_temp.Right(4);
// 文件信息赋值给对象成员
str_subBlock.Format("\\StringFileInfo\\%s\\ProductName",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.ProductName = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\Comments",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.Comments = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\CompanyName",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.CompanyName = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\LegalCopyright",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.LegalCopyright = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\FileDescription",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.FileDescription = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\FileVersion",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.FileVersion = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\ProductVersion",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.ProductVersion = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\InternalName",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.InternalName = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\OriginalFilename",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.OriginalFilename = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\PrivateBuild",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.PrivateBuild = p_verValue;
str_subBlock.ReleaseBuffer();
str_subBlock.Format("\\StringFileInfo\\%s\\SpecialBuild",str_translation);
VerQueryValue(p_verInfo,str_subBlock.GetBufferSetLength(256),(LPVOID*)&p_verValue,&verValueSize);
fvi.SpecialBuild = p_verValue;
str_subBlock.ReleaseBuffer();
return TRUE;
}
// dos 文件路径转 windows 文件路径
BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
{
TCHAR szDriveStr[500];
TCHAR szDrive[3];
TCHAR szDevName[100];
INT cchDevName;
INT i;
//检查参数
if(!pszDosPath || !pszNtPath )
return FALSE;
//获取本地磁盘字符串
if(GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
{
for(i = 0; szDriveStr[i]; i += 4)
{
if(!lstrcmpi(&(szDriveStr[i]), _T("A:\\")) || !lstrcmpi(&(szDriveStr[i]), _T("B:\\"))){continue;}
szDrive[0] = szDriveStr[i];
szDrive[1] = szDriveStr[i + 1];
szDrive[2] = '\0';
// 查询 Dos 设备名
if(!QueryDosDevice(szDrive, szDevName, 100)){return FALSE;}
// 命中
cchDevName = lstrlen(szDevName);
if(_tcsnicmp(pszDosPath, szDevName, cchDevName) == 0){
// 复制驱动器
lstrcpy(pszNtPath, szDrive);
// 复制路径
lstrcat(pszNtPath, pszDosPath + cchDevName);
return TRUE;
}
}
}
lstrcpy(pszNtPath, pszDosPath);
return FALSE;
}
// 获取进程全路径
BOOL GetProcessFullPath(DWORD dwPID,string &fullPath){
TCHAR szImagePath[MAX_PATH];
TCHAR pszFullPath[MAX_PATH];
HANDLE hProcess;
// 初始化失败
if(!pszFullPath){return FALSE;}
pszFullPath[0] = '\0';
// 获取进程句柄失败
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPID);
if(!hProcess){return FALSE;}
// 获取进程完整路径失败
if(!GetProcessImageFileName(
hProcess, // 进程句柄
szImagePath, // 接收进程所属文件全路径的指针
MAX_PATH // 缓冲区大小
)){
CloseHandle(hProcess);
return FALSE;
}
// 路径转换失败
if(!DosPathToNtPath(szImagePath, pszFullPath)){
CloseHandle(hProcess);
return FALSE;
}
CloseHandle(hProcess);
// 导出文件全路径
fullPath = pszFullPath;
return TRUE;
}
#pragma endregion
bool pchunter(string& detail){
// 创建进程快照
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hProcessSnap){cout << "CreateToolhelp32Snapshot failed." << endl;return false;}
// 遍历进程
PROCESSENTRY32 process = {sizeof(PROCESSENTRY32)};
for(BOOL flag = Process32First(hProcessSnap,&process);flag;flag = Process32Next(hProcessSnap,&process)){
// 获取进程文件全路径
string str_filePath;
GetProcessFullPath(process.th32ProcessID,str_filePath);
// 获取文件版本信息
FileVerInfo fvi;
getFileVerInfo(stringToCharP(str_filePath),fvi);
if(fvi.Comments == "一普明为Windows系统信息查看工具(安全类)" &&
fvi.OriginalFilename == "PCHunter.exe"
){
cout << "匹配到特征!" << endl;
// 拼接字符串,返回特征信息
detail+=fvi.Comments; detail+=",";
detail+=fvi.CompanyName; detail+=",";
detail+=fvi.FileDescription; detail+=",";
detail+=fvi.FileVersion; detail+=",";
detail+=fvi.InternalName; detail+=",";
detail+=fvi.LegalCopyright; detail+=",";
detail+=fvi.LegalTrademarks; detail+=",";
detail+=fvi.OriginalFilename; detail+=",";
detail+=fvi.PrivateBuild; detail+=",";
detail+=fvi.ProductName; detail+=",";
detail+=fvi.ProductVersion; detail+=",";
detail+=fvi.SpecialBuild;
return true;
}
}
return false;
}