xex2 loader now guesses sizes to allocate.

This may not be right in all cases, but seems to work.
This commit is contained in:
Ben Vanik 2013-05-29 23:26:34 -07:00
parent f307bc9eb1
commit 7990146001
1 changed files with 54 additions and 25 deletions

View File

@ -530,18 +530,28 @@ int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header,
const uint8_t *xex_addr, const uint8_t *xex_addr,
const size_t xex_length, const size_t xex_length,
xe_memory_ref memory) { xe_memory_ref memory) {
uint8_t *buffer = (uint8_t*)xe_memory_addr(memory, header->exe_address); // Allocate in-place the XEX memory.
size_t buffer_size = 0x40000000;
const size_t exe_length = xex_length - header->exe_offset; const size_t exe_length = xex_length - header->exe_offset;
size_t uncompressed_size = exe_length;
uint32_t alloc_result =
xe_memory_heap_alloc(memory,
header->exe_address, (uint32_t)uncompressed_size,
0);
if (!alloc_result) {
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.",
header->exe_address, uncompressed_size);
return 2;
}
uint8_t *buffer = (uint8_t*)xe_memory_addr(memory, header->exe_address);
const uint8_t *p = (const uint8_t*)xex_addr + header->exe_offset; const uint8_t *p = (const uint8_t*)xex_addr + header->exe_offset;
switch (header->file_format_info.encryption_type) { switch (header->file_format_info.encryption_type) {
case XEX_ENCRYPTION_NONE: case XEX_ENCRYPTION_NONE:
return xe_copy_memory(buffer, buffer_size, p, exe_length); return xe_copy_memory(buffer, uncompressed_size, p, exe_length);
case XEX_ENCRYPTION_NORMAL: case XEX_ENCRYPTION_NORMAL:
xe_xex2_decrypt_buffer(header->session_key, p, exe_length, buffer, xe_xex2_decrypt_buffer(header->session_key, p, exe_length, buffer,
buffer_size); uncompressed_size);
return 0; return 0;
default: default:
XEASSERTALWAYS(); XEASSERTALWAYS();
@ -555,28 +565,44 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
const uint8_t *xex_addr, const uint8_t *xex_addr,
const size_t xex_length, const size_t xex_length,
xe_memory_ref memory) { xe_memory_ref memory) {
uint8_t *buffer = (uint8_t*)xe_memory_addr(memory, header->exe_address);
size_t buffer_size = 0x40000000;
const size_t exe_length = xex_length - header->exe_offset; const size_t exe_length = xex_length - header->exe_offset;
const uint8_t* source_buffer = (const uint8_t*)xex_addr + header->exe_offset; const uint8_t* source_buffer = (const uint8_t*)xex_addr + header->exe_offset;
const uint8_t *p = source_buffer; const uint8_t *p = source_buffer;
// Calculate uncompressed length.
size_t uncompressed_size = 0;
const xe_xex2_file_basic_compression_info_t* comp_info =
&header->file_format_info.compression_info.basic;
for (size_t n = 0; n < comp_info->block_count; n++) {
const size_t data_size = comp_info->blocks[n].data_size;
const size_t zero_size = comp_info->blocks[n].zero_size;
uncompressed_size += data_size + zero_size;
}
// Allocate in-place the XEX memory.
uint32_t alloc_result =
xe_memory_heap_alloc(memory,
header->exe_address, (uint32_t)uncompressed_size,
0);
if (!alloc_result) {
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.",
header->exe_address, uncompressed_size);
XEFAIL();
}
uint8_t *buffer = (uint8_t*)xe_memory_addr(memory, header->exe_address);
uint8_t *d = buffer; uint8_t *d = buffer;
uint32_t rk[4 * (MAXNR + 1)]; uint32_t rk[4 * (MAXNR + 1)];
uint8_t ivec[16] = {0}; uint8_t ivec[16] = {0};
int32_t Nr = rijndaelKeySetupDec(rk, header->session_key, 128); int32_t Nr = rijndaelKeySetupDec(rk, header->session_key, 128);
const xe_xex2_file_basic_compression_info_t* comp_info =
&header->file_format_info.compression_info.basic;
for (size_t n = 0; n < comp_info->block_count; n++) { for (size_t n = 0; n < comp_info->block_count; n++) {
const size_t data_size = comp_info->blocks[n].data_size; const size_t data_size = comp_info->blocks[n].data_size;
const size_t zero_size = comp_info->blocks[n].zero_size; const size_t zero_size = comp_info->blocks[n].zero_size;
switch (header->file_format_info.encryption_type) { switch (header->file_format_info.encryption_type) {
case XEX_ENCRYPTION_NONE: case XEX_ENCRYPTION_NONE:
XEEXPECTZERO(xe_copy_memory(d, buffer_size - (d - buffer), p, XEEXPECTZERO(xe_copy_memory(d, uncompressed_size - (d - buffer), p,
exe_length - (p - source_buffer))); exe_length - (p - source_buffer)));
break; break;
case XEX_ENCRYPTION_NORMAL: case XEX_ENCRYPTION_NORMAL:
@ -614,9 +640,6 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
const uint8_t *xex_addr, const uint8_t *xex_addr,
const size_t xex_length, const size_t xex_length,
xe_memory_ref memory) { xe_memory_ref memory) {
uint8_t *buffer = (uint8_t*)xe_memory_addr(memory, header->exe_address);
size_t buffer_size = 0x40000000;
const size_t exe_length = xex_length - header->exe_offset; const size_t exe_length = xex_length - header->exe_offset;
const uint8_t *exe_buffer = (const uint8_t*)xex_addr + header->exe_offset; const uint8_t *exe_buffer = (const uint8_t*)xex_addr + header->exe_offset;
@ -635,6 +658,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
uint8_t *d = NULL; uint8_t *d = NULL;
uint8_t *deblock_buffer = NULL; uint8_t *deblock_buffer = NULL;
size_t block_size = 0; size_t block_size = 0;
size_t uncompressed_size = 0;
struct mspack_system *sys = NULL; struct mspack_system *sys = NULL;
mspack_memory_file *lzxsrc = NULL; mspack_memory_file *lzxsrc = NULL;
mspack_memory_file *lzxdst = NULL; mspack_memory_file *lzxdst = NULL;
@ -686,18 +710,33 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
xe_copy_memory(d, exe_length - (d - compress_buffer), p, chunk_size); xe_copy_memory(d, exe_length - (d - compress_buffer), p, chunk_size);
p += chunk_size; p += chunk_size;
d += chunk_size; d += chunk_size;
uncompressed_size += 0x8000;
} }
p = pnext; p = pnext;
block_size = next_size; block_size = next_size;
} }
// Allocate in-place the XEX memory.
uint32_t alloc_result =
xe_memory_heap_alloc(memory,
header->exe_address, (uint32_t)uncompressed_size,
0);
if (!alloc_result) {
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.",
header->exe_address, uncompressed_size);
result_code = 2;
XEFAIL();
}
uint8_t *buffer = (uint8_t*)xe_memory_addr(memory, header->exe_address);
// Setup decompressor and decompress. // Setup decompressor and decompress.
sys = mspack_memory_sys_create(); sys = mspack_memory_sys_create();
XEEXPECTNOTNULL(sys); XEEXPECTNOTNULL(sys);
lzxsrc = mspack_memory_open(sys, (void*)compress_buffer, d - compress_buffer); lzxsrc = mspack_memory_open(sys, (void*)compress_buffer, d - compress_buffer);
XEEXPECTNOTNULL(lzxsrc); XEEXPECTNOTNULL(lzxsrc);
lzxdst = mspack_memory_open(sys, buffer, buffer_size); lzxdst = mspack_memory_open(sys, buffer, uncompressed_size);
XEEXPECTNOTNULL(lzxdst); XEEXPECTNOTNULL(lzxdst);
lzxd = lzxd_init( lzxd = lzxd_init(
sys, sys,
@ -740,16 +779,6 @@ XECLEANUP:
int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr, int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr,
const size_t xex_length, xe_memory_ref memory) { const size_t xex_length, xe_memory_ref memory) {
const xe_xex2_header_t *header = &xex->header; const xe_xex2_header_t *header = &xex->header;
// Allocate in-place the XEX memory.
uint32_t alloc_result =
xe_memory_heap_alloc(memory, header->exe_address, xex_length, 0);
if (!alloc_result) {
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.",
header->exe_address, xex_length);
return 2;
}
switch (header->file_format_info.compression_type) { switch (header->file_format_info.compression_type) {
case XEX_COMPRESSION_NONE: case XEX_COMPRESSION_NONE:
return xe_xex2_read_image_uncompressed( return xe_xex2_read_image_uncompressed(