たいていのオンラインゲームではサーバーと通信する上で暗号化されたパケットをやりとりしています。
暗号化されたパケットを解読することは難しいので暗号化される前のパケットを取得する必要があります。
送信するパケットについては暗号化を、受信するパケットについては復号化を行うルーチンがクライアント内に存在しているはずです。
これは、順序的には平文パケットに対して暗号化ルーチンを介した後で"Send"APIを呼び出し、"Recv"APIを呼び出した後で取得したパケットを復号化のルーチンを介して平文パケットにするような処理が存在するということです。
これらの処理を介してパケットを取得します。
Sendパケットを引数に取るルーチンを見つける
ws2_32.dllの"send"APIのアドレスを調べます。
imageプラグインエラー : ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (packet_1.PNG)
"send"APIをコールしているアドレスを探します。
"send"APIをコールしているルーチンをコールしているルーチンを探します。
暗号化される前の平文パケットを引数に取るルーチンが見つかりました。
Recvパケットを引数に取るルーチンを見つける
ws2_32.dllの"recv"APIのアドレスを調べます。
2箇所での呼び出しが見つかりますが、後者を調べます。
imageプラグインエラー : ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (packet_8.PNG)
後者のルーチンにおいて一番最後に呼び出されているサブルーチンコールを調べます。
imageプラグインエラー : ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (packet_9.PNG)
下から2番めにコールされているルーチンが平文パケットを引数にとるルーチンです。
imageプラグインエラー : ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (packet_10.PNG)
CEでパケットを送信するスクリプトの例
[ENABLE]
ALLOC(SendPacket,128)
ALLOC(pstructure,16) // パケット構造体のサイズ
DEFINE(size,#11) // パケットのサイズ定義 (CEAでは手前に#を付けると10進数として認識)
ALLOC(packet,size) // パケット割り当て
CREATETHREAD(SendPacket) // スレッド生成
SendPacket:
mov ecx,[00******] // ソケット(?)のポインタ
mov eax,pstructure
mov [eax+4],packet
mov [eax+8],size
push eax
call 00****** // ゲーム内のパケット送信用関数を利用
ret
packet:
db ** ** ** ** ** ** ** ** ** ** ** // 任意のパケット (この場合サイズは11バイト)
[DISABLE]
DEALLOC(SendPacket)
DEALLOC(pstructure)
DEALLOC(packet)
最終更新:2014年07月13日 15:57