Skip to content

Commit

Permalink
apt: add deliver arg support to chainloader + minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
TuxSH committed Feb 25, 2023
1 parent 98324d4 commit b18f04d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
15 changes: 14 additions & 1 deletion libctru/include/3ds/services/apt.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,22 @@ void aptClearChainloader(void);
*/
void aptSetChainloader(u64 programID, u8 mediatype);

/// Configures the chainloader to launch the previous application.
void aptSetChainloaderToCaller(void);

/// Configures the chainloader to relaunch the current application (i.e. soft-reset)
void aptSetChainloaderToSelf(void);

/**
* @brief Sets the "deliver arg" and HMAC for the chainloader, which will
* be passed to the target 3DS/DS(i) application. The meaning of each
* parameter varies on a per-application basis.
* @param deliverArg Deliver arg to pass to the target application.
* @param deliverArgSize Size of the deliver arg, maximum 0x300 bytes.
* @param hmac HMAC buffer, 32 bytes. Use NULL to pass an all-zero dummy HMAC.
*/
void aptSetChainloaderArgs(const void *deliverArg, size_t deliverArgSize, const void *hmac);

/**
* @brief Gets an APT lock handle.
* @param flags Flags to use.
Expand Down Expand Up @@ -565,4 +578,4 @@ Result APT_GetSharedFont(Handle* fontHandle, u32* mapAddr);
* @param sender Pointer to output the sender's AppID to.
* @param received Pointer to output whether an argument was received to.
*/
Result APT_ReceiveDeliverArg(const void* param, size_t paramSize, const void* hmac, u64* sender, bool* received);
Result APT_ReceiveDeliverArg(void* param, size_t paramSize, void* hmac, u64* sender, bool* received);
36 changes: 31 additions & 5 deletions libctru/source/services/apt.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ enum
static u8 aptHomeButtonState;
static u32 aptFlags;
static u32 aptParameters[0x1000/4];
static u8 aptChainloadFlags;
static u64 aptChainloadTid;
static u8 aptChainloadDeliverArg[0x300];
static u32 aptChainloadDeliverArgSize = sizeof(aptChainloadDeliverArg);
static u8 aptChainloadHmac[0x20];
static u8 aptChainloadMediatype;
static u8 aptChainloadFlags;

typedef enum
{
Expand Down Expand Up @@ -315,6 +318,9 @@ static void aptClearJumpToHome(void)
void aptClearChainloader(void)
{
aptFlags &= ~FLAG_CHAINLOAD;
aptChainloadDeliverArgSize = sizeof(aptChainloadDeliverArg);
memset(aptChainloadDeliverArg, 0, sizeof(aptChainloadDeliverArg));
memset(aptChainloadHmac, 0, sizeof(aptChainloadHmac));
}

void aptSetChainloader(u64 programID, u8 mediatype)
Expand All @@ -325,6 +331,14 @@ void aptSetChainloader(u64 programID, u8 mediatype)
aptChainloadMediatype = mediatype;
}

void aptSetChainloaderToCaller(void)
{
aptFlags |= FLAG_CHAINLOAD;
aptChainloadFlags = 1;
aptChainloadTid = 0;
aptChainloadMediatype = 0;
}

void aptSetChainloaderToSelf(void)
{
aptFlags |= FLAG_CHAINLOAD;
Expand All @@ -333,6 +347,20 @@ void aptSetChainloaderToSelf(void)
aptChainloadMediatype = 0;
}

void aptSetChainloaderArgs(const void *deliverArg, size_t deliverArgSize, const void *hmac)
{
if (deliverArgSize >= sizeof(aptChainloadDeliverArg))
deliverArgSize = sizeof(aptChainloadDeliverArg);

aptChainloadDeliverArgSize = deliverArgSize;
memcpy(aptChainloadDeliverArg, deliverArg, deliverArgSize);

if (hmac != NULL)
memcpy(aptChainloadHmac, hmac, sizeof(aptChainloadHmac));
else
memset(aptChainloadHmac, 0, sizeof(aptChainloadHmac));
}

extern void (*__system_retAddr)(void);

static void aptExitProcess(void)
Expand Down Expand Up @@ -370,10 +398,8 @@ void aptExit(void)
if (R_SUCCEEDED(APT_IsRegistered(aptGetMenuAppID(), &hmRegistered)) && hmRegistered)
{
// Normal, sane chainload
u8 param[0x300] = {0};
u8 hmac[0x20] = {0};
APT_PrepareToDoApplicationJump(aptChainloadFlags, aptChainloadTid, aptChainloadMediatype);
APT_DoApplicationJump(param, sizeof(param), hmac);
APT_DoApplicationJump(aptChainloadDeliverArg, aptChainloadDeliverArgSize, aptChainloadHmac);
}
else
{
Expand Down Expand Up @@ -1430,7 +1456,7 @@ Result APT_GetSharedFont(Handle* fontHandle, u32* mapAddr)
return ret;
}

Result APT_ReceiveDeliverArg(const void* param, size_t paramSize, const void* hmac, u64* sender, bool* received)
Result APT_ReceiveDeliverArg(void* param, size_t paramSize, void* hmac, u64* sender, bool* received)
{
u32 cmdbuf[16];
cmdbuf[0]=IPC_MakeHeader(0x35,2,0); // 0x350080
Expand Down

0 comments on commit b18f04d

Please sign in to comment.