Jump to content


Photo

บทความ การแกะแพคเกต WMO


  • Please log in to reply
20 replies to this topic

#1 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 11:49:07 AM


พอดีไป ค้นหาแล้วเจอ บทความการแกะแพคเกต WMO ครับ
ซึ่งเนื้อหา แนะนำขั้นตอนการแกะ Hash (น่าจะเป็นตัวเข้ารหัส หรืออะไรทำนองนั้น)
ซึ่งในบทความ กล่าวถึง Xtrap NProtect ไม่แน่ใจว่าเกี่ยวอะไรกัน
คราวนี้ จากตัวอย่างครับ โค้ด เป็น ภาษา C รบกวนผู้รู้ แปลงเป็น ภาษาเดลไฟให้ด้วยครับ


อ้างอิง ::
http://reversing.us/...ket Hacking.htm

CODE

Packet Hacking  (Reversing HASH 1 in Water Margin)
Part 1
g3nuin3 & hunter

Welcome to this hopefully not too long paper covering packet deciphering and
emulating raw packets. This series is going to cover how I and hunter hacked water margin and worked on deciphering the packets, this paper will only covers reversing hash one for the sent packet data. We won’t reveal every bit of it, but hopefully cover enough. This tutorial assumes a bit of assembly knowledge and knowing how to debug and understanding some debugging terms will help as well..



Many MMO’s nowadays are taking drastic measures to protect their game, their databases and to protect their players.. I for one am not against this and I’m not the type of person to fuck their games up out of pure evil.. its for knowledge and practice..and fun…With that said, what you do with the information revealed in this article is not my responsibility..


When embarking on a mission to decipher a games packets there are few things to expect.. For one, failure.. and lots of it…Second.. time.. and LOTS of it..and skill…lots of it would be nice. Understanding assembly is a must. Because depending on how tough the game encrypts its data.. you will be tracing quite a bit of code.

Now, there’s no one way to find out how a games packets are to be deciphered, so please don’t take this article and try to use the same techniques for all other games. You probably won’t get far. There are many obstacles that may get in the way, such as anti-hack protections that use their own encryptions on the games protocol (XTrap, Hackshield, Nprotect), and in some cases where an attack on the server is the only way to manipulate the games important data…

Water Margin in this case takes none of those into consideration..just simple protocol encryption between client and server using crc32 tables and hashes.


I’m sure by now you’ve heard of a tool called WPE Pro. It’s a middle man program which injects a dll into a preferred process and attempts to hook some known winsock functions, the hook simply transfers any raw packet data used by the send/WSASend/recv/WSArecv API’s and puts it into a nice little format for us to use.. we can then do what we please with the data, edit it, send it back.. modify incoming data and edit them on the fly.. Now you may think this is effective. But in our case.. not much, Only when a game uses no kind of encryption is wpe totally useful, When working with encrypted data, it can only help us identify that the game uses encryption. Now, how do we know if we’re working with encrypted packets ( I will be referring to packets that expire or timestamped as well as other terms as ‘encrypted’ for simplicity)?


If you have Water Margin, open it up and target it with WPE Pro.  The easiest but not best way to work with packets is by seeing what you get from the chat packets.(Although some games  don’t encrypt their chat packets, it’s a great starting point to trace code from) Understand that packets are only just hex data being sent to the server from the client. In WPE I like to filter the options for the current data Im analyzing.. for now we want to log the sent packets so in wpe go to VIEW -> Option.. Under Winsock 1.1 tick only Send. And under Winsock 2.0 tick WSASend, the buffer size can remain where it is.. mine is at 5000.( we will probably never log that much at once.)


#2 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 11:50:06 AM

IPB Image


CODE
Ok. Now that Water Margin is running, youre in the server, wherever you may be it doesn’t matter right now. In WPE start recording by pressing on the ‘PLAY’ looking button.  In the game type the letter ‘A’.  Now Type the letter ‘B’, then type the word ‘ABC’.. Ok, that should suffice for now. Let us take a look at what we got.





