[iosocket.CGenericMessage::GetState][Data]
Packet Content: [Packet length] [Packet type] [Magic header] [Checksum] [Packet State][Data]
Length: [4 bytes] [4 bytes] [4 bytes] [4 bytes] [4 bytes][N bytes]
分析:
1.編寫初步payload
AA AA AA AA BB BB BB BB CC CC CC CC DD DD DD DD EE EE EE EE FF
AA=最後根據封包長度而填寫(注意16進制)
2.找Packet type(BB)
利用字串 找到Enter Channel字樣
Address: 484DB0
利用CE找 484DB0
找到其中一個結果是00700783 call 484DB0
向上找到700430
這個地址是UDP接收到封包後會根據你的Packet type而去跳到不同的function(做不同的工作)
我們可以發現700430 是其中一個function
0070046F會判斷目前GameState是否等於4(cmp dword ptr ds:[0x7E00D0],0x4)
不是的話就跳到00700507
我們可以發現00700507對接收回來的封包讀到第0x24的內容(4 bytes)
mov eax,dword ptr ds:[esi+0x24]
由於我們不是GameState=4 因此我們可以知道由0x16~0x24內容是對我們沒有用,利用0x00進行填充
目前的Payload:
AA AA AA AA BB BB BB BB CC CC CC CC DD DD DD DD EE EE EE EE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
而0070050A進行了比較 先將0x24的內容進行讀取,再加上-0x64,最後結果比較是不是0x8
我們向下可以看到位於00700510 (ja 007007F8)比較eax是不是大於8 大於8就跳
007007F8 不是我們想跳的地方 我們要跳回00700783附近地址 讓封包接收後 我們就能call 484DB0(讓遊戲進入選頻)
經過強制修改eax後 我們最後發現eax=0x7 先會跳到007006AB
所以我們只要把0x64+0x7=0x6B
只要我們的封包內容是6B 00 00 00,系統就會判斷跳到007006AB
目前的Payload:
AA AA AA AA BB BB BB BB CC CC CC CC DD DD DD DD EE EE EE EE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6B 00 00 00
位於007006C9 (repe cmps byte ptr es:[edi],byte ptr ds:[esi])
先把edi寫入"SPEEDHACK"字串
跟esi判斷到底是否跟相同
不相同就跳到00700706
位於00700714 (repe cmps byte ptr es:[edi],byte ptr ds:[esi])
先把edi寫入"prev ping"字串
跟esi判斷到底是否跟相同
相同就不用跳
最後會運行到我們想要到的地址00700783(call 00484DB0)
最後的封包構成:
32 00 00 00 21 11 00 00 1C 2B 00 00 A4 C7 C0 71 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6B 00 00 00 70 72 65 76 20 70 69 6E 67 00加密後:
32 00 00 00 F6 77 FF FF 1F A6 FF FF DA C1 F9 74 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF A4 FF FF FF 7C 6C D4 4C FE 7C B4 8C C4 FF