forked from metin2/server
330 lines
7.9 KiB
C++
330 lines
7.9 KiB
C++
|
#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");
|
|||
|
//}
|
|||
|
}
|