For the letter ‘A’ I got:



AA 0F 00 00 00 09 00 00 00 52 CB F9 D3 78 9C 13 17 60 66 00 02 47 06 00 01 EF 00 6C



For the letter ‘B’ I got:



AA 0F 00 00 00 09 00 00 00 5B 39 F0 39 78 9C 13 17 60 66 00 02 27 06 00 01 F1 00 6D



And for ‘ABC’ I got:



AA 11 00 00 00 0B 00 00 00 B3 C5 AD AA 78 9C 13 17 60 65 00 02 47 27 67 06 00 04 25 00 F3





NOTE:  When working with packets, you will usually notice that the first one or two hex data’s are a ‘packet singature’, this will usually tell you what kind of packet you are working with, signifies ‘type of packet’. The other will more than likely be the size of the packet data. Then comes some miscellaneous data.. Whether it be the encrypted data.. some hash, timestamp, etc.. it will probably also end with some sort of ‘packet footer’ which signifies end of packet data. This is not ALWAYS the case, so be cautious and do your research.



Now, if you’re a thinker you would probably have noticed that our packets wont be the same at every point.. Now if we try and recognize what these packets are we will be wasting a lot of time. How do we know we’re working with encrypted data? Take a look at the dump in WPE…notice anything strange? Yes.. if we typed in A, why isn’t it in the raw dump? Encryption is the only answer to that question.



            Ok so now that we did a small recording, its safe to say that WPE’s job is done.. yep, that’s right.. its of no use to us.. You can go ahead and re-send the packet data for the chat.. you will successfully send it again J , you’re probably saying why the hell then are we trying to decipher them… well.. take a look at your movement packets and try resending those;-)  Our mission in this paper is to show you how to chase packet encryption.. and nevertheless.. The chat packets are being encrypted.. But they are not expired till the next execution of the game.. This game uses what we call a session key. This is when you login to the game and the server sends a unique key that will be the basis of the encryption of the packets for that game session. Let’s prove this theory, close water margin and save the packet data from wpe. Now restart Water margin and try sending the previous sessions packets, it won’t work;). Unfortunately they were at least smart enough to not make the same mistake for movement packets. And more important things;). But that’s for another day to explain..



Anyways, now what do we do next? We go fishing for some raw data J Think about it, you are typing strings, when you press enter, the data you write has to be held somewhere to be encrypted correct? Well then.. Lets see if we can find this.. on the way to that we will find other things like encryption routines and such. But before we begin to fish, let’s cheat a little, since we know that we are dealing with some sort of encryption, let us see if it’s using any kind of public encryption. We will use PEID along with the KANAL plug-in to do this. If I’m not mistaken PEID comes with this plug-in equipped, if not I will have it attached along with this paper. So after using the Krypto Analzyer plug-in here is what we get.


#3 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 11:51:01 AM

IPB Image


IPB Image

CODE
Ok, now this here could mean anything, it could mean that the game uses crc32 to calculate some other checksum, but there are quite a few references to the crc table.. Let’s try and remember these just in case we stumble upon them later. We give special attention to the first reference “Referenced at 005651D3”


#4 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 11:53:14 AM

CODE
Tracing the Code
Ok, we’re now at the part where we are going to try and find some sign of raw data, before its encrypted state. This is where your own intuition comes in, to make educated guesses as to what routine we should trace, at the beginning you’ll find yourself tracing through a lot of code, and it gets boring. So the first thing we do is make sure we have a debugger handy. OllyDebugger,  in my case.

So now Run the game, and attach olly to it. Our goal now is to back-trace from the Winsock Send() function, and hopefully find some interesting routines to work with.

Once we successfully have done that, we type “bp send” in the olly command bar.

Now in Water Margin type anything…We quickly break inside the call to send().

IPB Image

