1. 程式人生 > >網路遊戲協議封包需注意點

網路遊戲協議封包需注意點

對於強客戶端的遊戲,就有很大可能出現離線掛,因為一切客戶端的計算、處理邏輯都不需要進行,只需要將最理想的作弊資料包直接發給伺服器,就能達到遊戲收益最大化。

下面這幾點是需要多加註意的點。

1.send函式

根據send呼叫的buffer,進行回溯,找到加密函式。對於send呼叫的buffer,最好是保持隨機呼叫,如果固定的話會非常容易分析。

2.耦合、離散

軟體工程中提倡低耦合,高內聚。但是就耦合這點在封包傳送階段,應該做到高耦合,這樣可以讓逆向分析陷入迷茫,找不到關鍵點。對於包結構或者組包過程要做到高離散,這樣會讓逆向分析無法理解其確實的意義。

3.加密函式

加密函式主要完成資料加密,變換。使用的指令也會跟正常函式有所不同,比如位操作,byte操作。對於加密函式,最好不要一步完成,不然很容易分析出加密引數,每次將構造的協議交由加密函式處理,做出封包外掛。

下面用三個遊戲來說明

一、B遊戲

1.首先對send函式下斷點


2.可以看到傳送的加密資料(必然加密)


3.向上回溯,尋找加密函式


4.逆向解密函式,或者黑盒呼叫

sub     esp, 8
mov     eax, dword ptr [esp+C]
push    ebx
push    ebp
mov     edx, ecx
mov     ecx, dword ptr [eax]
push    esi
mov     esi, dword ptr [edx+18]
mov     edx, dword ptr [edx+C]
add     eax, 4
mov     ebx, dword ptr [eax+4]
push    edi
mov     edi, dword ptr [esi]
mov     ebp, eax
add     edi, dword ptr [ebp]
mov     ebp, dword ptr [eax+8]
add     ebp, dword ptr [esi+4]
add     eax, 4
add     esi, 8
test    edx, edx
mov     dword ptr [esp+1C], ebx
jbe     short 06FE50A7
mov     dword ptr [esp+10], edx
lea     ebx, dword ptr [ebx]
lea     edx, dword ptr [edi+edi+1]      
imul    edx, edi
lea     eax, dword ptr [ebp+ebp+1]
imul    eax, ebp
rol     edx, 5
rol     eax, 5
mov     ebx, edx
xor     ebx, ecx
mov     cl, al
xor     eax, dword ptr [esp+1C]
rol     ebx, cl
mov     cl, dl
rol     eax, cl
mov     dword ptr [esp+1C], ebp
mov     ebp, dword ptr [esi]
mov     dword ptr [esp+14], edi
add     eax, dword ptr [esi+4]
mov     ecx, dword ptr [esp+14]
add     ebp, ebx
add     esi, 8
sub     dword ptr [esp+10], 1
mov     edi, eax
jnz     short 06FE5060
mov     ebx, dword ptr [esp+1C]
add     ebx, dword ptr [esi+4]
mov     esi, dword ptr [esi]
mov     eax, dword ptr [esp+20]
add     esi, ecx
test    eax, eax
je      short 06FE50BA
mov     ecx, dword ptr [eax]
jmp     short 06FE50BC
xor     ecx, ecx
mov     edx, dword ptr [esp+24]
xor     ecx, esi
test    eax, eax
mov     dword ptr [edx], ecx
lea     ecx, dword ptr [edx+4]
je      short 06FE50D4
add     eax, 4
je      short 06FE50D4
mov     edx, dword ptr [eax]
jmp     short 06FE50D6
xor     edx, edx
xor     edx, edi
mov     dword ptr [ecx], edx
add     ecx, 4
test    eax, eax
je      short 06FE50EA
add     eax, 4
je      short 06FE50EA
mov     edx, dword ptr [eax]
jmp     short 06FE50EC
xor     edx, edx
xor     edx, ebx
mov     dword ptr [ecx], edx
add     ecx, 4
test    eax, eax
je      short 06FE510C
add     eax, 4
je      short 06FE510C
mov     eax, dword ptr [eax]
pop     edi
pop     esi
xor     eax, ebp
pop     ebp
mov     dword ptr [ecx], eax
pop     ebx
add     esp, 8
retn    0C

