uint32_t __stdcall crev_old(uint32_t padd, uint8_t archive_ver, uint8_t *seed, uint8_t *ini_file, uint8_t *ini_header, uint32_t *version, uint32_t *checksum, uint8_t *result){ uint64_t A = 0; uint64_t B = 0; uint64_t C = 0; uint32_t S = 0; uint32_t x = 0; uint32_t y = 0; uint32_t file_size = 0; uint8_t ops[4]; uint8_t *files[4]; uint8_t *buff = safe_malloc(MAX_PATH); const uint8_t *keys[] = {"Exe", "Util", "Network"}; const uint32_t seeds[] = {0xE7F4CB62, 0xF6A14FFC, 0xAA5504AF, 0x871FCDC2, 0x11BF6A18, 0xC57292E6, 0x7927D27E, 0x2FEC8733}; uint8_t *tok; uint8_t *tok_pos; //uint8_t *tmp = safe_malloc(MAX_PATH * 2); if(archive_ver > 7){ free(buff); return CREV_UNKNOWN_REVISION; } tok = strtok_s(seed, " ", &tok_pos); for(x = 0; x < 3; x++){ if(tok == NULL) return CREV_MALFORMED_SEED; if(tok[1] == '='){ if(tok[0] == 'A' || tok[0] == 'a') A = strtoul((uint8_t*)&tok[2], NULL, 10); if(tok[0] == 'B' || tok[0] == 'b') B = strtoul((uint8_t*)&tok[2], NULL, 10); if(tok[0] == 'C' || tok[0] == 'c') C = strtoul((uint8_t*)&tok[2], NULL, 10); }else{ return CREV_MALFORMED_SEED; } tok = strtok_s(NULL, " ", &tok_pos); } /* *sprintf_s(tmp, MAX_PATH * 2, "A: %lu\n", A); wwrite_to_file(tmp); *sprintf_s(tmp, MAX_PATH * 2, "B: %lu\n", B); wwrite_to_file(tmp); *sprintf_s(tmp, MAX_PATH * 2, "C: %lu\n", C); wwrite_to_file(tmp); */ tok = strtok_s(NULL, " ", &tok_pos); //Skip the '4' for(x = 0; x < 4; x++){ if(tok == NULL) return CREV_MALFORMED_SEED; ops[x] = tok[3]; tok[3] = '.'; switch(x){ case 0: if(_stricmp(tok, "A=A.S") != 0) return CREV_MALFORMED_SEED; break; case 1: if(_stricmp(tok, "B=B.C") != 0) return CREV_MALFORMED_SEED; break; case 2: if(_stricmp(tok, "C=C.A") != 0) return CREV_MALFORMED_SEED; break; case 3: if(_stricmp(tok, "A=A.B") != 0) return CREV_MALFORMED_SEED; break; } tok = strtok_s(NULL, " ", &tok_pos); } //sprintf_s(tmp, MAX_PATH * 2, "Ops: %c%c%c%c\n", ops[0], ops[1], ops[2], ops[3]); wwrite_to_file(tmp); read_ini_new(ini_file, ini_header, "Path", "", buff, MAX_PATH); files[0] = safe_malloc(MAX_PATH); combine_paths(buff, "", files[0], MAX_PATH); for(x = 1; x < 4; x++){ read_ini_new(ini_file, ini_header, (uint8_t*)keys[x-1], "\xFF", buff, MAX_PATH); if(buff[0] == 0xFF){ for(y = 0; y < x; y++) if(files[y] != NULL) free(files[y]); sprintf_s(result, crev_max_result(), "%s\x00", keys[x-1]); return CREV_MISSING_FILENAME; } if (_stricmp(buff, "NULL") == 0){ files[x] = NULL; }else{ files[x] = safe_malloc(MAX_PATH); combine_paths(files[0], buff, files[x], MAX_PATH); } } free(buff); /* *sprintf_s(tmp, MAX_PATH * 2, "Path: %s\n", files[0]); wwrite_to_file(tmp); *sprintf_s(tmp, MAX_PATH * 2, "Exe: %s %d\n", files[1], get_file_size(files[1])); wwrite_to_file(tmp); *sprintf_s(tmp, MAX_PATH * 2, "Util: %s %d\n", files[2], get_file_size(files[2])); wwrite_to_file(tmp); *sprintf_s(tmp, MAX_PATH * 2, "Network: %s %d\n", files[3], get_file_size(files[3])); wwrite_to_file(tmp); */ A ^= seeds[archive_ver]; for(x = 1; x < 4; x++){ if (files[x] == NULL){ continue; } file_size = get_file_size(files[x]); if((file_size % 1024) != 0){ if(padd == 1) file_size += (1024 - (file_size % 1024)); else file_size -= (file_size % 1024); } if(file_size == 0){ sprintf_s(result, CREV_MAX_RESULT, files[x]); return CREV_MISSING_FILE; } buff = safe_malloc(file_size); get_file_data(files[x], buff, file_size, padd); for(y = 0; y < file_size; y+= 4){ S = (*(uint32_t*)&buff[y]); switch (ops[0]) { case '^': A ^= S; break; case '+': A += S; break; case '-': A -= S; break; case '*': A *= S; break; case '/': A /= S; break; } switch (ops[1]){ case '^': B ^= C; break; case '+': B += C; break; case '-': B -= C; break; case '*': B *= C; break; case '/': B /= C; break; } switch (ops[2]){ case '^': C ^= A; break; case '+': C += A; break; case '-': C -= A; break; case '*': C *= A; break; case '/': C /= A; break; } switch (ops[3]){ case '^': A ^= B; break; case '+': A += B; break; case '-': A -= B; break; case '*': A *= B; break; case '/': A /= B; break; } } free(buff); } *checksum = (uint32_t)(C & 0x00000000FFFFFFFF); *version = crev_get_file_version(files[1]); S = crev_get_file_information(files[1], result, CREV_MAX_RESULT); for(x = 0; x < 4; x++){ if(files[x] != NULL) free(files[x]); } return S; }
uint32_t __stdcall crev_ver3(uint8_t *archive_time, uint8_t *archive_name, uint8_t *seed, uint8_t *ini_file, uint8_t *ini_header, uint32_t *version, uint32_t *checksum, uint8_t *result){ uint32_t x = 0; uint32_t y = 0; uint32_t z = 0; uint32_t lret; uint8_t *files[5]; //uint8_t *tok; uint8_t *buff; uint8_t *buff2; uint32_t archive_rev = 0; uint32_t header_size = 0; sha1_context sha; lockdown_heep ldh; uint32_t pe_file; PE_IMAGE_NT_HEADERS *nt; PE_IMAGE_SECTION_HEADER *sections; const uint8_t *keys[] = {"Exe", "Util", "Network", "Screen"}; const uint32_t seeds[] = { 0xA1F3055A, 0x5657124C, 0x1780AB47, 0x80B3A410, 0xAF2179EA, 0x0837B808, 0x6F2516C6, 0xE3178148, 0x0FCF90B6, 0xF2F09516, 0x378D8D8C, 0x07F8E083, 0xB0EE9741, 0x7923C9AF, 0xCA11A05E, 0xD723C016, 0xFD545590, 0xFB600C2E, 0x684C8785, 0x58BEDE0B }; sha.version = lSHA1; sha1_reset(&sha); if( (archive_name[14] < '0' || archive_name[14] > '1') || (archive_name[15] < '0' || archive_name[15] > '9')){ return CREV_UNKNOWN_REVISION; } archive_rev = ((archive_name[14] - '0') * 10) + (archive_name[15] - '0'); buff = safe_malloc(MAX_PATH); read_ini_new(ini_file, ini_header, "Path", "", buff, MAX_PATH); files[0] = safe_malloc(MAX_PATH); combine_paths(buff, "", files[0], MAX_PATH); for(x = 1; x < 5; x++){ read_ini_new(ini_file, ini_header, (uint8_t*)keys[x-1], "\xFF", buff, MAX_PATH); if(buff[0] == 0xFF){ for(y = 0; y < x; y++) if(files[y] != NULL) free(files[y]); sprintf_s(result, crev_max_result(), "%s\x00", keys[x-1]); free(buff); return CREV_MISSING_FILENAME; } files[x] = safe_malloc(MAX_PATH); combine_paths(files[0], buff, files[x], MAX_PATH); } read_ini_new(ini_file, "CRev_Main", "LockdownPath", "", buff, MAX_PATH); combine_paths(buff, "", files[0], MAX_PATH); sprintf_s(files[0], MAX_PATH, "%s\\Lockdown-IX86-%02d.dll", files[0], archive_rev); free(buff); lockdown_shuffle_seed(seed); buff = safe_malloc(0x40); memset(buff, '6', 0x40); for(x = 0; x < 0x10; x++) buff[x] ^= seed[x]; sha1_input(&sha, buff, 0x40); free(buff); for(x = 0; x < 4; x++){ pe_file = pe_load_library(files[x]); if(pe_file == 0){ sprintf_s(result, CREV_MAX_RESULT, files[x]); for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); return CREV_MISSING_FILE; } nt = (PE_IMAGE_NT_HEADERS*)(pe_file + ((PE_IMAGE_DOS_HEADER*)pe_file)->e_lfanew); if(nt->OptionalHeader.NumberOfRvaAndSizes <= 0x0D){ for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); pe_unload_library(pe_file); return CREV_TOFEW_RVAS; } header_size = nt->OptionalHeader.SizeOfHeaders; if((header_size % nt->OptionalHeader.FileAlignment) != 0) header_size += (nt->OptionalHeader.FileAlignment - (header_size % nt->OptionalHeader.FileAlignment)); sha1_input(&sha, (uint8_t*)pe_file, header_size); //Hash the PE Header lockdown_heep_create(&ldh); lret = lockdown_proc_reloc(pe_file, &ldh); if(lret != CREV_SUCCESS){ sprintf_s(result, CREV_MAX_RESULT, files[x]); for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); pe_unload_library(pe_file); return lret; } lret = lockdown_proc_import(pe_file, &ldh); if(lret != CREV_SUCCESS){ sprintf_s(result, CREV_MAX_RESULT, files[x]); for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); pe_unload_library(pe_file); return lret; } lockdown_heep_sort(&ldh); /*for(y = 0; y < ldh.cur_len; y += 0x10){ wwrite_to_file(tto_hex((uint8_t*)(ldh.mem + y), 16, FALSE)); wwrite_to_file("\n"); }*/ sections = (PE_IMAGE_SECTION_HEADER *)(pe_file + nt->FileHeader.SizeOfOptionalHeader + ((PE_IMAGE_DOS_HEADER*)pe_file)->e_lfanew + PE_SIZE_OF_NT_SIGNATURE + PE_IMAGE_SIZEOF_FILE_HEADER); for(y = 0; y < nt->FileHeader.NumberOfSections; y++){ lret = lockdown_hash1(&sha, &ldh, (uint32_t)(§ions[y]), pe_file, seeds[archive_rev]); if(lret != CREV_SUCCESS){ sprintf_s(result, CREV_MAX_RESULT, files[x]); for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); pe_unload_library(pe_file); return lret; } } lockdown_heep_cleanup(&ldh); pe_unload_library(pe_file); } //Hash Screen Buffer x = get_file_size(files[4]); if(x == 0){ sprintf_s(result, CREV_MAX_RESULT, files[3]); return CREV_MISSING_FILE; } buff = safe_malloc(x); get_file_data(files[4], buff, x, 0); sha1_input(&sha, buff, x); free(buff); sha1_input(&sha, "\x01\x00\x00\x00", 4); //Verify Return Address sha1_input(&sha, "\x00\x00\x00\x00", 4); //Verify Module Offset buff2 = safe_malloc(sha1_hash_size); sha1_digest(&sha, buff2); //wwrite_to_file(tto_hex(buff2, sha1_hash_size, FALSE)); wwrite_to_file("\n"); //Second SHA Pass buff = safe_malloc(0x40); memset(buff, '\\', 0x40); for(x = 0; x < 0x10; x++) buff[x] ^= seed[x]; sha1_reset(&sha); sha1_input(&sha, buff, 0x40); sha1_input(&sha, buff2, sha1_hash_size); memset(buff2, 0, sha1_hash_size); sha1_digest(&sha, buff2); lockdown_shuffle_digest((uint8_t*)(&buff2[4])); *version = crev_get_file_version(files[1]); *checksum = (*(uint32_t*)&buff2[0]); memcpy(result, (uint8_t*)(&buff2[4]), 0x10); for(x = 0; x < 5; x++) if(files[x] != NULL) free(files[x]); return CREV_SUCCESS; }