Added functionality for service-list override.
Currently disabled due to devkitARM build system not in place.
This commit is contained in:
parent
d35233fb1c
commit
bb5d5b290f
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user