Skip to content

Commit

Permalink
Merge pull request #33 from berichan/master
Browse files Browse the repository at this point in the history
Add freeze thread, pointer follows, keyboard emulation + threads for both hid emu
  • Loading branch information
berichan authored Feb 24, 2021
2 parents 31a1283 + 36b3428 commit bf8f471
Show file tree
Hide file tree
Showing 10 changed files with 703 additions and 42 deletions.
2 changes: 1 addition & 1 deletion sys-botbase/.vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
}
],
"version": 4
}
}
23 changes: 23 additions & 0 deletions sys-botbase/source/.vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"configurations": [
{
"name": "DKP aarch64",
"includePath": [
"C:/devkitPro/devkitA64/aarch64-none-elf/include/**",
"C:/devkitPro/devkitA64/lib/gcc/aarch64-none-elf/10.2.0/include/**",
"C:/devkitPro/libnx/include/**",
"C:/devkitPro/portlibs/switch/include/**"
],
"defines": [
"SWITCH",
"__SWITCH__",
"DEBUG"
],
"compilerPath": "C:/devkitPro/devkitA64/bin/aarch64-none-elf-g++",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-arm64"
}
],
"version": 4
}
5 changes: 5 additions & 0 deletions sys-botbase/source/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files.associations": {
"switch.h": "c"
}
}
104 changes: 92 additions & 12 deletions sys-botbase/source/commands.c
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
#include <switch.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "commands.h"
#include "util.h"

Mutex actionLock;

//Controller:
bool bControllerIsInitialised = false;
HiddbgHdlsHandle controllerHandle = {0};
HiddbgHdlsDeviceInfo controllerDevice = {0};
HiddbgHdlsState controllerState = {0};

//Keyboard:
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;

void attach()
Expand Down Expand Up @@ -142,27 +146,31 @@ void initController()
rc = hiddbgAttachHdlsVirtualDevice(&controllerHandle, &controllerDevice);
if (R_FAILED(rc) && debugResultCodes)
printf("hiddbgAttachHdlsVirtualDevice: %d\n", rc);
//init a dummy keyboard state for assignment between keypresses
dummyKeyboardState.keys[3] = 0x800000000000000UL; // Hackfix found by Red: an unused key press (KBD_MEDIA_CALC) is required to allow sequential same-key presses. bitfield[3]
bControllerIsInitialised = true;
}



void poke(u64 offset, u64 size, u8* val)
{
attach();
Result rc = svcWriteDebugProcessMemory(debughandle, val, offset, size);
writeMem(offset, size, val);
detach();
}

void writeMem(u64 offset, u64 size, u8* val)
{
Result rc = svcWriteDebugProcessMemory(debughandle, val, offset, size);
if (R_FAILED(rc) && debugResultCodes)
printf("svcWriteDebugProcessMemory: %d\n", rc);
detach();
}

void peek(u64 offset, u64 size)
{
u8 *out = malloc(sizeof(u8) * size);
attach();
Result rc = svcReadDebugProcessMemory(out, debughandle, offset, size);
if (R_FAILED(rc) && debugResultCodes)
printf("svcReadDebugProcessMemory: %d\n", rc);
readMem(out, offset, size);
detach();

u64 i;
Expand All @@ -174,6 +182,13 @@ void peek(u64 offset, u64 size)
free(out);
}

void readMem(u8* out, u64 offset, u64 size)
{
Result rc = svcReadDebugProcessMemory(out, debughandle, offset, size);
if (R_FAILED(rc) && debugResultCodes)
printf("svcReadDebugProcessMemory: %d\n", rc);
}

void click(HidControllerKeys btn)
{
initController();
Expand Down Expand Up @@ -211,26 +226,91 @@ void setStickState(int side, int dxVal, int dyVal)
hiddbgSetHdlsState(controllerHandle, &controllerState);
}

void reverseArray(u8* arr, int start, int end)
{
int temp;
while (start < end)
{
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}

u64 followMainPointer(s64* jumps, size_t count)
{
u64 offset;
u64 size = sizeof offset;
u8 *out = malloc(size);
MetaData meta = getMetaData();

attach();
readMem(out, meta.main_nso_base + jumps[0], size);
offset = *(u64*)out;
int i;
for (i = 1; i < count; ++i)
{
readMem(out, offset + jumps[i], size);
offset = *(u64*)out;
}
detach();
free(out);

return offset;
}

void touch(HidTouchState* state, u64 sequentialCount, u64 holdTime, bool hold)
{
initController();
state->delta_time = holdTime;
state->delta_time = holdTime; // only the first touch needs this for whatever reason
for (u32 i = 0; i < sequentialCount; i++)
{
hiddbgSetTouchScreenAutoPilotState(&state[i], 1);
svcSleepThread(holdTime);
if (!hold)
{
hiddbgSetTouchScreenAutoPilotState(NULL, 0);
svcSleepThread(TOUCHPOLLMIN);
svcSleepThread(pollRate * 1e+6L);
}
}

if(hold) // send finger release event
{
hiddbgSetTouchScreenAutoPilotState(NULL, 0);
svcSleepThread(TOUCHPOLLMIN);
svcSleepThread(pollRate * 1e+6L);
}

hiddbgUnsetTouchScreenAutoPilotState();
}
}

