l2-unlegits/l2detect/GameClient_sniff_PP_client.cpp
2012-02-01 05:25:08 +00:00

333 lines
10 KiB
C++

#include "stdafx.h"
#include "ConfigIni.h"
#include "Logger.h"
#include "GameClient.h"
#include "GameListener.h"
#include "L2PacketTypes.h"
extern class CConfig g_cfg;
void GameClient::PP_sniff_fromClient( unsigned char *bytes, unsigned int len )
{
//int i = 0;
if( !bytes || len<1 ) return;
if( len<3 )
{
log_error( LOG_WARNING, "PP_sniff_fromClient(): packet len < 3!\n" );
log_error( LOG_WARNING, "PP_sniff_fromClient(): bytes=0x%p, len=%d\n", bytes, len );
return;
}
// should we decrypt it?
if( this->xor_enabled ) // yeah :)
{
if( !L2GamePacket::decodeXOR_buffer( bytes, len, this->key_client_cs ) )
log_error( LOG_ERROR, "PP_sniff_fromClient(): decodeXOR_buffer() failed!\n" );
}
// some vars
unsigned char ptype = bytes[2];
unsigned short int ptype2 = 0x0000;
unsigned short int ptype3 = 0x0000;
if( len >= 5 )
{
ptype2 |= (unsigned short int)(bytes[3] & 0xFFFF);
ptype2 |= (unsigned short int)(bytes[4] << 8 & 0xFFFF);
}
if( len >= 7 )
{
ptype3 |= (unsigned short int)(bytes[5] & 0xFFFF);
ptype3 |= (unsigned short int)(bytes[6] << 8 & 0xFFFF);
}
// obfuscator
class L2PCodeObfuscator *lpco;
lpco = (class L2PCodeObfuscator *)this->clsObfuscator;
if( lpco )
{
if( lpco->isEnabled() )
{
unsigned char pcode_prev = ptype;
unsigned short pcode2_prev = ptype2;
bool decode_res = lpco->decodeOpcode( ptype, ptype2, ptype3 );
if( decode_res )
{
if( pcode2_prev == ptype2 )
log_error( LOG_PACKETNAME, " **** de-obfuscated %02X -> %02X\n", pcode_prev, ptype );
else
log_error( LOG_PACKETNAME, " **** de-obfuscated %02X:%02X -> %02X:%02X\n",
pcode_prev, pcode2_prev, ptype, ptype2 );
}
else
log_error( LOG_ERROR, "PP_sniff_fromClient(): ERROR de-obfuscating %02X\n", pcode_prev );
}
}
L2PacketTypes_LogClient( (L2_VERSION)g_cfg.L2_client_version, this->state, ptype, ptype2, ptype3 );
// from client
switch( this->state )
{
case GCST_CONNECTED:
{
switch( ptype )
{
//case 0x00: // ProtocolVersion // Interlude
case 0x0e: // ProtocolVersion // Hellbound
{
L2Game_ProtocolVersion *p = new L2Game_ProtocolVersion( bytes, len );
p->read_protoVer( &(this->gameProtoVer) );
delete p;
log_error( LOG_PACKETNAME, "Client: 0e ProtocolVersion %u\n", this->gameProtoVer );
// client sends protocolVersion = 0xFFFFFFFF when it pings server (not tries to connect really)
if( this->gameProtoVer >= 0xFFFFFFF0 )
{
log_error( LOG_PACKETNAME, "Received client ping server... no process\n" );
this->thisWasJustServerPing = true; // received client ping (sniff)
}
} break; // ProtocolVersion
// case 0x08: // AuthLogin // Interlude
case 0x2b: // AuthLogin // Hellbound
{
L2Game_AuthLogin *p = new L2Game_AuthLogin( bytes, len );
char login[32] = {0};
p->read_login( login );
delete p;
log_error( LOG_PACKETNAME, "Client: 2b AuthLogin: Login: \"%s\"\n", login );
} break; // AuthLogin
default:
{
log_error( LOG_DEBUGDUMP, "Client: Unknown packet %02X in state: CONNECTED\n",
(unsigned int)ptype );
if( g_cfg.DumpUnknownToStdout )
{
printf( "============================================\n" );
L2GamePacket *p = new L2GamePacket( bytes, len );
p->dumpToFile( stdout );
delete p;
printf( "============================================\n" );
}
} break;
} // switch( ptype )
} break; // CONNECTED
case GCST_AUTHED:
{
switch( ptype )
{
//case 0x00: // LogoutRequest
// {
// log_error( LOG_PACKETNAME, "Client: 00 LogoutRequest\n" );
// } break;
case 0x12: // CharacterSelect // Hellbound
{
int charSlot = bytes[3];
//L2Game_CharacterSelect *p = new L2Game_CharacterSelect( bytes, len );
log_error( LOG_PACKETNAME, "Client: 12 CharacterSelect: #%d\n", charSlot );
//this->state = GCST_IN_GAME;
//log_error( LOG_DEBUG, "Client: 12 CharacterSelect: switch state to IN_GAME\n" );
} break; // CharacterSelect
//case 0x13: // NewCharacter
// {
// log_error( LOG_PACKETNAME, "Client: 13 NewCharacter\n" );
// } break; // NewCharacter
//case 0x0c: // CharacterCreate
// {
// wchar_t charNameU[64] = {0};
// char charName[64] = {0};
// wcscpy( charNameU, (const wchar_t *)(bytes+3) );
// sprintf( charName, "%S", charNameU );
// log_error( LOG_PACKETNAME, "Client: 0c CharacterCreate [%s]\n", charName );
// } break; // CharacterCreate
case 0xd0:
{
ptype2 = 0x0000;
if( len >= 5 )
{
ptype2 |= (unsigned short int)(bytes[3] & 0xFFFF);
ptype2 |= (unsigned short int)(bytes[4] << 8 & 0xFFFF);
if( ptype2 == 0x0039 )
{
log_error( LOG_PACKETNAME, "Client: d0:0039 RequestGotoLobby\n" );
}
else
{
log_error( LOG_WARNING, "Client: Unknown opcode2 %04X for state AUTHED packet 0xD0\n",
(unsigned int)ptype2 );
}
}
else
log_error( LOG_WARNING, "Client: (AUTHED) sent 0xd0 without second opcode!\n" );
} break; // double opcode packet
default:
{
log_error( LOG_PACKETNAME, "Client: Unknown packet %02X in state: AUTHED\n",
(unsigned int)ptype );
if( g_cfg.DumpUnknownToStdout )
{
printf( "============================================\n" );
L2GamePacket *p = new L2GamePacket( bytes, len );
p->dumpToFile( stdout );
delete p;
printf( "============================================\n" );
}
} break;
} // switch( ptype )
} break; // AUTHED
case GCST_IN_GAME:
{
switch( ptype )
{
//case 0x00: // LogoutRequest
// {
// log_error( LOG_PACKETNAME, "Client: 00 LogoutRequest\n" );
// } break;
//case 0x0f: // MoveBackwardToLocation
// {
// log_error( LOG_PACKETNAME, "Client: 0f MoveBackwardToLocation\n" );
// } break;
//case 0x11: // EnterWorld
// {
// log_error( LOG_PACKETNAME, "Client: 11 EnterWorld\n" );
// } break;
//case 0x14: // RequestItemList
// {
// log_error( LOG_PACKETNAME, "Client: 14 RequestItemList\n" );
// } break;
//case 0x19: // UseItem
// {
// log_error( LOG_PACKETNAME, "Client: 19 UseItem\n" );
// } break;
case 0x1F: // Action
{
//log_error( LOG_PACKETNAME, "Client: 1F Action\n" );
L2Game_Action *p = new L2Game_Action( bytes, len );
unsigned int oid = p->read_objectID();
p->read_originX();
p->read_originY();
p->read_originZ();
char useShift = p->read_useShift();
delete p;
if( useShift /* && g_cfg.altGameViewNpc */ )
{
L2OBJECT_TYPE objType = L2OT_NONE;
int index = -1;
if( WorldObjectTree_GetInfoByObjectID( oid, &objType, &index ) )
{
if( objType == L2OT_NPC )
{
L2Npc *npc = npc_array[index];
char filename[256];
sprintf( filename, "npc_%d_stats.txt", npc->templateID );
FILE *f = fopen( filename, "wt" );
fprintf( f, "x,y,z,heading: (%d,%d,%d) %u\n", npc->x, npc->y, npc->z, npc->heading );
fprintf( f, "mAtkSpd, pAtkSpd: %d, %d\n", npc->mAtkSpd, npc->pAtkSpd );
fprintf( f, "runSpeed, walkSpeed: %d, %d\n", npc->runSpeed, npc->walkSpeed );
fprintf( f, "colR, colH: %0.2f, %0.2f\n", npc->collisionRadius, npc->collisionHeight );
fprintf( f, "rhand, chest, lhand: %u, %u, %u\n", npc->iid_right_hand, npc->iid_chest, npc->iid_left_hand );
fclose( f );
}
}
}
} break;
//case 0x23: // RequestBypassToServer
// {
// log_error( LOG_PACKETNAME, "Client: 23 RequestBypassToServer\n" );
// } break;
//case 0x39: // RequestMagicSkillUse
// {
// log_error( LOG_PACKETNAME, "Client: 39 RequestMagicSkillUse\n" );
// } break;
//case 0x3d: // RequestMagicSkillUse
// {
// log_error( LOG_PACKETNAME, "Client: 3D RequestShortCutReg\n" );
// } break;
//case 0x48: // RequestTargetCanceld
// {
// log_error( LOG_PACKETNAME, "Client: 48 RequestTargetCanceld\n" );
// } break;
//case 0x57: // RequestRestart
// {
// log_error( LOG_PACKETNAME, "Client: 57 RequestRestart\n" );
// //this->state = GCST_AUTHED;
// } break;
//case 0x59: // ValidatePosition
// {
// log_error( LOG_PACKETNAME, "Client: 59 ValidatePosition\n" );
// } break;
//case 0x65: // RequestPledgeInfo
// {
// // TODO: parse RequestPledgeInfo?
// log_error( LOG_PACKETNAME, "Client: 65 RequestPledgeInfo\n" );
// } break;
//case 0x8B: // RequestGmList
// {
// log_error( LOG_PACKETNAME, "Client: 8B RequestGmList\n" );
// } break;
//case 0xA6: // RequestSkillCoolTime
// {
// log_error( LOG_PACKETNAME, "Client: A6 RequestSkillCoolTime\n" );
// } break;
//case 0xCB: // GameGuardReply
// {
// log_error( LOG_PACKETNAME, "Client: CB GameGuardReply\n" );
// } break;
//case 0xd0:
// {
// ptype2 = 0x00;
// if( len >= 5 )
// {
// ptype2 |= (unsigned short int)(bytes[3] & 0xFFFF);
// ptype2 |= (unsigned short int)(bytes[4] << 8 & 0xFFFF);
// if( ptype2 == 0x01 )
// {
// log_error( LOG_PACKETNAME, "Client: D0:01 RequestManorList\n" );
// }
// else if( ptype2 == 0x0d )
// {
// log_error( LOG_PACKETNAME, "Client: D0:0D RequestAutoSoulShot\n" );
// }
// else if( ptype2 == 0x17 )
// {
// // TODO: RequestPledgeWarList
// log_error( LOG_PACKETNAME, "Client: D0:17 RequestPledgeWarList\n" );
// }
// else if( ptype2 == 0x21 )
// {
// log_error( LOG_PACKETNAME, "Client: D0:21 RequestKeyMapping\n" );
// }
// else if( ptype2 == 0x24 )
// {
// log_error( LOG_PACKETNAME, "Client: D0:24 RequestSaveInventoryOrder\n" );
// }
// else
// {
// log_error( LOG_WARNING, "Client: Unknown opcode2 %04X for IN_GAME packet 0xD0\n",
// (unsigned int)ptype2 );
// }
// }
// else
// log_error( LOG_WARNING, "Client: (IN_GAME) sent 0xD0 without second opcode!\n" );
// } break; // double opcode packet
default:
{
log_error( LOG_PACKETNAME, "Client: Unknown packet %02X in state: IN_GAME\n",
(unsigned int)ptype );
if( g_cfg.DumpUnknownToStdout )
{
printf( "============================================\n" );
L2GamePacket *p = new L2GamePacket( bytes, len );
p->dumpToFile( stdout );
delete p;
printf( "============================================\n" );
}
} break;
} // switch( ptype )
} break; // IN_GAME
} // switch( state )
}