mirror of
https://github.com/wiiu-env/CustomRPXLoader.git
synced 2024-11-22 09:59:17 +01:00
Read the payload.rpx with a properly aligned buffer, fix some missing free calls
This commit is contained in:
parent
9e96647469
commit
db9e908226
@ -68,6 +68,26 @@ set_##FNAME( TYPE val ) \
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
struct membuf : std::streambuf {
|
||||||
|
membuf(char* begin, char* end) {
|
||||||
|
this->setg(begin, begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in) override {
|
||||||
|
if (dir == std::ios_base::cur)
|
||||||
|
gbump(off);
|
||||||
|
else if (dir == std::ios_base::end)
|
||||||
|
setg(eback(), egptr() + off, egptr());
|
||||||
|
else if (dir == std::ios_base::beg)
|
||||||
|
setg(eback(), eback() + off, egptr());
|
||||||
|
return gptr() - eback();
|
||||||
|
}
|
||||||
|
|
||||||
|
pos_type seekpos(pos_type sp, std::ios_base::openmode which) override {
|
||||||
|
return seekoff(sp - pos_type(off_type(0)), std::ios_base::beg, which);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace ELFIO {
|
namespace ELFIO {
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -97,6 +117,13 @@ class elfio
|
|||||||
create_mandatory_sections();
|
create_mandatory_sections();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool load(char * buffer, size_t length) {
|
||||||
|
membuf sbuf(buffer, buffer + length);
|
||||||
|
std::istream in(&sbuf);
|
||||||
|
return load(in);
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool load( const std::string& file_name )
|
bool load( const std::string& file_name )
|
||||||
{
|
{
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include "ModuleDataFactory.h"
|
#include "ModuleDataFactory.h"
|
||||||
#include "../ElfUtils.h"
|
#include "../ElfUtils.h"
|
||||||
#include "elfio/elfio.hpp"
|
#include "../utils/FileUtils.h"
|
||||||
#include <coreinit/cache.h>
|
#include <coreinit/cache.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -30,9 +30,17 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address, u
|
|||||||
elfio reader;
|
elfio reader;
|
||||||
ModuleData moduleData;
|
ModuleData moduleData;
|
||||||
|
|
||||||
|
uint8_t *buffer = nullptr;
|
||||||
|
uint32_t fsize = 0;
|
||||||
|
if (LoadFileToMem(path.c_str(), &buffer, &fsize) < 0) {
|
||||||
|
DEBUG_FUNCTION_LINE("Failed to load file");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
// Load ELF data
|
// Load ELF data
|
||||||
if (!reader.load(path)) {
|
if (!reader.load(reinterpret_cast<char *>(buffer), fsize)) {
|
||||||
DEBUG_FUNCTION_LINE("Can't find or process %s", path.c_str());
|
DEBUG_FUNCTION_LINE("Can't find or process %s", path.c_str());
|
||||||
|
free(buffer);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +48,11 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address, u
|
|||||||
|
|
||||||
auto **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num);
|
auto **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num);
|
||||||
|
|
||||||
|
if (!destinations) {
|
||||||
|
DEBUG_FUNCTION_LINE("Failed to alloc memory for destinations");
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t sizeOfModule = 0;
|
uint32_t sizeOfModule = 0;
|
||||||
for (uint32_t i = 0; i < sec_num; ++i) {
|
for (uint32_t i = 0; i < sec_num; ++i) {
|
||||||
section *psec = reader.sections[i];
|
section *psec = reader.sections[i];
|
||||||
@ -54,6 +67,8 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address, u
|
|||||||
|
|
||||||
if (sizeOfModule > maximum_size) {
|
if (sizeOfModule > maximum_size) {
|
||||||
DEBUG_FUNCTION_LINE("Module is too big.");
|
DEBUG_FUNCTION_LINE("Module is too big.");
|
||||||
|
free(buffer);
|
||||||
|
free(destinations);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +108,7 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address, u
|
|||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE("Unhandled case");
|
DEBUG_FUNCTION_LINE("Unhandled case");
|
||||||
free(destinations);
|
free(destinations);
|
||||||
|
free(buffer);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +146,7 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address, u
|
|||||||
if (!linkSection(reader, psec->get_index(), (uint32_t) destinations[psec->get_index()], offset_text, offset_data, trampolin_data, trampolin_data_length)) {
|
if (!linkSection(reader, psec->get_index(), (uint32_t) destinations[psec->get_index()], offset_text, offset_data, trampolin_data, trampolin_data_length)) {
|
||||||
DEBUG_FUNCTION_LINE("elfLink failed");
|
DEBUG_FUNCTION_LINE("elfLink failed");
|
||||||
free(destinations);
|
free(destinations);
|
||||||
|
free(buffer);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,6 +163,7 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address, u
|
|||||||
ICInvalidateRange((void *) baseOffset, totalSize);
|
ICInvalidateRange((void *) baseOffset, totalSize);
|
||||||
|
|
||||||
free(destinations);
|
free(destinations);
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
moduleData.setEntrypoint(entrypoint);
|
moduleData.setEntrypoint(entrypoint);
|
||||||
DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint);
|
DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint);
|
||||||
@ -153,7 +171,6 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address, u
|
|||||||
return moduleData;
|
return moduleData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<RelocationData> ModuleDataFactory::getImportRelocationData(const elfio &reader, uint8_t **destinations) {
|
std::vector<RelocationData> ModuleDataFactory::getImportRelocationData(const elfio &reader, uint8_t **destinations) {
|
||||||
std::vector<RelocationData> result;
|
std::vector<RelocationData> result;
|
||||||
std::map<uint32_t, std::string> infoMap;
|
std::map<uint32_t, std::string> infoMap;
|
||||||
|
62
src/utils/FileUtils.cpp
Normal file
62
src/utils/FileUtils.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define ROUNDDOWN(val, align) ((val) & ~(align - 1))
|
||||||
|
#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align - 1)), align)
|
||||||
|
|
||||||
|
int32_t LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size) {
|
||||||
|
//! always initialze input
|
||||||
|
*inbuffer = nullptr;
|
||||||
|
if (size) {
|
||||||
|
*size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t iFd = open(filepath, O_RDONLY);
|
||||||
|
if (iFd < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t filesize = lseek(iFd, 0, SEEK_END);
|
||||||
|
lseek(iFd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
auto *buffer = (uint8_t *) malloc(ROUNDUP(filesize, 0x40));
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
close(iFd);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t blocksize = 0x20000;
|
||||||
|
uint32_t done = 0;
|
||||||
|
int32_t readBytes;
|
||||||
|
|
||||||
|
while (done < filesize) {
|
||||||
|
if (done + blocksize > filesize) {
|
||||||
|
blocksize = filesize - done;
|
||||||
|
}
|
||||||
|
readBytes = read(iFd, buffer + done, blocksize);
|
||||||
|
if (readBytes <= 0)
|
||||||
|
break;
|
||||||
|
done += readBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
::close(iFd);
|
||||||
|
|
||||||
|
if (done != filesize) {
|
||||||
|
free(buffer);
|
||||||
|
buffer = nullptr;
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
*inbuffer = buffer;
|
||||||
|
|
||||||
|
//! sign is optional input
|
||||||
|
if (size) {
|
||||||
|
*size = filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filesize;
|
||||||
|
}
|
3
src/utils/FileUtils.h
Normal file
3
src/utils/FileUtils.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
int32_t LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size);
|
Loading…
Reference in New Issue
Block a user