From 4cd7c985f0f3e4ce7b9d0e30cdea226ab3f9d511 Mon Sep 17 00:00:00 2001 From: Ryan Teal Date: Tue, 9 Jul 2019 22:35:51 +0100 Subject: [PATCH] IPC Episode 1 - Prologue --- app/CMakeLists.txt | 1 + app/src/main/cpp/core/hos/kernel/ipc.cpp | 49 +++++++++++++++++++++++ app/src/main/cpp/core/hos/kernel/ipc.h | 31 ++++++++++++++ app/src/main/cpp/core/hos/kernel/kernel.h | 2 + app/src/main/cpp/core/hos/kernel/svc.cpp | 34 +++++++++++++++- 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 app/src/main/cpp/core/hos/kernel/ipc.cpp create mode 100644 app/src/main/cpp/core/hos/kernel/ipc.h diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index e5db56af..ea548beb 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(lightswitch SHARED ${source_DIR}/core/arm/cpu.cpp ${source_DIR}/core/arm/memory.cpp + ${source_DIR}/core/hos/kernel/ipc.cpp ${source_DIR}/core/hos/kernel/kernel.cpp ${source_DIR}/core/hos/kernel/svc.cpp ${source_DIR}/core/hos/loaders/nro.cpp diff --git a/app/src/main/cpp/core/hos/kernel/ipc.cpp b/app/src/main/cpp/core/hos/kernel/ipc.cpp new file mode 100644 index 00000000..8fdba736 --- /dev/null +++ b/app/src/main/cpp/core/hos/kernel/ipc.cpp @@ -0,0 +1,49 @@ +#include +#include +#include "ipc.h" + +namespace core::kernel +{ + IpcRequest::IpcRequest(uint8_t* tlsPtr) + { + for(int i = 0; i < 32; i++) + syslog(LOG_DEBUG, "%02x\t%02x %02x %02x %02x %02x %02x %02x %02x", i*8, tlsPtr[0+(i*8)], tlsPtr[1+(i*8)], tlsPtr[2+(i*8)], tlsPtr[3+(i*8)], tlsPtr[4+(i*8)], tlsPtr[5+(i*8)], tlsPtr[6+(i*8)], tlsPtr[7+(i*8)]); + syslog(LOG_DEBUG, "-----------------------"); + uint32_t word1 = ((uint32_t*)tlsPtr)[1]; + type = *(uint16_t*)tlsPtr; + xCount = tlsPtr[2] & 0xF0 >> 4; + aCount = tlsPtr[2] & 0x0F; + bCount = tlsPtr[3] & 0xF0 >> 4; + wCount = tlsPtr[3] & 0x0F; + dataSize = word1 & 0x3FF; + dataPos = 8; + + if(tlsPtr[2] || tlsPtr[3]) + { + syslog(LOG_ERR, "IPC - X/A/B/W descriptors"); + exit(0); + } + + syslog(LOG_DEBUG, "Enable handle descriptor: %s", word1 >> 31 ? "yes" : "no"); + if(word1 >> 31) + { + syslog(LOG_ERR, "IPC - Handle descriptor"); + exit(0); + } + + // Align to 16 bytes + if((dataPos % 16) != 0) + dataPos += 16 - (dataPos % 16); + dataPtr = &tlsPtr[dataPos+16]; + + syslog(LOG_DEBUG, "Type: %x", type); + syslog(LOG_DEBUG, "X descriptors: 0x%x", xCount); + syslog(LOG_DEBUG, "A descriptors: 0x%x", aCount); + syslog(LOG_DEBUG, "B descriptors: 0x%x", bCount); + syslog(LOG_DEBUG, "W descriptors: 0x%x", wCount); + syslog(LOG_DEBUG, "Raw data size: 0x%x", word1 & 0x3FF); + syslog(LOG_DEBUG, "Data offset=%x, Data size=%x", dataPos, dataSize); + syslog(LOG_DEBUG, "Payload CmdId=%i", *((uint32_t*)&tlsPtr[dataPos+8])); + syslog(LOG_DEBUG, "Setting dataPtr to %08x", dataPos+16); + } +} \ No newline at end of file diff --git a/app/src/main/cpp/core/hos/kernel/ipc.h b/app/src/main/cpp/core/hos/kernel/ipc.h new file mode 100644 index 00000000..657392b2 --- /dev/null +++ b/app/src/main/cpp/core/hos/kernel/ipc.h @@ -0,0 +1,31 @@ +#pragma once +#include + +namespace core::kernel +{ +class IpcRequest +{ +public: + IpcRequest(uint8_t* tlsPtr); + + template + T GetValue() + { + dataPos += sizeof(T); + return *reinterpret_cast(&dataPtr[dataPos-sizeof(T)]); + } + + uint16_t type, xCount, aCount, bCount, wCount; + uint32_t dataSize; + +private: + uint8_t* dataPtr; + uint32_t dataPos; +}; + +class IpcResponse +{ +public: + IpcResponse() {} +}; +} \ No newline at end of file diff --git a/app/src/main/cpp/core/hos/kernel/kernel.h b/app/src/main/cpp/core/hos/kernel/kernel.h index 9e699390..309d3c23 100644 --- a/app/src/main/cpp/core/hos/kernel/kernel.h +++ b/app/src/main/cpp/core/hos/kernel/kernel.h @@ -2,6 +2,8 @@ #include #include +#define SM_HANDLE 0xd000 // sm: is hardcoded for now + namespace core::kernel { class KObject diff --git a/app/src/main/cpp/core/hos/kernel/svc.cpp b/app/src/main/cpp/core/hos/kernel/svc.cpp index 656c896b..5a1b9a9e 100644 --- a/app/src/main/cpp/core/hos/kernel/svc.cpp +++ b/app/src/main/cpp/core/hos/kernel/svc.cpp @@ -4,10 +4,40 @@ #include #include "core/arm/cpu.h" #include "core/arm/memory.h" +#include "kernel.h" +#include "ipc.h" #include "svc.h" using namespace core::cpu; namespace core::kernel { + static uint32_t ConnectToNamedPort() + { + std::string port(8, '\0'); + memory::Read((void*)port.data(), GetRegister(UC_ARM64_REG_X1), 8); + + if(std::strcmp(port.c_str(), "sm:") == 0) + SetRegister(UC_ARM64_REG_W1, SM_HANDLE); + else + { + syslog(LOG_ERR, "svcConnectToNamedPort tried connecting to invalid port '%s'", port.c_str()); + exit(0); + } + + return 0; + } + + static uint32_t SendSyncRequest() + { + syslog(LOG_INFO, "svcSendSyncRequest called for handle 0x%x, dumping TLS:", GetRegister(UC_ARM64_REG_X0)); + uint8_t tls[0x100]; + memory::Read(&tls, 0x2000000, 0x100); + + core::kernel::IpcRequest* r = new core::kernel::IpcRequest(tls); + + exit(0); + return 0; + } + static uint32_t OutputDebugString() { std::string debug(GetRegister(UC_ARM64_REG_X1), '\0'); @@ -71,9 +101,9 @@ namespace core::kernel { {0x1c, nullptr}, {0x1d, nullptr}, {0x1e, nullptr}, - {0x1f, nullptr}, + {0x1f, ConnectToNamedPort}, {0x20, nullptr}, - {0x21, nullptr}, + {0x21, SendSyncRequest}, {0x22, nullptr}, {0x23, nullptr}, {0x24, nullptr},