From 040121340ac97c487c296a9acd8c13f3d40d5f37 Mon Sep 17 00:00:00 2001 From: Starlet Leonhart Date: Tue, 2 Jul 2019 17:43:49 -0400 Subject: [PATCH] Minor code cleanup --- app/src/main/cpp/core/arm/cpu.cpp | 38 ++++++++++++++--------- app/src/main/cpp/core/arm/memory.cpp | 36 ++++++++++----------- app/src/main/cpp/core/arm/memory.h | 14 ++++----- app/src/main/cpp/core/hos/kernel/svc.cpp | 5 +-- app/src/main/cpp/core/hos/loaders/nro.cpp | 30 +++++++++--------- app/src/main/cpp/core/hos/loaders/nro.h | 2 +- app/src/main/cpp/lightswitch.cpp | 7 +++++ 7 files changed, 76 insertions(+), 56 deletions(-) diff --git a/app/src/main/cpp/core/arm/cpu.cpp b/app/src/main/cpp/core/arm/cpu.cpp index 17461f48..e543ba5e 100644 --- a/app/src/main/cpp/core/arm/cpu.cpp +++ b/app/src/main/cpp/core/arm/cpu.cpp @@ -9,48 +9,56 @@ namespace core::cpu { void HookInterrupt(uc_engine *uc, uint32_t intno, void *user_data); - bool Initialize() { + bool Initialize() + { uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc); uc_hook hook{}; uc_hook_add(uc, &hook, UC_HOOK_INTR, (void *) HookInterrupt, 0, 1, 0); // Map stack memory - if (!memory::Map(0x3000000, 0x1000000, "stack")) return false; + if (!memory::Map(0x3000000, 0x1000000, "Stack")) return false; SetRegister(UC_ARM64_REG_SP, 0x3100000); + // Map TLS memory - if (!memory::Map(0x2000000, 0x1000, "tls")) return false; + if (!memory::Map(0x2000000, 0x1000, "TLS")) return false; SetRegister(UC_ARM64_REG_TPIDRRO_EL0, 0x2000000); return true; } - void Run(uint64_t address) { + void Run(uint64_t address) + { uc_err err = uc_emu_start(uc, address, 1ULL << 63, 0, 0); - if (err) - syslog(LOG_ERR, "uc_emu_start failed: %s", uc_strerror(err)); + if (err) syslog(LOG_ERR, "uc_emu_start failed: %s", uc_strerror(err)); } - uint64_t GetRegister(uint32_t regid) { + uint64_t GetRegister(uint32_t regid) + { uint64_t registerValue; uc_reg_read(uc, regid, ®isterValue); return registerValue; } - void SetRegister(uint32_t regid, uint64_t value) { + void SetRegister(uint32_t regid, uint64_t value) + { uc_reg_write(uc, regid, &value); } - void HookInterrupt(uc_engine *uc, uint32_t intno, void *user_data) { - if (intno == 2) { + void HookInterrupt(uc_engine *uc, uint32_t intno, void *user_data) + { + if (intno == 2) + { uint32_t instr{}; uc_mem_read(uc, GetRegister(UC_ARM64_REG_PC) - 4, &instr, 4); uint32_t svcId = instr >> 5 & 0xFF; - if(core::kernel::SvcHandler(svcId) == 0x177202) + if (core::kernel::SvcHandler(svcId) == 0x177202) uc_close(uc); - } else { + } + else + { syslog(LOG_ERR, "Unhandled interrupt #%i", intno); uc_close(uc); } @@ -62,13 +70,15 @@ namespace core::memory { bool Map(uint64_t address, size_t size, std::string label) { void *ptr = mmap((void*)(address), size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0); - if (!ptr) { + if (!ptr) + { syslog(LOG_ERR, "Failed mapping region '%s'", label.c_str()); return false; } uc_err err = uc_mem_map_ptr(core::cpu::uc, address, size, UC_PROT_ALL, (void*)(address)); - if (err) { + if (err) + { syslog(LOG_ERR, "UC map failed: %s", uc_strerror(err)); return false; } diff --git a/app/src/main/cpp/core/arm/memory.cpp b/app/src/main/cpp/core/arm/memory.cpp index 778b351f..9ae4813d 100644 --- a/app/src/main/cpp/core/arm/memory.cpp +++ b/app/src/main/cpp/core/arm/memory.cpp @@ -4,24 +4,24 @@ #include "memory.h" namespace core::memory { -// std::vector memoryRegions; -// -// bool Map(uint64_t address, size_t size, std::string label) { -// void* ptr = mmap((void*)(address), size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0); -// if (!ptr) { -// syslog(LOG_ERR, "Failed mapping region '%s'", label.c_str()); -// return false; -// } -// -// syslog(LOG_INFO, "Mapping region '%s' to 0x%x, pointer %x", label.c_str(), address, (uint64_t)ptr); -// -// if (core::cpu::MapUnicorn(address, size, ptr)) return false; -// -// syslog(LOG_INFO, "Successfully mapped region '%s' to 0x%x", label.c_str(), address); -// -// memoryRegions.push_back({label, address, size, ptr}); -// return true; -// } + /*std::vector memoryRegions; + + bool Map(uint64_t address, size_t size, std::string label) { + void* ptr = mmap((void*)(address), size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0); + if (!ptr) { + syslog(LOG_ERR, "Failed mapping region '%s'", label.c_str()); + return false; + } + + syslog(LOG_INFO, "Mapping region '%s' to 0x%x, pointer %x", label.c_str(), address, (uint64_t)ptr); + + if (core::cpu::MapUnicorn(address, size, ptr)) return false; + + syslog(LOG_INFO, "Successfully mapped region '%s' to 0x%x", label.c_str(), address); + + memoryRegions.push_back({label, address, size, ptr}); + return true; + }*/ // TODO: Boundary checks void Write(void* data, uint64_t offset, size_t size) { std::memcpy((void*)(offset), data, size); } diff --git a/app/src/main/cpp/core/arm/memory.h b/app/src/main/cpp/core/arm/memory.h index 80808b21..f7e02762 100644 --- a/app/src/main/cpp/core/arm/memory.h +++ b/app/src/main/cpp/core/arm/memory.h @@ -5,25 +5,25 @@ #define BASE_ADDRESS 0x80000000 namespace core::memory { - struct MemoryRegion { + /*struct MemoryRegion { std::string label; - uint64_t address; - size_t size; - void* ptr; - }; + uint64_t address; + size_t size; + void* ptr; + };*/ bool Map(uint64_t address, size_t size, std::string label = {}); void Write(void* data, uint64_t offset, size_t size); - void WriteU8 (uint8_t value, uint64_t offset); + void WriteU8(uint8_t value, uint64_t offset); void WriteU16(uint16_t value, uint64_t offset); void WriteU32(uint32_t value, uint64_t offset); void WriteU64(uint64_t value, uint64_t offset); void Read(void* destination, uint64_t offset, size_t size); - uint8_t ReadU8 (uint64_t offset); + uint8_t ReadU8(uint64_t offset); uint16_t ReadU16(uint64_t offset); uint32_t ReadU32(uint64_t offset); uint64_t ReadU64(uint64_t offset); diff --git a/app/src/main/cpp/core/hos/kernel/svc.cpp b/app/src/main/cpp/core/hos/kernel/svc.cpp index ba7b9e0c..eec203c5 100644 --- a/app/src/main/cpp/core/hos/kernel/svc.cpp +++ b/app/src/main/cpp/core/hos/kernel/svc.cpp @@ -8,7 +8,8 @@ using namespace core::cpu; namespace core::kernel { - static uint32_t OutputDebugString() { + static uint32_t OutputDebugString() + { std::string debug(GetRegister(UC_ARM64_REG_X1), '\0'); memory::Read((void*)debug.data(), GetRegister(UC_ARM64_REG_X0), GetRegister(UC_ARM64_REG_X1)); @@ -152,7 +153,7 @@ namespace core::kernel { { std::pair* result = &(svcTable[svc]); - if(result->second) + if (result->second) return result->second(); else { diff --git a/app/src/main/cpp/core/hos/loaders/nro.cpp b/app/src/main/cpp/core/hos/loaders/nro.cpp index 6142ea1d..6414a842 100644 --- a/app/src/main/cpp/core/hos/loaders/nro.cpp +++ b/app/src/main/cpp/core/hos/loaders/nro.cpp @@ -17,12 +17,14 @@ void ReadDataFromFile(std::string file, char* output, uint32_t offset, size_t si } namespace core::loader { - bool LoadNro(std::string file) { - syslog(LOG_INFO, "Loading NRO file %s\n", file.c_str()); + bool LoadNro(std::string filePath) + { + syslog(LOG_INFO, "Loading NRO file %s\n", filePath.c_str()); NroHeader header; - ReadDataFromFile(file, reinterpret_cast(&header), 0x0, sizeof(NroHeader)); - if (header.magic != 0x304F524E) { + ReadDataFromFile(filePath, reinterpret_cast(&header), 0x0, sizeof(NroHeader)); + if (header.magic != 0x304F524E) + { syslog(LOG_ERR, "Invalid NRO magic 0x%x\n", header.magic); return false; } @@ -32,21 +34,21 @@ namespace core::loader { ro.resize (header.segments[1].size); data.resize(header.segments[2].size); - ReadDataFromFile(file, reinterpret_cast(text.data()), header.segments[0].fileOffset, header.segments[0].size); - ReadDataFromFile(file, reinterpret_cast(ro.data()), header.segments[1].fileOffset, header.segments[1].size); - ReadDataFromFile(file, reinterpret_cast(data.data()), header.segments[2].fileOffset, header.segments[2].size); - - if( !memory::Map(BASE_ADDRESS, header.segments[0].size, ".text") || - !memory::Map(BASE_ADDRESS + header.segments[0].size, header.segments[1].size, ".ro") || - !memory::Map(BASE_ADDRESS + header.segments[0].size + header.segments[1].size, header.segments[2].size, ".data") || - !memory::Map(BASE_ADDRESS + header.segments[0].size + header.segments[1].size + header.segments[2].size, header.bssSize, ".bss")) { + ReadDataFromFile(filePath, reinterpret_cast(text.data()), header.segments[0].fileOffset, header.segments[0].size); + ReadDataFromFile(filePath, reinterpret_cast(ro.data()), header.segments[1].fileOffset, header.segments[1].size); + ReadDataFromFile(filePath, reinterpret_cast(data.data()), header.segments[2].fileOffset, header.segments[2].size); + if (!memory::Map(BASE_ADDRESS, header.segments[0].size, ".text") || + !memory::Map(BASE_ADDRESS + header.segments[0].size, header.segments[1].size, ".ro") || + !memory::Map(BASE_ADDRESS + header.segments[0].size + header.segments[1].size, header.segments[2].size, ".data") || + !memory::Map(BASE_ADDRESS + header.segments[0].size + header.segments[1].size + header.segments[2].size, header.bssSize, ".bss")) + { syslog(LOG_ERR, "Failed mapping regions for executable"); return false; } - memory::Write(text.data(), BASE_ADDRESS, text.size()); - memory::Write(ro.data(), BASE_ADDRESS + header.segments[0].size, ro.size()); + memory::Write(text.data(), BASE_ADDRESS, text.size()); + memory::Write(ro.data(), BASE_ADDRESS + header.segments[0].size, ro.size()); memory::Write(data.data(), BASE_ADDRESS + header.segments[0].size + header.segments[1].size, data.size()); return true; } diff --git a/app/src/main/cpp/core/hos/loaders/nro.h b/app/src/main/cpp/core/hos/loaders/nro.h index f0666c56..1b8291d1 100644 --- a/app/src/main/cpp/core/hos/loaders/nro.h +++ b/app/src/main/cpp/core/hos/loaders/nro.h @@ -27,5 +27,5 @@ namespace core::loader { NroSegmentHeader extraSegments[3]; }; - bool LoadNro(std::string file); + bool LoadNro(std::string filePath); } \ No newline at end of file diff --git a/app/src/main/cpp/lightswitch.cpp b/app/src/main/cpp/lightswitch.cpp index 92e676d2..755e927a 100644 --- a/app/src/main/cpp/lightswitch.cpp +++ b/app/src/main/cpp/lightswitch.cpp @@ -1,12 +1,19 @@ #include #include #include +#include +#include +#include extern "C" JNIEXPORT jstring JNICALL Java_gq_cyuubi_lightswitch_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) { + core::cpu::Initialize(); + core::loader::LoadNro("/sdcard/test.nro"); + core::cpu::Run(BASE_ADDRESS); + std::string finished = "finished!"; return env->NewStringUTF(finished.c_str()); }