Exemple #1
0
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;
}
Exemple #2
0
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)(&sections[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;
}