Properly parsing resource infos and implementing XexGetModuleSection.
This commit is contained in:
parent
d22b59555e
commit
0bc49621d4
|
@ -526,13 +526,19 @@ json_t* Processor::DumpModule(XexModule* module, bool& succeeded) {
|
||||||
}
|
}
|
||||||
json_object_set_new(module_json, "headers", headers_json);
|
json_object_set_new(module_json, "headers", headers_json);
|
||||||
|
|
||||||
// TODO(benvanik): resources.
|
json_t* resource_infos_json = json_array();
|
||||||
json_t* resource_info_json = json_object();
|
for (size_t n = 0; n < header->resource_info_count; n++) {
|
||||||
json_object_set_integer_new(
|
auto& res = header->resource_infos[n];
|
||||||
resource_info_json, "address", header->resource_info.address);
|
json_t* resource_info_json = json_object();
|
||||||
json_object_set_integer_new(
|
json_object_set_string_new(
|
||||||
resource_info_json, "size", header->resource_info.size);
|
resource_info_json, "name", res.name);
|
||||||
json_object_set_new(module_json, "resourceInfo", resource_info_json);
|
json_object_set_integer_new(
|
||||||
|
resource_info_json, "address", res.address);
|
||||||
|
json_object_set_integer_new(
|
||||||
|
resource_info_json, "size", res.size);
|
||||||
|
json_array_append_new(resource_infos_json, resource_info_json);
|
||||||
|
}
|
||||||
|
json_object_set_new(module_json, "resourceInfos", resource_infos_json);
|
||||||
|
|
||||||
json_t* sections_json = json_array();
|
json_t* sections_json = json_array();
|
||||||
for (size_t n = 0, i = 0; n < header->section_count; n++) {
|
for (size_t n = 0, i = 0; n < header->section_count; n++) {
|
||||||
|
|
|
@ -33,3 +33,9 @@ XModule::XModule(KernelState* kernel_state, const char* path) :
|
||||||
|
|
||||||
XModule::~XModule() {
|
XModule::~XModule() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X_STATUS XModule::GetSection(
|
||||||
|
const char* name,
|
||||||
|
uint32_t* out_section_data, uint32_t* out_section_size) {
|
||||||
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@ public:
|
||||||
const char* name() const { return name_; }
|
const char* name() const { return name_; }
|
||||||
|
|
||||||
virtual void* GetProcAddressByOrdinal(uint16_t ordinal) = 0;
|
virtual void* GetProcAddressByOrdinal(uint16_t ordinal) = 0;
|
||||||
|
virtual X_STATUS GetSection(
|
||||||
|
const char* name,
|
||||||
|
uint32_t* out_section_data, uint32_t* out_section_size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char name_[256];
|
char name_[256];
|
||||||
|
|
|
@ -124,23 +124,28 @@ XECLEANUP:
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XUserModule::GetSection(const char* name,
|
|
||||||
uint32_t* out_data, uint32_t* out_size) {
|
|
||||||
const PESection* section = xe_xex2_get_pe_section(xex_, name);
|
|
||||||
if (!section) {
|
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
*out_data = section->address;
|
|
||||||
*out_size = section->size;
|
|
||||||
return X_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* XUserModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
void* XUserModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
||||||
// TODO(benvanik): check export tables.
|
// TODO(benvanik): check export tables.
|
||||||
XELOGE("GetProcAddressByOrdinal not implemented");
|
XELOGE("GetProcAddressByOrdinal not implemented");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X_STATUS XUserModule::GetSection(
|
||||||
|
const char* name,
|
||||||
|
uint32_t* out_section_data, uint32_t* out_section_size) {
|
||||||
|
auto header = xe_xex2_get_header(xex_);
|
||||||
|
for (size_t n = 0; n < header->resource_info_count; n++) {
|
||||||
|
auto& res = header->resource_infos[n];
|
||||||
|
if (xestrcmpa(name, res.name) == 0) {
|
||||||
|
// Found!
|
||||||
|
*out_section_data = res.address;
|
||||||
|
*out_section_size = res.size;
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
X_STATUS XUserModule::Launch(uint32_t flags) {
|
X_STATUS XUserModule::Launch(uint32_t flags) {
|
||||||
const xe_xex2_header_t* header = xex_header();
|
const xe_xex2_header_t* header = xex_header();
|
||||||
|
|
||||||
|
@ -226,9 +231,11 @@ void XUserModule::Dump() {
|
||||||
|
|
||||||
// Resources.
|
// Resources.
|
||||||
printf("Resources:\n");
|
printf("Resources:\n");
|
||||||
printf(" %.8X, %db\n", header->resource_info.address,
|
for (size_t n = 0; n < header->resource_info_count; n++) {
|
||||||
header->resource_info.size);
|
auto& res = header->resource_infos[n];
|
||||||
printf(" TODO\n");
|
printf(" %-8s %.8X-%.8X, %db\n",
|
||||||
|
res.name, res.address, res.address + res.size, res.size);
|
||||||
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
// Section info.
|
// Section info.
|
||||||
|
|
|
@ -32,8 +32,10 @@ public:
|
||||||
X_STATUS LoadFromFile(const char* path);
|
X_STATUS LoadFromFile(const char* path);
|
||||||
X_STATUS LoadFromMemory(const void* addr, const size_t length);
|
X_STATUS LoadFromMemory(const void* addr, const size_t length);
|
||||||
|
|
||||||
X_STATUS GetSection(const char* name, uint32_t* out_data, uint32_t* out_size);
|
|
||||||
virtual void* GetProcAddressByOrdinal(uint16_t ordinal);
|
virtual void* GetProcAddressByOrdinal(uint16_t ordinal);
|
||||||
|
virtual X_STATUS GetSection(
|
||||||
|
const char* name,
|
||||||
|
uint32_t* out_section_data, uint32_t* out_section_size);
|
||||||
|
|
||||||
X_STATUS Launch(uint32_t flags);
|
X_STATUS Launch(uint32_t flags);
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ void xe_xex2_dealloc(xe_xex2_ref xex) {
|
||||||
|
|
||||||
xe_xex2_header_t *header = &xex->header;
|
xe_xex2_header_t *header = &xex->header;
|
||||||
xe_free(header->sections);
|
xe_free(header->sections);
|
||||||
|
xe_free(header->resource_infos);
|
||||||
if (header->file_format_info.compression_type == XEX_COMPRESSION_BASIC) {
|
if (header->file_format_info.compression_type == XEX_COMPRESSION_BASIC) {
|
||||||
xe_free(header->file_format_info.compression_info.basic.blocks);
|
xe_free(header->file_format_info.compression_info.basic.blocks);
|
||||||
}
|
}
|
||||||
|
@ -147,19 +148,31 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
||||||
|
|
||||||
const uint8_t *pp = p + opt_header->offset;
|
const uint8_t *pp = p + opt_header->offset;
|
||||||
switch (opt_header->key) {
|
switch (opt_header->key) {
|
||||||
|
default:
|
||||||
|
XELOGW("Unknown XEX header key %.8X", opt_header->key);
|
||||||
|
break;
|
||||||
|
case XEX_HEADER_CHECKSUM_TIMESTAMP:
|
||||||
|
case XEX_HEADER_ORIGINAL_PE_NAME:
|
||||||
|
case XEX_HEADER_LAN_KEY:
|
||||||
|
case XEX_HEADER_XBOX360_LOGO:
|
||||||
|
// Ignored.
|
||||||
|
break;
|
||||||
case XEX_HEADER_SYSTEM_FLAGS:
|
case XEX_HEADER_SYSTEM_FLAGS:
|
||||||
header->system_flags = (xe_xex2_system_flags)data_offset;
|
header->system_flags = (xe_xex2_system_flags)data_offset;
|
||||||
break;
|
break;
|
||||||
case XEX_HEADER_RESOURCE_INFO:
|
case XEX_HEADER_RESOURCE_INFO:
|
||||||
{
|
{
|
||||||
xe_xex2_resource_info_t *res = &header->resource_info;
|
header->resource_info_count = (opt_header->length - 4) / 16;
|
||||||
XEEXPECTZERO(xe_copy_memory(res->title_id,
|
header->resource_infos = (xe_xex2_resource_info_t*)xe_calloc(
|
||||||
sizeof(res->title_id), pp + 0x04, 8));
|
sizeof(xe_xex2_resource_info_t) * header->resource_info_count);
|
||||||
res->address = XEGETUINT32BE(pp + 0x0C);
|
const uint8_t* ph = pp + 0x04;
|
||||||
res->size = XEGETUINT32BE(pp + 0x10);
|
for (size_t n = 0; n < header->resource_info_count; n++) {
|
||||||
if ((opt_header->length - 4) / 16 > 1) {
|
auto& res = header->resource_infos[n];
|
||||||
// Ignoring extra resources (not yet seen)
|
XEEXPECTZERO(xe_copy_memory(res.name,
|
||||||
XELOGW("ignoring extra XEX_HEADER_RESOURCE_INFO resources");
|
sizeof(res.name), ph + 0x00, 8));
|
||||||
|
res.address = XEGETUINT32BE(ph + 0x08);
|
||||||
|
res.size = XEGETUINT32BE(ph + 0x0C);
|
||||||
|
ph += 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -246,7 +246,7 @@ typedef struct {
|
||||||
} xe_xex2_opt_header_t;
|
} xe_xex2_opt_header_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char title_id[8];
|
char name[9];
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
} xe_xex2_resource_info_t;
|
} xe_xex2_resource_info_t;
|
||||||
|
@ -431,7 +431,6 @@ typedef struct {
|
||||||
uint32_t certificate_offset;
|
uint32_t certificate_offset;
|
||||||
|
|
||||||
xe_xex2_system_flags system_flags;
|
xe_xex2_system_flags system_flags;
|
||||||
xe_xex2_resource_info_t resource_info;
|
|
||||||
xe_xex2_execution_info_t execution_info;
|
xe_xex2_execution_info_t execution_info;
|
||||||
xe_xex2_game_ratings_t game_ratings;
|
xe_xex2_game_ratings_t game_ratings;
|
||||||
xe_xex2_tls_info_t tls_info;
|
xe_xex2_tls_info_t tls_info;
|
||||||
|
@ -451,6 +450,8 @@ typedef struct {
|
||||||
size_t header_count;
|
size_t header_count;
|
||||||
xe_xex2_opt_header_t headers[64];
|
xe_xex2_opt_header_t headers[64];
|
||||||
|
|
||||||
|
size_t resource_info_count;
|
||||||
|
xe_xex2_resource_info_t* resource_infos;
|
||||||
size_t section_count;
|
size_t section_count;
|
||||||
xe_xex2_section_t* sections;
|
xe_xex2_section_t* sections;
|
||||||
} xe_xex2_header_t;
|
} xe_xex2_header_t;
|
||||||
|
|
|
@ -204,9 +204,35 @@ SHIM_CALL XexGetModuleHandle_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// SHIM_CALL XexGetModuleSection_shim(
|
SHIM_CALL XexGetModuleSection_shim(
|
||||||
// PPCContext* ppc_state, KernelState* state) {
|
PPCContext* ppc_state, KernelState* state) {
|
||||||
// }
|
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||||
|
uint32_t name_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
const char* name = (const char*)SHIM_MEM_ADDR(name_ptr);
|
||||||
|
uint32_t data_ptr = SHIM_GET_ARG_32(2);
|
||||||
|
uint32_t size_ptr = SHIM_GET_ARG_32(3);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
"XexGetModuleSection(%.8X, %s, %.8X, %.8X)",
|
||||||
|
handle, name, data_ptr, size_ptr);
|
||||||
|
|
||||||
|
XModule* module = NULL;
|
||||||
|
X_STATUS result =
|
||||||
|
state->object_table()->GetObject(handle, (XObject**)&module);
|
||||||
|
if (XSUCCEEDED(result)) {
|
||||||
|
uint32_t section_data = 0;
|
||||||
|
uint32_t section_size = 0;
|
||||||
|
result = module->GetSection(name, §ion_data, §ion_size);
|
||||||
|
if (XSUCCEEDED(result)) {
|
||||||
|
SHIM_SET_MEM_32(data_ptr, section_data);
|
||||||
|
SHIM_SET_MEM_32(size_ptr, section_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
module->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SHIM_CALL XexLoadImage_shim(
|
SHIM_CALL XexLoadImage_shim(
|
||||||
|
@ -323,7 +349,7 @@ void xe::kernel::xboxkrnl::RegisterModuleExports(
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexCheckExecutablePrivilege, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", XexCheckExecutablePrivilege, state);
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleHandle, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleHandle, state);
|
||||||
// SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleSection, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleSection, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexLoadImage, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", XexLoadImage, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexUnloadImage, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", XexUnloadImage, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexGetProcedureAddress, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", XexGetProcedureAddress, state);
|
||||||
|
|
Loading…
Reference in New Issue