CODE
We see this in our local stack window in olly..For now this information isn’t important. But just to explain the “Data” argument holds the packet data we see in WPE Pro, this of course being the already encrypted data. ( If you want to verify this.. Record with WPE, then while having a breakpoint set on send in olly.. send some data.. Olly will break, right click the data parameter and go to “Follow in Dump”, then press F9 to continue execution, the same data in that dump will be the packets you send out in WPE.)
            Ok now in the local stack window, right click the line “Call to send from 108Online.xxxxxxxx” Press “Follow in Dissassembler”.The CPU window changes to this.


IPB Image

#5 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 11:54:59 AM

CODE
CALL NEAR EDI was the call to the send function. Now the send function lies inside of one of the games own procedures.. many things go on before the initial data is sent, lets find the beginning of this function.
Scrolled up and we find this prologue routine.


IPB Image

CODE
Not your average prologue, but who cares.. Now I took a careful look at the function and tried to pick out some suspicious calls or suspicious code, being abit familiar with this type of work my eyes for some odd reason looked at the first call. I pressed F9 to let the game continue and set a breakpoint on the call at address 00584ADA. After setting the breakpoint, I once again typed random jibberish in the game, the breakpoint was hit. I immediately take a look at my stack.


IPB Image

#6 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 11:56:21 AM

CODE
My first inference was.. hmm nothing interesting yet, I followed the dump at ECX. But nothing seemed interesting at the time.


IPB Image

CODE
So now I followed this first Call, pressing F7 in olly. We have this very small but very interesting routine J.

005845D0    8B41 04              /MOV     EAX, DWORD PTR DS:[ECX+4]
005845D3    8B40 08              |MOV     EAX, DWORD PTR DS:[EAX+8]
005845D6    0341 08              ADD     EAX, DWORD PTR DS:[ECX+8]
005845D9    C3                   RETN

Following it line by line, let’s take a look at what we get. First instruction put the DWORD value pointed to by ECX+4 into EAX. My EAX now held 02165C10

Next line took the DWORD Value pointed to by EAX+8 and put it into EAX. Now EAX held 0933BE00. So I followed this address in the dump window.. and to my surprise look at what I got.


#7 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 11:58:09 AM

IPB Image

CODE
Can you guess what I typed in? Yep. “fff” was what I typed in the game. Quickly I knew that this was some place where our original data was being held. I highlighted it all the way to the ‘00’, I assumed that it would end with a Null Terminator. So from here I decided to test how it would go if I changed this data at this point to something else.

I highlighted the text “fff” in the dump window, right clicked it and went to Binary -> Edit. Keeping the size intact I wrote another sequence of three letters.


IPB Image

[code=auto:0]I changed it to YYY, then I continued execution of the game. Here’s what I got J.[code=auto:0]

IPB Image

#8 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 11:58:50 AM

CODE
Yup, Now we could stop here and do this all the time, but come on..we want to be better than that.. now I thought.. hmm.. this data was being accessed from some place, but this is not where we actually see the data being created, another good alternative is to find somewhere ‘only’ the data  is being passed as an argument to a procedure, this way we can hook it and send data ourselves.

            Another inference was that the data we got earlier in that function where our raw data was, is some kind of structure…Why would we think that you ask? Well..lets try it out, lets move ingame instead of write something and see how the dump changes. After moving and breaking on that call, I got this in my dumped data.


IPB Image

CODE
Isn’t it nice how olly tells us in red what data has changed? So looking here we can make a few educated guesses. In our chat dump the first byte was 17, now its 19.. hmmm, the third byte in our chat packet was some number other than 10, depending on what you typed right?, lets just for sanity’s sake record one more chat packet, this time I typed in 4 letters ( ‘gggg’). My dump looked similar to the first except one part. The third byte, three letters was 05, now 4 letters is 06.. hmmm, could this third byte represent the size of data? so I also took a look at the actual data. Our previous chat data was 3 letters, meaning 3 bytes, but remember it ended with a null terminator, so 4 bytes..I took another look and realized that for some odd reason, the packet data must also be preceded with an 00, why? Well who cares, there could be no other explanation for it. So the third byte is presumed to be the size of the real data. And data is preceded with and ends with Null terminators, or for clarity 0’s. And the First WORD is the type of packet.