void key(HiddbgKeyboardAutoPilotState* states, u64 sequentialCount)
{
initController();
HiddbgKeyboardAutoPilotState tempState = {0};
u32 i;
for (i = 0; i < sequentialCount; i++)
{
memcpy(&tempState.keys, states[i].keys, sizeof(u64) * 4);
tempState.modifiers = states[i].modifiers;
hiddbgSetKeyboardAutoPilotState(&tempState);
svcSleepThread(keyPressSleepTime * 1e+6L);

if (i != (sequentialCount-1))
{
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);
}
}
else
{
hiddbgSetKeyboardAutoPilotState(&dummyKeyboardState);
svcSleepThread(pollRate * 1e+6L);
}
}

hiddbgUnsetKeyboardAutoPilotState();
}
25 changes: 23 additions & 2 deletions sys-botbase/source/commands.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#include <switch.h>
#define TOUCHPOLLMIN 15000000L // touch screen polling rate seems to be 15ms (no idea how to change)

extern Handle debughandle;
extern bool bControllerIsInitialised;
extern HiddbgHdlsHandle controllerHandle;
extern HiddbgHdlsDeviceInfo controllerDevice;
extern HiddbgHdlsState controllerState;
extern HiddbgKeyboardAutoPilotState dummyKeyboardState;
extern u64 buttonClickSleepTime;
extern u64 keyPressSleepTime;
extern u64 pollRate;
extern u32 fingerDiameter;

typedef struct {
Expand All @@ -16,6 +18,20 @@ typedef struct {
u8 buildID[0x20];
} MetaData;

typedef struct {
HidTouchState* states;
u64 sequentialCount;
u64 holdTime;
bool hold;
u8 state;
} TouchData;

typedef struct {
HiddbgKeyboardAutoPilotState* states;
u64 sequentialCount;
u8 state;
} KeyData;

void attach();
void detach();
u64 getMainNsoBase(u64 pid);
Expand All @@ -25,9 +41,14 @@ void getBuildID(MetaData* meta, u64 pid);
MetaData getMetaData(void);

void poke(u64 offset, u64 size, u8* val);
void writeMem(u64 offset, u64 size, u8* val);
void peek(u64 offset, u64 size);
void readMem(u8* out, u64 offset, u64 size);
void click(HidControllerKeys btn);
void press(HidControllerKeys btn);
void release(HidControllerKeys btn);
void setStickState(int side, int dxVal, int dyVal);
void touch(HidTouchState* state, u64 sequentialCount, u64 holdTime, bool hold);
void reverseArray(u8* arr, int start, int end);
u64 followMainPointer(s64* jumps, size_t count);
void touch(HidTouchState* state, u64 sequentialCount, u64 holdTime, bool hold);
void key(HiddbgKeyboardAutoPilotState* states, u64 sequentialCount);
100 changes: 100 additions & 0 deletions sys-botbase/source/freeze.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <switch.h>
#include "freeze.h"

FreezeBlock* freezes;

void initFreezes(void)
{
freezes = calloc(FREEZE_DIC_LENGTH, sizeof(FreezeBlock));
}

void freeFreezes(void)
{
free(freezes);
}

int findAddrSlot(u64 addr)
{
for (int i = 0; i < FREEZE_DIC_LENGTH; i++)
{
if (freezes[i].address == addr)
return i;
}

return -1;
}

int findNextEmptySlot()
{
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;
}

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 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;
}

// 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;
}
21 changes: 21 additions & 0 deletions sys-botbase/source/freeze.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <switch.h>
#define FREEZE_DIC_LENGTH 255

typedef struct {
char state;
u64 address;
u8* vData;
u64 size;
u64 titleId;
} FreezeBlock;

extern FreezeBlock* freezes;

void initFreezes(void);
void freeFreezes(void);
int findAddrSlot(u64 addr);
int findNextEmptySlot();
int addToFreezeMap(u64 addr, u8* v_data, u64 v_size, u64 tid);
int removeFromFreezeMap(u64 addr);
int getFreezeCount(bool print);
u8 clearFreezes(void);
Loading

0 comments on commit bf8f471

Please sign in to comment.