Added functionality for service-list override.

Currently disabled due to devkitARM build system not in place.
This commit is contained in:
plutoo 2014-08-12 22:41:40 +02:00
parent d35233fb1c
commit bb5d5b290f

View File

@ -7,8 +7,63 @@
#include <3ds/svc.h> #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; 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 srvInit()
{ {
Result rc = 0; Result rc = 0;
@ -30,6 +85,7 @@ Result srvExit()
svcCloseHandle(g_srv_handle); svcCloseHandle(g_srv_handle);
g_srv_handle = 0; g_srv_handle = 0;
return 0;
} }
Result srvRegisterClient() Result srvRegisterClient()
@ -47,15 +103,24 @@ Result srvRegisterClient()
Result srvGetServiceHandle(Handle* out, char* name) Result srvGetServiceHandle(Handle* out, char* name)
{ {
u8 len = strlen(name); #ifdef SRV_OVERRIDE_SUPPORT
Result rc; /* 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(); u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x50100; cmdbuf[0] = 0x50100;
strcpy((char*) &cmdbuf[1], name); strcpy((char*) &cmdbuf[1], name);
cmdbuf[3] = len; cmdbuf[3] = strlen(name);
cmdbuf[4] = 0x0; cmdbuf[4] = 0x0;
Result rc;
if(rc = svcSendSyncRequest(g_srv_handle)) if(rc = svcSendSyncRequest(g_srv_handle))
return rc; return rc;