#define _GNU_SOURCE #include #include #define WIN32_LEAN_AND_MEAN #include #include "npifc.h" #include "rest.h" tir_signature_t ts; HMODULE npclient; /* typedef int (*NP_RegisterWindowHandle_t)(HWND hwnd); typedef int (*NP_UnregisterWindowHandle_t)(void); typedef int (*NP_RegisterProgramProfileID_t)(unsigned short id); typedef int (*NP_QueryVersion_t)(unsigned short *version); typedef int (*NP_RequestData_t)(unsigned short req); typedef int (*NP_GetSignature_t)(tir_signature_t *sig); typedef int (*NP_GetData_t)(tir_data_t *data); typedef int (*NP_GetParameter_t)(void); typedef int (*NP_SetParameter_t)(void); typedef int (*NP_StartCursor_t)(void); typedef int (*NP_StopCursor_t)(void); typedef int (*NP_ReCenter_t)(void); typedef int (*NP_StartDataTransmission_t)(void); typedef int (*NP_StopDataTransmission_t)(void); */ NP_RegisterWindowHandle_t NP_RegisterWindowHandle = NULL; NP_UnregisterWindowHandle_t NP_UnregisterWindowHandle = NULL; NP_RegisterProgramProfileID_t NP_RegisterProgramProfileID = NULL; NP_QueryVersion_t NP_QueryVersion = NULL; NP_RequestData_t NP_RequestData = NULL; NP_GetSignature_t NP_GetSignature = NULL; NP_GetData_t NP_GetData = NULL; NP_GetParameter_t NP_GetParameter = NULL; NP_SetParameter_t NP_SetParameter = NULL; NP_StartCursor_t NP_StartCursor = NULL; NP_StopCursor_t NP_StopCursor = NULL; NP_ReCenter_t NP_ReCenter = NULL; NP_StartDataTransmission_t NP_StartDataTransmission = NULL; NP_StopDataTransmission_t NP_StopDataTransmission = NULL; bool crypted = false; unsigned char table[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char *client_path() { HKEY hkey = 0; RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\NaturalPoint\\NATURALPOINT\\NPClient Location", 0, KEY_QUERY_VALUE, &hkey); if(!hkey){ printf("Can't open registry key\n"); return NULL; } BYTE path[1024]; DWORD buf_len = 1024; LONG result = RegQueryValueEx(hkey, "Path", NULL, NULL, path, &buf_len); char *full_path = NULL; int res = -1; if(result == ERROR_SUCCESS && buf_len > 0){ #ifdef FOR_WIN64 res = asprintf(&full_path, "%s/NPClient64.dll", path); #else res = asprintf(&full_path, "%s/NPClient.dll", path); #endif } RegCloseKey(hkey); if(res > 0){ return full_path; }else{ return NULL; } } bool initialized = false; bool npifc_init(HWND wnd, int id) { //table[] = {0xb3, 0x16, 0x36, 0xeb, 0xb9, 0x05, 0x4f, 0xa4}; game_desc_t gd; if(game_data_get_desc(id, &gd)){ crypted = gd.encrypted; if(gd.encrypted){ table[0] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8; table[1] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8; table[2] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8; table[3] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8; table[4] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8; table[5] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8; table[6] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8; table[7] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8; } } printf("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", table[0], table[1], table[2], table[3], table[4], table[5], table[6], table[7]); char *client = client_path(); if(client == NULL){ printf("Couldn't obtain client path!\n"); return false; } npclient = LoadLibrary(client); if(!npclient){ printf("Can't load client %s\n", client); return false; } NP_RegisterWindowHandle = (NP_RegisterWindowHandle_t)GetProcAddress(npclient, "NP_RegisterWindowHandle"); NP_UnregisterWindowHandle = (NP_UnregisterWindowHandle_t)GetProcAddress(npclient, "NP_UnregisterWindowHandle"); NP_RegisterProgramProfileID = (NP_RegisterProgramProfileID_t)GetProcAddress(npclient, "NP_RegisterProgramProfileID"); NP_QueryVersion = (NP_QueryVersion_t)GetProcAddress(npclient, "NP_QueryVersion"); NP_RequestData = (NP_RequestData_t)GetProcAddress(npclient, "NP_RequestData"); NP_GetSignature = (NP_GetSignature_t)GetProcAddress(npclient, "NP_GetSignature"); NP_GetData = (NP_GetData_t)GetProcAddress(npclient, "NP_GetData"); NP_GetParameter = (NP_GetParameter_t)GetProcAddress(npclient, "NP_GetParameter"); NP_SetParameter = (NP_SetParameter_t)GetProcAddress(npclient, "NP_SetParameter"); NP_StartCursor = (NP_StartCursor_t)GetProcAddress(npclient, "NP_StartCursor"); NP_StopCursor = (NP_StopCursor_t)GetProcAddress(npclient, "NP_StopCursor"); NP_ReCenter = (NP_ReCenter_t)GetProcAddress(npclient, "NP_ReCenter"); NP_StartDataTransmission = (NP_StartDataTransmission_t)GetProcAddress(npclient, "NP_StartDataTransmission"); NP_StopDataTransmission = (NP_StopDataTransmission_t)GetProcAddress(npclient, "NP_StopDataTransmission"); if((NP_RegisterWindowHandle == NULL) || (NP_UnregisterWindowHandle == NULL) || (NP_RegisterProgramProfileID == NULL) || (NP_QueryVersion == NULL) || (NP_RequestData == NULL) || (NP_GetSignature == NULL) || (NP_GetData == NULL) || (NP_GetParameter == NULL) || (NP_SetParameter == NULL) || (NP_StartCursor == NULL) || (NP_StopCursor == NULL) || (NP_ReCenter == NULL) || (NP_StartDataTransmission == NULL) || (NP_StopDataTransmission == NULL)){ printf("Couldn't bind all necessary functions!\n"); return false; } tir_signature_t sig; int res; if((res = NP_GetSignature(&sig)) != 0){ printf("Error retrieving signature! %d\n", res); return false; } printf("Dll Sig:%s\nApp Sig2:%s\n", sig.DllSignature, sig.AppSignature); NP_RegisterWindowHandle(wnd); if(NP_RegisterProgramProfileID(id) != 0){ printf("Couldn't register profile id!\n"); return false; } printf("Program profile registered!\n"); NP_RequestData(65535); NP_StopCursor(); NP_StartDataTransmission(); initialized = true; return true; } void npifc_close() { if(initialized){ NP_StopDataTransmission(); NP_StartCursor(); NP_UnregisterWindowHandle(); } initialized = false; } void c_encrypt(unsigned char buf[], unsigned int size, unsigned char code_table[], unsigned int table_size) { unsigned int table_ptr = 0; unsigned char var = 0x88; unsigned char tmp; if((size <= 0) || (table_size <= 0) || (buf == NULL) || (code_table == NULL)) return; do{ tmp = buf[--size]; buf[size] = tmp ^ code_table[table_ptr] ^ var; var += size + tmp; ++table_ptr; if(table_ptr >= table_size){ table_ptr -= table_size; } }while(size != 0); } void decrypt(unsigned char buf[], unsigned int size, unsigned char code_table[], unsigned int table_size) { unsigned int table_ptr = 0; unsigned char var = 0x88; unsigned char tmp; if((size <= 0) || (table_size <= 0) || (buf == NULL) || (code_table == NULL)){ return; } do{ tmp = buf[--size]; buf[size] = tmp ^ code_table[table_ptr] ^ var; var += size + buf[size]; ++table_ptr; if(table_ptr >= table_size){ table_ptr -= table_size; } }while(size != 0); } unsigned int cksum(unsigned char buf[], unsigned int size) { if((size == 0) || (buf == NULL)){ return 0; } int rounds = size >> 2; int rem = size % 4; int c = size; int a0 = 0; int a2 = 0; while(rounds != 0){ a0 = *(short int*)buf; a2 = *(short int*)(buf+2); buf += 4; c += a0; a2 ^= (c << 5); a2 <<= 11; c ^= a2; c += (c >> 11); --rounds; } switch(rem){ case 3: a0 = *(short int*)buf; a2 = *(signed char*)(buf+2); c += a0; a2 = (a2 << 2) ^ c; c ^= (a2 << 16); a2 = (c >> 11); break; case 2: a2 = *(short int*)buf; c += a2; c ^= (c << 11); a2 = (c >> 17); break; case 1: a2 = *(signed char*)(buf); c += a2; c ^= (c << 10); a2 = (c >> 1); break; default: break; } if(rem != 0){ c+=a2; } c ^= (c << 3); c += (c >> 5); c ^= (c << 4); c += (c >> 17); c ^= (c << 25); c += (c >> 6); return (unsigned int)c; } int decode_frame(tir_data_t *td) { //printf("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", // table[0], table[1], table[2], table[3], // table[4], table[5], table[6], table[7]); unsigned int csum; decrypt((unsigned char*)td, sizeof(*td), table, sizeof(table)); csum = td->cksum; td->cksum = 0; if(csum != cksum((unsigned char*)td, sizeof(*td))){ printf("Problem with frame!\n"); //int a0; //printf("Dec: "); //for(a0 = 0; a0 < (int)sizeof(tir_data_t); ++a0) //{ // printf("%02X", ((unsigned char *)td)[a0]); //} //printf("\n"); //printf("Cksum: %04X vs computed: %04X\n", csum, cksum((unsigned char*)td, sizeof(*td))); return -1; } //printf("Frame OK!\n"); return 0; } int npifc_getdata(tir_data_t *data) { int res = NP_GetData(data); if(crypted){ decode_frame(data); } return res; }