Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ INITIALIZE_PLUGIN() {
}

DEINITIALIZE_PLUGIN() {
token::resetTokens();
curl_global_cleanup();
patches::icon::perform_hbm_patches(false);

Expand Down
9 changes: 7 additions & 2 deletions src/patches/aistFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,19 @@ DECL_FUNCTION(int, AcquireIndependentServiceToken__Q2_2nn3actFPcPCcUibT4, uint8_
if (client_id && utils::isVinoClientID(client_id) && config::connectToRose) {
AISTCallCount++;
DEBUG_FUNCTION_LINE("AISTCallCount is %d!", AISTCallCount);

patches::ssl::addCertificateToWebKit();
DEBUG_FUNCTION_LINE("Faking service sucess for '%s' (should be Vino)", client_id);
DEBUG_FUNCTION_LINE("Size: %d", token::currentReplacementToken.size());

DEBUG_FUNCTION_LINE("Replacing token with %s", token::currentReplacementToken.c_str());
memcpy(token, token::currentReplacementToken.c_str(), token::currentReplacementToken.size());
DEBUG_FUNCTION_LINE("Patched %s", token);

DEBUG_FUNCTION_LINE("Faking service sucess for '%s' (should be Vino)", client_id);
return 0;
}

DEBUG_FUNCTION_LINE("Not faking - calling real");

// make sure we set the token again in case the following replaces it just in case
return real_AcquireIndependentServiceToken__Q2_2nn3actFPcPCcUibT4(token, client_id);
}
Expand Down
198 changes: 51 additions & 147 deletions src/utils/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,87 +13,19 @@
#include <sysapp/title.h>

#include "token.hpp"
#include "utils/utils.hpp"
#include "utils/logger.h"
#include "utils/Notification.hpp"
#include "logger.h"
#include "Notification.hpp"

extern "C" MCPError MCP_GetDeviceId(int handle, char* out);
extern "C" MCPError MCP_GetCompatDeviceId(int handle, char* out);

namespace token {
std::string currentReplacementToken = "";
std::vector<std::string> roseKeys(13);

char replacementToken1[20];
char replacementToken2[20];
char replacementToken3[20];
char replacementToken4[20];
char replacementToken5[20];
char replacementToken6[20];
char replacementToken7[20];
char replacementToken8[20];
char replacementToken9[20];
char replacementToken10[20];
char replacementToken11[20];
char replacementToken12[20];
char codeId[8];
char serialId[12];

void setReplacementToken(char token[20], nn::act::SlotNo slot) {
// really stupid thing i am gonna do but yeahaha
switch (slot) {
case 1:
strcpy(replacementToken1, token);
break;

case 2:
strcpy(replacementToken2, token);
break;

case 3:
strcpy(replacementToken3, token);
break;

case 4:
strcpy(replacementToken4, token);
break;

case 5:
strcpy(replacementToken5, token);
break;

case 6:
strcpy(replacementToken6, token);
break;

case 7:
strcpy(replacementToken7, token);
break;

case 8:
strcpy(replacementToken8, token);
break;

case 9:
strcpy(replacementToken9, token);
break;

case 10:
strcpy(replacementToken10, token);
break;

case 11:
strcpy(replacementToken11, token);
break;

case 12:
strcpy(replacementToken12, token);
break;

default:
break;
}
}

void initToken() {
// enable RNG in case we need it.
srand(time(NULL));
Expand All @@ -114,19 +46,15 @@ namespace token {
MCP_Close(handle);

unsigned int pid = 0;
char key[20] = { '\0' };
for (size_t i = 1; i < 12; i++) {
if (!nn::act::IsSlotOccupied(i)) {
// No more accounts
DEBUG_FUNCTION_LINE("Slot %d not occupied", i);
return;
}
std::string key;

// FIXME: < or <=?
for (uint8_t accountSlot = 1; accountSlot < nn::act::GetNumOfAccounts(); accountSlot++) {
// may help with instability issues?
OSMemoryBarrier();

nn::act::GetPrincipalIdEx(&pid, i);
DEBUG_FUNCTION_LINE("index %d, pid: %d", i, pid);
nn::act::GetPrincipalIdEx(&pid, accountSlot);
DEBUG_FUNCTION_LINE("index %d, pid: %d", accountSlot, pid);
if(pid == 0) {
DEBUG_FUNCTION_LINE("PID is 0; account probably not linked to NNID/PNID");
continue;
Expand All @@ -141,95 +69,71 @@ namespace token {

fp = fopen(filePath.c_str(), "w");

std::string newKey = ""; // Ensure reset
key.clear(); // Ensure we are empty

// open disclosure: made w/ help of chatgpt
for(int i = 0; i < 17; i++) {
int randNum = rand() % 62;
char randNum = rand() % 62;
if (randNum < 26) {
newKey += 'a' + randNum; // lowercase letters a-z
key += 'a' + randNum; // lowercase letters a-z
} else if (randNum < 52) {
newKey += 'A' + (randNum - 26); // uppercase letters A-Z
key += 'A' + (randNum - 26); // uppercase letters A-Z
} else {
newKey += '0' + (randNum - 52); // digits 0-9
key += '0' + (randNum - 52); // digits 0-9
}
}

newKey.shrink_to_fit();
key.shrink_to_fit();

DEBUG_FUNCTION_LINE("newly generated key: %s", newKey.c_str());
fputs(newKey.c_str(), fp);
strcpy(key, newKey.c_str());

newKey = "";
DEBUG_FUNCTION_LINE("newly generated key: %s", key.c_str());
fputs(key.c_str(), fp);

fclose(fp);
} else {
fread(key, 20, 1, fp);
DEBUG_FUNCTION_LINE("read key: %s", key);
char buf[20];
fread(buf, 20, 1, fp);

buf[17] = '\0'; // null terminate

key = std::string(buf);
key.shrink_to_fit();

DEBUG_FUNCTION_LINE("read key: %s", key.c_str());

fclose(fp);
}

setReplacementToken(key, i);
DEBUG_FUNCTION_LINE("slot: %d", accountSlot);
DEBUG_FUNCTION_LINE("old vec data: %s", roseKeys.at(accountSlot).c_str());
if(roseKeys.at(accountSlot).empty()) {
roseKeys.insert(roseKeys.begin() + accountSlot, key);
DEBUG_FUNCTION_LINE("new vec data: %s", roseKeys.at(accountSlot).c_str());
} else {
DEBUG_FUNCTION_LINE("not empty, was %s", roseKeys.at(accountSlot).c_str());
}
}

// when we are done:
roseKeys.shrink_to_fit();

updCurrentToken();
}

// This sounds pointless, but if we don't want to double insert things
void resetTokens() {
DEBUG_FUNCTION_LINE("Resetting tokens");
roseKeys.clear();
roseKeys.shrink_to_fit();

roseKeys.reserve(13);
}

void updCurrentToken() {
DEBUG_FUNCTION_LINE("Getting token from slot %d", nn::act::GetSlotNo());
switch (nn::act::GetSlotNo()) {
case 1:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken1, codeId, serialId);
break;

case 2:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken2, codeId, serialId);
break;

case 3:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken3, codeId, serialId);
break;

case 4:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken4, codeId, serialId);
break;

case 5:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken5, codeId, serialId);
break;

case 6:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken6, codeId, serialId);
break;

case 7:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken7, codeId, serialId);
break;

case 8:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken8, codeId, serialId);
break;

case 9:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken9, codeId, serialId);
break;

case 10:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken10, codeId, serialId);
break;

case 11:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken11, codeId, serialId);
break;

case 12:
currentReplacementToken = std::format("[{}, {}, {}]", replacementToken12, codeId, serialId);
break;

default:
break;
}

currentReplacementToken = std::format("[{}, {}, {}]", roseKeys.at(nn::act::GetSlotNo()), codeId, serialId);
reverse(std::next(currentReplacementToken.begin()), std::prev(currentReplacementToken.end()));

DEBUG_FUNCTION_LINE("result: %s", currentReplacementToken.c_str());
}
} // namespace token
} // namespace token
1 change: 1 addition & 0 deletions src/utils/token.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ namespace token

void setReplacementToken(std::string token, nn::act::SlotNo slot);
void initToken();
void resetTokens();
void updCurrentToken();
} // namespace token
Loading