#9 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 12:00:54 PM

CODE
Retrieving Hashes
            Ok since we made a few inferences about how the packet structure is formed we really need a suitable spot to test this. After some RE work and help with a Curse-x Fellow member, we found a very interesting function that used a pointer to the raw data as well as return a hash using it. This is the hash we will emulate in this paper. We decided it was a suitable place to make a hook to and send our own chat data’s to retrieve its hash. But first I’ll show you the function. The location we settled with was 005655F1. In Olly the function looked like this.


IPB Image

CODE
Seeing the function the first thing I wanted to see was what it would return, looking a bit below you see that the value of EAX was being moved into EBX+30. Right now it doesn’t matter what EBX+30 is, so setting a breakpoint here I wrote jibberish ingame and pressed enter, it broke here(005655F1). When it broke EAX held some value, I then Stepped OVER the function in olly with F8. Immediately the value of EAX in the registers window was red and another value greeted me, a strange value, that’s when I decided that this function returns some value using the data being passed to it. It returns a hash, let’s get this hash eh.

            At first sight we can see that it pushes 3 arguments onto the stack. Let’s find out what it’s pushing, So what I did was break several times in the function and analyzed the arguments each time. I take a look at my Local Stack in Olly. ( The local stack will show you the values that are being push’d or pop’d onto/from the stack.) I break several times and this was my local stack values.[code]

[img]http://reversing.us/pages/g3n/Packeter/Packet%20Hacking_files/image016.jpg[/img]

[code]Since it pushes 3 values I look at the first 3 values currently on the stack, then I followed the second parameter in Olly’s Dump. I got this:


IPB Image

CODE
The address to our raw packet structure. Being sufficed with that, the first parameter always seemed to be 1. The last parameter was the size of the packet structure in bytes.

Ok so we found a function that uses our raw packet structure only to perform some actions, for this paper it doesn’t really matter what it uses the data for ( although a very important function overall;) ). So now that we’ve gotten the packet structure reversed ( by pure EDUCATED GUESSES EH and some RE skills) lets see if we can code something to test this. Lets code a bit.


#10 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 12:01:48 PM

CODE
Coding Hash-Getter.



            Ok, up to this part we’ve done a lot of reversing and guess work, but we can’t really prove that our assumptions are correct yet about the packet structure.

Since we are working with chat packets only here let’s put some of our information together. We know that the first two bytes represent a packet ID, identifying the action being taken, all of our chat packets thus far have started with 17 10. Knowing how memory works and the intel’s reversed byte structure (Little Endian) This is represented as 0x1017 in C++ language. The next 4 bytes are the size of the data. Remember a 0 is appended to the beginning and also ends with a null terminator. Then comes the data.



So we have our Packet Structure defined.



struct Packet {

    short packetID;

    int dataSize;

    char data[50];

};



The maximum data size later on after stepping into that function we had earlier came out to be 5552 (15b0h). We can change it to that if we want, but it doesn’t matter as long as it doesn’t exceed this limit. Now all that’s needed is a simple Edit box to retrieve some text from, we can then fill in the packet structure according to this. The meat of the code lies In here:



int SendInfo1(Packet *p, char *data)

{
      int rett;//returned hash
      p->PacketID = 0x1017;//chat ID
      strcpy(p->data+1, (data)-1);//copy the data in the data element +1 ( remember the prepended 00)



      p->data[0] = 0; //the 0 before the data.
      p->datasize = 2 + strlen(p->data);  // the size of the data is the length of the actual data plus the prepended 0.

      Packet *pp = p;



      int sizeofPacket = sizeof(short)+sizeof(int)+ p->datasize;  //  PacketID + PacketSize + data
      unsigned int func = 0x0056D445;

      __asm{
                  push sizeofPacket
                  push pp
                  push 1
                  call func
                  mov rett, eax //this is just that hash we mentioned, not doing anything with it now;)

      }

      return rett;

}

