diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7eea5c9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# All Files +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +tab_width = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +# Makefile +[Makefile] +indent_style = tab diff --git a/.github/workflows/built.yml b/.github/workflows/built.yml index e60d6da..9af4df7 100644 --- a/.github/workflows/built.yml +++ b/.github/workflows/built.yml @@ -27,7 +27,7 @@ jobs: # Set current version for release naming - name: Set current version id: version - run: echo "VERSION=2.4${{ github.run_number }}" >> "$GITHUB_OUTPUT" + run: echo "VERSION=2.5${{ github.run_number }}" >> "$GITHUB_OUTPUT" # Replace version number and build - name: Built diff --git a/README.md b/README.md index a544b5a..cf866d3 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A Nintendo Switch (CFW) sys-module that allows users to remote control their Swi ### Remote Control: - Set controller state -- Simulate buttons press, hold, and release +- Simulate button press, hold, and release - Simulate touch screen drawing ### Memory Reading and Writing: diff --git a/sys-botbase/source/args.c b/sys-botbase/source/args.c index 5c27cc0..8f907d9 100644 --- a/sys-botbase/source/args.c +++ b/sys-botbase/source/args.c @@ -2,15 +2,15 @@ #include #include -int parseArgs(char *origargstr, int (*callback)(int, char **)) +int parseArgs(char* origargstr, int (*callback)(int, char**)) { - char *argstr = malloc(strlen(origargstr) + 1); + char* argstr = malloc(strlen(origargstr) + 1); memcpy(argstr, origargstr, strlen(origargstr) + 1); int argc = 0; - char *tmpstr = malloc(strlen(argstr) + 1); + char* tmpstr = malloc(strlen(argstr) + 1); memcpy(tmpstr, argstr, strlen(argstr) + 1); - for (char *p = strtok(tmpstr, " \r\n"); p != NULL; p = strtok(NULL, " \r\n")) { + for (char* p = strtok(tmpstr, " \r\n"); p != NULL; p = strtok(NULL, " \r\n")) { argc++; } free(tmpstr); @@ -20,9 +20,9 @@ int parseArgs(char *origargstr, int (*callback)(int, char **)) return (*callback)(argc, NULL); } - char **argv = malloc(sizeof(char *) * argc); + char** argv = malloc(sizeof(char*) * argc); int i = 0; - for (char *p = strtok(argstr, " \r\n"); p != NULL; p = strtok(NULL, " \r\n")) + for (char* p = strtok(argstr, " \r\n"); p != NULL; p = strtok(NULL, " \r\n")) argv[i++] = p; int ret = (*callback)(argc, argv); diff --git a/sys-botbase/source/commands.c b/sys-botbase/source/commands.c index cba0b4d..bee2551 100644 --- a/sys-botbase/source/commands.c +++ b/sys-botbase/source/commands.c @@ -11,9 +11,9 @@ //Controller: bool bControllerIsInitialised = false; HidDeviceType controllerInitializedType = HidDeviceType_FullKey3; -HiddbgHdlsHandle controllerHandle = {0}; -HiddbgHdlsDeviceInfo controllerDevice = {0}; -HiddbgHdlsState controllerState = {0}; +HiddbgHdlsHandle controllerHandle = { 0 }; +HiddbgHdlsDeviceInfo controllerDevice = { 0 }; +HiddbgHdlsState controllerState = { 0 }; USBResponse response; time_t curTime = 0; @@ -21,16 +21,16 @@ time_t origTime = 0; time_t unixTime = 0; //Keyboard: -HiddbgKeyboardAutoPilotState dummyKeyboardState = {0}; +HiddbgKeyboardAutoPilotState dummyKeyboardState = { 0 }; Handle debughandle = 0; u64 buttonClickSleepTime = 50; u64 keyPressSleepTime = 25; u64 pollRate = 17; // polling is linked to screen refresh rate (system UI) or game framerate. Most cases this is 1/60 or 1/30 u32 fingerDiameter = 50; -HiddbgHdlsSessionId sessionId = {0}; -bool initflag=0; -u8 *workmem = NULL; +HiddbgHdlsSessionId sessionId = { 0 }; +bool initflag = 0; +u8* workmem = NULL; size_t workmem_size = 0x1000; void attach() @@ -48,28 +48,32 @@ void attach() printf("svcDebugActiveProcess: %d\n", rc); } -void detach(){ +void detach() { if (debughandle != 0) svcCloseHandle(debughandle); } -u64 getMainNsoBase(u64 pid){ +u64 getMainNsoBase(u64 pid) { LoaderModuleInfo proc_modules[2]; s32 numModules = 0; Result rc = ldrDmntGetProcessModuleInfo(pid, proc_modules, 2, &numModules); - if (R_FAILED(rc) && debugResultCodes) - printf("ldrDmntGetProcessModuleInfo: %d\n", rc); + if (R_FAILED(rc)) { + if (debugResultCodes) + printf("ldrDmntGetProcessModuleInfo: %d\n", rc); + return 0; + } - LoaderModuleInfo *proc_module = 0; - if(numModules == 2){ + LoaderModuleInfo* proc_module = 0; + if (numModules == 2) { proc_module = &proc_modules[1]; - }else{ + } + else { proc_module = &proc_modules[0]; } return proc_module->base_address; } -u64 getHeapBase(Handle handle){ +u64 getHeapBase(Handle handle) { u64 heap_base = 0; Result rc = svcGetInfo(&heap_base, InfoType_HeapRegionAddress, debughandle, 0); if (R_FAILED(rc) && debugResultCodes) @@ -78,7 +82,7 @@ u64 getHeapBase(Handle handle){ return heap_base; } -u64 getTitleId(u64 pid){ +u64 getTitleId(u64 pid) { u64 titleId = 0; Result rc = pminfoGetProgramId(&titleId, pid); if (R_FAILED(rc) && debugResultCodes) @@ -86,15 +90,21 @@ u64 getTitleId(u64 pid){ return titleId; } -u64 GetTitleVersion(u64 pid){ +u64 GetTitleVersion(u64 pid) { u64 titleV = 0; s32 out; Result rc = nsInitialize(); - if (R_FAILED(rc)) + if (R_FAILED(rc)) fatalThrow(rc); - NsApplicationContentMetaStatus *MetaStatus = malloc(sizeof(NsApplicationContentMetaStatus[100U])); + NsApplicationContentMetaStatus* MetaStatus = malloc(sizeof(NsApplicationContentMetaStatus[100U])); + if (MetaStatus == NULL) { + // Handle allocation failure + printf("Failed to allocate memory for MetaStatus\n"); + nsExit(); + return 0; // or another appropriate error value + } rc = nsListApplicationContentMetaStatus(getTitleId(pid), 0, MetaStatus, 100, &out); if (R_FAILED(rc) && debugResultCodes) printf("nsListApplicationContentMetaStatus: %d\n", rc); @@ -108,7 +118,7 @@ u64 GetTitleVersion(u64 pid){ return (titleV / 0x10000); } -u64 getoutsize(NsApplicationControlData* buf){ +u64 getoutsize(NsApplicationControlData* buf) { Result rc = nsInitialize(); if (R_FAILED(rc)) fatalThrow(rc); @@ -122,32 +132,43 @@ u64 getoutsize(NsApplicationControlData* buf){ nsExit(); return outsize; } -void getBuildID(MetaData* meta, u64 pid){ + +void getBuildID(MetaData* meta, u64 pid) { LoaderModuleInfo proc_modules[2]; s32 numModules = 0; Result rc = ldrDmntGetProcessModuleInfo(pid, proc_modules, 2, &numModules); - if (R_FAILED(rc) && debugResultCodes) - printf("ldrDmntGetProcessModuleInfo: %d\n", rc); + if (R_FAILED(rc)) { + if (debugResultCodes) + printf("ldrDmntGetProcessModuleInfo: %d\n", rc); + memset(meta->buildID, 0, 0x20); + return; + } - LoaderModuleInfo *proc_module = 0; - if(numModules == 2){ + LoaderModuleInfo* proc_module = 0; + if (numModules == 2) { proc_module = &proc_modules[1]; - }else{ + } + else { proc_module = &proc_modules[0]; } memcpy(meta->buildID, proc_module->build_id, 0x20); } -MetaData getMetaData(){ +MetaData getMetaData() { MetaData meta; attach(); - u64 pid = 0; + u64 pid = 0; Result rc = pmdmntGetApplicationProcessId(&pid); - if (R_FAILED(rc) && debugResultCodes) - printf("pmdmntGetApplicationProcessId: %d\n", rc); - + if (R_FAILED(rc)) { + if (debugResultCodes) + printf("pmdmntGetApplicationProcessId: %d\n", rc); + detach(); + memset(&meta, 0, sizeof(meta)); + return meta; + } + meta.main_nso_base = getMainNsoBase(pid); - meta.heap_base = getHeapBase(debughandle); + meta.heap_base = getHeapBase(debughandle); meta.titleID = getTitleId(pid); meta.titleVersion = GetTitleVersion(pid); getBuildID(&meta, pid); @@ -158,7 +179,7 @@ MetaData getMetaData(){ bool getIsProgramOpen(u64 id) { - u64 pid = 0; + u64 pid = 0; Result rc = pmdmntGetProcessId(&pid, id); if (pid == 0 || R_FAILED(rc)) return false; @@ -168,11 +189,11 @@ bool getIsProgramOpen(u64 id) void initController() { - if(bControllerIsInitialised) return; + if (bControllerIsInitialised) return; //taken from switchexamples github Result rc = hiddbgInitialize(); - if (R_FAILED(rc) && debugResultCodes) { + if (R_FAILED(rc) && debugResultCodes) { printf("hiddbgInitialize(): 0x%x\n", rc); } else { @@ -181,15 +202,15 @@ void initController() initflag = 1; else printf("workmem alloc failed\n"); } - - // Set the controller type to Pro-Controller, and set the npadInterfaceType. + + // Set the controller type to Pro-Controller, and set the npadInterfaceType. controllerDevice.deviceType = controllerInitializedType; controllerDevice.npadInterfaceType = HidNpadInterfaceType_Bluetooth; // Set the controller colors. The grip colors are for Pro-Controller on [9.0.0+]. - controllerDevice.singleColorBody = RGBA8_MAXALPHA(255,255,255); - controllerDevice.singleColorButtons = RGBA8_MAXALPHA(0,0,0); - controllerDevice.colorLeftGrip = RGBA8_MAXALPHA(230,255,0); - controllerDevice.colorRightGrip = RGBA8_MAXALPHA(0,40,20); + controllerDevice.singleColorBody = RGBA8_MAXALPHA(255, 255, 255); + controllerDevice.singleColorButtons = RGBA8_MAXALPHA(0, 0, 0); + controllerDevice.colorLeftGrip = RGBA8_MAXALPHA(230, 255, 0); + controllerDevice.colorRightGrip = RGBA8_MAXALPHA(0, 40, 20); // Setup example controller state. controllerState.battery_level = 4; // Set battery charge to full. @@ -220,7 +241,7 @@ void detachController() if (R_FAILED(rc) && debugResultCodes) printf("hiddbgReleaseHdlsWorkBuffer: %d\n", rc); hiddbgExit(); - free(workmem); + free(workmem); bControllerIsInitialised = false; sessionId.id = 0; } @@ -241,11 +262,23 @@ void writeMem(u64 offset, u64 size, u8* val) void peek(u64 offset, u64 size) { - u8 *out = malloc(sizeof(u8) * size); + u8* out = malloc(sizeof(u8) * size); + if (out == NULL) { + printf("\n"); + return; + } attach(); - readMem(out, offset, size); - detach(); + Result rc = readMem(out, offset, size); + if (R_FAILED(rc)) + { + if (!usb) + printf("\n"); + detach(); + free(out); + return; + } + detach(); if (usb) { response.size = size; @@ -253,12 +286,12 @@ void peek(u64 offset, u64 size) sendUsbResponse(response); } else - { - u64 i; - for (i = 0; i < size; i++) - printf("%02X", out[i]); + { + u64 i; + for (i = 0; i < size; i++) + printf("%02X", out[i]); printf("\n"); - } + } free(out); } @@ -266,17 +299,31 @@ void peekInfinite(u64 offset, u64 size) { u64 sizeRemainder = size; u64 totalFetched = 0; - u8 *out = malloc(sizeof(u8) * MAX_LINE_LENGTH); - u8 *usbOut = malloc(size); + u64 i; + u8* out = malloc(sizeof(u8) * MAX_LINE_LENGTH); + u8* usbOut = malloc(size); + if (out == NULL || usbOut == NULL) { + // add USB handling + printf("\n"); + return; + } attach(); while (sizeRemainder > 0) { u64 thisBuffersize = sizeRemainder > MAX_LINE_LENGTH ? MAX_LINE_LENGTH : sizeRemainder; sizeRemainder -= thisBuffersize; - readMem(out, offset + totalFetched, thisBuffersize); + Result rc = readMem(out, offset + totalFetched, thisBuffersize); + if (R_FAILED(rc)) + { + if (!usb) + printf("\n"); + detach(); + free(out); + free(usbOut); + return; + } - u64 i; for (i = 0; i < thisBuffersize; i++) { if (usb) @@ -305,38 +352,47 @@ void peekMulti(u64* offset, u64* size, u64 count) u64 totalSize = 0; for (int i = 0; i < count; i++) totalSize += size[i]; - - u8 *out = malloc(sizeof(u8) * totalSize); + + u8* out = malloc(sizeof(u8) * totalSize); u64 ofs = 0; attach(); for (int i = 0; i < count; i++) { - readMem(out + ofs, offset[i], size[i]); + Result rc = readMem(out + ofs, offset[i], size[i]); + if (R_FAILED(rc)) + { + if (!usb) + printf("\n"); + detach(); + free(out); + return; + } ofs += size[i]; } - detach(); + detach(); if (usb) { response.size = totalSize; response.data = &out[0]; sendUsbResponse(response); - } - else - { - u64 i; - for (i = 0; i < totalSize; i++) - printf("%02X", out[i]); + } + else + { + u64 i; + for (i = 0; i < totalSize; i++) + printf("%02X", out[i]); printf("\n"); - } + } free(out); } -void readMem(u8* out, u64 offset, u64 size) +Result readMem(u8* out, u64 offset, u64 size) { Result rc = svcReadDebugProcessMemory(out, debughandle, offset, size); if (R_FAILED(rc) && debugResultCodes) printf("svcReadDebugProcessMemory: %d\n", rc); + return rc; } void click(HidNpadButton btn) @@ -386,30 +442,45 @@ void reverseArray(u8* arr, int start, int end) int temp; while (start < end) { - temp = arr[start]; + temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; start++; end--; - } -} + } +} -u64 followMainPointer(s64* jumps, size_t count) +u64 followMainPointer(s64* jumps, size_t count) { u64 offset; u64 size = sizeof offset; u8* out = malloc(size); - MetaData meta = getMetaData(); - + MetaData meta = getMetaData(); + if (meta.main_nso_base == 0) + return 0; + attach(); - readMem(out, meta.main_nso_base + jumps[0], size); + Result rc = readMem(out, meta.main_nso_base + jumps[0], size); + if (R_FAILED(rc)) + { + detach(); + free(out); + return 0; + } offset = *(u64*)out; + int i; for (i = 1; i < count; ++i) { - readMem(out, offset + jumps[i], size); + rc = readMem(out, offset + jumps[i], size); + if (R_FAILED(rc)) + { + detach(); + free(out); + return 0; + } offset = *(u64*)out; - // this traversal resulted in an error + // This traversal resulted in an error if (offset == 0) break; } @@ -437,19 +508,19 @@ void touch(HidTouchState* state, u64 sequentialCount, u64 holdTime, bool hold, u break; } - if(hold) // send finger release event + if (hold) // send finger release event { hiddbgSetTouchScreenAutoPilotState(NULL, 0); svcSleepThread(pollRate * 1e+6L); } - + hiddbgUnsetTouchScreenAutoPilotState(); } void key(HiddbgKeyboardAutoPilotState* states, u64 sequentialCount) { initController(); - HiddbgKeyboardAutoPilotState tempState = {0}; + HiddbgKeyboardAutoPilotState tempState = { 0 }; u32 i; for (i = 0; i < sequentialCount; i++) { @@ -458,9 +529,9 @@ void key(HiddbgKeyboardAutoPilotState* states, u64 sequentialCount) hiddbgSetKeyboardAutoPilotState(&tempState); svcSleepThread(keyPressSleepTime * 1e+6L); - if (i != (sequentialCount-1)) + if (i != (sequentialCount - 1)) { - if (memcmp(states[i].keys, states[i+1].keys, sizeof(u64) * 4) == 0 && states[i].modifiers == states[i+1].modifiers) + if (memcmp(states[i].keys, states[i + 1].keys, sizeof(u64) * 4) == 0 && states[i].modifiers == states[i + 1].modifiers) { hiddbgSetKeyboardAutoPilotState(&dummyKeyboardState); svcSleepThread(pollRate * 1e+6L); @@ -485,7 +556,7 @@ void clickSequence(char* seq, u8* token) const char startLStick = '%'; const char startRStick = '&'; char* command = strtok(seq, &delim); - HidNpadButton currKey = {0}; + HidNpadButton currKey = { 0 }; u64 currentWait = 0; initController(); @@ -498,28 +569,28 @@ void clickSequence(char* seq, u8* token) { // l stick s64 x = parseStringToSignedLong(&command[1]); - if(x > JOYSTICK_MAX) x = JOYSTICK_MAX; - if(x < JOYSTICK_MIN) x = JOYSTICK_MIN; + if (x > JOYSTICK_MAX) x = JOYSTICK_MAX; + if (x < JOYSTICK_MIN) x = JOYSTICK_MIN; s64 y = 0; command = strtok(NULL, &delim); if (command != NULL) y = parseStringToSignedLong(command); - if(y > JOYSTICK_MAX) y = JOYSTICK_MAX; - if(y < JOYSTICK_MIN) y = JOYSTICK_MIN; + if (y > JOYSTICK_MAX) y = JOYSTICK_MAX; + if (y < JOYSTICK_MIN) y = JOYSTICK_MIN; setStickState(JOYSTICK_LEFT, (s32)x, (s32)y); } else if (!strncmp(command, &startRStick, 1)) { // r stick s64 x = parseStringToSignedLong(&command[1]); - if(x > JOYSTICK_MAX) x = JOYSTICK_MAX; - if(x < JOYSTICK_MIN) x = JOYSTICK_MIN; + if (x > JOYSTICK_MAX) x = JOYSTICK_MAX; + if (x < JOYSTICK_MIN) x = JOYSTICK_MIN; s64 y = 0; command = strtok(NULL, &delim); if (command != NULL) y = parseStringToSignedLong(command); - if(y > JOYSTICK_MAX) y = JOYSTICK_MAX; - if(y < JOYSTICK_MIN) y = JOYSTICK_MIN; + if (y > JOYSTICK_MAX) y = JOYSTICK_MAX; + if (y < JOYSTICK_MIN) y = JOYSTICK_MIN; setStickState(JOYSTICK_RIGHT, (s32)x, (s32)y); } else if (!strncmp(command, &startPress, 1)) @@ -527,13 +598,13 @@ void clickSequence(char* seq, u8* token) // press currKey = parseStringToButton(&command[1]); press(currKey); - } + } else if (!strncmp(command, &startRelease, 1)) { // release currKey = parseStringToButton(&command[1]); release(currKey); - } + } else if (!strncmp(command, &startWait, 1)) { // wait diff --git a/sys-botbase/source/commands.h b/sys-botbase/source/commands.h index 54c5d7b..ee0e698 100644 --- a/sys-botbase/source/commands.h +++ b/sys-botbase/source/commands.h @@ -65,7 +65,7 @@ void writeMem(u64 offset, u64 size, u8* val); void peek(u64 offset, u64 size); void peekInfinite(u64 offset, u64 size); void peekMulti(u64* offset, u64* size, u64 count); -void readMem(u8* out, u64 offset, u64 size); +Result readMem(u8* out, u64 offset, u64 size); void click(HidNpadButton btn); void press(HidNpadButton btn); void release(HidNpadButton btn); @@ -80,4 +80,4 @@ void dateSet(uint64_t date); void resetTime(); void resetTimeNTP(); long getUnixTime(); -long getCurrentTime(); \ No newline at end of file +long getCurrentTime(); diff --git a/sys-botbase/source/freeze.c b/sys-botbase/source/freeze.c index 62b6804..15cb95a 100644 --- a/sys-botbase/source/freeze.c +++ b/sys-botbase/source/freeze.c @@ -12,89 +12,89 @@ FreezeBlock* freezes; void initFreezes(void) { - freezes = calloc(FREEZE_DIC_LENGTH, sizeof(FreezeBlock)); + freezes = calloc(FREEZE_DIC_LENGTH, sizeof(FreezeBlock)); } void freeFreezes(void) { - free(freezes); + free(freezes); } int findAddrSlot(u64 addr) { - for (int i = 0; i < FREEZE_DIC_LENGTH; i++) - { - if (freezes[i].address == addr) - return i; - } - - return -1; + for (int i = 0; i < FREEZE_DIC_LENGTH; i++) + { + if (freezes[i].address == addr) + return i; + } + + return -1; } int findNextEmptySlot() { - return findAddrSlot(0); + return findAddrSlot(0); } int addToFreezeMap(u64 addr, u8* v_data, u64 v_size, u64 tid) { - // update slot if already exists - int slot = findAddrSlot(addr); - if (slot == -1) - slot = findNextEmptySlot(); - else - removeFromFreezeMap(addr); - - if (slot == -1) - return 0; - - freezes[slot].address = addr; - freezes[slot].vData = v_data; - freezes[slot].size = v_size; - freezes[slot].state = 1; - freezes[slot].titleId = tid; - - return slot; + // update slot if already exists + int slot = findAddrSlot(addr); + if (slot == -1) + slot = findNextEmptySlot(); + else + removeFromFreezeMap(addr); + + if (slot == -1) + return 0; + + freezes[slot].address = addr; + freezes[slot].vData = v_data; + freezes[slot].size = v_size; + freezes[slot].state = 1; + freezes[slot].titleId = tid; + + return slot; } int removeFromFreezeMap(u64 addr) { - int slot = findAddrSlot(addr); - if (slot == -1) - return 0; - freezes[slot].address = 0; - freezes[slot].state = 0; - free(freezes[slot].vData); - return slot; + int slot = findAddrSlot(addr); + if (slot == -1) + return 0; + freezes[slot].address = 0; + freezes[slot].state = 0; + free(freezes[slot].vData); + return slot; } int getFreezeCount(bool print) { - int count = 0; - for (int i = 0; i < FREEZE_DIC_LENGTH; i++) - { - if (freezes[i].state != 0) - ++count; - } - if (print) - { - printf("%02X", count); - printf("\n"); - } - return count; + int count = 0; + for (int i = 0; i < FREEZE_DIC_LENGTH; i++) + { + if (freezes[i].state != 0) + ++count; + } + if (print) + { + printf("%02X", count); + printf("\n"); + } + return count; } // returns 0 if there was nothing to clear u8 clearFreezes(void) { - u8 clearedOne = 0; - for (int i = 0; i < FREEZE_DIC_LENGTH; i++) - { - if (freezes[i].state != 0) - { - removeFromFreezeMap(freezes[i].address); - clearedOne = 1; - } - } - return clearedOne; + u8 clearedOne = 0; + for (int i = 0; i < FREEZE_DIC_LENGTH; i++) + { + if (freezes[i].state != 0) + { + removeFromFreezeMap(freezes[i].address); + clearedOne = 1; + } + } + return clearedOne; } diff --git a/sys-botbase/source/freeze.h b/sys-botbase/source/freeze.h index 7183e12..b5ce56e 100644 --- a/sys-botbase/source/freeze.h +++ b/sys-botbase/source/freeze.h @@ -2,11 +2,11 @@ #define FREEZE_DIC_LENGTH 255 typedef struct { - char state; - u64 address; - u8* vData; - u64 size; - u64 titleId; + char state; + u64 address; + u8* vData; + u64 size; + u64 titleId; } FreezeBlock; extern FreezeBlock* freezes; diff --git a/sys-botbase/source/main.c b/sys-botbase/source/main.c index d86f5bc..ee56637 100644 --- a/sys-botbase/source/main.c +++ b/sys-botbase/source/main.c @@ -201,6 +201,12 @@ int argmain(int argc, char** argv) return 0; MetaData meta = getMetaData(); + if (meta.main_nso_base == 0) + { + printf("\n"); + return 0; + } + u64 offset = parseStringToInt(argv[1]); u64 size = parseStringToInt(argv[2]); peekInfinite(meta.heap_base + offset, size); @@ -212,6 +218,11 @@ int argmain(int argc, char** argv) return 0; MetaData meta = getMetaData(); + if (meta.main_nso_base == 0) + { + printf("\n"); + return 0; + } u64 itemCount = (argc - 1) / 2; u64 offsets[itemCount]; @@ -258,6 +269,12 @@ int argmain(int argc, char** argv) return 0; MetaData meta = getMetaData(); + if (meta.main_nso_base == 0) + { + printf("\n"); + return 0; + } + u64 offset = parseStringToInt(argv[1]); u64 size = parseStringToInt(argv[2]); peekInfinite(meta.main_nso_base + offset, size); @@ -269,6 +286,11 @@ int argmain(int argc, char** argv) return 0; MetaData meta = getMetaData(); + if (meta.main_nso_base == 0) + { + printf("\n"); + return 0; + } u64 itemCount = (argc - 1) / 2; u64 offsets[itemCount]; @@ -289,6 +311,12 @@ int argmain(int argc, char** argv) return 0; MetaData meta = getMetaData(); + if (meta.main_nso_base == 0) + { + printf("\n"); + return 0; + } + u64 offset = parseStringToInt(argv[1]); u64 size = 0; u8* data = parseStringToByteBuffer(argv[2], &size); @@ -316,6 +344,12 @@ int argmain(int argc, char** argv) return 0; MetaData meta = getMetaData(); + if (meta.main_nso_base == 0) + { + printf("\n"); + return 0; + } + u64 offset = parseStringToInt(argv[1]); u64 size = 0; u8* data = parseStringToByteBuffer(argv[2], &size); @@ -342,6 +376,10 @@ int argmain(int argc, char** argv) u64 sizeArg = strlen(argv[1]) + 1; char* seqNew = malloc(sizeArg); + if (seqNew == NULL) { + printf("\n"); + return 0; + } strcpy(seqNew, argv[1]); makeClickSeq(seqNew); } @@ -539,23 +577,37 @@ int argmain(int argc, char** argv) if (!strcmp(argv[0], "getTitleID")) { MetaData meta = getMetaData(); - if (usb) + if (meta.main_nso_base == 0) { - response.size = sizeof(meta.titleID); - response.data = &meta.titleID; - sendUsbResponse(response); + if (!usb) + printf("\n"); + return 0; } + + if (usb) + { + response.size = sizeof(meta.titleID); + response.data = &meta.titleID; + sendUsbResponse(response); + } else printf("%016lX\n", meta.titleID); } if (!strcmp(argv[0], "getTitleVersion")) { MetaData meta = getMetaData(); - if (usb) + if (meta.main_nso_base == 0) { - response.size = sizeof(meta.titleVersion); - response.data = &meta.titleVersion; - sendUsbResponse(response); + if (!usb) + printf("\n"); + return 0; } + + if (usb) + { + response.size = sizeof(meta.titleVersion); + response.data = &meta.titleVersion; + sendUsbResponse(response); + } else printf("%016lX\n", meta.titleVersion); } @@ -577,35 +629,56 @@ int argmain(int argc, char** argv) if (!strcmp(argv[0], "getMainNsoBase")) { MetaData meta = getMetaData(); - if (usb) + if (meta.main_nso_base == 0) { - response.size = sizeof(meta.main_nso_base); - response.data = &meta.main_nso_base; - sendUsbResponse(response); + if (!usb) + printf("\n"); + return 0; } + + if (usb) + { + response.size = sizeof(meta.main_nso_base); + response.data = &meta.main_nso_base; + sendUsbResponse(response); + } else printf("%016lX\n", meta.main_nso_base); } if (!strcmp(argv[0], "getBuildID")) { MetaData meta = getMetaData(); - if (usb) + if (meta.main_nso_base == 0) { - response.size = sizeof(u8); - response.data = &meta.buildID; - sendUsbResponse(response); + if (!usb) + printf("\n"); + return 0; } + + if (usb) + { + response.size = sizeof(u8); + response.data = &meta.buildID; + sendUsbResponse(response); + } else printf("%02x%02x%02x%02x%02x%02x%02x%02x\n", meta.buildID[0], meta.buildID[1], meta.buildID[2], meta.buildID[3], meta.buildID[4], meta.buildID[5], meta.buildID[6], meta.buildID[7]); } if (!strcmp(argv[0], "getHeapBase")) { MetaData meta = getMetaData(); - if (usb) + if (meta.main_nso_base == 0) { - response.size = sizeof(meta.heap_base); - response.data = &meta.heap_base; - sendUsbResponse(response); + if (!usb) + printf("\n"); + return 0; } + + if (usb) + { + response.size = sizeof(meta.heap_base); + response.data = &meta.heap_base; + sendUsbResponse(response); + } else printf("%016lX\n", meta.heap_base); } @@ -668,11 +741,11 @@ int argmain(int argc, char** argv) { if (argc < 2) return 0; - s64 jumps[argc - 1]; - for (int i = 1; i < argc; i++) - jumps[i - 1] = parseStringToSignedLong(argv[i]); + s64 jumps[argc - 1]; + for (int i = 1; i < argc; i++) + jumps[i - 1] = parseStringToSignedLong(argv[i]); - u64 solved = followMainPointer(jumps, argc - 1); + u64 solved = followMainPointer(jumps, argc - 1); if (usb) { response.data = &solved; @@ -690,11 +763,10 @@ int argmain(int argc, char** argv) return 0; s64 finalJump = parseStringToSignedLong(argv[argc - 1]); u64 count = argc - 2; - s64 jumps[count]; - for (int i = 1; i < argc - 1; i++) - jumps[i - 1] = parseStringToSignedLong(argv[i]); - - u64 solved = followMainPointer(jumps, count); + s64 jumps[count]; + for (int i = 1; i < argc - 1; i++) + jumps[i - 1] = parseStringToSignedLong(argv[i]); + u64 solved = followMainPointer(jumps, count); if (solved != 0) solved += finalJump; @@ -705,13 +777,13 @@ int argmain(int argc, char** argv) sendUsbResponse(response); } else printf("%016lX\n", solved); - } + } - // pointerRelative - // returns offset relative to heap - if (!strcmp(argv[0], "pointerRelative")) - { - if (argc < 3) + // pointerRelative + // returns offset relative to heap + if (!strcmp(argv[0], "pointerRelative")) + { + if(argc < 3) return 0; s64 finalJump = parseStringToSignedLong(argv[argc - 1]); u64 count = argc - 2; @@ -723,6 +795,12 @@ int argmain(int argc, char** argv) { solved += finalJump; MetaData meta = getMetaData(); + if (meta.main_nso_base == 0) + { + if (!usb) + printf("\n"); + return 0; + } solved -= meta.heap_base; } @@ -831,6 +909,12 @@ int argmain(int argc, char** argv) return 0; MetaData meta = getMetaData(); + if (meta.main_nso_base == 0) + { + if (!usb) + printf("\n"); + return 0; + } u64 offset = parseStringToInt(argv[1]); u64 size = 0; @@ -1055,6 +1139,109 @@ int argmain(int argc, char** argv) else printf("%d\n", fd_count); } + if (!strcmp(argv[0], "getSwitchTime")) + { + time_t posix = 0; + Result res = timeGetCurrentTime(TimeType_UserSystemClock, (u64*)&posix); + if (R_FAILED(res)) + { + sendResult(0, &response); + return 0; + } + + struct tm* time = localtime(&posix); + if (time->tm_year >= 160) + { + time->tm_year = 100; + time->tm_mon = 0; + time->tm_mday = 1; + + res = timeSetCurrentTime(TimeType_NetworkSystemClock, mktime(time)); + if (R_FAILED(res)) + { + sendResult(0, &response); + return 0; + } + + posix = mktime(time); + } + + if (usb) + { + response.size = sizeof(long); + response.data = &posix; + sendUsbResponse(response); + } + else + { + printf("%ld\n", posix); + } + } + + if (!strcmp(argv[0], "setSwitchTime")) + { + if (argc != 2) + return 0; + + time_t input = (time_t)strtoull(argv[1], NULL, 10); + struct tm* toSet = localtime(&input); + if (toSet->tm_year >= 160) + { + int fail = 0; + if (usb) + { + response.size = sizeof(fail); + response.data = &fail; + sendUsbResponse(response); + } + else + { + printf("%d\n", fail); + } + + return 0; + } + + Result res = timeSetCurrentTime(TimeType_NetworkSystemClock, input); + if (R_FAILED(res)) + { + sendResult(0, &response); + return 0; + } + + sendResult(1, &response); + } + + if (!strcmp(argv[0], "resetSwitchTime")) + { + bool sync; + Result res = setsysInitialize(); + if (R_FAILED(res)) + { + sendResult(0, &response); + return 0; + } + + res = setsysIsUserSystemClockAutomaticCorrectionEnabled(&sync); + if (R_FAILED(res) || !sync) + { + setsysExit(); + sendResult(0, &response); + return 0; + } + + setsysExit(); + if (!isConnectedToInternet(&response)) + return 0; + + time_t ntp = ntpGetTime(); + res = timeSetCurrentTime(TimeType_NetworkSystemClock, ntp); + if (R_FAILED(res)) + sendResult(0, &response); + + sendResult(1, &response); + } + if(!strcmp(argv[0], "dateSet")) dateSet(parseStringToInt(argv[1])); @@ -1159,7 +1346,8 @@ void wifiMainLoop() int c = sizeof(struct sockaddr_in); struct sockaddr_in client; - struct pollfd* pfds = malloc(sizeof(*pfds) * fd_size); + + struct pollfd* pfds = malloc(sizeof * pfds * fd_size); int listenfd = setupServerSocket(); pfds[0].fd = listenfd; @@ -1186,8 +1374,7 @@ void wifiMainLoop() { add_to_pfds(&pfds, newfd, &fd_count, &fd_size); } - else - { + else { svcSleepThread(1e+9L); close(listenfd); listenfd = setupServerSocket(); @@ -1200,8 +1387,7 @@ void wifiMainLoop() { bool readEnd = false; int readBytesSoFar = 0; - while (!readEnd) - { + while (!readEnd) { int len = recv(pfds[i].fd, &linebuf[readBytesSoFar], 1, 0); if (len <= 0) { @@ -1212,8 +1398,7 @@ void wifiMainLoop() else { readBytesSoFar += len; - if (linebuf[readBytesSoFar - 1] == '\n') - { + if (linebuf[readBytesSoFar - 1] == '\n') { readEnd = true; linebuf[readBytesSoFar - 1] = 0; @@ -1222,8 +1407,7 @@ void wifiMainLoop() parseArgs(linebuf, &argmain); - if (echoCommands) - { + if (echoCommands) { printf("%s\n", linebuf); } } diff --git a/sys-botbase/source/ntp.c b/sys-botbase/source/ntp.c index 2bbd52f..d5bdc54 100644 --- a/sys-botbase/source/ntp.c +++ b/sys-botbase/source/ntp.c @@ -1,57 +1,63 @@ -/* This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -For more information, please refer to -Additionally, the ntp_packet struct uses code licensed under the BSD 3-clause. See LICENSE-THIRD-PARTY for more -information. */ - -#define _BSD_SOURCE - -#include "ntp.h" -#include -#include -#include -#include -#include -#include - -time_t ntpGetTime() { - static const char* SERVER_NAME = "0.pool.ntp.org"; - int sockfd = -1; - sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - struct hostent* server; - server = gethostbyname(SERVER_NAME); - - struct sockaddr_in serv_addr; - memset(&serv_addr, 0, sizeof(struct sockaddr_in)); - serv_addr.sin_family = AF_INET; - memcpy((char*)&serv_addr.sin_addr.s_addr, (char*)server->h_addr_list[0], 4); - serv_addr.sin_port = htons(123); - connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); - - ntp_packet packet; - memset(&packet, 0, sizeof(ntp_packet)); - packet.li_vn_mode = (0 << 6) | (4 << 3) | 3; // LI 0 | Client version 4 | Mode 3 - packet.txTm_s = htonl(NTP_TIMESTAMP_DELTA + time(NULL)); // Current networktime on the console - send(sockfd, (char*)&packet, sizeof(ntp_packet), 0); - (size_t)(recv(sockfd, (char*)&packet, sizeof(ntp_packet), 0)); - packet.txTm_s = ntohl(packet.txTm_s); - - return (time_t)(packet.txTm_s - NTP_TIMESTAMP_DELTA); -} \ No newline at end of file +/* This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +For more information, please refer to +Additionally, the ntp_packet struct uses code licensed under the BSD 3-clause. See LICENSE-THIRD-PARTY for more +information. */ + +#define _BSD_SOURCE + +#include "ntp.h" +#include +#include +#include +#include +#include +#include +#include + +time_t ntpGetTime() { + Result si = socketInitializeDefault(); + if (R_FAILED(si)) + return 0; + + static const char* SERVER_NAME = "0.pool.ntp.org"; + int sockfd = -1; + sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + struct hostent* server; + server = gethostbyname(SERVER_NAME); + + struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(struct sockaddr_in)); + serv_addr.sin_family = AF_INET; + memcpy((char*)&serv_addr.sin_addr.s_addr, (char*)server->h_addr_list[0], 4); + serv_addr.sin_port = htons(123); + connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); + + ntp_packet packet; + memset(&packet, 0, sizeof(ntp_packet)); + packet.li_vn_mode = (0 << 6) | (4 << 3) | 3; // LI 0 | Client version 4 | Mode 3 + packet.txTm_s = htonl(NTP_TIMESTAMP_DELTA + time(NULL)); // Current networktime on the console + send(sockfd, (char*)&packet, sizeof(ntp_packet), 0); + (size_t)(recv(sockfd, (char*)&packet, sizeof(ntp_packet), 0)); + packet.txTm_s = ntohl(packet.txTm_s); + + socketExit(); + return (time_t)(packet.txTm_s - NTP_TIMESTAMP_DELTA); +} diff --git a/sys-botbase/source/ntp.h b/sys-botbase/source/ntp.h index b843b5e..59b948e 100644 --- a/sys-botbase/source/ntp.h +++ b/sys-botbase/source/ntp.h @@ -1,59 +1,59 @@ -/* This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -For more information, please refer to -Additionally, the ntp_packet struct uses code licensed under the BSD 3-clause. See LICENSE-THIRD-PARTY for more -information. */ - -#pragma once - -#include - -#define NTP_TIMESTAMP_DELTA 2208988800ull - -/* ------------- BEGIN BSD 3-CLAUSE LICENSED CODE-------------------- */ -// https://www.cisco.com/c/en/us/about/press/internet-protocol-journal/back-issues/table-contents-58/154-ntp.html -// Struct adapted from https://github.com/lettier/ntpclient , see LICENSE-THIRD-PARTY for more information. -typedef struct { - uint8_t li_vn_mode; // li: two bits, leap indicator. vn: three bits, protocol version number. mode: three bits, - // client mode. - - uint8_t stratum; // Stratum level of the local clock. - uint8_t poll; // Maximum interval between successive messages. - uint8_t precision; // Precision of the local clock. - - uint32_t rootDelay; // Total round trip delay time. - uint32_t rootDispersion; // Max error allowed from primary clock source. - uint32_t refId; // Reference clock identifier. - - uint32_t refTm_s; // Reference time-stamp seconds. - uint32_t refTm_f; // Reference time-stamp fraction of a second. - - uint32_t origTm_s; // Originate time-stamp seconds. - uint32_t origTm_f; // Originate time-stamp fraction of a second. - - uint32_t rxTm_s; // Received time-stamp seconds. - uint32_t rxTm_f; // Received time-stamp fraction of a second. - - uint32_t txTm_s; // Transmit time-stamp seconds. - uint32_t txTm_f; // Transmit time-stamp fraction of a second. -} ntp_packet; -/* ------------- END BSD 3-CLAUSE LICENSED CODE-------------------- */ - -time_t ntpGetTime(); +/* This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +For more information, please refer to +Additionally, the ntp_packet struct uses code licensed under the BSD 3-clause. See LICENSE-THIRD-PARTY for more +information. */ + +#pragma once + +#include + +#define NTP_TIMESTAMP_DELTA 2208988800ull + +/* ------------- BEGIN BSD 3-CLAUSE LICENSED CODE-------------------- */ +// https://www.cisco.com/c/en/us/about/press/internet-protocol-journal/back-issues/table-contents-58/154-ntp.html +// Struct adapted from https://github.com/lettier/ntpclient , see LICENSE-THIRD-PARTY for more information. +typedef struct { + uint8_t li_vn_mode; // li: two bits, leap indicator. vn: three bits, protocol version number. mode: three bits, + // client mode. + + uint8_t stratum; // Stratum level of the local clock. + uint8_t poll; // Maximum interval between successive messages. + uint8_t precision; // Precision of the local clock. + + uint32_t rootDelay; // Total round trip delay time. + uint32_t rootDispersion; // Max error allowed from primary clock source. + uint32_t refId; // Reference clock identifier. + + uint32_t refTm_s; // Reference time-stamp seconds. + uint32_t refTm_f; // Reference time-stamp fraction of a second. + + uint32_t origTm_s; // Originate time-stamp seconds. + uint32_t origTm_f; // Originate time-stamp fraction of a second. + + uint32_t rxTm_s; // Received time-stamp seconds. + uint32_t rxTm_f; // Received time-stamp fraction of a second. + + uint32_t txTm_s; // Transmit time-stamp seconds. + uint32_t txTm_f; // Transmit time-stamp fraction of a second. +} ntp_packet; +/* ------------- END BSD 3-CLAUSE LICENSED CODE-------------------- */ + +time_t ntpGetTime(); diff --git a/sys-botbase/source/util.c b/sys-botbase/source/util.c index f20782d..7493951 100644 --- a/sys-botbase/source/util.c +++ b/sys-botbase/source/util.c @@ -65,7 +65,7 @@ int setupServerSocket() server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(6000); - while (bind(lissock, (struct sockaddr *)&server, sizeof(server)) < 0) + while (bind(lissock, (struct sockaddr*)&server, sizeof(server)) < 0) { svcSleepThread(1e+9L); } @@ -73,9 +73,9 @@ int setupServerSocket() return lissock; } -u64 parseStringToInt(char* arg){ - if(strlen(arg) > 2){ - if(arg[1] == 'x'){ +u64 parseStringToInt(char* arg) { + if (strlen(arg) > 2) { + if (arg[1] == 'x') { u64 ret = strtoul(arg, NULL, 16); return ret; } @@ -84,9 +84,9 @@ u64 parseStringToInt(char* arg){ return ret; } -s64 parseStringToSignedLong(char* arg){ - if(strlen(arg) > 2){ - if(arg[1] == 'x' || arg[2] == 'x'){ +s64 parseStringToSignedLong(char* arg) { + if (strlen(arg) > 2) { + if (arg[1] == 'x' || arg[2] == 'x') { s64 ret = strtol(arg, NULL, 16); return ret; } @@ -97,12 +97,12 @@ s64 parseStringToSignedLong(char* arg){ u8* parseStringToByteBuffer(char* arg, u64* size) { - char toTranslate[3] = {0}; + char toTranslate[3] = { 0 }; int length = strlen(arg); bool isHex = false; - if(length > 2){ - if(arg[1] == 'x'){ + if (length > 2) { + if (arg[1] == 'x') { isHex = true; length -= 2; arg = &arg[2]; //cut off 0x @@ -112,29 +112,32 @@ u8* parseStringToByteBuffer(char* arg, u64* size) bool isFirst = true; bool isOdd = (length % 2 == 1); u64 bufferSize = length / 2; - if(isOdd) bufferSize++; - u8 *buffer = malloc(bufferSize); + if (isOdd) bufferSize++; + u8* buffer = malloc(bufferSize); u64 i; - for (i = 0; i < bufferSize; i++){ - if(isOdd){ - if(isFirst){ + for (i = 0; i < bufferSize; i++) { + if (isOdd) { + if (isFirst) { toTranslate[0] = '0'; toTranslate[1] = arg[i]; - }else{ + } + else { toTranslate[0] = arg[(2 * i) - 1]; toTranslate[1] = arg[(2 * i)]; } - }else{ - toTranslate[0] = arg[i*2]; - toTranslate[1] = arg[(i*2) + 1]; + } + else { + toTranslate[0] = arg[i * 2]; + toTranslate[1] = arg[(i * 2) + 1]; } isFirst = false; - if(isHex){ + if (isHex) { buffer[i] = strtoul(toTranslate, NULL, 16); - }else{ + } + else { buffer[i] = strtoul(toTranslate, NULL, 10); } } @@ -147,7 +150,7 @@ HidNpadButton parseStringToButton(char* arg) if (strcmp(arg, "A") == 0) { return HidNpadButton_A; - } + } else if (strcmp(arg, "B") == 0) { return HidNpadButton_B; @@ -228,24 +231,24 @@ HidNpadButton parseStringToButton(char* arg) return HidNpadButton_A; //I guess lol } -Result capsscCaptureForDebug(void *buffer, size_t buffer_size, u64 *size) { +Result capsscCaptureForDebug(void* buffer, size_t buffer_size, u64* size) { struct { u32 a; u64 b; - } in = {0, 10000000000}; + } in = { 0, 10000000000 }; return serviceDispatchInOut(capsscGetServiceSession(), 1204, in, *size, - .buffer_attrs = {SfBufferAttr_HipcMapTransferAllowsNonSecure | SfBufferAttr_HipcMapAlias | SfBufferAttr_Out}, + .buffer_attrs = { SfBufferAttr_HipcMapTransferAllowsNonSecure | SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { buffer, buffer_size } }, - ); + ); } static void sendPatternStatic(const HidsysNotificationLedPattern* pattern, const HidNpadIdType idType) { s32 total_entries; - HidsysUniquePadId unique_pad_ids[2]={0}; + HidsysUniquePadId unique_pad_ids[2] = { 0 }; Result rc = hidsysGetUniquePadsFromNpad(idType, unique_pad_ids, 2, &total_entries); - if (R_FAILED(rc)) + if (R_FAILED(rc)) return; // probably incompatible or no pads connected for (int i = 0; i < total_entries; i++) diff --git a/sys-botbase/source/util.h b/sys-botbase/source/util.h index 288b8f8..124be54 100644 --- a/sys-botbase/source/util.h +++ b/sys-botbase/source/util.h @@ -9,5 +9,5 @@ u64 parseStringToInt(char* arg); s64 parseStringToSignedLong(char* arg); u8* parseStringToByteBuffer(char* arg, u64* size); HidNpadButton parseStringToButton(char* arg); -Result capsscCaptureForDebug(void *buffer, size_t buffer_size, u64 *size); //big thanks to Behemoth from the Reswitched Discord! +Result capsscCaptureForDebug(void* buffer, size_t buffer_size, u64* size); //big thanks to Behemoth from the Reswitched Discord! void flashLed(void); diff --git a/sys-botbase/sys-botbase.json b/sys-botbase/sys-botbase.json index cb4bb7a..ef0508a 100644 --- a/sys-botbase/sys-botbase.json +++ b/sys-botbase/sys-botbase.json @@ -1,186 +1,186 @@ { - "name": "sys-botbase", - "program_id": "0x430000000000000B", - "program_id_range_min": "0x430000000000000B", - "program_id_range_max": "0x430000000000000B", - "version": "0", - "optimize_memory_allocation": false, - "enable_alias_region_extra_size": false, - "prevent_code_reads": false, - "signature_key_generation": 0, - "main_thread_stack_size": "0x00024000", - "main_thread_priority": 42, - "default_cpu_id": 3, - "process_category" : 0, - "is_retail": true, - "pool_partition": 2, - "is_64_bit": true, - "address_space_type": 3, - "system_resource_size": "0", - "disable_device_address_space_merge": true, - "filesystem_access": { - "permissions": "0xffffffffffffffff" - }, - "service_access": [ "*" ], - "service_host": [ "*" ], - "kernel_capabilities": [ - { - "type": "kernel_flags", - "value": { - "highest_thread_priority": 63, - "lowest_thread_priority": 24, - "lowest_cpu_id": 3, - "highest_cpu_id": 3 - } - }, - { - "type": "syscalls", - "value": { - "svcUnknown": "0x00", - "svcSetHeapSize": "0x01", - "svcSetMemoryPermission": "0x02", - "svcSetMemoryAttribute": "0x03", - "svcMapMemory": "0x04", - "svcUnmapMemory": "0x05", - "svcQueryMemory": "0x06", - "svcExitProcess": "0x07", - "svcCreateThread": "0x08", - "svcStartThread": "0x09", - "svcExitThread": "0x0a", - "svcSleepThread": "0x0b", - "svcGetThreadPriority": "0x0c", - "svcSetThreadPriority": "0x0d", - "svcGetThreadCoreMask": "0x0e", - "svcSetThreadCoreMask": "0x0f", - "svcGetCurrentProcessorNumber": "0x10", - "svcSignalEvent": "0x11", - "svcClearEvent": "0x12", - "svcMapSharedMemory": "0x13", - "svcUnmapSharedMemory": "0x14", - "svcCreateTransferMemory": "0x15", - "svcCloseHandle": "0x16", - "svcResetSignal": "0x17", - "svcWaitSynchronization": "0x18", - "svcCancelSynchronization": "0x19", - "svcArbitrateLock": "0x1a", - "svcArbitrateUnlock": "0x1b", - "svcWaitProcessWideKeyAtomic": "0x1c", - "svcSignalProcessWideKey": "0x1d", - "svcGetSystemTick": "0x1e", - "svcConnectToNamedPort": "0x1f", - "svcSendSyncRequestLight": "0x20", - "svcSendSyncRequest": "0x21", - "svcSendSyncRequestWithUserBuffer": "0x22", - "svcSendAsyncRequestWithUserBuffer": "0x23", - "svcGetProcessId": "0x24", - "svcGetThreadId": "0x25", - "svcBreak": "0x26", - "svcOutputDebugString": "0x27", - "svcReturnFromException": "0x28", - "svcGetInfo": "0x29", - "svcFlushEntireDataCache": "0x2a", - "svcFlushDataCache": "0x2b", - "svcMapPhysicalMemory": "0x2c", - "svcUnmapPhysicalMemory": "0x2d", - "svcGetFutureThreadInfo": "0x2e", - "svcGetLastThreadInfo": "0x2f", - "svcGetResourceLimitLimitValue": "0x30", - "svcGetResourceLimitCurrentValue": "0x31", - "svcSetThreadActivity": "0x32", - "svcGetThreadContext3": "0x33", - "svcWaitForAddress": "0x34", - "svcSignalToAddress": "0x35", - "svcUnknown": "0x36", - "svcUnknown": "0x37", - "svcUnknown": "0x38", - "svcUnknown": "0x39", - "svcUnknown": "0x3a", - "svcUnknown": "0x3b", - "svcDumpInfo": "0x3c", - "svcDumpInfoNew": "0x3d", - "svcUnknown": "0x3e", - "svcUnknown": "0x3f", - "svcCreateSession": "0x40", - "svcAcceptSession": "0x41", - "svcReplyAndReceiveLight": "0x42", - "svcReplyAndReceive": "0x43", - "svcReplyAndReceiveWithUserBuffer": "0x44", - "svcCreateEvent": "0x45", - "svcUnknown": "0x46", - "svcUnknown": "0x47", - "svcMapPhysicalMemoryUnsafe": "0x48", - "svcUnmapPhysicalMemoryUnsafe": "0x49", - "svcSetUnsafeLimit": "0x4a", - "svcCreateCodeMemory": "0x4b", - "svcControlCodeMemory": "0x4c", - "svcSleepSystem": "0x4d", - "svcReadWriteRegister": "0x4e", - "svcSetProcessActivity": "0x4f", - "svcCreateSharedMemory": "0x50", - "svcMapTransferMemory": "0x51", - "svcUnmapTransferMemory": "0x52", - "svcCreateInterruptEvent": "0x53", - "svcQueryPhysicalAddress": "0x54", - "svcQueryIoMapping": "0x55", - "svcCreateDeviceAddressSpace": "0x56", - "svcAttachDeviceAddressSpace": "0x57", - "svcDetachDeviceAddressSpace": "0x58", - "svcMapDeviceAddressSpaceByForce": "0x59", - "svcMapDeviceAddressSpaceAligned": "0x5a", - "svcMapDeviceAddressSpace": "0x5b", - "svcUnmapDeviceAddressSpace": "0x5c", - "svcInvalidateProcessDataCache": "0x5d", - "svcStoreProcessDataCache": "0x5e", - "svcFlushProcessDataCache": "0x5f", - "svcDebugActiveProcess": "0x60", - "svcBreakDebugProcess": "0x61", - "svcTerminateDebugProcess": "0x62", - "svcGetDebugEvent": "0x63", - "svcContinueDebugEvent": "0x64", - "svcGetProcessList": "0x65", - "svcGetThreadList": "0x66", - "svcGetDebugThreadContext": "0x67", - "svcSetDebugThreadContext": "0x68", - "svcQueryDebugProcessMemory": "0x69", - "svcReadDebugProcessMemory": "0x6a", - "svcWriteDebugProcessMemory": "0x6b", - "svcSetHardwareBreakPoint": "0x6c", - "svcGetDebugThreadParam": "0x6d", - "svcUnknown": "0x6e", - "svcGetSystemInfo": "0x6f", - "svcCreatePort": "0x70", - "svcManageNamedPort": "0x71", - "svcConnectToPort": "0x72", - "svcSetProcessMemoryPermission": "0x73", - "svcMapProcessMemory": "0x74", - "svcUnmapProcessMemory": "0x75", - "svcQueryProcessMemory": "0x76", - "svcMapProcessCodeMemory": "0x77", - "svcUnmapProcessCodeMemory": "0x78", - "svcCreateProcess": "0x79", - "svcStartProcess": "0x7a", - "svcTerminateProcess": "0x7b", - "svcGetProcessInfo": "0x7c", - "svcCreateResourceLimit": "0x7d", - "svcSetResourceLimitLimitValue": "0x7e", - "svcCallSecureMonitor": "0x7f" - } - }, - { - "type": "min_kernel_version", - "value": "0x0060" - }, - { - "type": "handle_table_size", - "value": 1023 - }, - { - "type": "debug_flags", - "value": { - "allow_debug": false, - "force_debug": true, - "force_debug_prod": false - } - } - ] + "name": "sys-botbase", + "program_id": "0x430000000000000B", + "program_id_range_min": "0x430000000000000B", + "program_id_range_max": "0x430000000000000B", + "version": "0", + "optimize_memory_allocation": false, + "enable_alias_region_extra_size": false, + "prevent_code_reads": false, + "signature_key_generation": 0, + "main_thread_stack_size": "0x00024000", + "main_thread_priority": 42, + "default_cpu_id": 3, + "process_category" : 0, + "is_retail": true, + "pool_partition": 2, + "is_64_bit": true, + "address_space_type": 3, + "system_resource_size": "0", + "disable_device_address_space_merge": true, + "filesystem_access": { + "permissions": "0xffffffffffffffff" + }, + "service_access": [ "*" ], + "service_host": [ "*" ], + "kernel_capabilities": [ + { + "type": "kernel_flags", + "value": { + "highest_thread_priority": 63, + "lowest_thread_priority": 24, + "lowest_cpu_id": 3, + "highest_cpu_id": 3 + } + }, + { + "type": "syscalls", + "value": { + "svcUnknown": "0x00", + "svcSetHeapSize": "0x01", + "svcSetMemoryPermission": "0x02", + "svcSetMemoryAttribute": "0x03", + "svcMapMemory": "0x04", + "svcUnmapMemory": "0x05", + "svcQueryMemory": "0x06", + "svcExitProcess": "0x07", + "svcCreateThread": "0x08", + "svcStartThread": "0x09", + "svcExitThread": "0x0a", + "svcSleepThread": "0x0b", + "svcGetThreadPriority": "0x0c", + "svcSetThreadPriority": "0x0d", + "svcGetThreadCoreMask": "0x0e", + "svcSetThreadCoreMask": "0x0f", + "svcGetCurrentProcessorNumber": "0x10", + "svcSignalEvent": "0x11", + "svcClearEvent": "0x12", + "svcMapSharedMemory": "0x13", + "svcUnmapSharedMemory": "0x14", + "svcCreateTransferMemory": "0x15", + "svcCloseHandle": "0x16", + "svcResetSignal": "0x17", + "svcWaitSynchronization": "0x18", + "svcCancelSynchronization": "0x19", + "svcArbitrateLock": "0x1a", + "svcArbitrateUnlock": "0x1b", + "svcWaitProcessWideKeyAtomic": "0x1c", + "svcSignalProcessWideKey": "0x1d", + "svcGetSystemTick": "0x1e", + "svcConnectToNamedPort": "0x1f", + "svcSendSyncRequestLight": "0x20", + "svcSendSyncRequest": "0x21", + "svcSendSyncRequestWithUserBuffer": "0x22", + "svcSendAsyncRequestWithUserBuffer": "0x23", + "svcGetProcessId": "0x24", + "svcGetThreadId": "0x25", + "svcBreak": "0x26", + "svcOutputDebugString": "0x27", + "svcReturnFromException": "0x28", + "svcGetInfo": "0x29", + "svcFlushEntireDataCache": "0x2a", + "svcFlushDataCache": "0x2b", + "svcMapPhysicalMemory": "0x2c", + "svcUnmapPhysicalMemory": "0x2d", + "svcGetFutureThreadInfo": "0x2e", + "svcGetLastThreadInfo": "0x2f", + "svcGetResourceLimitLimitValue": "0x30", + "svcGetResourceLimitCurrentValue": "0x31", + "svcSetThreadActivity": "0x32", + "svcGetThreadContext3": "0x33", + "svcWaitForAddress": "0x34", + "svcSignalToAddress": "0x35", + "svcUnknown": "0x36", + "svcUnknown": "0x37", + "svcUnknown": "0x38", + "svcUnknown": "0x39", + "svcUnknown": "0x3a", + "svcUnknown": "0x3b", + "svcDumpInfo": "0x3c", + "svcDumpInfoNew": "0x3d", + "svcUnknown": "0x3e", + "svcUnknown": "0x3f", + "svcCreateSession": "0x40", + "svcAcceptSession": "0x41", + "svcReplyAndReceiveLight": "0x42", + "svcReplyAndReceive": "0x43", + "svcReplyAndReceiveWithUserBuffer": "0x44", + "svcCreateEvent": "0x45", + "svcUnknown": "0x46", + "svcUnknown": "0x47", + "svcMapPhysicalMemoryUnsafe": "0x48", + "svcUnmapPhysicalMemoryUnsafe": "0x49", + "svcSetUnsafeLimit": "0x4a", + "svcCreateCodeMemory": "0x4b", + "svcControlCodeMemory": "0x4c", + "svcSleepSystem": "0x4d", + "svcReadWriteRegister": "0x4e", + "svcSetProcessActivity": "0x4f", + "svcCreateSharedMemory": "0x50", + "svcMapTransferMemory": "0x51", + "svcUnmapTransferMemory": "0x52", + "svcCreateInterruptEvent": "0x53", + "svcQueryPhysicalAddress": "0x54", + "svcQueryIoMapping": "0x55", + "svcCreateDeviceAddressSpace": "0x56", + "svcAttachDeviceAddressSpace": "0x57", + "svcDetachDeviceAddressSpace": "0x58", + "svcMapDeviceAddressSpaceByForce": "0x59", + "svcMapDeviceAddressSpaceAligned": "0x5a", + "svcMapDeviceAddressSpace": "0x5b", + "svcUnmapDeviceAddressSpace": "0x5c", + "svcInvalidateProcessDataCache": "0x5d", + "svcStoreProcessDataCache": "0x5e", + "svcFlushProcessDataCache": "0x5f", + "svcDebugActiveProcess": "0x60", + "svcBreakDebugProcess": "0x61", + "svcTerminateDebugProcess": "0x62", + "svcGetDebugEvent": "0x63", + "svcContinueDebugEvent": "0x64", + "svcGetProcessList": "0x65", + "svcGetThreadList": "0x66", + "svcGetDebugThreadContext": "0x67", + "svcSetDebugThreadContext": "0x68", + "svcQueryDebugProcessMemory": "0x69", + "svcReadDebugProcessMemory": "0x6a", + "svcWriteDebugProcessMemory": "0x6b", + "svcSetHardwareBreakPoint": "0x6c", + "svcGetDebugThreadParam": "0x6d", + "svcUnknown": "0x6e", + "svcGetSystemInfo": "0x6f", + "svcCreatePort": "0x70", + "svcManageNamedPort": "0x71", + "svcConnectToPort": "0x72", + "svcSetProcessMemoryPermission": "0x73", + "svcMapProcessMemory": "0x74", + "svcUnmapProcessMemory": "0x75", + "svcQueryProcessMemory": "0x76", + "svcMapProcessCodeMemory": "0x77", + "svcUnmapProcessCodeMemory": "0x78", + "svcCreateProcess": "0x79", + "svcStartProcess": "0x7a", + "svcTerminateProcess": "0x7b", + "svcGetProcessInfo": "0x7c", + "svcCreateResourceLimit": "0x7d", + "svcSetResourceLimitLimitValue": "0x7e", + "svcCallSecureMonitor": "0x7f" + } + }, + { + "type": "min_kernel_version", + "value": "0x0060" + }, + { + "type": "handle_table_size", + "value": 1023 + }, + { + "type": "debug_flags", + "value": { + "allow_debug": false, + "force_debug": true, + "force_debug_prod": false + } + } + ] }