diff --git a/ARMv8/Interpreter.cpp b/ARMv8/Interpreter.cpp index f612bc5..107d8e1 100644 --- a/ARMv8/Interpreter.cpp +++ b/ARMv8/Interpreter.cpp @@ -21,7 +21,7 @@ static uint64_t counter; void Interpreter::Run() { debug_print ("Running with Interpreter\n"); - uint64_t estimate = 3728000, mx = 200000; + uint64_t estimate = 3728000, mx = 400000; //uint64_t estimate = 3000000, mx = 10000; //uint64_t estimate = 0, mx = 1000000; while (Cpu::GetState () == Cpu::State::Running) { diff --git a/ARMv8/MMU.cpp b/ARMv8/MMU.cpp index 723878a..267e037 100644 --- a/ARMv8/MMU.cpp +++ b/ARMv8/MMU.cpp @@ -31,7 +31,7 @@ static T ReadFromRAM(const uint64_t gpa) { template static void WriteToRAM(const uint64_t gpa, T value) { uint8_t *emu_mem = static_cast(Memory::GetRawPtr(gpa, sizeof(T))); - debug_print("WriteToRAM: 0x%lx, (%d) RawPtr(%p)\n", gpa, sizeof(T), (void *)emu_mem); + debug_print("WriteToRAM: 0x%lx, (%d) RawPtr(%p)\n", gpa, sizeof(T), (void *)emu_mem); for (uint64_t addr = gpa; addr < gpa + sizeof(T); addr++) { uint8_t byte = value & 0xff; std::memcpy (&emu_mem[addr - gpa], &byte, sizeof(uint8_t)); diff --git a/Ipc.cpp b/Ipc.cpp index b60ff78..b833767 100644 --- a/Ipc.cpp +++ b/Ipc.cpp @@ -72,10 +72,10 @@ void IpcMessage::GenBuf(unsigned int _move_cnt, unsigned int _copy_cnt, unsigned obuf[pos] = byte_swap32_str("SFCO"); } -void IpcMessage::SetErrorCode(uint32_t ecode) { - error_code = ecode; - if (raw_ptr) { - raw_ptr[(payload_off >> 2) + 2] = error_code; +void IpcMessage::SetErrorCode() { + uint32_t *buf = (uint32_t *) raw_ptr; + if (buf) { + buf[(payload_off >> 2) + 2] = error_code; } } @@ -116,10 +116,15 @@ uint32_t ProcMessage(IpcService *handler, uint8_t buf[]) { req.ParseMessage(); IpcMessage resp(obuf, is_domainobj); uint32_t ret = 0xf601; + + //#if 0 + ns_print("Incoming message\n"); + bindump(buf, 0x100); + //#endif switch(req.type) { case 2: //Close resp.GenBuf(0, 0, 0); - resp.SetErrorCode(0); + resp.error_code = 0; ret = 0x25a0b; break; case 4: //Normal @@ -132,21 +137,21 @@ uint32_t ProcMessage(IpcService *handler, uint8_t buf[]) { resp.GenBuf(0, 0, 4); is_domainobj = true; *resp.GetDataPointer(8) = handler->handle; - resp.SetErrorCode(0); + resp.error_code = 0; break; case 2: // DuplicateSession debug_print("DuplicateSession\n"); is_domainobj = false; resp.GenBuf(1, 0, 0); resp.SetMove(0, NewHandle(handler)); - resp.SetErrorCode(0); + resp.error_code = 0; ret = 0; break; case 3: // QueryPointerBufferSize debug_print("QueryPointerBufferSize\n"); resp.GenBuf(0, 0, 4); *resp.GetDataPointer(8) = 0x500; - resp.SetErrorCode(0); + resp.error_code = 0; ret = 0; break; case 4: // DuplicateSession @@ -154,7 +159,7 @@ uint32_t ProcMessage(IpcService *handler, uint8_t buf[]) { is_domainobj = false; resp.GenBuf(1, 0, 0); resp.SetMove(0, NewHandle(handler)); - resp.SetErrorCode(0); + resp.error_code = 0; ret = 0; break; default: @@ -162,8 +167,14 @@ uint32_t ProcMessage(IpcService *handler, uint8_t buf[]) { } } if (ret == 0) { + resp.SetErrorCode(); memcpy (buf, obuf, 0x100); } + //#if 0 + ns_print("Out message\n"); + bindump(buf, 0x100); + //#endif + return ret; } diff --git a/Service/Sm.cpp b/Service/Sm.cpp index 207a7ef..6fbf07d 100644 --- a/Service/Sm.cpp +++ b/Service/Sm.cpp @@ -9,7 +9,8 @@ uint32_t SmService::GetService(ServiceName _name, IpcService*& service) { std::string name = (char *) _name; if (IPC::services.find(name) == IPC::services.end()) { ns_print("Unknown service name %s\n", name.c_str()); - return 0xC15; //error code + //return 0xC15; //error code + return 0x415; //error code } service = IPC::services[name]; ns_print("Found: %s => %p\n", name.c_str(), (void *)service); diff --git a/Svc.cpp b/Svc.cpp index 70ff8f7..f1239fd 100644 --- a/Svc.cpp +++ b/Svc.cpp @@ -328,26 +328,49 @@ uint64_t OutputDebugString(uint64_t ptr, uint64_t size) { delete[] str; return 0; } -#define matchone(a, v) do { if(id1 == (a)) return make_tuple(0, (v)); } while(0) -#define matchpair(a, b, v) do { if(id1 == (a) && id2 == (b)) return make_tuple(0, (v)); } while(0) + std::tuple GetInfo(uint64_t id1, uint32_t handle, uint64_t id2) { ns_print("GetInfo id1: %llu, id2: %llu, handle: %u\n", id1, id2, handle); - matchpair(0, 0, 0xF); - matchpair(1, 0, 0xFFFFFFFF00000000); - matchpair(2, 0, 0xbb0000000); // map region - matchpair(3, 0, 0x1000000000); // size - matchpair(4, 0, Memory::heap_base); // heap region - matchpair(5, 0, Memory::heap_size); // size - matchpair(6, 0, 0x400000); - matchpair(7, 0, 0x10000); - matchpair(12, 0, 0x8000000); - matchpair(13, 0, 0x7ff8000000); - matchpair(14, 0, 0xbb0000000); // new map region - matchpair(15, 0, 0x1000000000); // size - matchpair(18, 0, 0x0100000000000036); // Title ID - matchone(11, 0); - - ns_abort ("Unknown getinfo %llu, %llu\n", id1, id2); + switch (id1) { + case GetInfoType::AllowedCpuIdBitmask: + return make_tuple(0, 0xf); + case GetInfoType::AllowedThreadPrioBitmask: + return make_tuple(0, 0xFFFFFFFF00000000); //Core::CurrentProcess()->allowed_thread_priority_mask; + case GetInfoType::MapRegionBaseAddr: + return make_tuple(0, 0xbb0000000); + case GetInfoType::MapRegionSize: + return make_tuple(0, 0x1000000000); + case GetInfoType::HeapRegionBaseAddr: + return make_tuple(0, Memory::heap_base); + case GetInfoType::HeapRegionSize: + return make_tuple(0, Memory::heap_size); + case GetInfoType::TotalMemoryUsage: + return make_tuple(0, 0x400000); + case GetInfoType::TotalHeapUsage: + return make_tuple(0, 0x10000); + case GetInfoType::IsCurrentProcessBeingDebugged: + return make_tuple(0, 0); + case GetInfoType::RandomEntropy: + return make_tuple(0, 0); + case GetInfoType::AddressSpaceBaseAddr: + return make_tuple(0, 0x8000000); + case GetInfoType::AddressSpaceSize: + return make_tuple(0, 0x7ff8000000); + case GetInfoType::NewMapRegionBaseAddr: + return make_tuple(0, 0xbb0000000); + case GetInfoType::NewMapRegionSize: + return make_tuple(0, 0x1000000000); + case GetInfoType::IsVirtualAddressMemoryEnabled: + return make_tuple(0, 1); + case GetInfoType::TitleId: + return make_tuple(0, 0x0100000000000036); + case GetInfoType::PrivilegedProcessId: + return make_tuple(0, 0); + case GetInfoType::UserExceptionContextAddr: + return make_tuple(0, 0); + default: + ns_abort ("Unknown getinfo %llu, %llu\n", id1, id2); + } } std::tuple CreateSession(uint32_t clientOut, uint32_t serverOut, uint64_t unk) { diff --git a/include/Ipc.hpp b/include/Ipc.hpp index 1d4cdc9..f3728df 100644 --- a/include/Ipc.hpp +++ b/include/Ipc.hpp @@ -28,7 +28,6 @@ public: } template T GetDataPointer(uint offset) { - ns_print("req.type=%u, raw_ptr:0x%x, payload_off:0x%x\n", type, raw_ptr, payload_off); return (T) (raw_ptr + payload_off + 8 + offset); } uint64_t GetBuffer(int btype, int num, unsigned int& size) { @@ -76,7 +75,7 @@ public: return 0; } void GenBuf(unsigned int _move_cnt, unsigned int _copy_cnt, unsigned int _data_bytes); - void SetErrorCode(uint32_t error_code); + void SetErrorCode(); void ParseMessage(); void SetMove(int offset, uint32_t handler) { uint32_t *buf = (uint32_t *) raw_ptr; diff --git a/include/IpcStubs.hpp b/include/IpcStubs.hpp index 2232845..01ae53b 100644 --- a/include/IpcStubs.hpp +++ b/include/IpcStubs.hpp @@ -812,6 +812,7 @@ namespace nv::gemcoredump { resp->error_code = GetService(req->GetDataPointer(8), temp1); if(temp1 != nullptr) resp->SetMove(0, IPC::NewHandle((IpcService *)temp1)); + ns_print("GetService = 0x%x\n", resp->error_code); return 0; } case 2: { diff --git a/include/Svc.hpp b/include/Svc.hpp index 253c869..b4f2187 100644 --- a/include/Svc.hpp +++ b/include/Svc.hpp @@ -7,6 +7,36 @@ extern std::function svc_handlers[0x80]; void Init(); +enum GetInfoType { + // 1.0.0+ + AllowedCpuIdBitmask = 0, + AllowedThreadPrioBitmask = 1, + MapRegionBaseAddr = 2, + MapRegionSize = 3, + HeapRegionBaseAddr = 4, + HeapRegionSize = 5, + TotalMemoryUsage = 6, + TotalHeapUsage = 7, + IsCurrentProcessBeingDebugged = 8, + ResourceHandleLimit = 9, + IdleTickCount = 10, + RandomEntropy = 11, + PerformanceCounter = 0xF0000002, + // 2.0.0+ + AddressSpaceBaseAddr = 12, + AddressSpaceSize = 13, + NewMapRegionBaseAddr = 14, + NewMapRegionSize = 15, + // 3.0.0+ + IsVirtualAddressMemoryEnabled = 16, + PersonalMmHeapUsage = 17, + TitleId = 18, + // 4.0.0+ + PrivilegedProcessId = 19, + // 5.0.0+ + UserExceptionContextAddr = 20, +}; + std::tuple SetHeapSize(uint64_t size); uint64_t SetMemoryAttribute(uint64_t addr, uint64_t size, uint64_t state0, uint64_t state1); uint64_t MirrorStack(uint64_t dest, uint64_t src, uint64_t size);