With this function utilized, rett will hold the hash created by the function located in 0056D445. To lazy reversers this would be enough to stop. But the point of reversing a games packets is to to be able to re-create them ourselves, We will now go back to Reversing and reverse this hash function and try and create our own hashes for our packets J.


#11 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 12:04:13 PM

CODE
Reversing Hash Function.
            Ok. Remember where the function was that we wanted correct. Indeed it was, lets use IDA along with Olly to reverse this and code our own version of it. An Ollydebug strip of the code looks like this:


108Onlin_0056D445:                          ;<= Procedure Start
        PUSH    EBP
        MOV     EBP, ESP
        MOV     ECX, [ARG.2]; ECX holds pointer to raw data
        PUSH    ESI
        PUSH    EDI
        MOV     EDI, [ARG.1];Holds key. (always 1  :/)
        MOV     ESI, EDI; temporary ‘key’ holder (first param
        AND     ESI, 0xFFFF; AND’s the temp key with 0xFFFF(65535)
        SHR     EDI, 0x10; right shifts argument 1 with 0x10(16)
        TEST    ECX, ECX; checks if there is any data to work with
        JNZ     108Onlin_0056D467; does check for size parameter if there is.
        XOR     EAX, EAX; if not
        INC     EAX; returns 1
        JMP     108Onlin_0056D55A; exit



108Onlin_0056D467:
        CMP     [ARG.3], 0; size if zero or below?
        JBE     108Onlin_0056D553; jmp
        PUSH    EBX; ebx is pointer to original data



108Onlin_0056D472: //Checks size limit
        MOV     EDX, 0x15B0
        CMP     [ARG.3], EDX
        JNB     108Onlin_0056D47F; If the size is larger than 5552, truncate it
        MOV     EDX, [ARG.3]


108Onlin_0056D47F: //
        SUB     [ARG.3], EDX; subtracts size from itself.
        CMP     EDX, 0x10 ; jump is the datas size  is lower than 16.
        JL      108Onlin_0056D522; takes the jump for our chats
        MOV     EAX, EDX
        SHR     EAX, 4
        MOV     EBX, EAX
        NEG     EBX
        SHL     EBX, 4
        ADD     EDX, EBX


108Onlin_0056D499:  // this routine is NOT very important after some tracing.
        MOVZX   EBX, BYTE PTR DS:[ECX]
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+1]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+2]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+3]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+4]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+5]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+6]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+7]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+8]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+9]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+0xA]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+0xB]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+0xC]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+0xD]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+0xE]
        ADD     EDI, ESI
        ADD     ESI, EBX
        MOVZX   EBX, BYTE PTR DS:[ECX+0xF]
        ADD     EDI, ESI
        ADD     ESI, EBX
        ADD     EDI, ESI
        ADD     ECX, 0x10
        DEC     EAX
        JNZ     108Onlin_0056D499


108Onlin_0056D522:
        TEST    EDX, EDX  ; another check to see if it was 0 (size of data)
        JE      108Onlin_0056D531; if it was 0 jump.This eventually means that no data will be sent in send()



108Onlin_0056D526: // this little routine here adds up the byte data in our packet struct.
        MOVZX   EAX, BYTE PTR DS:[ECX]; ECX is our packet structs data.
        ADD     ESI, EAX; ESI is the result of our bytes being added.
        INC     ECX; move to next byte
        ADD     EDI, ESI; add this byte to EDI
        DEC     EDX; EDX is size of packet, decreases till end.
        JNZ     108Onlin_0056D526; loop



108Onlin_0056D531:
        MOV     EAX, ESI ; the end result is put into EAX
        XOR     EDX, EDX ; zeroes out EDX
        MOV     EBX, 0xFFF1;
        MOV     ESI, EBX;
        DIV     ESI
        MOV     EAX, EDI; EDI held small ‘checksum’ of our data being added.
        MOV     ESI, EDX;EDX == the end result ESI Held.
        XOR     EDX, EDX;Zeroes out EDX
        DIV     EBX ; EBX == EDI.
        CMP     [ARG.3], 0 ; checks third argument, remember it was zeroed out.
        MOV     EDI, EDX; EDI = EDX
        JA      108Onlin_0056D472; no jump.
        POP     EBX;



