Files
Sun1602/Client/GameClient/GameCheckMananger.cpp
T
2022-10-26 12:25:11 +08:00

604 lines
14 KiB
C++

#include "SunClientPrecompiledHeader.h"
#include "GameCheckMananger.h"
#include <shlwapi.h>
#pragma comment(lib,"shlwapi.lib")
#include <Psapi.h>
#pragma comment (lib,"Psapi.lib")
#include "GlobalFunc.h"
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lparam);
HANDLE m_CheckHandle[2];
DWORD WINAPI GameCheck(LPVOID lpparentet);
HANDLE CheckThreadHandle = NULL;
#include "Application.h"
GameCheckMananger::GameCheckMananger(void):
bIsInit(false),bIsChecked(false)
{
if (!Initialize())
{
SetChecked("检测模块初始化失败","初始化失败");
}
}
GameCheckMananger::~GameCheckMananger(void)
{
//[清理][BY:十里坡剑神][QQ:112582793][2020-4-17 0:09]
m_ProcessInfo.clear();
m_ModuleInfo.clear();
m_WindowsText.clear();
m_ProcessList.clear();
m_ModuleList.clear();
m_WindwosList.clear();
}
StringVector GameCheckMananger::split(string& str, const char* c)
{//字符串分割
char *cstr = NULL;
char *p = NULL;
char * buff = NULL;
StringVector res;
cstr = new char[str.size() + 1];
strcpy_s(cstr, str.size() + 1, str.c_str());
p = strtok_s(cstr, c, &buff);
while (p != NULL)
{
res.push_back(p);
p = strtok_s(NULL, c, &buff);
}
if (p != NULL)
{
delete[] p;
p = NULL;
}
if (cstr != NULL)
{
delete[]cstr;
cstr = NULL;
}
return res;
}
void GameCheckMananger::SetUserID(string UserID)
{
mUserID = UserID;
}
void GameCheckMananger::SetCharName(string CharName)
{
mCharName=CharName;
}
void GameCheckMananger::GetCheatData()
{//检测列表初始化
//下载检测列表
string Ret = Download("http://sun2.online/ProgramList.txt");
//清空待检测列表容器
m_WindwosList.clear();
m_ProcessList.clear();
m_ModuleList.clear();
StringVector vCheckList, vCheckInfo;
vCheckList = split(Ret, "#\r\n");
StringVector::iterator iter;
iter = vCheckList.begin();
if(vCheckList.size()==0)
{
return ;
}
while (1)
{
if (iter==vCheckList.end())
break;
else
{
vCheckInfo = split(*iter, "|");
if (vCheckInfo.size() == 3)
{
string strCheckName;
strCheckName = vCheckInfo[1];
std::transform(strCheckName.begin(),strCheckName.end(),strCheckName.begin(),::toupper);
switch (atol(vCheckInfo[0].c_str()))
{
case 1:
m_WindwosList.push_back(strCheckName);
break;
case 2:
m_ProcessList.push_back(strCheckName);
break;
case 3:
m_ModuleList.push_back(strCheckName);
break;
case 4:
m_SysList.push_back(strCheckName);
break;
default:
break;
}
}
//else MYDEBUGMSG("vCheckInfo.size()!= 3--%s",iter->c_str());
std::vector<std::string>(vCheckInfo).swap(vCheckInfo);
iter++;
}
}
std::vector<std::string>(vCheckList).swap(vCheckList);
}
void GameCheckMananger::InitGameCheck()
{
if(bIsInit) return;
GetCheatData();
m_CheckHandle[0] = CreateEvent(NULL,FALSE,FALSE,NULL);
m_CheckHandle[1] = CreateEvent(NULL,FALSE,FALSE,NULL);
bIsInit = true;
CheckThreadHandle = CreateThread(NULL, 0, GameCheck, NULL, 0, NULL);
if (CheckThreadHandle == NULL)
{
SetChecked("检测线程创建失败","线程创建失败");
}
}
void GameCheckMananger::Process()
{
if(!bIsInit)
{
if(bIsChecked&&GetTickCount()-mdwCloseCount>5000)
{
//GlobalFunc::LogOutGame();
}
return;
}
if(mUserID.length()>0&&
mCharName.length()>0&&
mProgramName.length()>0&&
mProgramPath.length()>0&&bIsChecked)
{//检测到外挂信息,以及所需信息收集足够,发送信息到服务端然后退出游戏
MSG_CG_CONNECTION_HACKER_SYN msg;
Sprintf(msg.pszCharName,"%s",mCharName.c_str());
Sprintf(msg.pszProgramName,"%s",mProgramName.c_str());
Sprintf(msg.pszProgramPath,"%s",mProgramPath.c_str());
Sprintf(msg.pszUserID,"%s",mUserID.c_str());
//GlobalFunc::SendPacket( CI_GAMESERVERIDX, &msg, sizeof(msg));
//bIsInit=false;
//mdwCloseCount=GetTickCount();
return;
}
if(bIsChecked)
return;
SetEvent(m_CheckHandle[1]);
DWORD dwRet = ResumeThread(CheckThreadHandle);
if (dwRet != 0)
{//[线程被挂起][BY:十里坡剑神][QQ:112582793][2020-4-5 18:21]
SetChecked("检测线程被挂起","线程被挂起");
}
//操作GM工具会导致游戏线程挂起,导致误判.GM工具下屏蔽该检测
//具体表现为工具点击发放物品游戏闪退,可以用此方法放一些测试端,共享端.
//[获取检测线程上下文内容,线程被结束GetLastError返回5,否则返回0,返回1400是因为线程没初始化完成][BY:十里坡剑神][QQ:112582793][2020-4-5 18:23]
CONTEXT context = { 0 };
context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS;
GetThreadContext(CheckThreadHandle, &context);
dwRet = 0;
dwRet = GetLastError();
if (dwRet == 5)
{//[线程被结束][BY:十里坡剑神][QQ:112582793][2020-4-5 18:21]
SetChecked("检测线程被结束","线程被结束");
}
}
BOOL GameCheckMananger::GetProcessInfo()
{
m_ProcessInfo.clear();
m_ModuleInfo.clear();
m_WindowsText.clear();
m_SysInfo.clear();
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 stcPe32={0,};
stcPe32.dwSize = sizeof(PROCESSENTRY32);
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hProcessSnap==INVALID_HANDLE_VALUE)
{
return FALSE;
}
if(!Process32First(hProcessSnap,&stcPe32))
{
CloseHandle(hProcessSnap);
return FALSE;
}
do
{
try
{
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,stcPe32.th32ProcessID);
if(hProcess)
{
int nPriority = GetPriorityClass(hProcess);
CloseHandle(hProcess);
}
PROCINFO info;
info.dwPId =stcPe32.th32ProcessID;
info.ProcessName = stcPe32.szExeFile;
info.ProcessPath = GetProcessFullPath(stcPe32.th32ProcessID);
std::transform(info.ProcessName.begin(),info.ProcessName.end(),info.ProcessName.begin(),::toupper);
m_ProcessInfo[info.ProcessName] = info;
GetModuleInfo(stcPe32.th32ProcessID);
}
catch (...)
{
//CHATMGR->AddMsg(CTC_SYSMSG,"异常处理");
}
} while (Process32Next(hProcessSnap,&stcPe32));
CloseHandle(hProcessSnap);
return TRUE;
}
BOOL GameCheckMananger::GetModuleInfo(DWORD dwPId)
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32 ;
me32.dwSize = sizeof(MODULEENTRY32);
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32,dwPId);
if(hModuleSnap==INVALID_HANDLE_VALUE)
{
return FALSE;
}
if(!Module32First(hModuleSnap,&me32))
{
CloseHandle(hModuleSnap);
return FALSE;
}
do
{
try
{
std::string szModule(me32.szModule);
std::transform(szModule.begin(),szModule.end(),szModule.begin(),::toupper);
m_ModuleInfo[szModule] = me32.szExePath;
}
catch (...)
{
}
}
while (Module32Next(hModuleSnap,&me32));
CloseHandle(hModuleSnap);
return TRUE;
}
BOOL GameCheckMananger::DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
{
TCHAR szDriveStr[500] = {0,};
TCHAR szDrive[3] = { 0, };
TCHAR szDevName[100] = { 0, };
INT cchDevName = 0;
INT i = 0;
//[检查参数][By:十里坡剑神][QQ:112582793][2017/12/27]
if(!pszDosPath || !pszNtPath )
{
return FALSE;
}
//[获取本地磁盘字符串 ][By:十里坡剑神][QQ:112582793][2017/12/27]
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';
if(!QueryDosDevice(szDrive, szDevName, 100))//[查询 Dos 设备名 ][By:十里坡剑神][QQ:112582793][2017/12/27]
{
return FALSE;
}
cchDevName = lstrlen(szDevName);
if(_tcsnicmp(pszDosPath, szDevName, cchDevName) == 0)//[命中][By:十里坡剑神][QQ:112582793][2017/12/27]
{
lstrcpy(pszNtPath, szDrive);//[复制驱动器 ][By:十里坡剑神][QQ:112582793][2017/12/27]
lstrcat(pszNtPath, pszDosPath + cchDevName);//[复制路径][By:十里坡剑神][QQ:112582793][2017/12/27]
return TRUE;
}
}
}
lstrcpy(pszNtPath, pszDosPath);
return FALSE;
}
string GameCheckMananger::GetProcessFullPath(DWORD dwPID)
{
TCHAR szImagePath[MAX_PATH];
TCHAR pszFullPath[MAX_PATH];
HANDLE hProcess;
std::string strPath;
strPath = "";
if(!pszFullPath)
return strPath;
pszFullPath[0] = '\0';
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPID);
if(!hProcess)
return strPath;
if(!GetProcessImageFileName(hProcess, szImagePath, MAX_PATH))
{
CloseHandle(hProcess);
return strPath;
}
if(!DosPathToNtPath(szImagePath, pszFullPath))
{
CloseHandle(hProcess);
return strPath;
}
CloseHandle(hProcess);
strPath = pszFullPath;
return strPath;
}
void GameCheckMananger::AddSysInfo(std::string sysName)
{
std::transform(sysName.begin(), sysName.end(), sysName.begin(), ::toupper);
m_SysInfo.push_back(sysName);
}
void GameCheckMananger::AddWindowText(std::string str,HWND hwnd)
{
std::transform(str.begin(),str.end(),str.begin(),::toupper);
m_WindowsText[str] = hwnd;
}
BOOL GameCheckMananger::CheckProcessList()
{
if (m_ProcessInfo.size() == 0 || m_ProcessList.size() == 0 /*|| m_ProcessInfo.size() < 20 || m_ProcessList.size() < 20*/)
{//进程检测加进程数量检测,虚拟机一般进程数比较少
//m_ProcessInfo不重复进程数,m_ProcessList检测文件加载的进程检测数目
char buff[1024]={0};
sprintf(buff,"m_ProcessInfo=%d---m_ProcessList=%d",m_ProcessInfo.size(),m_ProcessList.size());
SetChecked(buff,"进程列表异常");
return TRUE;
}
std::vector<std::string>::iterator iter;
std::map<std::string,PROCINFO>::iterator mIter;
iter = m_ProcessList.begin();
while(TRUE)
{
if(iter==m_ProcessList.end())
break;
else
{
mIter = m_ProcessInfo.find(iter->c_str());
if(mIter!=m_ProcessInfo.end())
{
//[检测到指定进程,发送消息到服务端记录][By:十里坡剑神][QQ:112582793][2017/12/27]
SetChecked(mIter->second.ProcessName,mIter->second.ProcessPath);
return TRUE;
}
}
iter++;
}
return FALSE;
}
BOOL GameCheckMananger::CheckModuleList()
{
//return FALSE;
if(m_ModuleInfo.size()==0||m_ModuleList.size()==0)
{
char buff[1024]={0};
sprintf(buff,"m_ModuleInfo=%d---m_ModuleList=%d",m_ModuleInfo.size(),m_ModuleList.size());
SetChecked(buff,"模块列表异常");
return TRUE;
}
std::map<std::string,std::string>::iterator mIter;
std::vector<std::string>::iterator iter;
iter = m_ModuleList.begin();
while(TRUE)
{
if(iter==m_ModuleList.end())
break;
else
{
mIter = m_ModuleInfo.find(iter->c_str());
if(mIter!=m_ModuleInfo.end())
{
SetChecked(iter->c_str(),mIter->second);
return TRUE;
}
}
iter++;
}
return FALSE;
}
void GameCheckMananger::GetSysInfo()
{
m_SysInfo.clear();
LPVOID drivers[1024] = { 0 };
DWORD cbNeeded;
int cDrivers, i;
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers))
{
char szDriver[1024] = { 0 };
cDrivers = cbNeeded / sizeof(drivers[0]);
for (i = 0; i < cDrivers; i++)
{
if (GetDeviceDriverBaseName(drivers[i], szDriver, sizeof(szDriver) / sizeof(szDriver[0])))
{
AddSysInfo(szDriver);
}
}
}
}
BOOL GameCheckMananger::CheckSysList()
{//驱动模块检测
if (m_SysList.size() == 0 || m_SysInfo.size() == 0)
{
char buff[1024]={0};
sprintf(buff,"m_SysList=%d---m_SysInfo=%d",m_SysList.size(),m_SysInfo.size());
SetChecked(buff,"驱动列表异常");
return TRUE;
}
std::vector<std::string>::iterator iter;
iter = m_SysList.begin();
for (; iter != m_SysList.end(); iter++)
{
if (std::find(m_SysInfo.begin(), m_SysInfo.end(), *iter) != m_SysInfo.end())
{
//[检测到指定进程,发送消息到服务端记录][By:十里坡剑神][QQ:112582793][2017/12/27]
SetChecked((*iter).c_str(),(*iter).c_str());
return TRUE;
}
}
return FALSE;
}
void GameCheckMananger::SetChecked(string Name,string Path)
{
bIsChecked=true;
mProgramName=Name;
mProgramPath=Path;
MYDEBUGMSG("%s-%s",Name.c_str(),Path.c_str());
}
BOOL GameCheckMananger::CheckWindowList()
{
if(m_WindowsText.size()==0||m_WindwosList.size()==0)
{
char buff[1024]={0};
sprintf(buff,"m_SysList=%d---m_SysInfo=%d",m_SysList.size(),m_SysInfo.size());
SetChecked(buff,"窗口列表异常");
return FALSE;
}
std::vector<std::string>::iterator iter;
iter = m_WindwosList.begin();
while(TRUE)
{
if(iter==m_WindwosList.end())
break;
else
{
std::map<std::string,HWND>::iterator mIter1;
mIter1 = m_WindowsText.begin();
while(TRUE)
{
if(mIter1==m_WindowsText.end())
break;
else
{
if(mIter1->first.find(iter->c_str())!=mIter1->first.npos)
{
SetChecked(iter->c_str(),mIter1->first.c_str());
return TRUE;
}
}
mIter1++;
}
}
iter++;
}
return FALSE;
}
BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam)
{
char temp1[256] = { 0 }, temp2[256] = {0};
::SendMessage(hWnd, WM_GETTEXT, sizeof(temp1) / sizeof(char), (LPARAM)temp2);
if(strlen(temp2)>0)
{
GameCheckMananger::Instance()->AddWindowText(temp2,hWnd);
}
return true;
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lparam)
{
char str[512] = {0,};
::GetWindowText(hwnd,str,sizeof(str));
if(strlen(str)>0)
{
GameCheckMananger::Instance()->AddWindowText(str,hwnd);
::EnumChildWindows(hwnd, EnumChildProc, 0);
}
return TRUE;
}
DWORD WINAPI GameCheck(LPVOID lpparentet)
{
MYDEBUGMSG("GameCheck Start!!");
while(TRUE)
{
DWORD dwID = WaitForMultipleObjects(2,m_CheckHandle,FALSE,INFINITE);
switch(dwID)
{
case 1:
{
GameCheckMananger::Instance()->GetProcessInfo();
::EnumWindows(EnumWindowsProc,NULL);
GameCheckMananger::Instance()->GetSysInfo();
//Sleep(2000);
SetEvent(m_CheckHandle[0]);
}
break;
case 0:
{
byte * FristCode = (byte*)&GetTickCount;
if (*FristCode == 0xE9)
{//加速检测
//发送检测消息给服务端记录.不发送的话直接退出
GameCheckMananger::Instance()->SetChecked("进程被加速","加速检测");
}
if(GameCheckMananger::Instance()->CheckProcessList())
{
return 0;
}
if(GameCheckMananger::Instance()->CheckModuleList())
{
return 0;
}
if(GameCheckMananger::Instance()->CheckWindowList())
{
return 0;
}
if (GameCheckMananger::Instance()->CheckSysList())
{
return 0;
}
}
break;
}
}
}