Jump to content

(Update for 4.0.3)tiawps patch for 4.0.x, for helping research opcodes


Recommended Posts

Posted

Hi, I've made a rough patch for tiawps (https://github.com/arrai/tiawps), to decrypt 4.0.x wow sniff data.

4.0.3 CONNECTION_PTR_OFFSET is 0xCB2F8C, session key offset is still 1288.

4.0.1 CONNECTION_PTR_OFFSET is 0xCA5C34, session key offset is still 1288.

Update:

2010-11-10: Now handling SMSG_REDIRECT_CLIENT

2010-11-23: Update for 4.0.3

Patch for 4.0.3 (for git master branch)

patch for reader 4.0.3:

diff --git a/src/reader/reader.bat b/src/reader/reader.bat
index 7f8177e..58b125e
--- a/src/reader/reader.bat
+++ b/src/reader/reader.bat
@@ -1,5 +1,6 @@
@echo off
-echo "Tiawps sessionkey reader Build 12340 3.3.5"
+echo "Tiawps sessionkey reader Build 13287 4.0.3"

SET PATH=%~dp0
REM Switch to drive
@@ -7,5 +8,7 @@ REM Switch to drive

cd %PATH%

-tiawps_reader.exe 13081844 1288
+rem CONNECTION_PTR_OFFSET = 0xCB2F8C
+tiawps_reader.exe 13315980 1288
PAUSE

patch for decrypter 4.0.3:

diff --git a/src/decrypter/main.c b/src/decrypter/main.c
old mode 100644
new mode 100755
index 8bfe4ff..3f92af0
--- a/src/decrypter/main.c
+++ b/src/decrypter/main.c
@@ -4,6 +4,8 @@
#include <time.h>
#include <ctype.h>
#include <sqlite3.h>
+#include <openssl/bn.h>
+//#include <openssl/rsa.h>

#include "pcapreader.h"
#include "structs.h"
@@ -13,10 +15,14 @@
#define DEBUG               0

                                // SIZE  SIZE  CMD   CMD
-const uint8_t MAGIC_WOW_START[] = {0x00, 0x2A, 0xEC, 0x01};
+//const uint8_t MAGIC_WOW_START[] = {0x00, 0x2A, 0xEC, 0x01}; // 3.3.5
+//const uint8_t MAGIC_WOW_START[] = {0x00, 0x27, 0x00, 0x85}; // 4.0.1
+const uint8_t MAGIC_WOW_START[] = {0x00, 0x27, 0x00, 0x34}; // 4.0.3

static uint8_t SESSIONKEY[sESSION_KEY_LENGTH];

