]> Chaos Git - corbenik/ctrulib.git/commitdiff
Added functionality for service-list override.
authorplutoo <plutoo@univor.se>
Tue, 12 Aug 2014 20:41:40 +0000 (22:41 +0200)
committerplutoo <plutoo@univor.se>
Tue, 12 Aug 2014 20:41:40 +0000 (22:41 +0200)
Currently disabled due to devkitARM build system not in place.

libctru/source/srv.c

index da34c35ac508ef17dc35d95bf1bd6a112f773f57..4365b44483443a46015fefe8779f96af8be17740 100644 (file)
@@ -7,8 +7,63 @@
 #include <3ds/svc.h>
 
 
+#ifdef SRV_OVERRIDE_SUPPORT
+/*
+  The homebrew loader can choose to supply a list of service handles that have
+  been "stolen" from other processes that have been compromised. This allows us
+  to access services that are normally restricted from the current process.
+
+  For every service requested by the application, we shall first check if the
+  list given to us contains the requested service and if so use it. If we don't
+  find the service in that list, we ask the service manager and hope for the
+  best.
+ */
+
+typedef struct {
+    u32 num;
+
+    struct {
+        char name[8];
+        Handle handle;
+    } services[];
+} service_list_t;
+
+extern service_list_t* _service_ptr;
+#endif
+
 static Handle g_srv_handle = 0;
 
+
+
+#ifdef SRV_OVERRIDE_SUPPORT
+static int __name_cmp(const char* a, const char* b) {
+    u32 i;
+
+    for(i=0; i<8; i++) {
+        if(a[i] != b[i])
+            return 1;
+        if(a[i] == '\0')
+            return 0;
+    }
+
+    return 0;
+}
+
+static Handle __get_handle_from_list(char* name) {
+    if((u32)_service_ptr == 0)
+        return 0;
+
+    u32 i, num = _service_ptr->num;
+
+    for(i=0; i<num; i++) {
+        if(__name_cmp(_service_ptr->services[i].name, name) == 0)
+            return _service_ptr->services[i].handle;
+    }
+
+    return 0;
+}
+#endif
+
 Result srvInit()
 {
     Result rc = 0;
@@ -30,6 +85,7 @@ Result srvExit()
         svcCloseHandle(g_srv_handle);
 
     g_srv_handle = 0;
+    return 0;
 }
 
 Result srvRegisterClient()
@@ -47,15 +103,24 @@ Result srvRegisterClient()
 
 Result srvGetServiceHandle(Handle* out, char* name)
 {
-    u8 len = strlen(name);
-    Result rc;
+#ifdef SRV_OVERRIDE_SUPPORT
+    /* Look in service-list given to us by loader. If we find find a match,
+       we return it. */
+    Handle h = __get_handle_from_list(name);
 
+    if(h != 0) {
+       *out = h; return 0;
+    }
+#endif
+
+    /* Normal request to service manager. */
     u32* cmdbuf = getThreadCommandBuffer();
     cmdbuf[0] = 0x50100;
     strcpy((char*) &cmdbuf[1], name);
-    cmdbuf[3] = len;
+    cmdbuf[3] = strlen(name);
     cmdbuf[4] = 0x0;
 
+    Result rc;
     if(rc = svcSendSyncRequest(g_srv_handle))
         return rc;