108Onlin_0056D553:
        MOV     EAX, EDI ; EAX = EAX << 16 || ESI
        SHL     EAX, 0x10;
        OR      EAX, ESI;



108Onlin_0056D55A:
        POP     EDI
        POP     ESI
        POP     EBP
        RETN                                ;<= Procedure End




#12 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 12:05:36 PM

CODE
This output was used with Olly plugin “CodeRipper” , thanks to whoever wrote it;).  Ok so now that we had figured out the routine.. the real meat was really where it started to move the data “MOVZX   EAX, BYTE PTR DS:[ECX]”. So here’s the C++ implementation of this function, removing most of the junk not needed to create the hash.


unsigned int __cdecl getHashB(int key, void *data,unsigned int size)
{
     unsigned char *pData = (unsigned char *)data; //save data in temp as to not corrupt it
     unsigned int sum = key & 65535; // temp being the key AND's with 0xFFFF

      key >>= 16; //shr 0X10
      if(pData == 0) {
            return 1;
      } else {
            if(size > 0) { // truncating if size is larger than limit
                  if(size > 5552)
                        size = 5552;
                  for (int i=0;i < size;i++) {  //
                        sum += ( pData[i] & 255);
                        key += sum;
                  }
            }
            return (key << 16) | sum;
            /*    MOV     EAX, EDI ; EAX = EAX << 16 || ESI
                  SHL     EAX, 0x10;
                  OR      EAX, ESI;
                  */
      }
}



With that completed we had to test if our hash function returned the same hash as the games’. So I added a few more additions to the Hash Test Program to see this comparison. And the results are? J


IPB Image

#13 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 12:07:28 PM

CODE
And this Modified SendInfo Function, called SendInfo2.


int SendInfo2(Packet *p, char *pdata)
{
      int rett;//returned hash
      p->PacketID = 0x1017;//chat ID
      strcpy(p->data+1, (pdata)-1);//copy the data in the data element +1 ( remember the prepended 00)
      p->data[0] = 0; //the 0 before the data.
      p->datasize = 2 + strlen(p->data);  // the size of the data is the length of the actual data plus the prepended 0.
      Packet *pp = p;
      int sizeofPacket = sizeof(short)+sizeof(int)+ p->datasize;  //  PacketID + PacketSize + data
      int i = 1; // arg 1 == 1.
      rett = getHashB(i, pp, sizeofPacket);
      return rett;
}


Well we’ve successfully reversed a hash returning function, lets congratulate ourselves..In Part 2 of this series I will go deeper into why we are doing all this and we may even chase another one.. using the crc table, in this paper I only barely mentioned the crc because I wanted to bring it to your attention now.  The information in this paper is by no means a complete paper on the work me and hunter have put behind the game, hopefully I feel like writing more of it, depending on the feedback,

I wrote this paper because of the lack of MP hacking tuts on the net and how much work is actually put behing the packet bots or emulators you see roaming, it isnt easy work by a long shot. So I hope you learned something and try and get further than this.. See if you can Reverse the crc function :D and I wont leave you with any hints lol! BYE!



CODE

Tools included with this paper.
Full source code to chattest dll.
My DLL Injector (g3ntool)
And PEID plugin (kanal.dll)


References.

It’s a pity to say there is only about two or three references I could get my hands on but they are very useful.

http://cellframework.sourceforge.net/uploads/Introduction%20to%20Server%20Side%20Emulation.pdf    : This paper was very enlightening and goes into the world of Emulator creation, and lightly covers reversing packets and coding emulators, useful tips in this one.
http://www.ghu.as.ro/ghtuts/thong1.htm  : A tutorial By Thong.