F5之後,還是直接黑盒呼叫比較方便。

B遊戲的加密比較簡單,可以直接構造資料包,然後基於加密演算法自己加密後傳送至伺服器。

二、W遊戲

分析W遊戲的TCP部分,可以發現相較B遊戲的資料包,資料包結構要嚴格並且複雜一些。


但是還是存在一個固定的點可以進行HOOK,存在風險。


三、N遊戲例項

#ifndef     __COMMON_H_
#define     __COMMON_H_

#include    <windows.h>


BOOL _HookApi( unsigned long _My_Addr, unsigned long _Hook_Addr);


/*command 資料*/
/*向右走*/
#define RUN_RIGHT_LEN   0x0e
#define RUN_RIGHT   0x0e,0x00,0xe0,0x55,0x8d,0xe2,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00

/*喊話*/
//喊話封包的長度不固定-首部為封包長度-然後8個位元組的命令,接著4個位元組的字元長度,跟到字串
#define SPECK_ONE   0x00,0x00,0xe0,0x55,0xb9,0x6f,0x00,0x00


#endif

#include    "InjectDll.h"

//BYTE  nCmd[0x0e]={0x0E,0x00,0xe0,0x55,0x91,0x10,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned long   MyApi = 0;
unsigned long   hookApi = 0;
DWORD     dwWrite = 0;
BYTE      lpResetSend[0x05]={0x8B,0XFF,0X55,0X8B,0XEC};//用於恢復HookSend的5個位元組
HINSTANCE hws2_32 = NULL;//ws2_32控制代碼
HANDLE    my_sendhandle;//儲存用於傳送send的控制代碼


