#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;
svcCloseHandle(g_srv_handle);
g_srv_handle = 0;
+ return 0;
}
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;