+static int merge_files = 0;
+
void readSessionkeyFile(const char* file)
{
    FILE *fp = fopen(file, "r");
@@ -385,6 +391,258 @@ void removeInvalidConnections()

struct tcp_connection *currentDecryptedConnection;

+static BIGNUM *my_BN_bin2bn(const uint8_t *s, int len, BIGNUM *ret)
+{
+    uint8_t tmp[1024] = {0};
+    for (int i = 0; i < len; i++)
+        tmp[i] = s[len-1-i];
+    return BN_bin2bn(tmp, len, ret);
+}
+
+static int my_BN_bn2bin(const BIGNUM *a, unsigned char *to)
+{
+    uint8_t tmp[1024] = {0};
+    int len = BN_bn2bin(a, tmp);
+    for (int i = 0; i < len; i++)
+        to[i] = tmp[len-1-i];
+    return len;
+}
+
+static int parse_SMSG_REDIRECT_CLIENT(const uint8_t *in, uint8_t *out)
+{
+    uint8_t b_e[] = { 0x01, 0x00, 0x01, 0x00 }; // public-key exp
+    uint8_t b_m[] = { // modulus
+        0x91, 0xD5, 0x9B, 0xB7, 0xD4, 0xE1, 0x83, 0xA5, 0x22, 0x2B, 0x5F, 0x38, 0xF4, 0xB8, 0x86, 0xFF,
+        0x32, 0x84, 0x38, 0x2D, 0x99, 0x38, 0x8F, 0xBA, 0xF3, 0xC9, 0x22, 0x5D, 0x51, 0x73, 0x1E, 0x28,
+        0x87, 0x24, 0x8F, 0xB5, 0xC9, 0xB0, 0x7C, 0x95, 0xD0, 0x6B, 0x5B, 0xF4, 0x94, 0xC5, 0x94, 0x9D,
+        0xFA, 0x6F, 0x47, 0x3A, 0xA3, 0x86, 0xC0, 0xA8, 0x37, 0xF3, 0x9B, 0xEF, 0x2F, 0xC1, 0xFB, 0xB3,
+        0xF4, 0x1C, 0x2B, 0x0E, 0xD3, 0x6D, 0x88, 0xBB, 0x02, 0xE0, 0x4E, 0x63, 0xFA, 0x76, 0xE3, 0x43,
+        0xF9, 0x01, 0xFD, 0x23, 0x5E, 0x6A, 0x0B, 0x14, 0xEC, 0x5E, 0x91, 0x34, 0x0D, 0x0B, 0x4F, 0xA3,
+        0x5A, 0x46, 0xC5, 0x5E, 0xDC, 0xB5, 0xCD, 0xC1, 0x47, 0x6B, 0x59, 0xCA, 0xFA, 0xA9, 0xBE, 0x24,
+        0x9F, 0xF5, 0x05, 0x6B, 0xBB, 0x67, 0x8B, 0xB7, 0xE4, 0x3A, 0x43, 0x00, 0x5C, 0x1C, 0xB7, 0xCA,
+        0x98, 0x90, 0x79, 0x77, 0x6D, 0x05, 0x4F, 0x83, 0xCC, 0xAC, 0x06, 0x2E, 0x50, 0x11, 0x87, 0x23,
+        0xD8, 0xA6, 0xF7, 0x6F, 0x7A, 0x59, 0x87, 0xA6, 0xDE, 0x5D, 0xD8, 0xEC, 0x44, 0xBE, 0x45, 0x31,
+        0x7F, 0x8A, 0xF0, 0x58, 0x89, 0x53, 0x74, 0xDF, 0xCC, 0xAD, 0x01, 0x24, 0xD8, 0x19, 0x65, 0x1C,
+        0x25, 0xD3, 0xE1, 0x6B, 0x8B, 0xDA, 0xFE, 0x1D, 0xA4, 0x2C, 0x8B, 0x25, 0xED, 0x7C, 0xFF, 0x6A,
+        0xE0, 0x63, 0xD0, 0x52, 0x20, 0x7E, 0x62, 0x49, 0xD2, 0xB3, 0x6B, 0xCC, 0x91, 0x69, 0xA5, 0x08,
+        0x8B, 0x69, 0x65, 0xFF, 0xB9, 0xC9, 0x17, 0x02, 0x5D, 0xD8, 0x8E, 0x1A, 0x63, 0xD9, 0x2A, 0x7F,
+        0xDB, 0xE3, 0xF8, 0x76, 0x6D, 0xEA, 0x0E, 0x36, 0x98, 0x78, 0x19, 0xC5, 0x87, 0xBA, 0x6C, 0x20,
+        0xB6, 0x08, 0x44, 0x04, 0x4C, 0xA8, 0xD5, 0xB6, 0x9D, 0x4D, 0x00, 0x20, 0x40, 0x00, 0x90, 0x04
+    };
+
+    // decrypt data (RSA-decrypt)
+    BIGNUM r, a, e, m;
+    BN_init(&r);
+    BN_init(&a);
+    BN_init(&e);
+    BN_init(&m);
+    my_BN_bin2bn(in, 256, &a);
+    my_BN_bin2bn(b_e, 4, &e);
+    my_BN_bin2bn(b_m, 256, &m);
+    BN_CTX *ctx = BN_CTX_new();
+    BN_mod_exp(&r, &a, &e, &m, ctx); //FIXME: use RSA-decrypt
+    BN_CTX_free(ctx);
+
+    uint8_t d_out[256] = {0};
+    int len = my_BN_bn2bin(&r, d_out);
+    printf("len = %d\\n", len);
+    if (len < 0)
+        return len;
+
+    // make data ordered
+    uint8_t *p = d_out;
+    memcpy(out+6, p, 1); p++;
+    memcpy(out+104, p, 1); p++;
+    memcpy(out+8, p, 1); p++;
+    memcpy(out+134, p, 2); p+=2;
+    memcpy(out+124, p, 1); p++;
+    memcpy(out+140, p, 2); p+=2;
+    memcpy(out+19, p, 1); p++;
+    memcpy(out+142, p, 2); p+=2;
+    memcpy(out+160, p, 2); p+=2;
+    memcpy(out+52, p, 1); p++;
+    memcpy(out, p, 1); p++;
+    memcpy(out+26, p, 1); p++;
+    memcpy(out+248, p, 1); p++;
+    memcpy(out+84, p, 1); p++;
+    memcpy(out+86, p, 1); p++;
+    memcpy(out+56, p, 1); p++;
+    memcpy(out+235, p, 1); p++;
+    memcpy(out+154, p, 2); p+=2;
+    memcpy(out+68, p, 1); p++;
+    memcpy(out+48, p, 1); p++;
+    memcpy(out+13, p, 1); p++;
+    memcpy(out+81, p, 1); p++;
+    memcpy(out+252, p, 2); p+=2;
+    memcpy(out+110, p, 1); p++;
+    memcpy(out+128, p, 1); p++;
+    memcpy(out+32, p, 1); p++;
+    memcpy(out+62, p, 1); p++;
+    memcpy(out+256, p, 4); p+=4;
+    memcpy(out+126, p, 1); p++;
+    memcpy(out+138, p, 2); p+=2;
+    memcpy(out+123, p, 1); p++;
+    memcpy(out+121, p, 1); p++;
+    memcpy(out+82, p, 1); p++;
+    memcpy(out+200, p, 4); p+=4;
+    memcpy(out+245, p, 1); p++;
+    memcpy(out+50, p, 1); p++;
+    memcpy(out+9, p, 1); p++;
+    memcpy(out+232, p, 1); p++;
+    memcpy(out+148, p, 2); p+=2;
+    memcpy(out+35, p, 1); p++;
+    memcpy(out+21, p, 1); p++;
+    memcpy(out+4, p, 1); p++;
+    memcpy(out+95, p, 1); p++;
+    memcpy(out+168, p, 4); p+=4;
+    memcpy(out+37, p, 1); p++;
+    memcpy(out+97, p, 1); p++;
+    memcpy(out+71, p, 1); p++;
+    memcpy(out+25, p, 1); p++;
+    memcpy(out+130, p, 2); p+=2;
+    memcpy(out+224, p, 4); p+=4;
+    memcpy(out+23, p, 1); p++;
+    memcpy(out+61, p, 1); p++;
+    memcpy(out+36, p, 1); p++;
+    memcpy(out+40, p, 1); p++;
+    memcpy(out+57, p, 1); p++;
+    memcpy(out+65, p, 1); p++;
+    memcpy(out+233, p, 1); p++;
+    memcpy(out+74, p, 1); p++;
+    memcpy(out+34, p, 1); p++;
+    memcpy(out+249, p, 1); p++;
+    memcpy(out+42, p, 1); p++;
+    memcpy(out+47, p, 1); p++;
+    memcpy(out+118, p, 1); p++;
+    memcpy(out+76, p, 1); p++;
+    memcpy(out+108, p, 1); p++;
+    memcpy(out+78, p, 1); p++;
+    memcpy(out+33, p, 1); p++;
+    memcpy(out+192, p, 4); p+=4;
+    memcpy(out+156, p, 2); p+=2;
+    memcpy(out+132, p, 2); p+=2;
+    memcpy(out+152, p, 2); p+=2;
+    memcpy(out+45, p, 1); p++;
+    memcpy(out+67, p, 1); p++;
+    memcpy(out+180, p, 4); p+=4;
+    memcpy(out+92, p, 1); p++;
+    memcpy(out+91, p, 1); p++;
+    memcpy(out+75, p, 1); p++;
+    memcpy(out+101, p, 1); p++;
+    memcpy(out+216, p, 4); p+=4;
+    memcpy(out+120, p, 1); p++;
+    memcpy(out+44, p, 1); p++;
+    memcpy(out+240, p, 1); p++;
+    memcpy(out+109, p, 1); p++;
+    memcpy(out+99, p, 1); p++;
+    memcpy(out+234, p, 1); p++;
+    memcpy(out+15, p, 1); p++;
+    memcpy(out+125, p, 1); p++;
+    memcpy(out+89, p, 1); p++;
+    memcpy(out+196, p, 4); p+=4;
+    memcpy(out+251, p, 1); p++;
+    memcpy(out+66, p, 1); p++;
+    memcpy(out+31, p, 1); p++;
+    memcpy(out+93, p, 1); p++;
+    memcpy(out+29, p, 1); p++;
+    memcpy(out+239, p, 1); p++;
+    memcpy(out+64, p, 1); p++;
+    memcpy(out+87, p, 1); p++;
+    memcpy(out+73, p, 1); p++;
+    memcpy(out+238, p, 1); p++;
+    memcpy(out+55, p, 1); p++;
+    memcpy(out+70, p, 1); p++;
+    memcpy(out+150, p, 2); p+=2;
+    memcpy(out+63, p, 1); p++;
+    memcpy(out+246, p, 1); p++;
+    memcpy(out+243, p, 1); p++;
+    memcpy(out+49, p, 1); p++;
+    memcpy(out+241, p, 1); p++;
+    memcpy(out+172, p, 4); p+=4;
+    memcpy(out+79, p, 1); p++;
+    memcpy(out+103, p, 1); p++;
+    memcpy(out+1, p, 1); p++;
+    memcpy(out+12, p, 1); p++;
+    memcpy(out+122, p, 1); p++;
+    memcpy(out+41, p, 1); p++;
+    memcpy(out+18, p, 1); p++;
+    memcpy(out+106, p, 1); p++;
+    memcpy(out+46, p, 1); p++;
+    memcpy(out+22, p, 1); p++;
+    memcpy(out+208, p, 4); p+=4;
+    memcpy(out+102, p, 1); p++;
+    memcpy(out+30, p, 1); p++;
+    memcpy(out+54, p, 1); p++;
+    memcpy(out+247, p, 1); p++;
+    memcpy(out+77, p, 1); p++;
+    memcpy(out+228, p, 4); p+=4;
+    memcpy(out+85, p, 1); p++;
+    memcpy(out+100, p, 1); p++;
+    memcpy(out+146, p, 2); p+=2;
+    memcpy(out+111, p, 1); p++;
+    memcpy(out+11, p, 1); p++;
+    memcpy(out+43, p, 1); p++;
+    memcpy(out+242, p, 1); p++;
+    memcpy(out+94, p, 1); p++;
+    memcpy(out+14, p, 1); p++;
+    memcpy(out+90, p, 1); p++;
+    memcpy(out+28, p, 1); p++;
+    memcpy(out+53, p, 1); p++;
+    memcpy(out+72, p, 1); p++;
+    memcpy(out+98, p, 1); p++;
+    memcpy(out+114, p, 1); p++;
+    memcpy(out+127, p, 1); p++;
+    memcpy(out+236, p, 1); p++;
+    memcpy(out+204, p, 4); p+=4;
+    memcpy(out+59, p, 1); p++;
+    memcpy(out+212, p, 4); p+=4;
+    memcpy(out+184, p, 4); p+=4;
+    memcpy(out+60, p, 1); p++;
+    memcpy(out+17, p, 1); p++;
+    memcpy(out+113, p, 1); p++;
+    memcpy(out+105, p, 1); p++;
+    memcpy(out+107, p, 1); p++;
+    memcpy(out+5, p, 1); p++;
+    memcpy(out+83, p, 1); p++;
+    memcpy(out+27, p, 1); p++;
+    memcpy(out+96, p, 1); p++;
+    memcpy(out+164, p, 4); p+=4;
+    memcpy(out+24, p, 1); p++;
+    memcpy(out+158, p, 2); p+=2;
+    memcpy(out+119, p, 1); p++;
+    memcpy(out+250, p, 1); p++;
+    memcpy(out+58, p, 1); p++;
+    memcpy(out+88, p, 1); p++;
+    memcpy(out+10, p, 1); p++;
+    memcpy(out+7, p, 1); p++;
+    memcpy(out+20, p, 1); p++;
+    memcpy(out+51, p, 1); p++;
+    memcpy(out+3, p, 1); p++;
+    memcpy(out+144, p, 2); p+=2;
+    memcpy(out+188, p, 4); p+=4;
+    memcpy(out+16, p, 1); p++;
+    memcpy(out+136, p, 2); p+=2;
+    memcpy(out+116, p, 1); p++;
+    memcpy(out+39, p, 1); p++;
+    memcpy(out+38, p, 1); p++;
+    memcpy(out+237, p, 1); p++;
+    memcpy(out+2, p, 1); p++;
+    memcpy(out+69, p, 1); p++;
+    memcpy(out+220, p, 4); p+=4;
+    memcpy(out+115, p, 1); p++;
+    memcpy(out+117, p, 1); p++;
+    memcpy(out+112, p, 1); p++;
+    memcpy(out+176, p, 4); p+=4;
+    memcpy(out+80, p, 1); p++;
+    memcpy(out+244, p, 1); p++;
+
+    // verify data
+    if (*(uint32_t*)(out+256) != 0x77177AB3)
+        return -1;
+
+    return len;
+}
+
void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, uint32_t data_len, void *db)
{
    insertPacket(s2c, time, opcode, data, data_len, db);
@@ -397,16 +655,24 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
    switch(opcode)
    {
        // forwarding connection
-        case 1293:
+        case 0x9000:// 0x8400(4.0.1) //SMSG_REDIRECT_CLIENT //1293:
        {
-            const uint32_t expected_size = 4+2+4+20;
+            const uint32_t expected_size = 1+256+4+8; //4+2+4+20;
            if(data_len != expected_size)
            {
-                printf("WARNING: packet 1293 is %u bytes long, but we expected %u\\n", data_len, expected_size);
+                printf("WARNING: packet SMSG_REDIRECT_CLIENT is %u bytes long, but we expected %u\\n", data_len, expected_size);
                return;
            }
-            uint32_t fwd_addr = *(data)<<24 | *(data+1)<<16 | *(data+2) << 8 | *(data+3);
-            uint16_t fwd_port = ntohs(*((uint16_t*)(data+4)));
+            uint8_t ordered_data[256] = {0};
+            if (parse_SMSG_REDIRECT_CLIENT(data+1, ordered_data) < 0)
+            {
+                printf("WARNING: decrypt/parse packet SMSG_REDIRECT_CLIENT fail\\n");
+                break;
+            }
+            //uint32_t fwd_addr = *(data)<<24 | *(data+1)<<16 | *(data+2) << 8 | *(data+3);
+            //uint16_t fwd_port = ntohs(*((uint16_t*)(data+4)));
+            uint32_t fwd_addr = ntohl(*((uint32_t*)(ordered_data+164)));
+            uint16_t fwd_port = ntohs(*((uint16_t*)(ordered_data+252)));
            // find the connection
            for(uint32_t i=0; i<connection_count; ++i)
            {
@@ -416,6 +682,7 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
                {
                    printf("Set connection forwarding bit on %s:%u\\n", addrToStr(fwd_addr), ntohs(fwd_port));
                    connection->forwarded = 1;
+                    currentDecryptedConnection->forwarded = 2;
                    return;
                }
            }
@@ -427,6 +694,7 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,

void decrypt()
{
+    sqlite3 *db=NULL;
    for(uint32_t i=0; i<connection_count; ++i)
    {
        struct tcp_connection *connection = connections[i];
@@ -442,8 +710,8 @@ void decrypt()
        struct tm* timestruct = localtime(&time);
        strftime (filename, sizeof(filename), format, timestruct);

-        sqlite3 *db=NULL;
-        initDatabase(filename, &db);
+        if(!merge_files || (merge_files && !connection->forwarded))
+            initDatabase(filename, &db);

        struct decryption_state client_state, server_state;
        uint8_t custom_serverseed[16];
@@ -451,11 +719,11 @@ void decrypt()

        if(connection->forwarded)
        {
-            const uint32_t expected_size = 2+2*4+2*16;
+            const uint32_t expected_size = 2+4+1+2*16;//2+2*4+2*16;
            uint8_t* data = connection->to.data.buffer;
            uint32_t size = data[0]<<8 | data[1];
            uint32_t opcode = data[3]<<8 | data[2];
-            if(opcode != 492)
+            if(opcode != 0x3400) // 8500(4.0.1) //SMSG_AUTH_CHALLENGE //492)
            {
                printf("WARNING: first packet in stream is not 492 but %u\\n", opcode);
                continue;
@@ -465,12 +733,22 @@ void decrypt()
                printf("WARNING: packet 492 is %u bytes long, but we expected %u\\n", size, expected_size);
                continue;
            }
-            memcpy(custom_serverseed, data+4+2*4, 16);
-            memcpy(custom_clientseed, data+4+2*4+16, 16);
+            //memcpy(custom_serverseed, data+4+2*4, 16);
+            //memcpy(custom_clientseed, data+4+2*4+16, 16);
+            memcpy(custom_serverseed+0*4, data+4+3*4, 4);
+            memcpy(custom_serverseed+1*4, data+4+6*4+1, 4);
+            memcpy(custom_serverseed+2*4, data+4+8*4+1, 4);
+            memcpy(custom_serverseed+3*4, data+4+5*4+1, 4);
+            memcpy(custom_clientseed+0*4, data+4+0*4, 4);
+            memcpy(custom_clientseed+1*4, data+4+7*4+1, 4);
+            memcpy(custom_clientseed+2*4, data+4+4*4+1, 4);
+            memcpy(custom_clientseed+3*4, data+4+1*4, 4);
            printf("Using custom seeds for forwarded connection\\n");

            init_decryption_state_server(&server_state, SESSIONKEY, custom_serverseed);
            init_decryption_state_client(&client_state, SESSIONKEY, custom_clientseed);
+
+            connection->forwarded = 0;
        }
        else
        {
@@ -514,7 +792,8 @@ void decrypt()
            }
            update_decryption(nextState, participant->timeinfo.info[ti_counter].epoch_micro, data, datalen, db, decryptCallback);
        }
-        freeDatabase(&db);
+        if(!merge_files || (merge_files && !connection->forwarded))
+            freeDatabase(&db);

        free_decryption_state(&server_state);
        free_decryption_state(&client_state);
@@ -524,20 +803,28 @@ void decrypt()

int main(int argc, char *argv[])
{
-    if(argc != 3)
+    if(argc < 3)
    {
-        printf("Usage: %s $dumpfile.cap $keyfile.txt\\n", argv[0]);
+        printf("Usage: %s [-m] $dumpfile.cap $keyfile.txt\\n", argv[0]);
+        printf("                [-m] merge output files\\n");
        return 1;
    }
    char* pcapFile = argv[1];
    char* keyFile = argv[2];
+    if (!strcmp(argv[1], "-m"))
+    {
+        merge_files = 1;
+        pcapFile = argv[2];
+        keyFile = argv[3];
+    }

    // maybe switched arguments?
    char* magicKeyfileEnd = "txt";
    if(strlen(keyFile) >= 3 && memcmp(keyFile+strlen(keyFile)-3, magicKeyfileEnd, 3))
    {
-        pcapFile = argv[2];
-        keyFile = argv[1];
+        char *temp = pcapFile;
+        pcapFile = keyFile;
+        keyFile = temp;
    }

    readSessionkeyFile(keyFile);
diff --git a/src/decrypter/sqliteout.c b/src/decrypter/sqliteout.c
old mode 100644
new mode 100755
index cc75c05..2fcd4f4
--- a/src/decrypter/sqliteout.c
+++ b/src/decrypter/sqliteout.c
@@ -47,7 +47,8 @@ void insertClientBuild(uint8_t *data, uint32_t data_len, sqlite3 *db)
        printf("FATAL: got a packet with opcode = 493 = CMSG_AUTH_SESSION but payload len=%u < 4\\n", data_len);
        exit(1);
    }
-    uint32_t *clientBuild = (uint32_t*)data;
+    //uint32_t *clientBuild = (uint32_t*)data;
+    uint16_t *clientBuild = (uint16_t*)(data+2*1);

    const char* insertFormat = "insert into header values ('clientBuild', %u)";
    uint32_t allocSize = strlen(insertFormat)+10 /*uint32*/;
@@ -60,6 +61,19 @@ void insertClientBuild(uint8_t *data, uint32_t data_len, sqlite3 *db)
    sprintf(buffer, insertFormat, *clientBuild);
    executeSql(db, buffer);
    free(buffer);
+
+    // make sniffitzt happy
+    char sql[512];
+    sprintf(sql, "insert into header values ('clientLang', '%s')", "");
+    executeSql(db, sql);
+    sprintf(sql, "insert into header values ('accountName', '%s')", (char*)(data+22*1+1*2+1*8+5*4));
+    executeSql(db, sql);
+    sprintf(sql, "insert into header values ('realmName', '%s')", "");
+    executeSql(db, sql);
+    sprintf(sql, "insert into header values ('realmServer', '%s')", "");
+    executeSql(db, sql);
+    sprintf(sql, "insert into header values ('snifferVersion', '%s')", "");
+    executeSql(db, sql);    
}

void insertPacket(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, uint32_t data_len, void* arg)
@@ -83,7 +97,7 @@ void insertPacket(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, ui

    free(queryBuffer);

-    if(opcode == 493)
+    if(opcode == 0x880a) // 0x3000(4.0.1) //CMSG_AUTH_SESSION //493(3.3.5))
        insertClientBuild(data, data_len, db);
}

Patch for 4.0.1 (already in git cata branch)

BTW:

SMSG_AUTH_CHALLENGE = 0x8500 (4.0.1)
{
   uint32 ClientKey_part3;
   uint32 ServerKey_part1;
   uint8  unk;
   uint32 Seed;
   uint32 ServerKey_part3;
   uint32 ServerKey_part2;
   uint32 ClientKey_part1;
   uint32 ClientKey_part2;
   uint32 ServerKey_part4;
   uint32 ClientKey_part4;
}

patch for reader 4.0.1:

diff --git a/src/reader/reader.bat b/src/reader/reader.bat
index 7f8177e..58b125e
--- a/src/reader/reader.bat
+++ b/src/reader/reader.bat
@@ -1,5 +1,6 @@
@echo off
-echo "Tiawps sessionkey reader Build 12340 3.3.5"
+rem echo "Tiawps sessionkey reader Build 12340 3.3.5"
+echo "Tiawps sessionkey reader Build 13205 4.0.1"

SET PATH=%~dp0
REM Switch to drive
@@ -7,5 +8,7 @@ REM Switch to drive

cd %PATH%

-tiawps_reader.exe 13081844 1288
+rem tiawps_reader.exe 13081844 1288
+rem CONNECTION_PTR_OFFSET = 0xCA5C34
+tiawps_reader.exe 13261876 1288
PAUSE

patch for decrypter 4.0.1:

diff --git a/src/decrypter/main.c b/src/decrypter/main.c
old mode 100644
new mode 100755
index 228a7bc..b59e0e7
--- a/src/decrypter/main.c
+++ b/src/decrypter/main.c
@@ -4,6 +4,8 @@
#include <time.h>
#include <ctype.h>
#include <sqlite3.h>
+#include <openssl/bn.h>
+//#include <openssl/rsa.h>

#include "pcapreader.h"
#include "structs.h"
@@ -13,10 +15,13 @@
#define DEBUG               0

                                // SIZE  SIZE  CMD   CMD
-const uint8_t MAGIC_WOW_START[] = {0x00, 0x2A, 0xEC, 0x01};
+//const uint8_t MAGIC_WOW_START[] = {0x00, 0x2A, 0xEC, 0x01};
+const uint8_t MAGIC_WOW_START[] = {0x00, 0x27, 0x00, 0x85};

static uint8_t SESSIONKEY[sESSION_KEY_LENGTH];

+static int merge_files = 0;
+
void readSessionkeyFile(const char* file)
{
    FILE *fp = fopen(file, "r");
@@ -385,6 +390,257 @@ void removeInvalidConnections()

struct tcp_connection *currentDecryptedConnection;

+static BIGNUM *my_BN_bin2bn(const uint8_t *s, int len, BIGNUM *ret)
+{
+    uint8_t tmp[1024] = {0};
+    for (int i = 0; i < len; i++)
+        tmp[i] = s[len-1-i];
+    return BN_bin2bn(tmp, len, ret);
+}
+
+static int my_BN_bn2bin(const BIGNUM *a, unsigned char *to)
+{
+    uint8_t tmp[1024] = {0};
+    int len = BN_bn2bin(a, tmp);
+    for (int i = 0; i < len; i++)
+        to[i] = tmp[len-1-i];
+    return len;
+}
+
+static int parse_SMSG_REDIRECT_CLIENT(const uint8_t *in, uint8_t *out)
+{
+    uint8_t b_e[] = { 0x01, 0x00, 0x01, 0x00 }; // private-key exp
+    uint8_t b_m[] = { // modulus
+        0x91, 0xD5, 0x9B, 0xB7, 0xD4, 0xE1, 0x83, 0xA5, 0x22, 0x2B, 0x5F, 0x38, 0xF4, 0xB8, 0x86, 0xFF,
+        0x32, 0x84, 0x38, 0x2D, 0x99, 0x38, 0x8F, 0xBA, 0xF3, 0xC9, 0x22, 0x5D, 0x51, 0x73, 0x1E, 0x28,
+        0x87, 0x24, 0x8F, 0xB5, 0xC9, 0xB0, 0x7C, 0x95, 0xD0, 0x6B, 0x5B, 0xF4, 0x94, 0xC5, 0x94, 0x9D,
+        0xFA, 0x6F, 0x47, 0x3A, 0xA3, 0x86, 0xC0, 0xA8, 0x37, 0xF3, 0x9B, 0xEF, 0x2F, 0xC1, 0xFB, 0xB3,
+        0xF4, 0x1C, 0x2B, 0x0E, 0xD3, 0x6D, 0x88, 0xBB, 0x02, 0xE0, 0x4E, 0x63, 0xFA, 0x76, 0xE3, 0x43,
+        0xF9, 0x01, 0xFD, 0x23, 0x5E, 0x6A, 0x0B, 0x14, 0xEC, 0x5E, 0x91, 0x34, 0x0D, 0x0B, 0x4F, 0xA3,
+        0x5A, 0x46, 0xC5, 0x5E, 0xDC, 0xB5, 0xCD, 0xC1, 0x47, 0x6B, 0x59, 0xCA, 0xFA, 0xA9, 0xBE, 0x24,
+        0x9F, 0xF5, 0x05, 0x6B, 0xBB, 0x67, 0x8B, 0xB7, 0xE4, 0x3A, 0x43, 0x00, 0x5C, 0x1C, 0xB7, 0xCA,
+        0x98, 0x90, 0x79, 0x77, 0x6D, 0x05, 0x4F, 0x83, 0xCC, 0xAC, 0x06, 0x2E, 0x50, 0x11, 0x87, 0x23,
+        0xD8, 0xA6, 0xF7, 0x6F, 0x7A, 0x59, 0x87, 0xA6, 0xDE, 0x5D, 0xD8, 0xEC, 0x44, 0xBE, 0x45, 0x31,
+        0x7F, 0x8A, 0xF0, 0x58, 0x89, 0x53, 0x74, 0xDF, 0xCC, 0xAD, 0x01, 0x24, 0xD8, 0x19, 0x65, 0x1C,
+        0x25, 0xD3, 0xE1, 0x6B, 0x8B, 0xDA, 0xFE, 0x1D, 0xA4, 0x2C, 0x8B, 0x25, 0xED, 0x7C, 0xFF, 0x6A,
+        0xE0, 0x63, 0xD0, 0x52, 0x20, 0x7E, 0x62, 0x49, 0xD2, 0xB3, 0x6B, 0xCC, 0x91, 0x69, 0xA5, 0x08,
+        0x8B, 0x69, 0x65, 0xFF, 0xB9, 0xC9, 0x17, 0x02, 0x5D, 0xD8, 0x8E, 0x1A, 0x63, 0xD9, 0x2A, 0x7F,
+        0xDB, 0xE3, 0xF8, 0x76, 0x6D, 0xEA, 0x0E, 0x36, 0x98, 0x78, 0x19, 0xC5, 0x87, 0xBA, 0x6C, 0x20,
+        0xB6, 0x08, 0x44, 0x04, 0x4C, 0xA8, 0xD5, 0xB6, 0x9D, 0x4D, 0x00, 0x20, 0x40, 0x00, 0x90, 0x04
+    };
+
+    // decrypt data (RSA-decrypt)
+    BIGNUM r, a, e, m;
+    BN_init(&r);
+    BN_init(&a);
+    BN_init(&e);
+    BN_init(&m);
+    my_BN_bin2bn(in, 256, &a);
+    my_BN_bin2bn(b_e, 4, &e);
+    my_BN_bin2bn(b_m, 256, &m);
+    BN_CTX *ctx = BN_CTX_new();
+    BN_mod_exp(&r, &a, &e, &m, ctx); //FIXME: use RSA-decrypt
+    BN_CTX_free(ctx);
+
+    uint8_t d_out[256] = {0};
+    int len = my_BN_bn2bin(&r, d_out);
+    if (len < 0)
+        return len;
+
+    // make data ordered
+    uint8_t *p = d_out;
+    memcpy(out+89, p, 1); p++;
+    memcpy(out+94, p, 1); p++;
+    memcpy(out+151, p, 1); p++;
+    memcpy(out+159, p, 1); p++;
+    memcpy(out+155, p, 1); p++;
+    memcpy(out+118, p, 1); p++;
+    memcpy(out+46, p, 2); p+=2;
+    memcpy(out+129, p, 1); p++;
+    memcpy(out+127, p, 1); p++;
+    memcpy(out+44, p, 2); p+=2;
+    memcpy(out+32, p, 2); p+=2;
+    memcpy(out+157, p, 1); p++;
+    memcpy(out+164, p, 1); p++;
+    memcpy(out+134, p, 1); p++;
+    memcpy(out+124, p, 1); p++;
+    memcpy(out+83, p, 1); p++;
+    memcpy(out+122, p, 1); p++;
+    memcpy(out+96, p, 1); p++;
+    memcpy(out+71, p, 1); p++;
+    memcpy(out+50, p, 2); p+=2;
+    memcpy(out+17, p, 1); p++;
+    memcpy(out+4, p, 1); p++;
+    memcpy(out+132, p, 1); p++;
+    memcpy(out+112, p, 1); p++;
+    memcpy(out+156, p, 1); p++;
+    memcpy(out+220, p, 4); p+=4;
+    memcpy(out+59, p, 1); p++;
+    memcpy(out+72, p, 1); p++;
+    memcpy(out+130, p, 1); p++;
+    memcpy(out+182, p, 1); p++;
+    memcpy(out+154, p, 1); p++;
+    memcpy(out+138, p, 1); p++;
+    memcpy(out+61, p, 1); p++;
+    memcpy(out+166, p, 1); p++;
+    memcpy(out+139, p, 1); p++;
+    memcpy(out+186, p, 1); p++;
+    memcpy(out+10, p, 1); p++;
+    memcpy(out+137, p, 1); p++;
+    memcpy(out+68, p, 1); p++;
+    memcpy(out+36, p, 2); p+=2;
+    memcpy(out+115, p, 1); p++;
+    memcpy(out+87, p, 1); p++;
+    memcpy(out+175, p, 1); p++;
+    memcpy(out+172, p, 1); p++;
+    memcpy(out+252, p, 4); p+=4;
+    memcpy(out+16, p, 1); p++;
+    memcpy(out+88, p, 1); p++;
+    memcpy(out+248, p, 4); p+=4;
+    memcpy(out+180, p, 1); p++;
+    memcpy(out+18, p, 1); p++;
+    memcpy(out+78, p, 1); p++;
+    memcpy(out+11, p, 1); p++;
+    memcpy(out+24, p, 2); p+=2;
+    memcpy(out+162, p, 1); p++;
+    memcpy(out+204, p, 4); p+=4;
+    memcpy(out+54, p, 2); p+=2;
+    memcpy(out+125, p, 1); p++;
+    memcpy(out+98, p, 1); p++;
+    memcpy(out+102, p, 1); p++;
+    memcpy(out+114, p, 1); p++;
+    memcpy(out+216, p, 4); p+=4;
+    memcpy(out+20, p, 1); p++;
+    memcpy(out+136, p, 1); p++;
+    memcpy(out+116, p, 1); p++;
+    memcpy(out+185, p, 1); p++;
+    memcpy(out+224, p, 4); p+=4;
+    memcpy(out+146, p, 1); p++;
+    memcpy(out+109, p, 1); p++;
+    memcpy(out+106, p, 1); p++;
+    memcpy(out+244, p, 4); p+=4;
+    memcpy(out+135, p, 1); p++;
+    memcpy(out+62, p, 1); p++;
+    memcpy(out+60, p, 1); p++;
+    memcpy(out+84, p, 1); p++;
+    memcpy(out+91, p, 1); p++;
+    memcpy(out+48, p, 2); p+=2;
+    memcpy(out+144, p, 1); p++;
+    memcpy(out+108, p, 1); p++;
+    memcpy(out+63, p, 1); p++;
+    memcpy(out+121, p, 1); p++;
+    memcpy(out+145, p, 1); p++;
+    memcpy(out+19, p, 1); p++;
+    memcpy(out+13, p, 1); p++;
+    memcpy(out+12, p, 1); p++;
+    memcpy(out+52, p, 2); p+=2;
+    memcpy(out+6, p, 1); p++;
+    memcpy(out+74, p, 1); p++;
+    memcpy(out+176, p, 1); p++;
+    memcpy(out+69, p, 1); p++;
+    memcpy(out+5, p, 1); p++;
+    memcpy(out+99, p, 1); p++;
+    memcpy(out+97, p, 1); p++;
+    memcpy(out+14, p, 1); p++;
+    memcpy(out+140, p, 1); p++;
+    memcpy(out+177, p, 1); p++;
+    memcpy(out+149, p, 1); p++;
+    memcpy(out+101, p, 1); p++;
+    memcpy(out+107, p, 1); p++;
+    memcpy(out+228, p, 4); p+=4;
+    memcpy(out+82, p, 1); p++;
+    memcpy(out+184, p, 1); p++;
+    memcpy(out+119, p, 1); p++;
+    memcpy(out+158, p, 1); p++;
+    memcpy(out+143, p, 1); p++;
+    memcpy(out+196, p, 4); p+=4;
+    memcpy(out+86, p, 1); p++;
+    memcpy(out+38, p, 2); p+=2;
+    memcpy(out+142, p, 1); p++;
+    memcpy(out+240, p, 4); p+=4;
+    memcpy(out+104, p, 1); p++;
+    memcpy(out+77, p, 1); p++;
+    memcpy(out+168, p, 1); p++;
+    memcpy(out+150, p, 1); p++;
+    memcpy(out+9, p, 1); p++;
+    memcpy(out+22, p, 1); p++;
+    memcpy(out+7, p, 1); p++;
+    memcpy(out+95, p, 1); p++;
+    memcpy(out+110, p, 1); p++;
+    memcpy(out+34, p, 2); p+=2;
+    memcpy(out+161, p, 1); p++;
+    memcpy(out+117, p, 1); p++;
+    memcpy(out+141, p, 1); p++;
+    memcpy(out+111, p, 1); p++;
+    memcpy(out+212, p, 4); p+=4;
+    memcpy(out+179, p, 1); p++;
+    memcpy(out+200, p, 4); p+=4;
+    memcpy(out+147, p, 1); p++;
+    memcpy(out+66, p, 1); p++;
+    memcpy(out+70, p, 1); p++;
+    memcpy(out+67, p, 1); p++;
+    memcpy(out+100, p, 1); p++;
+    memcpy(out+128, p, 1); p++;
+    memcpy(out+133, p, 1); p++;
+    memcpy(out+28, p, 2); p+=2;
+    memcpy(out+15, p, 1); p++;
+    memcpy(out+188, p, 4); p+=4;
+    memcpy(out, p, 4); p+=4;
+    memcpy(out+165, p, 1); p++;
+    memcpy(out+169, p, 1); p++;
+    memcpy(out+76, p, 1); p++;
+    memcpy(out+65, p, 1); p++;
+    memcpy(out+163, p, 1); p++;
+    memcpy(out+85, p, 1); p++;
+    memcpy(out+148, p, 1); p++;
+    memcpy(out+23, p, 1); p++;
+    memcpy(out+208, p, 4); p+=4;
+    memcpy(out+183, p, 1); p++;
+    memcpy(out+56, p, 2); p+=2;
+    memcpy(out+73, p, 1); p++;
+    memcpy(out+21, p, 1); p++;
+    memcpy(out+120, p, 1); p++;
+    memcpy(out+152, p, 1); p++;
+    memcpy(out+113, p, 1); p++;
+    memcpy(out+232, p, 4); p+=4;
+    memcpy(out+170, p, 1); p++;
+    memcpy(out+64, p, 1); p++;
+    memcpy(out+81, p, 1); p++;
+    memcpy(out+80, p, 1); p++;
+    memcpy(out+123, p, 1); p++;
+    memcpy(out+8, p, 1); p++;
+    memcpy(out+79, p, 1); p++;
+    memcpy(out+26, p, 2); p+=2;
+    memcpy(out+236, p, 4); p+=4;
+    memcpy(out+92, p, 1); p++;
+    memcpy(out+30, p, 2); p+=2;
+    memcpy(out+42, p, 2); p+=2;
+    memcpy(out+174, p, 1); p++;
+    memcpy(out+131, p, 1); p++;
+    memcpy(out+75, p, 1); p++;
+    memcpy(out+93, p, 1); p++;
+    memcpy(out+40, p, 2); p+=2;
+    memcpy(out+167, p, 1); p++;
+    memcpy(out+171, p, 1); p++;
+    memcpy(out+173, p, 1); p++;
+    memcpy(out+160, p, 1); p++;
+    memcpy(out+105, p, 1); p++;
+    memcpy(out+178, p, 1); p++;
+    memcpy(out+103, p, 1); p++;
+    memcpy(out+192, p, 4); p+=4;
+    memcpy(out+58, p, 1); p++;
+    memcpy(out+90, p, 1); p++;
+    memcpy(out+126, p, 1); p++;
+    memcpy(out+181, p, 1); p++;
+    memcpy(out+153, p, 1); p++;
+
+    // verify data
+    if (*(uint32_t*)out != 0x77177AB3)
+        return -1;
+
+    return len;
+}
+
void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, uint32_t data_len, void *db)
{
    insertPacket(s2c, time, opcode, data, data_len, db);
@@ -397,16 +653,24 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
    switch(opcode)
    {
        // forwarding connection
-        case 1293:
+        case 0x8400: //SMSG_REDIRECT_CLIENT //1293:
        {
-            const uint32_t expected_size = 4+2+4+20;
+            const uint32_t expected_size = 4+256+1; //4+2+4+20;
            if(data_len != expected_size)
            {
                printf("WARNING: packet 1293 is %u bytes long, but we expected %u\\n", data_len, expected_size);
                return;
            }
-            uint32_t fwd_addr = *(data)<<24 | *(data+1)<<16 | *(data+2) << 8 | *(data+3);
-            uint16_t fwd_port = ntohs(*((uint16_t*)(data+4)));
+            uint8_t ordered_data[256] = {0};
+            if (parse_SMSG_REDIRECT_CLIENT(data+4, ordered_data) < 0)
+            {
+                printf("WARNING: decrypt/parse packet SMSG_REDIRECT_CLIENT fail\\n");
+                break;
+            }
+            //uint32_t fwd_addr = *(data)<<24 | *(data+1)<<16 | *(data+2) << 8 | *(data+3);
+            //uint16_t fwd_port = ntohs(*((uint16_t*)(data+4)));
+            uint32_t fwd_addr = ntohl(*((uint32_t*)(ordered_data+252)));
+            uint16_t fwd_port = ntohs(*((uint16_t*)(ordered_data+24)));
            // find the connection
            for(uint32_t i=0; i<connection_count; ++i)
            {
@@ -416,6 +680,7 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
                {
                    printf("Set connection forwarding bit on %s:%u\\n", addrToStr(fwd_addr), ntohs(fwd_port));
                    connection->forwarded = 1;
+                    currentDecryptedConnection->forwarded = 2;
                    return;
                }
            }
@@ -427,6 +692,7 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,

void decrypt()
{
+    sqlite3 *db=NULL;
    for(uint32_t i=0; i<connection_count; ++i)
    {
        struct tcp_connection *connection = connections[i];
@@ -442,8 +708,8 @@ void decrypt()
        struct tm* timestruct = localtime(&time);
        strftime (filename, sizeof(filename), format, timestruct);

-        sqlite3 *db=NULL;
-        initDatabase(filename, &db);
+        if(!merge_files || (merge_files && !connection->forwarded))
+            initDatabase(filename, &db);

        struct decryption_state client_state, server_state;
        uint8_t custom_serverseed[16];
@@ -451,11 +717,11 @@ void decrypt()

        if(connection->forwarded)
        {
-            const uint32_t expected_size = 2+2*4+2*16;
+            const uint32_t expected_size = 2+4+1+2*16;//2+2*4+2*16;
            uint8_t* data = connection->to.data.buffer;
            uint32_t size = data[0]<<8 | data[1];
            uint32_t opcode = data[3]<<8 | data[2];
-            if(opcode != 492)
+            if(opcode != 0x8500) //SMSG_AUTH_CHALLENGE //492)
            {
                printf("WARNING: first packet in stream is not 492 but %u\\n", opcode);
                continue;
@@ -465,12 +731,22 @@ void decrypt()
                printf("WARNING: packet 492 is %u bytes long, but we expected %u\\n", size, expected_size);
                continue;
            }
-            memcpy(custom_serverseed, data+4+2*4, 16);
-            memcpy(custom_clientseed, data+4+2*4+16, 16);
+            //memcpy(custom_serverseed, data+4+2*4, 16);
+            //memcpy(custom_clientseed, data+4+2*4+16, 16);
+            memcpy(custom_serverseed+0*4, data+4+1*4, 4);
+            memcpy(custom_serverseed+1*4, data+4+4*4+1, 4);
+            memcpy(custom_serverseed+2*4, data+4+3*4+1, 4);
+            memcpy(custom_serverseed+3*4, data+4+7*4+1, 4);
+            memcpy(custom_clientseed+0*4, data+4+5*4+1, 4);
+            memcpy(custom_clientseed+1*4, data+4+6*4+1, 4);
+            memcpy(custom_clientseed+2*4, data+4+0*4, 4);
+            memcpy(custom_clientseed+3*4, data+4+8*4+1, 4);
            printf("Using custom seeds for forwarded connection\\n");

            init_decryption_state_server(&server_state, SESSIONKEY, custom_serverseed);
            init_decryption_state_client(&client_state, SESSIONKEY, custom_clientseed);
+
+            connection->forwarded = 0;
        }
        else
        {
@@ -514,7 +790,8 @@ void decrypt()
            }
            update_decryption(nextState, participant->timeinfo.info[ti_counter].epoch_micro, data, datalen, db, decryptCallback);
        }
-        freeDatabase(&db);
+        if(!merge_files || (merge_files && !connection->forwarded))
+            freeDatabase(&db);

        free_decryption_state(&server_state);
        free_decryption_state(&client_state);
@@ -524,20 +801,28 @@ void decrypt()

int main(int argc, char *argv[])
{
-    if(argc != 3)
+    if(argc < 3)
    {
-        printf("Usage: %s $dumpfile.cap $keyfile.txt\\n", argv[0]);
+        printf("Usage: %s [-m] $dumpfile.cap $keyfile.txt\\n", argv[0]);
+        printf("                [-m] merge output files\\n");
        return 1;
    }
    char* pcapFile = argv[1];
    char* keyFile = argv[2];
+    if (!strcmp(argv[1], "-m"))
+    {
+        merge_files = 1;
+        pcapFile = argv[2];
+        keyFile = argv[3];
+    }

    // maybe switched arguments?
    char* magicKeyfileEnd = "txt";
    if(strlen(keyFile) >= 3 && memcmp(keyFile+strlen(keyFile)-3, magicKeyfileEnd, 3))
    {
-        pcapFile = argv[2];
-        keyFile = argv[1];
+        char *temp = pcapFile;
+        pcapFile = keyFile;
+        keyFile = temp;
    }

    readSessionkeyFile(keyFile);
diff --git a/src/decrypter/sqliteout.c b/src/decrypter/sqliteout.c
index cc75c05..3a67983 100644
--- a/src/decrypter/sqliteout.c
+++ b/src/decrypter/sqliteout.c
@@ -60,6 +60,19 @@ void insertClientBuild(uint8_t *data, uint32_t data_len, sqlite3 *db)
    sprintf(buffer, insertFormat, *clientBuild);
    executeSql(db, buffer);
    free(buffer);
+
+    //FIXME make sniffitzt happy
+    char sql[512];
+    sprintf(sql, "insert into header values ('clientLang', '%s')", "");
+    executeSql(db, sql);
+    sprintf(sql, "insert into header values ('accountName', '%s')", (char*)(data+8));//FIXME
+    executeSql(db, sql);
+    sprintf(sql, "insert into header values ('realmName', '%s')", "");
+    executeSql(db, sql);
+    sprintf(sql, "insert into header values ('realmServer', '%s')", "");
+    executeSql(db, sql);
+    sprintf(sql, "insert into header values ('snifferVersion', '%s')", "");
+    executeSql(db, sql);    
}

void insertPacket(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, uint32_t data_len, void* arg)
@@ -83,7 +96,7 @@ void insertPacket(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, ui

    free(queryBuffer);

-    if(opcode == 493)
+    if(opcode == 0x3000) //CMSG_AUTH_SESSION //493)
        insertClientBuild(data, data_len, db);
}

Posted

Hello,

In this packet SMSG_REDIRECT_CLIENT @ offset 62 there is a string:

"We couldn't figure out anything that was funny enough to put here.

If you'd like, please make a suggestion for the next patch...

"

What is this for? encryption phrase?

Edit: Adding packet

18:22:20 id:000006 [s2C] SMSG_REDIRECT_CLIENT (33792 = 0x8400) len: 261
0000: 0b 00 00 00 b3 7a 17 77 8f e9 dd 7e a1 20 6f a7  |  .....zw...~. o.
0010: 5f 4e 2a 9d 22 20 dd b1 17 3b 10 b8 [u]5f 04[/u] 43 c9  |  _N*." ..;.._.C.
0020: 7a 2c f2 0b 01 b6 78 30 19 00 d5 ff 9f 8b c6 9b  |  z,....x0.......
0030: 51 da b0 3d 0d 98 38 bc 7a ea 12 41 de a5 57 65  |  Q..=..8.z..A..We
0040: 20 63 6f 75 6c 64 6e 27 74 20 66 69 67 75 72 65  |   couldn't figure
0050: 20 6f 75 74 20 61 6e 79 74 68 69 6e 67 20 74 68  |   out anything th
0060: 61 74 20 77 61 73 20 66 75 6e 6e 79 20 65 6e 6f  |  at was funny eno
0070: 75 67 68 20 74 6f 20 70 75 74 20 68 65 72 65 2e  |  ugh to put here.
0080: 0a 49 66 20 79 6f 75 27 64 20 6c 69 6b 65 2c 20  |  .If you'd like, 
0090: 70 6c 65 61 73 65 20 6d 61 6b 65 20 61 20 73 75  |  please make a su
00a0: 67 67 65 73 74 69 6f 6e 20 66 6f 72 20 74 68 65  |  ggestion for the
00b0: 20 6e 65 78 74 20 70 61 74 63 68 2e 2e 2e 0a 00  |   next patch.....
00c0: 47 f7 cb 44 b9 0e e1 8f 25 f2 a3 09 8d 84 8c dc  |  G..D....%.......
00d0: a2 25 46 b1 71 b0 d1 8c ae 64 ae 18 aa 91 17 b0  |  .%F.q....d....
00e0: eb 56 95 38 fa ea 2a d1 68 8a 05 8d 2a 57 a8 04  |  .V.8..*.h...*W..
00f0: a8 46 a9 ee 64 e8 d3 42 64 37 ea 0b e9 36 18 4f  |  .F..d..Bd7...6O
0100: [u]c3 0c ef 2e[/u] 00                                   |  .....

Underlined parts are port for first and IP address for the second.

Neo2003

Posted
hmm all of this is nice but we still dont know how to encrypt the data to be sent from the server -.-

We know it's not possible just because this packet is RSA encrypted with private part of the certificate and the client has obliviously the public one only.

Posted

yes i came to that conclusion after reading carefully the RSA crypt, even if we would reverse the formula using the only know key.

in the lkes of encrypt = (data ^ d) mod n;. where e was replaced with d -.-

hmm neo, another method that might work.

what if we use specific packets for each intended connection and redirect the ip using the hosts file? im sure any valid RSA packet previously sent by blizzard should not expire and still be valid each time is sent, right?, if it has a expiration data, then we are FCKD

  • 2 weeks later...
Posted
hmm neo2003, can u give me a 4.0.3 SMSG_REDIRECT packet encrypted and its matched IP and PORT please?, need one to try some stuff.

Update for 4.0.3 now.

  • 3 weeks later...
Posted
Hello,

In this packet SMSG_REDIRECT_CLIENT @ offset 62 there is a string:

"We couldn't figure out anything that was funny enough to put here.

If you'd like, please make a suggestion for the next patch...

"

What is this for? encryption phrase?

Edit: Adding packet

18:22:20 id:000006 [s2C] SMSG_REDIRECT_CLIENT (33792 = 0x8400) len: 261
0000: 0b 00 00 00 b3 7a 17 77 8f e9 dd 7e a1 20 6f a7  |  .....zw...~. o.
0010: 5f 4e 2a 9d 22 20 dd b1 17 3b 10 b8 [u]5f 04[/u] 43 c9  |  _N*." ..;.._.C.
0020: 7a 2c f2 0b 01 b6 78 30 19 00 d5 ff 9f 8b c6 9b  |  z,....x0.......
0030: 51 da b0 3d 0d 98 38 bc 7a ea 12 41 de a5 57 65  |  Q..=..8.z..A..We
0040: 20 63 6f 75 6c 64 6e 27 74 20 66 69 67 75 72 65  |   couldn't figure
0050: 20 6f 75 74 20 61 6e 79 74 68 69 6e 67 20 74 68  |   out anything th
0060: 61 74 20 77 61 73 20 66 75 6e 6e 79 20 65 6e 6f  |  at was funny eno
0070: 75 67 68 20 74 6f 20 70 75 74 20 68 65 72 65 2e  |  ugh to put here.
0080: 0a 49 66 20 79 6f 75 27 64 20 6c 69 6b 65 2c 20  |  .If you'd like, 
0090: 70 6c 65 61 73 65 20 6d 61 6b 65 20 61 20 73 75  |  please make a su
00a0: 67 67 65 73 74 69 6f 6e 20 66 6f 72 20 74 68 65  |  ggestion for the
00b0: 20 6e 65 78 74 20 70 61 74 63 68 2e 2e 2e 0a 00  |   next patch.....
00c0: 47 f7 cb 44 b9 0e e1 8f 25 f2 a3 09 8d 84 8c dc  |  G..D....%.......
00d0: a2 25 46 b1 71 b0 d1 8c ae 64 ae 18 aa 91 17 b0  |  .%F.q....d....
00e0: eb 56 95 38 fa ea 2a d1 68 8a 05 8d 2a 57 a8 04  |  .V.8..*.h...*W..
00f0: a8 46 a9 ee 64 e8 d3 42 64 37 ea 0b e9 36 18 4f  |  .F..d..Bd7...6O
0100: [u]c3 0c ef 2e[/u] 00                                   |  .....

Underlined parts are port for first and IP address for the second.

Neo2003

Blizzard is mocking us.

  • 2 weeks later...
Posted
Maybe an update for 4.0.3a (13329)

doesn't work with it

4.0.3a:

rem CONNECTION_PTR_OFFSET = 0xCB3F8C

tiawps_reader.exe 13320076 1288

it's 0xCB3F78 from what i can see in IDA.

Didn't test though, since i don't use Tiawps.

  • 2 months later...
  • 3 weeks later...
  • 1 month later...
Posted

Can one post a patch so that the session key reader works on Windows 7 with address randomization and have the offsets kept up-to date?

It's really not my cup of tea, I know nothing about memory reading and how to get the key offset.

Posted

The problem is that it is not work on Win7.

Got pointer: 0X10
couldn't read sessionkey, read 0 bytes instead of 40
reading sessionkey failed - will try again in 2 second

Posted
The problem is that it is not work on Win7.

Got pointer: 0X10
couldn't read sessionkey, read 0 bytes instead of 40
reading sessionkey failed - will try again in 2 second

It does work, you need to use it properly.

Posted

Thank you.

I will try to make the Reader compatible with ASLR with this.

I did not find a way to disable ASLR system wide on Windows 7 x64 and I don't want to risk my account by removing ASLR on wow.exe.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use