什么是线程循环发包 ?
介紹
有線程循環發包,就有非線循環程發包(也叫主線程發包)。在游戲中線程循環發包會導致調試器斷下后查看調用棧拿不到有用數據(不同的操作觸發的發包斷點,調用棧都一樣),而主線程發包則可以在調用棧中查看是誰調用了發包功能。相比線程發包,逆向主線程發包會更加容易。
如何分辨是不是主線程發包
首先肯定是跳轉到3大發包函數,send , sendto ,WSASend 分別下段。 如果還沒等你操作斷點就馬上就斷下而且斷的非常的頻繁,那么基本就是線程發包了。除此之外,是主線程發包的可能性比較大了。
主線程發包邏輯:
1.玩家操作
2.調用功能call
3.整合明文數據包
4.數據包加密
5.系統調用發包函數
這種情況,只需要在發包函數下斷點然后一直讓調試器執行到返回(也可以直接看棧回溯),最后就能回溯到功能call
線程循環發包邏輯:
**1.玩家操作
2.調用功能call
3.整合明文數據包
4.數據包加密
5.封包入隊列
6.發包線程從隊列中取出封包并發送
**
這種線程循環發包與真正的功能CALL是獨立的,所以如果要分析這種方式發包的游戲就得從發包的數據跟隨找數據來源。
因為我們要從數據的來源分析,所以就需要跟著 send 函數的buf 參數開始著手分析:
int send (SOCKET s, const char *buf, int len, int flags);給 buf 下內存寫入斷點,這個時候會基本都會斷在一個 mov xxx,yyy 的指令上,觀察 [yyy] 是否為你找找的包頭特征,如果是,就多次執行到返回,最后就可以到達程序領空。
為什么給buf設內存斷點就能跳出死循環?
因為給buf設內存斷點的時候,你斷到了組建buf的過程(也就是步驟 3/4),當你跳出這個過程的時候,那你就找到了組建的開始,也就是功能call執行完后,開始組包 。
為什么bp send會一直都是一樣的結果 ?
bp send的時候,斷到的是組好包后的結果,發包線程和功能call線程不在同線程,調試的時候只有一個線程是激活狀態,其他線程都出去掛起狀態,單步跟蹤無法跨越線程。
但是這種方法有一個前提,就是 buf 的地址必須是固定的,如果游戲的代碼寫成這樣:
// 如果是在循環外面,就可以使用上面內存寫入斷點的方法 // char buf[256] = {0}; while(1){char buf[256] = {0};// 調用 send 發包函數 }那么每次調用 send 的時候,buf 都是新申請的內存導致地址變更。但好在在這個大循環里創建變量本身就是很消耗性能的,大部分的游戲不會這么寫,但如果真碰到了只能找其他的思路了,比如從封包隊列入手。
總結
以上是生活随笔為你收集整理的什么是线程循环发包 ?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java毕业设计我爱短视频管理系统myb
- 下一篇: 关于海思HI3518+OV9712 IS