int WINAPI DllMain(HANDLE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
   // MessageBox( NULL, "yes", "yes", MB_OK);
    hModule = hinstDll;
    DWORD   dwThread;
   // UiThread( NULL);
   // 

   
    switch(fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        MessageBox( NULL, "Debug", "Debug", MB_OK);
        CreateThread( NULL, 0,(unsigned long (__stdcall *)(void *))UiThread,NULL,0,&dwThread);
       
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
   
    return TRUE;
}

DWORD    WINAPI   UiThread(LPARAM lParam)
{
    MSG msg;
    HWND hWnd;
    hWnd = CreateDialog( (HINSTANCE)hModule, MAKEINTRESOURCE(IDD_MAIN_PAGE), NULL, MainProc);
    ShowWindow( hWnd, SW_SHOW);
    UpdateWindow( hWnd);
    while(GetMessage(&msg,NULL,0,0))
    {
     TranslateMessage(&msg);
     DispatchMessage(&msg);
    }
    return 0;
}

int CALLBACK MainProc( HWND hWnd, UINT uMsg, WPARAM  wParam, LPARAM lParam)
{
    
    BYTE  nCmd[RUN_RIGHT_LEN]={RUN_RIGHT};
    HINSTANCE hws2_32;
    static  DWORD dwCount[2] = {0x58548565,0x00c45878};
    static  HANDLE hFile;
    BYTE    lpBuffer[0x2];
    char    szFormat[7];
    static  DWORD dwWrite = 7;
    RtlZeroMemory( lpBuffer,0x2 );
    DWORD dwRead;
    DWORD lpRead=0;
    int     nindex=0;
    switch( uMsg)
    {
    case WM_COMMAND:
        switch(wParam)
        {
        case IDC_BTN_TEST:
           
          //  MessageBox( NULL,"debug","debug",MB_OK);
           GoRight();
      //Speck_Something( "yangzhihao");
        
        
        /*
                 封包加密call
                 重組後send
           */
            
             
         //   MessageBox( NULL, "call","call", MB_OK);
            
            /*__asm{
                    pushad
                    push 0x0e
                    lea  eax, nCmd
                    push eax
                    mov  eax,0x23ba078
                    mov  ecx,eax
                    mov  ebx,0x729a00
                    mov  eax,0x0e
                    call ebx
                    popad
                }
         
            hws2_32 = LoadLibrary( "ws2_32.dll");
            (unsigned long)::GetProcAddress( hws2_32, "send");
            __asm
            {
                
                push 0x00
                push 0x0e
                lea  ebx, nCmd
                push ebx
                mov  ebx,my_sendhandle
                push ebx
                call eax
            }
            */
            
            break;
             case    IDC_READ_TABLE:
             MessageBox( NULL, "write", "write", MB_OK);
             for( nindex;nindex<0xa7a9;nindex++)
              {
                
                    lpRead = 0x00c45878+nindex;
                    ReadProcessMemory( GetCurrentProcess(), (LPVOID)lpRead,lpBuffer, 0x01, &dwRead);
                    sprintf( szFormat,"0x%2x",lpBuffer[0]);
                    WriteFile( hFile, szFormat, dwWrite, &dwRead, 0);

              }
                
            break;
             case IDC_BTN_HOOK:
                  hws2_32 = LoadLibrary( "ws2_32.dll");
                  hookApi = (unsigned long)::GetProcAddress( hws2_32, "send");
                  MyApi = (unsigned long )GetSendPara;
                  _HOOK_APIN( MyApi, hookApi);

                 break;
        default:
            break;
        }
        break;
    
    case WM_INITDIALOG:
        hFile = CreateFile( "c:\\MYDebugLog.txt",GENERIC_READ | GENERIC_WRITE ,FILE_SHARE_READ|FILE_SHARE_WRITE,
            NULL,OPEN_ALWAYS ,FILE_ATTRIBUTE_NORMAL,0);
        break;
    case WM_CLOSE:
        EndDialog( hWnd, 0);
        break;
    default:
        DefWindowProc( hWnd, uMsg, wParam, lParam);
    }
    return 0;
}





/*取send控制代碼*/
void    GetSendPara(void)
{

     __asm
     {
        /*首先對堆疊進行平衡*/
        pop eax
        pop eax
        pop eax
        pop eax
       
        /*執行判斷操作,取send控制代碼 */
        mov eax, dword ptr [esp + 0x0c]
        cmp eax,0x0e
        jnz JMP_HOOM
        mov eax,dword ptr[esp+0x04]
        mov my_sendhandle,eax
     }
     WriteProcessMemory( GetCurrentProcess(), (void*)hookApi, lpResetSend, 0x05, &dwWrite);
     dwWrite = 0;
     __asm
     {
        
JMP_HOOM:
        /*跳回原來的地方*/
        sub ebp,0x04
        mov eax,hookApi
        mov edi,edi
        push ebp
        mov  ebp,esp
        add eax,5
        jmp eax
 
     }
     return;
}



void    Encode( BYTE* pCmd, int nLen)
{
       __asm{
               pushad
               mov  eax,dword ptr[esp+0x34]//長度
               push eax
               mov  eax, dword ptr[esp+0x34]//明文字元序列
               push eax
               mov  eax,0x2fd078 //硬編碼
               mov  ecx,eax
               mov  ebx,0x729a00//加密call
               mov  eax,dword ptr[esp+0x08]//長度
               call ebx
               popad
             }
       return;
}


void    GoRight()
{
    BYTE lpCmd[RUN_RIGHT_LEN] = {RUN_RIGHT};
    Encode( lpCmd,RUN_RIGHT_LEN);
    
    /*傳送封包*/
    hws2_32 = LoadLibrary( "ws2_32.dll");
    (unsigned long)::GetProcAddress( hws2_32, "send");
    __asm
     {
                
           push 0x00
           push RUN_RIGHT_LEN
           lea  ebx, lpCmd
           push ebx
           mov  ebx,my_sendhandle
           push ebx
           call eax
       }
}

void    Speck_Something(char* pSpeckBuffer)
{
    //MessageBox( NULL, "speck","speck",MB_OK);
    BYTE  packLen;
  int count = 0;
  WCHAR  wszSpec[MAX_PATH];
  RtlZeroMemory( wszSpec,MAX_PATH*2);

    count = strlen( pSpeckBuffer);

  long nwLong = MultiByteToWideChar( CP_ACP, 0, pSpeckBuffer, strlen(pSpeckBuffer),
                      wszSpec,sizeof(wszSpec));

    BYTE    temp[0x08]={SPECK_ONE};
    BYTE    *lpCmd;
    lpCmd = new BYTE [200] ; //申請一塊封包的記憶體

  RtlZeroMemory( lpCmd, 200);
    
    memcpy( lpCmd,temp,0x08);    //com封包命令
    memcpy( lpCmd,(void*)&count,0x01);
  
  packLen = (BYTE)0x0c+nwLong*2+2;  //包頭 封包整個長度
  lpCmd[0] = packLen;
  lpCmd [0x0A] = (BYTE)nwLong+1;//包的11個位元組,字串長度 
  memcpy( (lpCmd+12), wszSpec, nwLong*2+1);//把字元放入訊息

  Encode( lpCmd, (int)lpCmd[0]);


  hws2_32 = LoadLibrary( "ws2_32.dll");
    (unsigned long)::GetProcAddress( hws2_32, "send");
    __asm
     {
                
        push 0x00
        push packLen
        lea  ebx, lpCmd
        push ebx
        mov  ebx,my_sendhandle
        push ebx
        call eax
     }

   // delete [] lpCmd;
    
}


相關推薦

網路遊戲協議注意

對於強客戶端的遊戲,就有很大可能出現離線掛,因為一切客戶端的計算、處理邏輯都不需要進行,只需要將最理想的作弊資料包直接發給伺服器,就能達到遊戲收益最大化。 下面這幾點是需要多加註意的點。 1.send函式 根據send呼叫的buffer,進行回溯,找到加密函式。對於send

SpannableStringBuilder的setSpan方法使用注意

以前偶然遇見一個問題,今天突然想起來了,機智的我趕緊貼過來以幫助遇見此問題尚未解決的小夥伴們 這個問題是關於SpannableStringBuilder類的setSpan方法的。 大家都知道setS

迴圈神經網路訓練時幾個引數注意的筆記

1、詞嵌入維度引數(embedding_size)     詞嵌入維度刻畫了模型表達詞彙的能力,對於翻譯任務,一般需與資料集的詞彙量大小保持一致。在詞嵌入維度較小的時候,詞彙容易被對映到相近的區域,互

網路遊戲中訊息結構

一  NetPacket: NetPacket(int buffersize,NetPacketPool* pool,bool scal=true,bool policy=false) {//建構函式,if(buffersize<7)buffersize = 7;/

計算機網路-DHCP協議分析筆記

前置問題:什麼是(網路)協議? 網路協議為計算機網路中進行資料交換而建立的規則、標準或約定的集合。 而且: 一個網路協議至少包括三要素:   語法:用來規定資訊格式;資料及控制資訊的格式、編碼及訊號電平等。   語義:用來說明通訊雙方應當怎麼做;用於協調與差錯處理的控制資訊。   時序:定義了何時進行通訊,

嵌入式Linux網路程式設計,網路基礎,OSI七層模型,TCP/IP四層模型,TCP/IP通訊模型、協議結構、與拆,TCP/UDP協議特點及適用情況

文章目錄 1,TCP協議分成了兩個不同的協議----->TCP/IP協議誕生 2,網路的體系結構 2.1,OSI開放系統互聯模型 2.2,TCP/IP協議族的體系結構 3,TCP/IP協議通訊模型 3.1

Unity C# 自定義TCP傳輸協議以及、解決粘問題(網路應用層協議

本文只是初步實現了一個簡單的基於TCP的自定協議,更為複雜的協議可以根據這種方式去擴充套件。 網路應用層協議,通俗一點的講,它是一種基於socket傳輸的由傳送方和接收方事先協商好的一種訊息包組成結構,主要由訊息頭和訊息體組成。  眾所周知,基於socket的資訊互動有兩

1 使用WPE工具分析遊戲網路

   WPE工具說明 在大多數的程式設計工具中winsock已經封裝成一個控制元件,成為網路程式設計的控制元件,是非常方便的,利用這個控制元件,程式設計工具就可以編寫外掛工具。 Client/server模式網路遊戲,我們的資訊全在伺服器上面,想從伺服器上修改我們的個人使

網路基礎,執著遊戲外掛教程

要想在修改遊戲中做到百戰百勝,是需要相當豐富的計算機知識的。有很多計算機高手就是從玩遊戲,修改遊戲中,逐步 對計算機產生濃厚的興趣,逐步成長起來的。不要在羨慕別人能夠做到的,因為別人能夠做的你也能夠!我相信你們看了 本教程後,會對遊戲有一個全新的認識,呵呵,因為我是個好老師!

1.使用WPE工具分析遊戲網路

 WPE工具說明 在大多數的程式設計工具中winsock已經封裝成一個控制元件,成為網路程式設計的控制元件,是非常方便的,利用這個控制元件,程式設計工具就可以編寫外掛工具。 Client/server模式網路遊戲,我們的資訊全在伺服器上面,想從伺服器上修改我們的個人使用者

網路遊戲基礎 作者不明

截包工具: http://free.ys168.com/?shoooo    WPRO.rar      MD5: 2E1E8E48FCC78972905E4F40081B608C    IRIS.rar         MD5: 6B919165C60D83

網路協議與拆方法

      最近在處理rtsp拆包的時候,發現自己在網路協議方面存在著很大的問題,其中最大的問題就是不清楚如何根據協議進行解析?因此,在做網路協議的拆包的時候如果這些知識沒有想清楚,理解透徹,那麼在做起來的時候你會發現各種各樣的錯誤讓除錯起來總是困難重重!因此,我們在解網路

將專案打成war並用tomcat部署的方法,步驟及注意

部署的遇到第一個問題,就是tomcat和jdk的環境問題: 首先 理解為啥要關注這二者的環境呢?他們還是有關係的–tomcat 作為比較流行的java Web伺服器也是用java來實現的一個比較大的軟體 它也必須在虛擬機器JVM上執行 。 而java很多運用都是用在web開發上 所以他們就聯絡在一起

資料協議之TCP

資料封包協議規定:整個資料包包含2位元組長度資訊+資料包體。2位元組長度資訊包含本身著2位元組。如:資料體是(abcdefg)7個位元組,整體封包就是09abcdefg,總共是9個位元組的協議 1、netbus接收到資料後傳送到static void on_recv_tcp_data(uv_

用phpqrcode生成帶logo二維碼, 注意,不注意是要進坑的哦.

先附上程式碼: include '../vendor/phpqrcode/phpqrcode.php'; $value = 'http://127.0.0.1/txw1958/'; //二維碼內容 $errorCorrectionLevel = 'L';//容錯級別

SSM整合注意:json資料使用jackson更合適

依賴 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <

網路分析軟體——WIRESHARK

0x00 wireshark 簡介 BurpSuite是一款大家熟知的抓包軟體,但它只能抓應用層的包,下面說的WireShark是與網絡卡進行資料交換的,可以抓到物理層的包,功能肥腸強大。 Wireshark(前稱Ethereal)是一個網路封包分析軟體。網路封包

關於各種 網路協議分析 的一些文章

各協議埠號 https://blog.csdn.net/ypt523/article/details/79636647   TCP/IP/UDP/ICMP/ARP/ethernet 各種協議頭部結構體 https://blog.csdn.net/xiexievv/art

專案中依賴module中的jar注意

1,為了方便開發我們常會將一些常用且通用的類或者jar整合在module中方便以後的專案隨時呼叫。 但是自從Android studio更新到3.0.0之後將complie改成api和implement後需要注意一點,如果module中的jar需要給主專案使用則需要使用ap

網路程式設計-TCP傳輸資料--

網路程式設計 如果你要開發的程式基於網路工作,要和其他計算機進行資料互動,就需要學會網路程式設計.請你思考,網路是什麼? 計算機之間相互傳輸資料,首先需要介質,可以是網線、光纖、無線電波,就能通過電(光)訊號進行基本的0和1傳輸,可以被計算機識別. 同樣的100個電訊號,50個為一組和20個為一組,得到