Jump to content

daveh

Members
  • Posts

    38
  • Joined

  • Last visited

    Never
  • Donations

    0.00 GBP 

About daveh

  • Birthday 01/01/1

daveh's Achievements

Advanced Member

Advanced Member (3/3)

0

Reputation

  1. Thank you, btw SMSG_AUTH_CHALLENGE is: struct SMSG_AUTH_CHALLENGE // Opcode: 0x8500 { 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; }
  2. 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); }
  3. Hi, any problem with this patch? It's such a big typo...
  4. * What bug does the patch fix? What features does the patch add? Server crashes on Linux at startup since 9170 * For which repository revision was the patch created? [9174] * Is there a thread in the bug report section or at lighthouse? If yes, please add a link to the thread. no. * Who has been writing this patch? Please include either forum user names or email addresses. daveh Patch: diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index ce4d88c..8923d99 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -186,7 +186,6 @@ static bool ReadDBCBuildFileText(const std::string& dbc_path, char const* locale { char buf[100]; fread(buf,1,100-1,file); - fclose(file); text = &buf[0]; fclose(file);
  5. * What bug does the patch fix? What features does the patch add? Hunter/Warlock summon a hunter/summon pet first, then can't summon a mini pet. * For which repository revision was the patch created? [9162] * Is there a thread in the bug report section or at lighthouse? If yes, please add a link to the thread. No * Who has been writing this patch? Please include either forum user names or email addresses. daveh Patch: diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index b082a09..318c4ee 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4759,6 +4759,8 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_ALREADY_HAVE_CHARM; } } + + break; } // Not used for summon? case SPELL_EFFECT_SUMMON_PHANTASM:
  6. Just found SMSG_SPELL_START and SMSG_SPELL_GO send unknown spell ID (not in Spell.dbc) in a offi server, while doing quest As the Crow Flies by using item Stormcrow Amulet: 1. When using item Stormcrow Amulet, it casts spell Stormcrow Amulet: 2. After sending spell Stormcrow Amulet, offi server sends some unknown spell IDs: How does this mean?
  7. Confirmed, mostly crash when player has pet and change map.
  8. Thanks. It confused sniffitzt btw...
  9. You sure the cache data is from offi server? And it's clean? I don't see level 0 in my clean WDB cache, they all are -1. And a quick search in wowhead.com show no level 0 quests: http://www.wowhead.com/?quests&filter=minle=0;maxle=0
  10. Didn't see "heal 0, overheal 698" in 3.1.3. 3.1.3 didn't send full overheal log to client, but 3.2.2a does. Sending full overheal log every 5s is really noisily, consider as a new 3.2.x blizz bug. So this problem is clear: mangos doesn't send overheal log to client for SPELL_AURA_OBS_MOD_HEALTH/SPELL_AURA_PERIODIC_HEAL. Anyway, the updated blizzlike patch: diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 2cf57a8..18179ea 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -6499,11 +6571,11 @@ void Aura::PeriodicTick() sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u", GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId()); - SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, 0, 0, 0.0f, isCrit); - m_target->SendPeriodicAuraLog(&pInfo); - int32 gain = m_target->ModifyHealth(pdamage); + SpellPeriodicAuraLogInfo pInfo(this, pdamage, pdamage-gain, 0, 0, 0.0f, isCrit); + m_target->SendPeriodicAuraLog(&pInfo); + // add HoTs to amount healed in bgs if( pCaster->GetTypeId() == TYPEID_PLAYER ) if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )
×
×
  • 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