XexGetProcedureAddress by name implemented.

This commit is contained in:
Dr. Chat 2015-05-04 17:38:34 -05:00
parent 78921c1a7e
commit 49c8efdc6d
8 changed files with 101 additions and 1 deletions

View File

@ -34,5 +34,10 @@ void* XKernelModule::GetProcAddressByOrdinal(uint16_t ordinal) {
return NULL;
}
void* XKernelModule::GetProcAddressByName(const char* name) {
XELOGE("GetProcAddressByName not implemented");
return NULL;
}
} // namespace kernel
} // namespace xe

View File

@ -24,6 +24,7 @@ class XKernelModule : public XModule {
virtual ~XKernelModule();
virtual void* GetProcAddressByOrdinal(uint16_t ordinal);
virtual void* GetProcAddressByName(const char* name);
protected:
Emulator* emulator_;

View File

@ -27,6 +27,7 @@ class XModule : public XObject {
const std::string& name() const { return name_; }
virtual void* GetProcAddressByOrdinal(uint16_t ordinal) = 0;
virtual void* GetProcAddressByName(const char *name) = 0;
virtual X_STATUS GetSection(const char* name, uint32_t* out_section_data,
uint32_t* out_section_size);

View File

@ -148,6 +148,17 @@ void* XUserModule::GetProcAddressByOrdinal(uint16_t ordinal) {
return NULL;
}
void* XUserModule::GetProcAddressByName(const char* name) {
PEExport export;
int ret = xe_xex2_lookup_export(xex_, name, export);
// Failure.
if (ret)
return NULL;
return (void *)export.addr;
}
X_STATUS XUserModule::GetSection(const char* name, uint32_t* out_section_data,
uint32_t* out_section_size) {
auto header = xe_xex2_get_header(xex_);

View File

@ -33,6 +33,7 @@ class XUserModule : public XModule {
X_STATUS LoadFromMemory(const void* addr, const size_t length);
virtual void* GetProcAddressByOrdinal(uint16_t ordinal);
virtual void* GetProcAddressByName(const char* name);
virtual X_STATUS GetSection(const char* name, uint32_t* out_section_data,
uint32_t* out_section_size);

View File

@ -49,6 +49,8 @@ typedef struct xe_xex2 {
size_t count;
xe_xex2_import_info_t *infos;
} library_imports[16];
xe_xex2_export_table *export_table;
} xe_xex2_t;
int xe_xex2_read_header(const uint8_t *addr, const size_t length,
@ -237,6 +239,11 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
case XEX_HEADER_DEFAULT_HEAP_SIZE:
header->exe_heap_size = opt_header->value;
break;
case XEX_HEADER_EXPORTS_BY_NAME: {
// IMAGE_DATA_DIRECTORY (w/ offset from PE file base)
header->export_table_offset = xe::load_and_swap<uint32_t>(pp);
// size = xe::load_and_swap<uint32_t>(pp + 0x04);
} break;
case XEX_HEADER_IMPORT_LIBRARIES: {
const size_t max_count = xe::countof(header->import_libraries);
size_t count = xe::load_and_swap<uint32_t>(pp + 0x08);
@ -869,6 +876,20 @@ int xe_xex2_load_pe(xe_xex2_ref xex) {
xex->sections->push_back(section);
}
if (header->export_table_offset) {
// This table is located inside of the PE (for some reason)
xe_xex2_export_table *table = (xe_xex2_export_table *)xex->memory->TranslateVirtual(xex->header.loader_info.export_table);
xex->export_table = table;
// cmp magic...
table->base = xe::load_and_swap<uint32_t>(&table->base);
table->imagebaseaddr = xe::load_and_swap<uint32_t>(&table->imagebaseaddr);
table->count = xe::load_and_swap<uint32_t>(&table->count);
for (int i = 0; i < table->count; i++) {
table->ordOffset[i] = xe::load_and_swap<uint32_t>(&table->ordOffset[i]);
}
}
// DumpTLSDirectory(pImageBase, pNTHeader, (PIMAGE_TLS_DIRECTORY32)0);
// DumpExportsSection(pImageBase, pNTHeader);
return 0;
@ -982,3 +1003,41 @@ int xe_xex2_get_import_infos(xe_xex2_ref xex,
*out_import_infos = xex->library_imports[library_index].infos;
return 0;
}
int xe_xex2_lookup_export(xe_xex2_ref xex, const char *name,
PEExport &peexport) {
auto header = xe_xex2_get_header(xex);
// no exports :(
if (!header->export_table_offset) {
return 1;
}
uint64_t loadaddr = (uint64_t)xex->memory->TranslateVirtual(header->loader_info.load_address);
IMAGE_EXPORT_DIRECTORY *e = (PIMAGE_EXPORT_DIRECTORY)(loadaddr + header->export_table_offset);
// e->AddressOfX RVAs are relative to the IMAGE_EXPORT_DIRECTORY!
uint32_t* function_table = (uint32_t*)((uint64_t)e + e->AddressOfFunctions); // Functions relative to base
uint32_t* name_table = (uint32_t*)((uint64_t)e + e->AddressOfNames); // Names relative to directory
uint16_t* ordinal_table = (uint16_t*)((uint64_t)e + e->AddressOfNameOrdinals); // Table of ordinals
const char* mod_name = (const char*)((uint64_t)e + e->Name);
for (int i = 0; i < e->NumberOfNames; i++) {
const char *fn_name = (const char *)((uint64_t)e + name_table[i]);
uint16_t ordinal = ordinal_table[i];
uint64_t addr = (uint64_t)(loadaddr + function_table[ordinal]);
if (!strcmp(name, fn_name)) {
// We have a match!
peexport.name = fn_name;
peexport.addr = addr;
peexport.ordinal = ordinal;
return 0;
}
}
// No match
return 1;
}

View File

@ -43,6 +43,13 @@ class PESection {
uint32_t flags; // kXEPESection*
};
struct PEExport {
const char *name;
uint32_t ordinal;
uint64_t addr; // Function address
};
xe_xex2_ref xe_xex2_load(xe::Memory* memory, const void* addr,
const size_t length, xe_xex2_options_t options);
void xe_xex2_dealloc(xe_xex2_ref xex);
@ -55,4 +62,7 @@ int xe_xex2_get_import_infos(xe_xex2_ref xex,
xe_xex2_import_info_t** out_import_infos,
size_t* out_import_info_count);
int xe_xex2_lookup_export(xe_xex2_ref xex, const char *name,
PEExport &peexport);
#endif // XENIA_KERNEL_UTIL_XEX2_H_

View File

@ -295,6 +295,17 @@ typedef struct {
xe_xex2_approval_type approval;
} xe_xex2_static_library_t;
// credits: some obscure pastebin (http://pastebin.com/ZRvr3Sgj)
typedef struct {
uint32_t magic[3];
uint32_t modulenumber[2];
uint32_t version[3];
uint32_t imagebaseaddr; // must be <<16 to be accurate
uint32_t count;
uint32_t base;
uint32_t ordOffset[1]; // ordOffset[0] + (imagebaseaddr << 16) = function offset of ordinal 1
} xe_xex2_export_table;
typedef enum {
XEX_ENCRYPTION_NONE = 0,
XEX_ENCRYPTION_NORMAL = 1,
@ -397,7 +408,7 @@ typedef struct {
uint8_t import_table_digest[20];
uint8_t media_id[16];
uint8_t file_key[16];
uint32_t export_table;
uint32_t export_table; // address of the export table
uint8_t header_digest[20];
xe_xex2_region_flags game_regions;
xe_xex2_media_flags media_flags;
@ -434,6 +445,7 @@ typedef struct {
xe_xex2_tls_info_t tls_info;
size_t import_library_count;
xe_xex2_import_library_t import_libraries[32];
size_t export_table_offset; // PE Export Directory
size_t static_library_count;
xe_xex2_static_library_t static_libraries[32];
xe_xex2_file_format_info_t file_format_info;