Packet reversing findings menu

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 15 of 30
  1. #1
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Packet reversing findings

    Okay, after a long reversing binge, I've found some stuff on packets being sent.

    CNet:SendPacket 0x5F92F0
    "FormPacket" 0x8361B0

    The parameters for SendPacket is CDataStore(i think). It's a class like this

    class CDataStore
    {
    uint *packet;
    }
    ([CDataStore + 0x4] = the packet)

    I'm unsure of the other values in the class. If you reverse more members/functions, please post them here

    BTW the send function is pre-encryption. You can send any packet you want(almost). I have yet to try these, but I'm almost positive they're correct.

    Packet reversing findings
  2. #2
    namreeb's Avatar Legendary

    Reputation
    668
    Join Date
    Sep 2008
    Posts
    1,029
    Thanks G/R
    8/222
    Trade Feedback
    0 (0%)
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)
    The value I saw passed to 0x005F92F0 via the esp register was 0x001EFD14. You're saying that [0x001EFD14+0x4] is the location of the packet? In my case, that would be 0x005A5257. The data contained at that address does not seem to have anything to do with the movement packet that I am trying to witness being sent. In fact, it lands us in the middle of a function!

    However, there are some other items of interest around 0x001EFD14. This is in the conext of a MSG_MOVE_START_FORWARD packet. Below:

    Code:
    struct sPacket                        // 0x001EFD14
    {
      DWORD p1;                           // [0x001EFD14] = p10 (0x001EFD4C)
      char unk1[0x04];                    // 0x001EFD18 - 0x001EFD1C
      DWORD p2;                           // [0x001EFD1C] = p3 (0x001EFD2C)
      DWORD opcode;                       // [0x001EFD20] = 0xB500000
      char unk2[0x08];                    // 0x001EFD24 - 0x001EFD2C
      DWORD p3;                           // 0x001EFD2C - 0x001EFD30
      DWORD p4;                           // 0x001EFD30 - 0x001EFD34
      DWORD p5;                           // 0x001EFD34 - 0x001EFD38
      DWORD p6;                           // 0x001EFD38 - 0x001EFD3C
      DWORD p7;                           // 0x001EFD3C - 0x001EFD40
      char unk3[0x04];                    // 0x001EFD40 - 0x001EFD44
      DWORD p8;                           // [0x001EFD44] = unk5 (0x001EFD50)
      DWORD p9;                           // [0x001EFD48] = unk6 (0x001EFD54)
      DWORD p10;                          // [0x001EFD4C] = p11 (0x001EFD7C)
      char unk4[0x04];                    // 0x001EFD50 - 0x001EFD54
      char unk5[0x04];                    // 0x001EFD54 - 0x001EFD58
      char partial_packet_contents[0x18]; // 0x001EFD58 - 0x001EFD70
      char unk6[0x04];                    // 0x001EFD70 - 0x001EFD74
      char unk7[0x08];                    // 0x001EFD74 - 0x001EFD7C
      DWORD p11;                          // 0x001EFD7C - 0x001EFD80
      char unk8[0x24];                    // 0x001EFD80 - 0x001EFDA4
      // ... ?
    }
    
    // values, direct from memory:
    // unk1 = 00 00 00 00
    // unk2 = D8 C6 44 22
    // unk3 = FF FF FF FF
    // unk4 = C8 4B 5C 00
    // unk5 = 66 77 B0 03
    // unk6 = 00 00 00 00
    // unk7 = 30 56 26 0F
    // unk8 = E2 76 57 00 66 77 B0 03 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    FF 00 00 00
    The structure may continue, but that was the end of obviously relevant data.

    The following is what Olly shows for the function you call 'CNet:SendPacket' at 0x005F92F0:

    Code:
    005F92F0  /$ 55             PUSH EBP
    005F92F1  |. 8BEC           MOV EBP,ESP
    005F92F3  |. 8B0D 949F1301  MOV ECX,DWORD PTR DS:[1139F94]
    005F92F9  |. 85C9           TEST ECX,ECX
    005F92FB  |. 74 09          JE SHORT WoW.005F9306
    005F92FD  |. 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
    005F9300  |. 50             PUSH EAX                                 ; /Arg1 = 001EFD2C
    005F9301  |. E8 3AF60800    CALL WoW.00688940                        ; \WoW.00688940
    005F9306  |> 5D             POP EBP
    005F9307  \. C3             RETN
    An area of interest is pointed to by my 'p2', or [sPacket + 0x8], which points to 'unk3'. This value (the address of unk3, or 0x001EFD2C) is what is passed to the function 0x00688940.

    Comments?
    Last edited by namreeb; 06-06-2009 at 04:38 PM.

  3. #3
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It was late, I think I made a mistake when I was taking notes in notepad. The main thing that I noticed was that at the end of the FormPacket function, eax gets set to the base address of the packet struct. Try putting a BP at 0x8361FB. You'll see the opcode of the packet being sent at [eax + 0x0]. If you continue through the rest of the formpacket calls, you'll see the rest of appending the packet data. Im currently reversing the calls from jumporascendstart.

    EDIT: Nvm. I don't know where I was coming from last night. I'm sick of looking at this damn opcode list. I'm probably done with packets for a while.
    Last edited by lanman92; 06-06-2009 at 03:41 PM.

  4. #4
    namreeb's Avatar Legendary

    Reputation
    668
    Join Date
    Sep 2008
    Posts
    1,029
    Thanks G/R
    8/222
    Trade Feedback
    0 (0%)
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)
    Looking at your 'FormPacket' function, I believe we can fill in a bit more about sPacket. Specifically, [p3 + 0xC] is a function! For me, this is 0x00835FB0 'func1'. I have edited the structure in the original post with the new information.

    The function called by 'FormPacket' is called thusly:

    Code:
    ecx = p3
    func1(p7, 4, p4, p5, p6, 0, 0) // [ebp + 0x8] gets set to opcode
    *(p4 + *p7) = opcode
    p7 = p7 + 4
    Clearly p3 points to a structure of some kind... yet still there are lots of holes to fill in.

  5. #5
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, it seems that 'formpacket' is somewhat of a wrapper around the vmt function.

    EDIT: Let's make a class to summarize this so far.

    Code:
    CData::FormPacket(uint value)
    {
        if(unk3 < unk2)
        {
            //not sure yet
            return;
        }
    
        unknownImportant(unk3, 4, &unk1, &unk2, &unk3, 0, 0);
        
        //same as above inside the if block
    }
    Code:
    class CData
    {
        CPacket *packet;
        uint unk1;
        uint unk2;
        uint unk3;
        
        public void FormPacket(uint opcode);
    
        virtual void func00();                                                               //[0x980C2C]
        virtual void func01();                                                               //[0x980C2C + 0x4]
        virtual void func02();                                                               //[0x980C2C + 0x8]
        virtual void unknownImportant(uint, uint, uint, uint, uint, uint, uint); //[0x980C2C + 0xC]
        virtual void func03();
        virtual void func04();
        virtual void func05();
        virtual void func06();
        virtual void func07();
        virtual void func08();
        virtual void func09();                                                                //[0x9802C + 0x24]
    };
    Last edited by lanman92; 06-06-2009 at 08:14 PM.

  6. #6
    namreeb's Avatar Legendary

    Reputation
    668
    Join Date
    Sep 2008
    Posts
    1,029
    Thanks G/R
    8/222
    Trade Feedback
    0 (0%)
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by lanman92 View Post
    Code:
    CData::FormPacket(uint value)
    {
        if(unk3 < unk2)
        {
            //not sure yet
            return;
        }
    
        unknownImportant(unk3, 4, &unk1, &unk2, &unk3, 0, 0);
        
        //same as above inside the if block
    }
    What I got from IDA:

    Code:
    CDataStore::Append(uint value)
    {
      unsigned int Length, v3;
    
      Length = *(DWORD *)(this + 0x10);
      v3 = *(DWORD *)(this + 0x8);
    
      if (Length < v3 || Length + 4 > v3 + *(DWORD *)(this + 0xC))
        this->unknownImportant(Length, 4, this + 0x4, this + 0x8, this + 0xC, 0, 0);
    
      *(DWORD *)(*(DWORD *)(this + 0x4) - v3 + Length) = value;
      *(DWORD *)(this + 0x10) += 4; // update new length
    }
    Last edited by namreeb; 06-06-2009 at 08:40 PM.

  7. #7
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    v2 and v3 are class members. The 0xF, I'm not sure where you got that. Is that the hexrays decompiling? I've never figured out how to get that working =/ Also, the above 'classes' are actually structs. You can tell because they are stored on the stack. I think v2 and v3 have something to do with the index of what's being written and the length of the packet.
    Last edited by lanman92; 06-06-2009 at 07:19 PM.

  8. #8
    namreeb's Avatar Legendary

    Reputation
    668
    Join Date
    Sep 2008
    Posts
    1,029
    Thanks G/R
    8/222
    Trade Feedback
    0 (0%)
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)
    Oops, that 0xF was supposed to be 0x10. And yes, this was done in Hex-Rays Decompiler, but I tweaked it to make it a bit more readable. It looks like this + 0x10 may be a pointer to the length of the packet buffer. If that is the case, it stands to reason that *(DWORD *)(this + 0x4) - *(DWORD *)(this + 0x points to the start of it. Moreover, it might be more appropriate to rename FormPacket to Append.

    Edit: Does this look familiar? https://starfish.westmont.edu/viewcv...=markup&rev=60

    Edit2: I've been reversing LoadMovePacket. It seems to be a member function of CGLocalPlayer_C. Moreover, I have identified a number of functions and their parameters. Below:

    Code:
    bool sub_689350(int Opcode)
    {
    
      if ( Opcode > CMSG_MOVE_STOP_SWIM_CHEAT )
      {
        if ( Opcode == MSG_MOVE_FLY_STATE_CHANGE || Opcode == 1133 )
          return 1;
    
    	return (Opcode == 1179);
      }
    
      if ( Opcode >= CMSG_MOVE_START_SWIM_CHEAT )
        return 1;
    
      if ( Opcode > MSG_MOVE_TOGGLE_COLLISION_CHEAT )
    	return (Opcode == MSG_MOVE_TOGGLE_GRAVITY_CHEAT);
    
      if ( Opcode == MSG_MOVE_TOGGLE_COLLISION_CHEAT || Opcode >= MSG_MOVE_START_SWIM && Opcode <= MSG_MOVE_STOP_SWIM )
        return 1;
    
      return 0;
    }
    
    bool CGLocalPlayer_C::sub_5A4FE0(int Opcode)
    {
      int v3; // eax@3
    
      v3 = *(DWORD *)(*(DWORD *)(this->dwInputControl) + 0xBC);
      return IsLocalPlayer(this) && (!v3 || *(DWORD *)(v3 + 0x20) & 0x400 || sub_689350(Opcode));
    }
    
    bool MovementCheck2(int a1) // Same check, different function?
    {
      return a1 == CMSG_FORCE_MOVE_ROOT_ACK
          || a1 == CMSG_FORCE_MOVE_UNROOT_ACK
          || a1 == MSG_MOVE_TELEPORT_ACK
          || a1 == CMSG_FORCE_RUN_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_SWIM_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_FLY_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_FLY_BACK_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_WALK_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_TURN_RATE_CHANGE_ACK
          || a1 == CMSG_MOVE_HOVER_ACK
          || a1 == CMSG_MOVE_FLY_MODE_CHANGE_ACK
          || a1 == CMSG_MOVE_FEATHER_FALL_ACK
          || a1 == CMSG_MOVE_WATER_WALK_ACK
          || a1 == CMSG_MOVE_KNOCK_BACK_ACK
          || a1 == 1117; // ???
    }
    
    bool MovementCheck1(int a1)  // Check if op packet requires our GUID?  Local guid appended to packet if true.
    {
      return a1 == CMSG_FORCE_MOVE_ROOT_ACK
          || a1 == CMSG_FORCE_MOVE_UNROOT_ACK
          || a1 == MSG_MOVE_TELEPORT_ACK
          || a1 == CMSG_FORCE_RUN_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_SWIM_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_FLY_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_FLY_BACK_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_WALK_SPEED_CHANGE_ACK
          || a1 == CMSG_FORCE_TURN_RATE_CHANGE_ACK
          || a1 == CMSG_MOVE_HOVER_ACK
          || a1 == CMSG_MOVE_FLY_MODE_CHANGE_ACK
          || a1 == CMSG_MOVE_FEATHER_FALL_ACK
          || a1 == CMSG_MOVE_WATER_WALK_ACK
          || a1 == CMSG_MOVE_KNOCK_BACK_ACK
          || a1 == CMSG_MOVE_NOT_ACTIVE_MOVER
          || a1 == 1117; // ???
    }
    
    
    int CGLocalPlayer_C::LoadMovePacket(int a2, int Opcode, CDataStore Packet, float a5, int a6)
    {
      int result; // eax@8
      float v10; // ST08_4@5
    
      Packet->Append(Opcode);
      if ( MovementCheck1(Opcode) )
      {
        Packet->Append64(this->GetGUID().ullGuid);
        if ( MovementCheck2(Opcode) )
    	  Packet->Append(a6);
      }
      else if (!(result = sub_5A4FE0(Opcode)))
        return 0;
    
      sub_59C560(Opcode, a2, Packet);
      if ( sub_59B270() )
      {
        __asm
        {
          fld     [ebp+arg_C]
          fstp    [esp+10h+var_10]
        }
        sub_836270(v10);
      }
      if ( *(_DWORD *)(*(_DWORD *)(this + 216) + 68) & 0x1000 )
        *(_DWORD *)(v7 + 2608) |= 0x80u;
      return 1;
    }
    Opcodes list available here: SourceForge.net Repository - [mangos] View of /trunk/src/game/Opcodes.h

    There's obviously more to do. I'll get at it more later.
    Last edited by namreeb; 06-06-2009 at 10:34 PM.

  9. #9
    kynox's Avatar Member
    Reputation
    830
    Join Date
    Dec 2006
    Posts
    888
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    CDataStore is an open source class, i hope you guys realize that.

  10. #10
    namreeb's Avatar Legendary

    Reputation
    668
    Join Date
    Sep 2008
    Posts
    1,029
    Thanks G/R
    8/222
    Trade Feedback
    0 (0%)
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)
    Once I realized that's what it was, that's when I moved to reversing 'LoadMovePacket'.

  11. #11
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is it in the MangOS source? Also, I see a lot of simple patches that could be done to that function o.O easy fly-hack, anyone?
    Last edited by lanman92; 06-06-2009 at 10:52 PM.

  12. #12
    kynox's Avatar Member
    Reputation
    830
    Join Date
    Dec 2006
    Posts
    888
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by lanman92 View Post
    Is it in the MangOS source? Also, I see a lot of simple patches that could be done to that function o.O easy fly-hack, anyone?
    You will be disconnected for sending the pitching packets when flying.

  13. #13
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Didn't you post a long time ago that you can hook SendPacket and just edit the packet so that you're not sending the pitch packets?

  14. #14
    kynox's Avatar Member
    Reputation
    830
    Join Date
    Dec 2006
    Posts
    888
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by lanman92 View Post
    Didn't you post a long time ago that you can hook SendPacket and just edit the packet so that you're not sending the pitch packets?


    (filler)

  15. #15
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Any help with what's wrong with this code? I don't think many other ppl can provide light on this. I keep getting a null pointer(0x0000 referencing 0x00000).

    dbgout << packet.m_buffer << std::endl;

    Should the packet be a pointer...?

Page 1 of 2 12 LastLast

Similar Threads

  1. Once again (where to find packet parse function for wsarecv call)
    By Esoserv2 in forum Elder Scrolls Online General
    Replies: 3
    Last Post: 03-01-2014, 05:44 PM
  2. Stuck with packet structure reversing
    By ZealX in forum WoW Memory Editing
    Replies: 7
    Last Post: 11-29-2013, 06:32 AM
  3. [STUPID QUESTION] How to find stuff while reversing.
    By cenron in forum Diablo 3 Memory Editing
    Replies: 4
    Last Post: 08-23-2012, 08:10 AM
  4. Where could i find the best/stable ascent reversion for me ?
    By Wheeze201 in forum World of Warcraft Emulator Servers
    Replies: 14
    Last Post: 01-27-2008, 08:48 PM
  5. [Exploit] Find out if an opposite faction player is online
    By Matt in forum World of Warcraft Exploits
    Replies: 7
    Last Post: 11-04-2006, 09:22 AM
All times are GMT -5. The time now is 11:59 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search