From 4310ffd4dd7248ee534a77cd693dab110f2614da Mon Sep 17 00:00:00 2001 From: Ryan Teal Date: Sun, 30 Jun 2019 22:07:10 +0100 Subject: [PATCH] Fix interrupt hook and memory maps --- app/src/main/cpp/core/arm/cpu.cpp | 23 +++++++++++++++++++---- app/src/main/cpp/core/arm/cpu.h | 6 ++++-- app/src/main/cpp/core/hos/loaders/nro.cpp | 10 ++++++---- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/app/src/main/cpp/core/arm/cpu.cpp b/app/src/main/cpp/core/arm/cpu.cpp index 8e17234a..06895271 100644 --- a/app/src/main/cpp/core/arm/cpu.cpp +++ b/app/src/main/cpp/core/arm/cpu.cpp @@ -1,16 +1,27 @@ #include "cpu.h" +#include "memory.h" // TODO: Handle Unicorn errors namespace core { + Cpu* currentContext; + void HookInterrupt(uc_engine *uc, uint32_t intno, void *user_data); + Cpu::Cpu() { uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc); uc_hook hook{}; - uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)HookInterrupt, this, 0, -1); + uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)HookInterrupt, this, 1, 0); + + // Map stack memory + memory::Map(uc, 0x3000000, 0x1000000, "stack"); + SetRegister(UC_ARM64_REG_SP, 0x3100000); + currentContext = this; } void Cpu::Run(uint64_t address) { - uc_emu_start(uc, address, 1ULL << 63, 0, 0); + 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)); } uint64_t Cpu::GetRegister(uint32_t regid) { @@ -23,17 +34,21 @@ namespace core { uc_reg_write(uc, regid, &value); } - void Cpu::HookInterrupt(uc_engine *uc, uint32_t intno, void *user_data) { + void HookInterrupt(uc_engine *uc, uint32_t intno, void *user_data) { + syslog(LOG_WARNING, "Interrupt called at x%x", currentContext->GetRegister(UC_ARM64_REG_PC)); if (intno == 2) { uint32_t instr{}; - uc_mem_read(uc, GetRegister(UC_ARM64_REG_PC) - 4, &instr, 4); + uc_mem_read(uc, currentContext->GetRegister(UC_ARM64_REG_PC) - 4, &instr, 4); uint32_t svcId = instr >> 5 & 0xFF; // TODO: Handle SVCs + syslog(LOG_DEBUG, "SVC 0x%x called!", svcId); } else { syslog(LOG_ERR, "Unhandled interrupt #%i", intno); uc_close(uc); } } + + Cpu* CpuContext() { return currentContext; } } \ No newline at end of file diff --git a/app/src/main/cpp/core/arm/cpu.h b/app/src/main/cpp/core/arm/cpu.h index d941235a..056ee0bc 100644 --- a/app/src/main/cpp/core/arm/cpu.h +++ b/app/src/main/cpp/core/arm/cpu.h @@ -14,7 +14,9 @@ namespace core { void SetRegister(uint32_t regid, uint64_t value); uc_engine *uc; - private: - void HookInterrupt(uc_engine *uc, uint32_t intno, void *user_data); +// private: +// void HookInterrupt(uc_engine *uc, uint32_t intno, void *user_data); }; + + Cpu* CpuContext(); } \ No newline at end of file diff --git a/app/src/main/cpp/core/hos/loaders/nro.cpp b/app/src/main/cpp/core/hos/loaders/nro.cpp index 7a033772..4fbee9ed 100644 --- a/app/src/main/cpp/core/hos/loaders/nro.cpp +++ b/app/src/main/cpp/core/hos/loaders/nro.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "../../arm/cpu.h" #include "../../arm/memory.h" #include "nro.h" @@ -35,10 +36,11 @@ namespace core::loader { 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(nullptr, BASE_ADDRESS, header.segments[0].size, ".text") || - !memory::Map(nullptr, BASE_ADDRESS + header.segments[0].size, header.segments[1].size, ".ro") || - !memory::Map(nullptr, BASE_ADDRESS + header.segments[0].size + header.segments[1].size, header.segments[2].size, ".data") || - !memory::Map(nullptr, BASE_ADDRESS + header.segments[0].size + header.segments[1].size + header.segments[2].size, header.bssSize, ".bss")) { + uc_engine* uc = core::CpuContext()->uc; + if( !memory::Map(uc, BASE_ADDRESS, header.segments[0].size, ".text") || + !memory::Map(uc, BASE_ADDRESS + header.segments[0].size, header.segments[1].size, ".ro") || + !memory::Map(uc, BASE_ADDRESS + header.segments[0].size + header.segments[1].size, header.segments[2].size, ".data") || + !memory::Map(uc, 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;