2019-09-24 22:54:27 +02:00
|
|
|
#include <vector>
|
|
|
|
#include "nro.h"
|
|
|
|
|
|
|
|
namespace skyline::loader {
|
2019-12-02 18:40:53 +01:00
|
|
|
NroLoader::NroLoader(const int romFd) : Loader(romFd) {
|
2019-09-24 22:54:27 +02:00
|
|
|
ReadOffset((u32 *) &header, 0x0, sizeof(NroHeader));
|
|
|
|
if (header.magic != constant::NroMagic)
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
throw exception("Invalid NRO magic! 0x{0:X}", header.magic);
|
2020-01-07 03:36:08 +01:00
|
|
|
mainEntry = constant::BaseAddr;
|
2019-10-13 10:04:47 +02:00
|
|
|
}
|
2019-09-24 22:54:27 +02:00
|
|
|
|
2019-10-13 10:04:47 +02:00
|
|
|
void NroLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
|
|
|
std::vector<u8> text(header.text.size);
|
|
|
|
std::vector<u8> rodata(header.ro.size);
|
|
|
|
std::vector<u8> data(header.data.size);
|
2019-09-24 22:54:27 +02:00
|
|
|
|
2019-10-13 10:04:47 +02:00
|
|
|
ReadOffset(text.data(), header.text.offset, header.text.size);
|
|
|
|
ReadOffset(rodata.data(), header.ro.offset, header.ro.size);
|
|
|
|
ReadOffset(data.data(), header.data.offset, header.data.size);
|
2019-09-24 22:54:27 +02:00
|
|
|
|
2020-01-07 03:36:08 +01:00
|
|
|
std::vector<u32> patch = state.nce->PatchCode(text, constant::BaseAddr, header.text.size + header.ro.size + header.data.size + header.bssSize);
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
|
|
|
|
u64 textSize = text.size();
|
|
|
|
u64 rodataSize = rodata.size();
|
|
|
|
u64 dataSize = data.size();
|
2019-12-25 20:03:57 +01:00
|
|
|
u64 patchSize = patch.size() * sizeof(u32);
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
|
|
|
|
process->MapPrivateRegion(constant::BaseAddr, textSize, {true, true, true}, memory::Type::CodeStatic, memory::Region::Text); // R-X
|
|
|
|
state.logger->Debug("Successfully mapped region .text @ 0x{0:X}, Size = 0x{1:X}", constant::BaseAddr, textSize);
|
|
|
|
|
|
|
|
process->MapPrivateRegion(constant::BaseAddr + textSize, rodataSize, {true, false, false}, memory::Type::CodeReadOnly, memory::Region::RoData); // R--
|
|
|
|
state.logger->Debug("Successfully mapped region .ro @ 0x{0:X}, Size = 0x{1:X}", constant::BaseAddr + textSize, rodataSize);
|
|
|
|
|
|
|
|
process->MapPrivateRegion(constant::BaseAddr + textSize + rodataSize, dataSize, {true, true, false}, memory::Type::CodeStatic, memory::Region::Data); // RW-
|
|
|
|
state.logger->Debug("Successfully mapped region .data @ 0x{0:X}, Size = 0x{1:X}", constant::BaseAddr + textSize + rodataSize, dataSize);
|
|
|
|
|
|
|
|
process->MapPrivateRegion(constant::BaseAddr + textSize + rodataSize + dataSize, header.bssSize, {true, true, true}, memory::Type::CodeMutable, memory::Region::Bss); // RWX
|
|
|
|
state.logger->Debug("Successfully mapped region .bss @ 0x{0:X}, Size = 0x{1:X}", constant::BaseAddr + textSize + rodataSize + dataSize, header.bssSize);
|
|
|
|
|
2019-12-25 20:03:57 +01:00
|
|
|
process->MapPrivateRegion(constant::BaseAddr + textSize + rodataSize + dataSize + header.bssSize, patchSize, {true, true, true}, memory::Type::CodeStatic, memory::Region::Text); // RWX
|
|
|
|
state.logger->Debug("Successfully mapped region .patch @ 0x{0:X}, Size = 0x{1:X}", constant::BaseAddr + textSize + rodataSize + dataSize + header.bssSize, patchSize);
|
|
|
|
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
process->WriteMemory(text.data(), constant::BaseAddr, textSize);
|
|
|
|
process->WriteMemory(rodata.data(), constant::BaseAddr + textSize, rodataSize);
|
|
|
|
process->WriteMemory(data.data(), constant::BaseAddr + textSize + rodataSize, dataSize);
|
2019-12-25 20:03:57 +01:00
|
|
|
process->WriteMemory(patch.data(), constant::BaseAddr + textSize + rodataSize + dataSize + header.bssSize, patchSize);
|
2019-09-24 22:54:27 +02:00
|
|
|
}
|
|
|
|
}
|