#14 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 17 March 2008 - 12:10:29 PM

จบแล้วครับ

กอปปี้ มาให้อ่าน กลัว เวบโน้นตาย เข้าไม่ได้
ผมจะอดรู้อะไรดีๆ ปัญหา ก็อย่างที่โพสไว้ด้านบนครับ
โค้ดเป็นภาษา C รบกวนผู้รู้แปลงเป็นภาษา เดลไฟ ให้ด้วยครับ
เพื่อให้สามารถนำไปประยุกต์ใช้ กับ เกมอื่นๆ ได้
และเป็นประโยชน์ แก่ลูกนกลูกตา (ตาดำๆ)

สาธุ onion36.gif

#15 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 18 March 2008 - 05:31:00 PM


ไม่มีใครแปลงโค้ด getHash ที่เป็นภาษา C ได้เลยหรือครับ T-T
แสดงว่า มันคงจะยากพอตัวเลย

onion12.gif


#16 Chumaker

Chumaker

    Exclusive Member

  • Exclusive Programmer
  • 10003 posts

Posted 18 March 2008 - 11:50:29 PM

แสดงว่าคุง CodeGeaR เล่น wmo อยู่ ปะงับเนี่ย

#17 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 20 March 2008 - 12:40:14 AM

QUOTE(Chumaker @ Mar 18 2008, 11:50 PM) ดูโพสต์

แสดงว่าคุง CodeGeaR เล่น wmo อยู่ ปะงับเนี่ย


ไม่ได้เล่นครับ ตัวอย่างเขาให้มาเกมนี้
โหยหา มาหลายวัน พระเอกขี่ม้าขาวมาช่วย
สุดท้าย ไม่รุ้ว่า จะเอาไปใช้งานยังไง

CODE
เครดิต :: Vittee
function getHashB(key: Integer; data: Pointer; size: Cardinal): Cardinal;
var pData: PByte;
    sum: Cardinal;
    i: Integer;
begin
      Result:=1;
      pData := data; //save data in temp as to not corrupt it
      sum := key and 65535; // temp being the key AND's with 0xFFFF
      key := key shr 16; //shr 0X10

      if pData = nil then Exit;
      if size > 0 then // truncating if size is larger than limit
    begin
           if size > 5552 then
              size := 5552;

           for i:=0 to size-1 do
          begin
                 sum := sum + (pData^ and 255);
                 key := key + sum;

                   Inc(pData);
              end;
        end;

        Result:= (key shl 16) or sum;
end;




#18 AssertionFailed

AssertionFailed

    Exclusive Member

  • Exclusive Programmer
  • 10116 posts

Posted 13 April 2008 - 12:30:53 AM

โทษทีที่ไม่ได้ตอบครับ
พอดีเพิ่งออนวันนี้ ณ เวลานี้

#19 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 13 April 2008 - 01:35:55 PM


ได้โค้ดมา ก็ไม่รุ้ว่ามันเอาไปใช้งานยังไงครับ
เหมือนไก่ได้พลอย เอาไปลองแกะ แพคเกต ก็ไม่ได้
ใช้งานไม่เป็น
อาการโง่ลงตับ (FuHepatits)

- -*
onion11.gif

#20 CodeGeaR

CodeGeaR

    Exclusive Member

  • Exclusive Programmer
  • 10218 posts

Posted 13 April 2008 - 01:51:06 PM

QUOTE(AssertionFailed @ Apr 13 2008, 12:30 AM) ดูโพสต์

โทษทีที่ไม่ได้ตอบครับ
พอดีเพิ่งออนวันนี้ ณ เวลานี้


สงสัยงานจะยุ่งมากครับ
ถ้าว่าง แกะเกม LUNA กันครับ
(ผมแกะไม่ได้ - -* แกะไม่เป็นจริงๆครับ)

เป็นแนวทาง ไปประยุกต์กับเกมอื่นครับ

onion34.gif อากาศร้อนจัง





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users