1
0
forked from metin2/server
server/game/src/XTrapManager.cpp
2022-03-05 12:44:06 +02:00

330 lines
7.9 KiB
C++
Raw Blame History

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
#include <io.h>
#include <windows.h>
#include <tchar.h>
#else
#include <dlfcn.h>
#include <unistd.h>
#endif
#include <XTrap_S_Interface.h>
#include "char.h"
#include "config.h"
#include "event.h"
#include "log.h"
#include "desc.h"
#include "packet.h"
#include "XTrapManager.h"
#define CSFILE_NUM 2
#define XTRAP_CS1_CHECK_CYCLE PASSES_PER_SEC(20) // per 20sec
unsigned char g_XTrap_ClientMap[CSFILE_NUM][XTRAP_CS4_BUFSIZE_MAP];
struct CXTrapManager::sXTrapContext
{
//API function pointers
PFN_XTrap_S_Start XTrap_S_Start;
PFN_XTrap_S_SessionInit XTrap_S_SessionInit;
PFN_XTrap_CS_Step1 XTrap_CS_Step1;
PFN_XTrap_CS_Step3 XTrap_CS_Step3;
PFN_XTrap_S_SetActiveCode XTrap_S_SetActiveCode;
PFN_XTrap_S_SetOption XTrap_S_SetOption;
PFN_XTrap_S_SetAllowDelay XTrap_S_SetAllowDelay;
PFN_XTrap_S_SendGamePacket XTrap_S_SendGamePacket;
PFN_XTrap_S_RecvGamePacket XTrap_S_RecvGamePacket;
//handle
void* hXTrap4Server;
};
CXTrapManager::CXTrapManager()
{
m_pImpl = M2_NEW sXTrapContext;
memset( m_pImpl, 0x00, sizeof(sXTrapContext) );
}
CXTrapManager::~CXTrapManager()
{
#ifdef __FreeBSD__
if (m_pImpl->hXTrap4Server)
{
dlclose(m_pImpl->hXTrap4Server);
}
#endif
M2_DELETE(m_pImpl);
}
#ifdef __FreeBSD__
void CXTrapManager::MapReloadSignalHandler( int signal )
{
for(int i=0; i<CSFILE_NUM; ++i )
{
if( Instance().LoadClientMapFile(i) )
sys_log(0, "client map file(map%d).CS3 is reloaded", i+1 );
}
}
void CXTrapManager::NotifyMapFileChanged( const std::string& fileName, eFileUpdatedOptions eUpdateOption )
{
MapReloadSignalHandler(1);
}
#endif
bool CXTrapManager::LoadXTrapModule()
{
#ifdef __FreeBSD__
//first load client mapfile
bool bClientMapFileLoaded = false;
for(int i=0; i<CSFILE_NUM; ++i )
{
if( LoadClientMapFile(i) )
{
bClientMapFileLoaded = true;
}
}
if( !bClientMapFileLoaded )
{
sys_err("XTrap-failed to load at least one client map file. map file name should be map1.CS3 or map2.CS3");
return false;
}
//load shared objects
char sDllBinFile[] ="./libXTrap4Server.so";
m_pImpl->hXTrap4Server = dlopen(sDllBinFile, RTLD_LAZY);
if (m_pImpl->hXTrap4Server == 0)
{
sys_err("XTrap-failed to load so reason:%s", dlerror()) ;
return false;
}
void* hXTrapHandle = m_pImpl->hXTrap4Server;
m_pImpl->XTrap_S_Start = (PFN_XTrap_S_Start) dlsym(hXTrapHandle, "XTrap_S_Start");
m_pImpl->XTrap_S_SessionInit = (PFN_XTrap_S_SessionInit) dlsym(hXTrapHandle, "XTrap_S_SessionInit");
m_pImpl->XTrap_CS_Step1 = (PFN_XTrap_CS_Step1) dlsym(hXTrapHandle, "XTrap_CS_Step1");
m_pImpl->XTrap_CS_Step3 = (PFN_XTrap_CS_Step3) dlsym(hXTrapHandle, "XTrap_CS_Step3");
m_pImpl->XTrap_S_SetActiveCode = (PFN_XTrap_S_SetActiveCode) dlsym(hXTrapHandle, "XTrap_S_SetActiveCode");
m_pImpl->XTrap_S_SetOption = (PFN_XTrap_S_SetOption) dlsym(hXTrapHandle, "XTrap_S_SetOption");
m_pImpl->XTrap_S_SetAllowDelay = (PFN_XTrap_S_SetAllowDelay) dlsym(hXTrapHandle, "XTrap_S_SetAllowDelay");
m_pImpl->XTrap_S_SendGamePacket = (PFN_XTrap_S_SendGamePacket) dlsym(hXTrapHandle, "XTrap_S_SendGamePacket");
m_pImpl->XTrap_S_RecvGamePacket = (PFN_XTrap_S_RecvGamePacket) dlsym(hXTrapHandle, "XTrap_S_RecvGamePacket");
if (m_pImpl->XTrap_S_Start == NULL ||
m_pImpl->XTrap_S_SessionInit == NULL ||
m_pImpl->XTrap_CS_Step1 == NULL ||
m_pImpl->XTrap_CS_Step3 == NULL ||
m_pImpl->XTrap_S_SetOption == NULL ||
m_pImpl->XTrap_S_SetAllowDelay == NULL ||
m_pImpl->XTrap_S_SendGamePacket == NULL ||
m_pImpl->XTrap_S_RecvGamePacket == NULL)
{
sys_err("XTrap-failed to load function ptrs");
return false;
}
//start server module
m_pImpl->XTrap_S_Start( 600, CSFILE_NUM, g_XTrap_ClientMap, NULL );
//NOTE : <20>ϴ<EFBFBD> XProtect<63><74><EFBFBD><20><><EFBFBD>װ<EFBFBD> <20>־ <20>ڵ念<DAB5><E5BFB5> üũ<C3BC><C5A9> <20><><EFBFBD><EFBFBD>.
m_pImpl->XTrap_S_SetActiveCode( XTRAP_ACTIVE_CODE_THEMIDA );
//setup signal
signal(SIGUSR2, CXTrapManager::MapReloadSignalHandler);
#endif
return true;
}
bool CXTrapManager::LoadClientMapFile( unsigned int iMapIndex )
{
#ifdef __FreeBSD__
//index check
if( iMapIndex >= CSFILE_NUM )
{
return false;
}
char szFileName[1024] = {0,};
snprintf(szFileName, sizeof(szFileName), "map%d.CS3", iMapIndex+1);
FILE* fi = 0;
fi = fopen(szFileName, "rb");
if (fi == NULL)
{
return false;
}
fread(g_XTrap_ClientMap[iMapIndex], XTRAP_CS4_BUFSIZE_MAP, 1, fi);
fclose(fi);
#endif
return true;
}
EVENTINFO(xtrap_cs1_check_info)
{
DynamicCharacterPtr ptrPC;
};
EVENTFUNC(xtrap_cs1_check_event)
{
xtrap_cs1_check_info* info = dynamic_cast<xtrap_cs1_check_info*>( event->info );
if ( info == NULL )
{
sys_err( "<xtrap_event> info null pointer" );
return 0;
}
TPacketXTrapCSVerify pack;
pack.bHeader = HEADER_GC_XTRAP_CS1_REQUEST;
bool bSuccess = CXTrapManager::instance().Verify_CSStep1( info->ptrPC, pack.bPacketData );
LPDESC lpClientDesc = info->ptrPC.Get()->GetDesc();
if( !lpClientDesc )
{
sys_err( "<xtrap_event> client session is invalid" );
return 0;
}
lpClientDesc->Packet( &pack, sizeof(pack) );
if( bSuccess )
{
return XTRAP_CS1_CHECK_CYCLE;
}
sys_err( "XTrap: hack is detected %s", lpClientDesc->GetHostName() );
info->ptrPC.Get()->Disconnect("XTrapCheckInvalid");
lpClientDesc->SetPhase(PHASE_CLOSE);
return 0;
}
bool CXTrapManager::CreateClientSession( LPCHARACTER lpCharSession )
{
if( !bXTrapEnabled )
return true;
if( !lpCharSession )
return false;
DWORD dwSessionID = lpCharSession->GetPlayerID();
ClientSessionMap::iterator it = m_mapClientSessions.find( dwSessionID );
if( it != m_mapClientSessions.end() )
{
sys_err("XTrap: client session is alreay registered");
return false;
}
//init session info
sSessionInfo infoData;
//xtrap session init
DWORD dwReturn = m_pImpl->XTrap_S_SessionInit( 600, CSFILE_NUM, g_XTrap_ClientMap, infoData.szSessionBuf );
if( dwReturn != 0 )
{
sys_err("XTrap: client session init failed");
}
xtrap_cs1_check_info* event_info = AllocEventInfo<xtrap_cs1_check_info>();
event_info->ptrPC = lpCharSession;
infoData.m_pCheckEvent = event_create(xtrap_cs1_check_event, event_info, XTRAP_CS1_CHECK_CYCLE);
m_mapClientSessions[dwSessionID] = infoData;
return true;
}
void CXTrapManager::DestroyClientSession( LPCHARACTER lpCharSession )
{
if( !bXTrapEnabled )
return;
if( !lpCharSession )
return;
DWORD dwSessionID = lpCharSession->GetPlayerID();
ClientSessionMap::iterator it = m_mapClientSessions.find( dwSessionID );
if( it == m_mapClientSessions.end() )
{
sys_err("XTrap: client session is already destroyed");
return;
}
event_cancel(&(it->second.m_pCheckEvent) );
m_mapClientSessions.erase(it);
}
bool CXTrapManager::Verify_CSStep1( LPCHARACTER lpCharSession, BYTE* pBufData )
{
if( !bXTrapEnabled )
return false;
if( !lpCharSession )
return false;
DWORD dwSessionID = lpCharSession->GetPlayerID();
ClientSessionMap::iterator it = m_mapClientSessions.find( dwSessionID );
if( it == m_mapClientSessions.end() )
{
sys_err("XTrap: client session is already destroyed");
return false;
}
int nReturn = m_pImpl->XTrap_CS_Step1( it->second.szSessionBuf, it->second.szPackBuf );
memcpy( pBufData, it->second.szPackBuf, VERIFY_PACK_LEN );
return (nReturn == 0) ? true : false;
}
void CXTrapManager::Verify_CSStep3( LPCHARACTER lpCharSession, BYTE* pBufData )
{
if( !bXTrapEnabled )
return;
if( !lpCharSession )
return;
DWORD dwSessionID = lpCharSession->GetPlayerID();
ClientSessionMap::iterator it = m_mapClientSessions.find( dwSessionID );
if( it == m_mapClientSessions.end() )
{
sys_log(0, "XTrap: client session is alreay destroyed");
return;
}
memcpy( it->second.szPackBuf, pBufData, VERIFY_PACK_LEN );
m_pImpl->XTrap_CS_Step3( it->second.szSessionBuf, it->second.szPackBuf );
//if( XTRAP_API_RETURN_DETECTHACK == m_pImpl->XTrap_CS_Step3( it->second.szSessionBuf, pBufData ) )
//{
// sys_error(0, "XTrap: client session is alreay destroyed");
//}
}