mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00:00
Fix some memory leaks in unedat.cpp.
This commit is contained in:
parent
01dbb8eb9a
commit
e47e37a8d2
1 changed files with 228 additions and 207 deletions
|
@ -1,135 +1,135 @@
|
|||
#include "stdafx.h"
|
||||
#include "unedat.h"
|
||||
|
||||
void generate_key(int crypto_mode, int version, unsigned char *key_final, unsigned char *iv_final, unsigned char *key, unsigned char *iv)
|
||||
{
|
||||
int mode = (int) (crypto_mode & 0xF0000000);
|
||||
switch (mode) {
|
||||
case 0x10000000:
|
||||
// Encrypted ERK.
|
||||
// Decrypt the key with EDAT_KEY + EDAT_IV and copy the original IV.
|
||||
aescbc128_decrypt(version ? EDAT_KEY_1 : EDAT_KEY_0, EDAT_IV, key, key_final, 0x10);
|
||||
memcpy(iv_final, iv, 0x10);
|
||||
break;
|
||||
case 0x20000000:
|
||||
// Default ERK.
|
||||
// Use EDAT_KEY and EDAT_IV.
|
||||
memcpy(key_final, version ? EDAT_KEY_1 : EDAT_KEY_0, 0x10);
|
||||
memcpy(iv_final, EDAT_IV, 0x10);
|
||||
break;
|
||||
case 0x00000000:
|
||||
// Unencrypted ERK.
|
||||
// Use the original key and iv.
|
||||
memcpy(key_final, key, 0x10);
|
||||
memcpy(iv_final, iv, 0x10);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
void generate_hash(int hash_mode, int version, unsigned char *hash_final, unsigned char *hash)
|
||||
{
|
||||
int mode = (int) (hash_mode & 0xF0000000);
|
||||
switch (mode) {
|
||||
case 0x10000000:
|
||||
// Encrypted HASH.
|
||||
// Decrypt the hash with EDAT_KEY + EDAT_IV.
|
||||
aescbc128_decrypt(version ? EDAT_KEY_1 : EDAT_KEY_0, EDAT_IV, hash, hash_final, 0x10);
|
||||
break;
|
||||
case 0x20000000:
|
||||
// Default HASH.
|
||||
// Use EDAT_HASH.
|
||||
memcpy(hash_final, version ? EDAT_HASH_1 : EDAT_HASH_0, 0x10);
|
||||
break;
|
||||
case 0x00000000:
|
||||
// Unencrypted ERK.
|
||||
// Use the original hash.
|
||||
memcpy(hash_final, hash, 0x10);
|
||||
break;
|
||||
};
|
||||
}
|
||||
void generate_key(int crypto_mode, int version, unsigned char *key_final, unsigned char *iv_final, unsigned char *key, unsigned char *iv)
|
||||
{
|
||||
int mode = (int) (crypto_mode & 0xF0000000);
|
||||
switch (mode) {
|
||||
case 0x10000000:
|
||||
// Encrypted ERK.
|
||||
// Decrypt the key with EDAT_KEY + EDAT_IV and copy the original IV.
|
||||
aescbc128_decrypt(version ? EDAT_KEY_1 : EDAT_KEY_0, EDAT_IV, key, key_final, 0x10);
|
||||
memcpy(iv_final, iv, 0x10);
|
||||
break;
|
||||
case 0x20000000:
|
||||
// Default ERK.
|
||||
// Use EDAT_KEY and EDAT_IV.
|
||||
memcpy(key_final, version ? EDAT_KEY_1 : EDAT_KEY_0, 0x10);
|
||||
memcpy(iv_final, EDAT_IV, 0x10);
|
||||
break;
|
||||
case 0x00000000:
|
||||
// Unencrypted ERK.
|
||||
// Use the original key and iv.
|
||||
memcpy(key_final, key, 0x10);
|
||||
memcpy(iv_final, iv, 0x10);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
bool crypto(int hash_mode, int crypto_mode, int version, unsigned char *in, unsigned char *out, int lenght, unsigned char *key, unsigned char *iv, unsigned char *hash, unsigned char *test_hash)
|
||||
{
|
||||
// Setup buffers for key, iv and hash.
|
||||
unsigned char key_final[0x10] = {};
|
||||
unsigned char iv_final[0x10] = {};
|
||||
unsigned char hash_final_10[0x10] = {};
|
||||
unsigned char hash_final_14[0x14] = {};
|
||||
|
||||
// Generate crypto key and hash.
|
||||
generate_key(crypto_mode, version, key_final, iv_final, key, iv);
|
||||
if ((hash_mode & 0xFF) == 0x01)
|
||||
generate_hash(hash_mode, version, hash_final_14, hash);
|
||||
else
|
||||
generate_hash(hash_mode, version, hash_final_10, hash);
|
||||
|
||||
if ((crypto_mode & 0xFF) == 0x01) // No algorithm.
|
||||
{
|
||||
memcpy(out, in, lenght);
|
||||
}
|
||||
else if ((crypto_mode & 0xFF) == 0x02) // AES128-CBC
|
||||
{
|
||||
aescbc128_decrypt(key_final, iv_final, in, out, lenght);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Error("EDAT: Unknown crypto algorithm!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((hash_mode & 0xFF) == 0x01) // 0x14 SHA1-HMAC
|
||||
{
|
||||
return hmac_hash_compare(hash_final_14, 0x14, in, lenght, test_hash);
|
||||
}
|
||||
else if ((hash_mode & 0xFF) == 0x02) // 0x10 AES-CMAC
|
||||
{
|
||||
return cmac_hash_compare(hash_final_10, 0x10, in, lenght, test_hash);
|
||||
}
|
||||
else if ((hash_mode & 0xFF) == 0x04) //0x10 SHA1-HMAC
|
||||
{
|
||||
return hmac_hash_compare(hash_final_10, 0x10, in, lenght, test_hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Error("EDAT: Unknown hashing algorithm!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* dec_section(unsigned char* metadata)
|
||||
{
|
||||
unsigned char *dec = new unsigned char[0x10];
|
||||
dec[0x00] = (metadata[0xC] ^ metadata[0x8] ^ metadata[0x10]);
|
||||
dec[0x01] = (metadata[0xD] ^ metadata[0x9] ^ metadata[0x11]);
|
||||
dec[0x02] = (metadata[0xE] ^ metadata[0xA] ^ metadata[0x12]);
|
||||
dec[0x03] = (metadata[0xF] ^ metadata[0xB] ^ metadata[0x13]);
|
||||
dec[0x04] = (metadata[0x4] ^ metadata[0x8] ^ metadata[0x14]);
|
||||
dec[0x05] = (metadata[0x5] ^ metadata[0x9] ^ metadata[0x15]);
|
||||
dec[0x06] = (metadata[0x6] ^ metadata[0xA] ^ metadata[0x16]);
|
||||
dec[0x07] = (metadata[0x7] ^ metadata[0xB] ^ metadata[0x17]);
|
||||
dec[0x08] = (metadata[0xC] ^ metadata[0x0] ^ metadata[0x18]);
|
||||
dec[0x09] = (metadata[0xD] ^ metadata[0x1] ^ metadata[0x19]);
|
||||
dec[0x0A] = (metadata[0xE] ^ metadata[0x2] ^ metadata[0x1A]);
|
||||
dec[0x0B] = (metadata[0xF] ^ metadata[0x3] ^ metadata[0x1B]);
|
||||
dec[0x0C] = (metadata[0x4] ^ metadata[0x0] ^ metadata[0x1C]);
|
||||
dec[0x0D] = (metadata[0x5] ^ metadata[0x1] ^ metadata[0x1D]);
|
||||
dec[0x0E] = (metadata[0x6] ^ metadata[0x2] ^ metadata[0x1E]);
|
||||
dec[0x0F] = (metadata[0x7] ^ metadata[0x3] ^ metadata[0x1F]);
|
||||
void generate_hash(int hash_mode, int version, unsigned char *hash_final, unsigned char *hash)
|
||||
{
|
||||
int mode = (int) (hash_mode & 0xF0000000);
|
||||
switch (mode) {
|
||||
case 0x10000000:
|
||||
// Encrypted HASH.
|
||||
// Decrypt the hash with EDAT_KEY + EDAT_IV.
|
||||
aescbc128_decrypt(version ? EDAT_KEY_1 : EDAT_KEY_0, EDAT_IV, hash, hash_final, 0x10);
|
||||
break;
|
||||
case 0x20000000:
|
||||
// Default HASH.
|
||||
// Use EDAT_HASH.
|
||||
memcpy(hash_final, version ? EDAT_HASH_1 : EDAT_HASH_0, 0x10);
|
||||
break;
|
||||
case 0x00000000:
|
||||
// Unencrypted ERK.
|
||||
// Use the original hash.
|
||||
memcpy(hash_final, hash, 0x10);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
bool crypto(int hash_mode, int crypto_mode, int version, unsigned char *in, unsigned char *out, int lenght, unsigned char *key, unsigned char *iv, unsigned char *hash, unsigned char *test_hash)
|
||||
{
|
||||
// Setup buffers for key, iv and hash.
|
||||
unsigned char key_final[0x10] = {};
|
||||
unsigned char iv_final[0x10] = {};
|
||||
unsigned char hash_final_10[0x10] = {};
|
||||
unsigned char hash_final_14[0x14] = {};
|
||||
|
||||
// Generate crypto key and hash.
|
||||
generate_key(crypto_mode, version, key_final, iv_final, key, iv);
|
||||
if ((hash_mode & 0xFF) == 0x01)
|
||||
generate_hash(hash_mode, version, hash_final_14, hash);
|
||||
else
|
||||
generate_hash(hash_mode, version, hash_final_10, hash);
|
||||
|
||||
if ((crypto_mode & 0xFF) == 0x01) // No algorithm.
|
||||
{
|
||||
memcpy(out, in, lenght);
|
||||
}
|
||||
else if ((crypto_mode & 0xFF) == 0x02) // AES128-CBC
|
||||
{
|
||||
aescbc128_decrypt(key_final, iv_final, in, out, lenght);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Error("EDAT: Unknown crypto algorithm!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((hash_mode & 0xFF) == 0x01) // 0x14 SHA1-HMAC
|
||||
{
|
||||
return hmac_hash_compare(hash_final_14, 0x14, in, lenght, test_hash);
|
||||
}
|
||||
else if ((hash_mode & 0xFF) == 0x02) // 0x10 AES-CMAC
|
||||
{
|
||||
return cmac_hash_compare(hash_final_10, 0x10, in, lenght, test_hash);
|
||||
}
|
||||
else if ((hash_mode & 0xFF) == 0x04) //0x10 SHA1-HMAC
|
||||
{
|
||||
return hmac_hash_compare(hash_final_10, 0x10, in, lenght, test_hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Error("EDAT: Unknown hashing algorithm!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* dec_section(unsigned char* metadata)
|
||||
{
|
||||
unsigned char *dec = new unsigned char[0x10];
|
||||
dec[0x00] = (metadata[0xC] ^ metadata[0x8] ^ metadata[0x10]);
|
||||
dec[0x01] = (metadata[0xD] ^ metadata[0x9] ^ metadata[0x11]);
|
||||
dec[0x02] = (metadata[0xE] ^ metadata[0xA] ^ metadata[0x12]);
|
||||
dec[0x03] = (metadata[0xF] ^ metadata[0xB] ^ metadata[0x13]);
|
||||
dec[0x04] = (metadata[0x4] ^ metadata[0x8] ^ metadata[0x14]);
|
||||
dec[0x05] = (metadata[0x5] ^ metadata[0x9] ^ metadata[0x15]);
|
||||
dec[0x06] = (metadata[0x6] ^ metadata[0xA] ^ metadata[0x16]);
|
||||
dec[0x07] = (metadata[0x7] ^ metadata[0xB] ^ metadata[0x17]);
|
||||
dec[0x08] = (metadata[0xC] ^ metadata[0x0] ^ metadata[0x18]);
|
||||
dec[0x09] = (metadata[0xD] ^ metadata[0x1] ^ metadata[0x19]);
|
||||
dec[0x0A] = (metadata[0xE] ^ metadata[0x2] ^ metadata[0x1A]);
|
||||
dec[0x0B] = (metadata[0xF] ^ metadata[0x3] ^ metadata[0x1B]);
|
||||
dec[0x0C] = (metadata[0x4] ^ metadata[0x0] ^ metadata[0x1C]);
|
||||
dec[0x0D] = (metadata[0x5] ^ metadata[0x1] ^ metadata[0x1D]);
|
||||
dec[0x0E] = (metadata[0x6] ^ metadata[0x2] ^ metadata[0x1E]);
|
||||
dec[0x0F] = (metadata[0x7] ^ metadata[0x3] ^ metadata[0x1F]);
|
||||
return dec;
|
||||
}
|
||||
|
||||
unsigned char* get_block_key(int block, NPD_HEADER *npd)
|
||||
{
|
||||
unsigned char empty_key[0x10] = {};
|
||||
unsigned char *src_key = (npd->version <= 1) ? empty_key : npd->dev_hash;
|
||||
unsigned char *dest_key = new unsigned char[0x10];
|
||||
memcpy(dest_key, src_key, 0xC);
|
||||
dest_key[0xC] = (block >> 24 & 0xFF);
|
||||
dest_key[0xD] = (block >> 16 & 0xFF);
|
||||
dest_key[0xE] = (block >> 8 & 0xFF);
|
||||
dest_key[0xF] = (block & 0xFF);
|
||||
unsigned char* get_block_key(int block, NPD_HEADER *npd)
|
||||
{
|
||||
unsigned char empty_key[0x10] = {};
|
||||
unsigned char *src_key = (npd->version <= 1) ? empty_key : npd->dev_hash;
|
||||
unsigned char *dest_key = new unsigned char[0x10];
|
||||
memcpy(dest_key, src_key, 0xC);
|
||||
dest_key[0xC] = (block >> 24 & 0xFF);
|
||||
dest_key[0xD] = (block >> 16 & 0xFF);
|
||||
dest_key[0xE] = (block >> 8 & 0xFF);
|
||||
dest_key[0xF] = (block & 0xFF);
|
||||
return dest_key;
|
||||
}
|
||||
}
|
||||
|
||||
// EDAT/SDAT functions.
|
||||
int decrypt_data(wxFile *in, wxFile *out, EDAT_SDAT_HEADER *edat, NPD_HEADER *npd, unsigned char* crypt_key, bool verbose)
|
||||
|
@ -301,20 +301,17 @@ int decrypt_data(wxFile *in, wxFile *out, EDAT_SDAT_HEADER *edat, NPD_HEADER *np
|
|||
return 0;
|
||||
}
|
||||
|
||||
int check_data(unsigned char *key, EDAT_SDAT_HEADER *edat, NPD_HEADER *npd, wxFile *f, bool verbose)
|
||||
static bool check_flags(EDAT_SDAT_HEADER *edat, NPD_HEADER *npd)
|
||||
{
|
||||
f->Seek(0);
|
||||
unsigned char *header = new unsigned char[0xA0];
|
||||
unsigned char *tmp = new unsigned char[0xA0];
|
||||
unsigned char *hash_result = new unsigned char[0x10];
|
||||
if (edat == nullptr || npd == nullptr)
|
||||
return false;
|
||||
|
||||
// Check NPD version and EDAT flags.
|
||||
if ((npd->version == 0) || (npd->version == 1))
|
||||
if (npd->version == 0 || npd->version == 1)
|
||||
{
|
||||
if (edat->flags & 0x7EFFFFFE)
|
||||
{
|
||||
ConLog.Error("EDAT: Bad header flags!\n");
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (npd->version == 2)
|
||||
|
@ -322,93 +319,113 @@ int check_data(unsigned char *key, EDAT_SDAT_HEADER *edat, NPD_HEADER *npd, wxFi
|
|||
if (edat->flags & 0x7EFFFFE0)
|
||||
{
|
||||
ConLog.Error("EDAT: Bad header flags!\n");
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ((npd->version == 3) || (npd->version == 4))
|
||||
else if (npd->version == 3 || npd->version == 4)
|
||||
{
|
||||
if (edat->flags & 0x7EFFFFC0)
|
||||
{
|
||||
ConLog.Error("EDAT: Bad header flags!\n");
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (npd->version > 4)
|
||||
{
|
||||
ConLog.Error("EDAT: Unknown version!\n");
|
||||
ConLog.Error("EDAT: Unknown version - %d\n", npd->version);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int check_data(unsigned char *key, EDAT_SDAT_HEADER *edat, NPD_HEADER *npd, wxFile *f, bool verbose)
|
||||
{
|
||||
f->Seek(0);
|
||||
unsigned char *header = new unsigned char[0xA0];
|
||||
unsigned char *tmp = new unsigned char[0xA0];
|
||||
unsigned char *hash_result = new unsigned char[0x10];
|
||||
|
||||
// Check NPD version and EDAT flags.
|
||||
if (!check_flags(edat, npd))
|
||||
{
|
||||
delete[] header;
|
||||
delete[] tmp;
|
||||
delete[] hash_result;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read in the file header.
|
||||
f->Read(header, 0xA0);
|
||||
f->Read(hash_result, 0x10);
|
||||
|
||||
// Setup the hashing mode and the crypto mode used in the file.
|
||||
int crypto_mode = 0x1;
|
||||
int hash_mode = ((edat->flags & EDAT_ENCRYPTED_KEY_FLAG) == 0) ? 0x00000002 : 0x10000002;
|
||||
if ((edat->flags & EDAT_DEBUG_DATA_FLAG) != 0)
|
||||
{
|
||||
ConLog.Warning("EDAT: DEBUG data detected!\n");
|
||||
hash_mode |= 0x01000000;
|
||||
}
|
||||
|
||||
// Setup header key and iv buffers.
|
||||
unsigned char header_key[0x10] = {};
|
||||
unsigned char header_iv[0x10] = {};
|
||||
|
||||
// Test the header hash (located at offset 0xA0).
|
||||
if (!crypto(hash_mode, crypto_mode, (npd->version == 4), header, tmp, 0xA0, header_key, header_iv, key, hash_result))
|
||||
{
|
||||
if (verbose)
|
||||
ConLog.Warning("EDAT: Header hash is invalid!\n");
|
||||
}
|
||||
|
||||
// Parse the metadata info.
|
||||
int metadata_section_size = 0x10;
|
||||
if (((edat->flags & EDAT_COMPRESSED_FLAG) != 0))
|
||||
{
|
||||
ConLog.Warning("EDAT: COMPRESSED data detected!\n");
|
||||
metadata_section_size = 0x20;
|
||||
}
|
||||
|
||||
int block_num = (int) ((edat->file_size + edat->block_size - 1) / edat->block_size);
|
||||
int bytes_read = 0;
|
||||
int metadata_offset = 0x100;
|
||||
|
||||
long bytes_to_read = metadata_section_size * block_num;
|
||||
while (bytes_to_read > 0)
|
||||
{
|
||||
// Locate the metadata blocks.
|
||||
int block_size = (0x3C00 > bytes_to_read) ? (int) bytes_to_read : 0x3C00; // 0x3C00 is the maximum block size.
|
||||
f->Seek(metadata_offset + bytes_read);
|
||||
unsigned char *data = new unsigned char[block_size];
|
||||
|
||||
// Read in the metadata.
|
||||
tmp = new unsigned char[block_size];
|
||||
f->Read(data, block_size);
|
||||
|
||||
// Check the generated hash against the metadata hash located at offset 0x90 in the header.
|
||||
memset(hash_result, 0, 0x10);
|
||||
f->Seek(0x90);
|
||||
f->Read(hash_result, 0x10);
|
||||
|
||||
// Generate the hash for this block.
|
||||
if (!crypto(hash_mode, crypto_mode, (npd->version == 4), data, tmp, block_size, header_key, header_iv, key, hash_result))
|
||||
{
|
||||
if (verbose)
|
||||
ConLog.Warning("EDAT: Metadata hash from block 0x%08x is invalid!\n", metadata_offset + bytes_read);
|
||||
}
|
||||
|
||||
// Adjust sizes.
|
||||
bytes_read += block_size;
|
||||
bytes_to_read -= block_size;
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
// Read in the file header.
|
||||
f->Read(header, 0xA0);
|
||||
f->Read(hash_result, 0x10);
|
||||
|
||||
// Setup the hashing mode and the crypto mode used in the file.
|
||||
int crypto_mode = 0x1;
|
||||
int hash_mode = ((edat->flags & EDAT_ENCRYPTED_KEY_FLAG) == 0) ? 0x00000002 : 0x10000002;
|
||||
if ((edat->flags & EDAT_DEBUG_DATA_FLAG) != 0)
|
||||
{
|
||||
ConLog.Warning("EDAT: DEBUG data detected!\n");
|
||||
hash_mode |= 0x01000000;
|
||||
}
|
||||
|
||||
// Setup header key and iv buffers.
|
||||
unsigned char header_key[0x10] = {};
|
||||
unsigned char header_iv[0x10] = {};
|
||||
|
||||
// Test the header hash (located at offset 0xA0).
|
||||
if (!crypto(hash_mode, crypto_mode, (npd->version == 4), header, tmp, 0xA0, header_key, header_iv, key, hash_result))
|
||||
{
|
||||
if (verbose)
|
||||
ConLog.Warning("EDAT: Header hash is invalid!\n");
|
||||
}
|
||||
|
||||
// Parse the metadata info.
|
||||
int metadata_section_size = 0x10;
|
||||
if (((edat->flags & EDAT_COMPRESSED_FLAG) != 0))
|
||||
{
|
||||
ConLog.Warning("EDAT: COMPRESSED data detected!\n");
|
||||
metadata_section_size = 0x20;
|
||||
}
|
||||
|
||||
int block_num = (int) ((edat->file_size + edat->block_size - 1) / edat->block_size);
|
||||
int bytes_read = 0;
|
||||
int metadata_offset = 0x100;
|
||||
|
||||
long bytes_to_read = metadata_section_size * block_num;
|
||||
while (bytes_to_read > 0)
|
||||
{
|
||||
// Locate the metadata blocks.
|
||||
int block_size = (0x3C00 > bytes_to_read) ? (int) bytes_to_read : 0x3C00; // 0x3C00 is the maximum block size.
|
||||
f->Seek(metadata_offset + bytes_read);
|
||||
unsigned char *data = new unsigned char[block_size];
|
||||
|
||||
// Read in the metadata.
|
||||
tmp = new unsigned char[block_size];
|
||||
f->Read(data, block_size);
|
||||
|
||||
// Check the generated hash against the metadata hash located at offset 0x90 in the header.
|
||||
memset(hash_result, 0, 0x10);
|
||||
f->Seek(0x90);
|
||||
f->Read(hash_result, 0x10);
|
||||
|
||||
// Generate the hash for this block.
|
||||
if (!crypto(hash_mode, crypto_mode, (npd->version == 4), data, tmp, block_size, header_key, header_iv, key, hash_result))
|
||||
{
|
||||
if (verbose)
|
||||
ConLog.Warning("EDAT: Metadata hash from block 0x%08x is invalid!\n", metadata_offset + bytes_read);
|
||||
}
|
||||
|
||||
// Adjust sizes.
|
||||
bytes_read += block_size;
|
||||
bytes_to_read -= block_size;
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
delete[] header;
|
||||
delete[] tmp;
|
||||
delete[] header;
|
||||
delete[] tmp;
|
||||
delete[] hash_result;
|
||||
|
||||
return 0;
|
||||
|
@ -501,6 +518,8 @@ bool extract_data(wxFile *input, wxFile *output, const char* input_file_name, un
|
|||
if(memcmp(NPD->magic, npd_magic, 4))
|
||||
{
|
||||
ConLog.Error("EDAT: File has invalid NPD header.");
|
||||
delete NPD;
|
||||
delete EDAT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -556,6 +575,8 @@ bool extract_data(wxFile *input, wxFile *output, const char* input_file_name, un
|
|||
if (!test)
|
||||
{
|
||||
ConLog.Error("EDAT: A valid RAP file is needed!");
|
||||
delete NPD;
|
||||
delete EDAT;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -670,4 +691,4 @@ int DecryptEDAT(const std::string& input_file_name, const std::string& output_fi
|
|||
input.Close();
|
||||
output.Close();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue