Freitag, 4. Oktober 2013

Finging strings in packets

As mentioned earlier the server will send some strings to the client to display. Today we'll take a look at how he does that and how.

First of all let's take a look how the strings are stored. I used lotrounpacker to take a look at the clients data. The site provides two binaries, the dat-unpacker and the localedata-extractor. The first one can be used to unpack client_local_English.dat, the later one will generate a large text file with all the strings. So how do we achieve that?

First of all copy DAT_UNPACKER.exe and datexport.dll to the root folder of LOTRO (it's a .NET 4 binary). After this simply call the binary from a commandline:
DAT_UNPACKER.exe client_local_English.dat
This command will run for some time (something like 10 mins), depending on your hardware and fragmentation of your hard disk. It will also eat about 600MB of disk. Once the command is finished you should have folder: data\client_local_English\2XXXXXXX\25XXXXXX\250XXXXX

Extract the LOCALDATAEXTRACTOR.exe into that directory and execute it (again a .NET 4 binary). It will generate the 30MB text file LocalData.txt containing all the strings. You can now browse this file in something capable dealing with larger text files (i.e. not notepad).

Now that we have the strings, how do we find out what the server is telling us? Basically the most simple way is to search for "25" in packtes. If we take the first 0x01000006 packet from the server and search for "25", we will find one occurence. If you now read 5 bytes backwards starting from the byte we found, we will read 250001FE0A. So we take a look at the LocaleData.txt to find "Authentifizierung wird überprüft ..." (in case of the client_local_DE, somehow the strings are wrong when using client_local_English). This is exactly the string the client is displaying during startup.

I also used a disassembler (ILSpy) on both binaries. The result does not provide us anything so far, but we might need to parse the files at a later point when the server is maturing. So far there still is a compile error due to an issue in the disassembling, but so far the code looks usable.

Donnerstag, 3. Oktober 2013

Analyzing the initial connection packets

I've spent the day analyzing the initial startup packets and how they are built up. First of all let's take a look at the order of the first seven packets:

The client starts by sending the server a 0x00010000 packet. This packet contains the clients version, the locale timestamp of the server in UTC and the login token obtained from the GLS server (this is the central server you are using for your login).

The server answers this by a 0x00040000 packet. This packets contains identifiers for the server, some seemingly random data, a test token to be sent back by the client, necessary instructions for checksumming and a constant.

Now the client will send a 0x00080000 packet to the server. The packet contains the test token from the server in reversed form and an unknown constant. From now on the connection is established and packets will be sent encrypted and properly checksummed.

After this step the server will start sending a large block of data, namely data worth 4 packets. The server will initiate this transfer with a 0x01000006 packet. This packet, again, constains the server identification and (at least in the case of my account) always the same data. The following two 0x00000006 (1, 2) packets are the same for my account no matter which server I chose. After this there always is another 0x00000006 packet, but it differes heavily depending on the server (or maybe other facts).

Further investigation is necessary, especially if the packets differ depending on the language of the client. It simply might be the case that Gwaihir has more information to tell than Vanyar, but this is unlikely. From what I remember we already know that these packets contain the strings (or better said the number of the string in a large list of strings known to the client) the client will display during the startup.