├── .gitignore ├── .gitmodules ├── README.md ├── input_loader ├── Makefile └── source │ └── main.c └── input_proc ├── Makefile ├── meta ├── audio.wav ├── banner.png └── icon.png └── source ├── heap_shim.c ├── injected.s └── main.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.smdh 2 | *.3dsx 3 | *.elf 4 | *.cia 5 | *.zip 6 | *.o 7 | *.d 8 | input_proc/output 9 | input_proc/build 10 | injector/build 11 | pc/input -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "input_proc/buildtools"] 2 | path = input_proc/buildtools 3 | url = https://github.com/Steveice10/buildtools 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # limitations 2 | i don't hook the IR service, so no zl/zr or c-stick 3 | 4 | ## credits and stuff 5 | Memory patching code taken from BootNTR 6 | 7 | Steveice10's buildtools used to build input_proc 8 | 9 | Shinyquagsire for inspiring me to start this with his writeup, then helping me along the way 10 | 11 | ## how do i use this 12 | Install the input_proc cia on your 3ds, then run the injector. 13 | 14 | use one of these input programs to actually get input to the ds: 15 | * [SDL for Linux](https://github.com/Stary2001/InputClient-SDL) 16 | * [XInput for Windows](https://github.com/Kazo/InputRedirectionClient) 17 | 18 | ## note 19 | buildtools requires a 1 line patch for the input redirector cia to work best: 20 | replace MemoryType: Application with MemoryType: Base in template.rsf line 70 21 | -------------------------------------------------------------------------------- /input_loader/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | TOPDIR ?= $(CURDIR) 10 | include $(DEVKITARM)/3ds_rules 11 | 12 | #--------------------------------------------------------------------------------- 13 | # TARGET is the name of the output 14 | # BUILD is the directory where object files & intermediate files will be placed 15 | # SOURCES is a list of directories containing source code 16 | # DATA is a list of directories containing data files 17 | # INCLUDES is a list of directories containing header files 18 | # 19 | # NO_SMDH: if set to anything, no SMDH file is generated. 20 | # ROMFS is the directory which contains the RomFS, relative to the Makefile (Optional) 21 | # APP_TITLE is the name of the app stored in the SMDH file (Optional) 22 | # APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional) 23 | # APP_AUTHOR is the author of the app stored in the SMDH file (Optional) 24 | # ICON is the filename of the icon (.png), relative to the project folder. 25 | # If not set, it attempts to use one of the following (in this order): 26 | # - .png 27 | # - icon.png 28 | # - /default_icon.png 29 | #--------------------------------------------------------------------------------- 30 | TARGET := $(notdir $(CURDIR)) 31 | BUILD := build 32 | SOURCES := source 33 | DATA := data 34 | INCLUDES := include 35 | #ROMFS := romfs 36 | 37 | #--------------------------------------------------------------------------------- 38 | # options for code generation 39 | #--------------------------------------------------------------------------------- 40 | ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft 41 | 42 | CFLAGS := -g -Wall -O2 -mword-relocations \ 43 | -fomit-frame-pointer -ffunction-sections \ 44 | $(ARCH) 45 | 46 | CFLAGS += $(INCLUDE) -DARM11 -D_3DS -DKHAX_DEBUG 47 | 48 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 49 | 50 | ASFLAGS := -g $(ARCH) 51 | LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 52 | 53 | LIBS := -lctru -lm 54 | 55 | #--------------------------------------------------------------------------------- 56 | # list of directories containing libraries, this must be the top level containing 57 | # include and lib 58 | #--------------------------------------------------------------------------------- 59 | LIBDIRS := $(CTRULIB) 60 | 61 | 62 | #--------------------------------------------------------------------------------- 63 | # no real need to edit anything past this point unless you need to add additional 64 | # rules for different file extensions 65 | #--------------------------------------------------------------------------------- 66 | ifneq ($(BUILD),$(notdir $(CURDIR))) 67 | #--------------------------------------------------------------------------------- 68 | 69 | export OUTPUT := $(CURDIR)/$(TARGET) 70 | export TOPDIR := $(CURDIR) 71 | 72 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 73 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 74 | 75 | export DEPSDIR := $(CURDIR)/$(BUILD) 76 | 77 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 78 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 79 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 80 | PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) 81 | SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) 82 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 83 | 84 | #--------------------------------------------------------------------------------- 85 | # use CXX for linking C++ projects, CC for standard C 86 | #--------------------------------------------------------------------------------- 87 | ifeq ($(strip $(CPPFILES)),) 88 | #--------------------------------------------------------------------------------- 89 | export LD := $(CC) 90 | #--------------------------------------------------------------------------------- 91 | else 92 | #--------------------------------------------------------------------------------- 93 | export LD := $(CXX) 94 | #--------------------------------------------------------------------------------- 95 | endif 96 | #--------------------------------------------------------------------------------- 97 | 98 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 99 | $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ 100 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 101 | 102 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 103 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 104 | -I$(CURDIR)/$(BUILD) 105 | 106 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 107 | 108 | ifeq ($(strip $(ICON)),) 109 | icons := $(wildcard *.png) 110 | ifneq (,$(findstring $(TARGET).png,$(icons))) 111 | export APP_ICON := $(TOPDIR)/$(TARGET).png 112 | else 113 | ifneq (,$(findstring icon.png,$(icons))) 114 | export APP_ICON := $(TOPDIR)/icon.png 115 | endif 116 | endif 117 | else 118 | export APP_ICON := $(TOPDIR)/$(ICON) 119 | endif 120 | 121 | ifeq ($(strip $(NO_SMDH)),) 122 | export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh 123 | endif 124 | 125 | ifneq ($(ROMFS),) 126 | export _3DSXFLAGS += --romfs=$(CURDIR)/$(ROMFS) 127 | endif 128 | 129 | .PHONY: $(BUILD) clean all 130 | 131 | #--------------------------------------------------------------------------------- 132 | all: $(BUILD) 133 | 134 | $(BUILD): 135 | @[ -d $@ ] || mkdir -p $@ 136 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 137 | 138 | #--------------------------------------------------------------------------------- 139 | clean: 140 | @echo clean ... 141 | @rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf 142 | 143 | 144 | #--------------------------------------------------------------------------------- 145 | else 146 | 147 | DEPENDS := $(OFILES:.o=.d) 148 | 149 | #--------------------------------------------------------------------------------- 150 | # main targets 151 | #--------------------------------------------------------------------------------- 152 | ifeq ($(strip $(NO_SMDH)),) 153 | $(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh 154 | else 155 | $(OUTPUT).3dsx : $(OUTPUT).elf 156 | endif 157 | 158 | $(OUTPUT).elf : $(OFILES) 159 | 160 | #--------------------------------------------------------------------------------- 161 | # you need a rule like this for each extension you use as binary data 162 | #--------------------------------------------------------------------------------- 163 | %.bin.o : %.bin 164 | #--------------------------------------------------------------------------------- 165 | @echo $(notdir $<) 166 | @$(bin2o) 167 | 168 | #--------------------------------------------------------------------------------- 169 | # rules for assembling GPU shaders 170 | #--------------------------------------------------------------------------------- 171 | define shader-as 172 | $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) 173 | picasso -o $(CURBIN) $1 174 | bin2s $(CURBIN) | $(AS) -o $@ 175 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h 176 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h 177 | echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h 178 | endef 179 | 180 | %.shbin.o : %.v.pica %.g.pica 181 | @echo $(notdir $^) 182 | @$(call shader-as,$^) 183 | 184 | %.shbin.o : %.v.pica 185 | @echo $(notdir $<) 186 | @$(call shader-as,$<) 187 | 188 | %.shbin.o : %.shlist 189 | @echo $(notdir $<) 190 | @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) 191 | 192 | -include $(DEPENDS) 193 | 194 | #--------------------------------------------------------------------------------------- 195 | endif 196 | #--------------------------------------------------------------------------------------- 197 | -------------------------------------------------------------------------------- /input_loader/source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include <3ds.h> 5 | 6 | int main() 7 | { 8 | gfxInitDefault(); 9 | 10 | consoleInit(GFX_BOTTOM, NULL); 11 | 12 | u32 pid; 13 | 14 | nsInit(); 15 | Result r = NS_LaunchTitle(0x0004000000123400LL, 3, &pid); 16 | nsExit(); 17 | if(r != 0) 18 | { 19 | printf("NS returned error %08lx\nPress Start to close.", r); 20 | // Main loop 21 | while (aptMainLoop()) 22 | { 23 | gspWaitForVBlank(); 24 | hidScanInput(); 25 | 26 | u32 kDown = hidKeysDown(); 27 | if (kDown & KEY_START) 28 | break; // break in order to return to hbmenu 29 | // Flush and swap framebuffers 30 | gfxFlushBuffers(); 31 | gfxSwapBuffers(); 32 | } 33 | } 34 | 35 | // Exit services 36 | gfxExit(); 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /input_proc/Makefile: -------------------------------------------------------------------------------- 1 | # TARGET # 2 | 3 | TARGET := 3DS 4 | LIBRARY := 0 5 | 6 | ifeq ($(TARGET),3DS) 7 | ifeq ($(strip $(DEVKITPRO)),) 8 | $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPro") 9 | endif 10 | 11 | ifeq ($(strip $(DEVKITARM)),) 12 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 13 | endif 14 | endif 15 | 16 | # COMMON CONFIGURATION # 17 | 18 | NAME := InputProc 19 | 20 | BUILD_DIR := build 21 | OUTPUT_DIR := output 22 | INCLUDE_DIRS := include 23 | SOURCE_DIRS := source 24 | 25 | EXTRA_OUTPUT_FILES := 26 | 27 | LIBRARY_DIRS := $(DEVKITPRO)/libctru 28 | LIBRARIES := ctru m 29 | 30 | BUILD_FLAGS := 31 | RUN_FLAGS := 32 | 33 | # 3DS CONFIGURATION # 34 | 35 | TITLE := $(NAME) 36 | DESCRIPTION := Relays input for the wifi thing. Go away. 37 | AUTHOR := Stary 38 | PRODUCT_CODE := CTR-P-CINP 39 | UNIQUE_ID := 0x1234 40 | 41 | SYSTEM_MODE := 64MB 42 | SYSTEM_MODE_EXT := Legacy 43 | 44 | ICON_FLAGS := --flags visible,ratingrequired,recordusage --cero 153 --esrb 153 --usk 153 --pegigen 153 --pegiptr 153 --pegibbfc 153 --cob 153 --grb 153 --cgsrr 153 45 | 46 | ROMFS_DIR := romfs 47 | BANNER_AUDIO := meta/audio.wav 48 | BANNER_IMAGE := meta/banner.png 49 | ICON := meta/icon.png 50 | 51 | # INTERNAL # 52 | 53 | include buildtools/make_base 54 | -------------------------------------------------------------------------------- /input_proc/meta/audio.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kazo/InputRedirection/b739f43da45d8f378154ea4470d32781e4a23801/input_proc/meta/audio.wav -------------------------------------------------------------------------------- /input_proc/meta/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kazo/InputRedirection/b739f43da45d8f378154ea4470d32781e4a23801/input_proc/meta/banner.png -------------------------------------------------------------------------------- /input_proc/meta/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kazo/InputRedirection/b739f43da45d8f378154ea4470d32781e4a23801/input_proc/meta/icon.png -------------------------------------------------------------------------------- /input_proc/source/heap_shim.c: -------------------------------------------------------------------------------- 1 | #include <3ds/types.h> 2 | #include <3ds/svc.h> 3 | #include <3ds/env.h> 4 | #include <3ds/os.h> 5 | #include <3ds/srv.h> 6 | 7 | extern char* fake_heap_start; 8 | extern char* fake_heap_end; 9 | 10 | u32 __ctru_heap; 11 | u32 __ctru_heap_size = 0x40000; // arbitrary but small 12 | u32 __ctru_linear_heap = 0; // We don't use the linear heap. 13 | u32 __ctru_linear_heap_size = 0; 14 | 15 | void __appInit() // dont't init unnecessary services 16 | { 17 | srvInit(); 18 | } 19 | 20 | void __appExit() 21 | { 22 | srvExit(); 23 | } 24 | 25 | void __system_allocateHeaps(void) 26 | { 27 | u32 tmp=0; 28 | 29 | // Allocate the application heap 30 | __ctru_heap = 0x08000000; 31 | svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); 32 | 33 | // Set up newlib heap 34 | fake_heap_start = (char*)__ctru_heap; 35 | fake_heap_end = fake_heap_start + __ctru_heap_size; 36 | } -------------------------------------------------------------------------------- /input_proc/source/injected.s: -------------------------------------------------------------------------------- 1 | .global read_input 2 | .global read_input_sz 3 | 4 | read_input: 5 | STMFD SP!, {R4-R6,LR} 6 | MOV R5, R1 7 | MRC p15, 0, R4,c13,c0, 3 8 | MOV R1, #0x10000 9 | STR R1, [R4,#0x80]! 10 | LDR R0, [R0] 11 | SVC 0x32 12 | ANDS R1, R0, #0x80000000 13 | BMI .ret 14 | push {r3} 15 | ldr r3, =0x10df08 16 | LDRD R0, [R4,#8] 17 | STRD R0, [R3, #8] 18 | LDRD r0, [R3] 19 | STRD r0, [R5] 20 | LDR R0, [R4,#4] 21 | pop {r3} 22 | 23 | @buttons init 24 | ldr r0, =0x10df20 25 | ldr r1, =0xFFF 26 | bl .init 27 | 28 | @touch init 29 | ldr r0, =0x10df24 30 | ldr r1, =0x2000000 31 | bl .init 32 | 33 | @cpad init 34 | ldr r0, =0x10df28 35 | ldr r1, =0x800800 36 | bl .init 37 | 38 | @buttons copy 39 | ldr r0, =0x10df20 40 | ldr r1, =0xFFF 41 | ldr r2, =0x1ec46000 42 | ldr r3, =0x10df00 43 | bl .copy 44 | 45 | @touch copy 46 | ldr r0, =0x10df24 47 | ldr r1, =0x2000000 48 | ldr r2, =0x10df10 49 | ldr r3, =0x10df08 50 | bl .copy 51 | 52 | @cpad copy 53 | ldr r0, =0x10df28 54 | ldr r1, =0x800800 55 | ldr r2, =0x10df14 56 | ldr r3, =0x10df0c 57 | bl .copy 58 | 59 | .ret: 60 | LDMFD SP!, {R4-R6,PC} 61 | 62 | .init: 63 | ldr r2, [r0] 64 | cmp r2, #0 65 | streq r1, [r0] 66 | mov pc, r14 67 | 68 | .copy: 69 | ldr r4, [r0] 70 | cmp r4, r1 71 | ldreq r4, [r2] 72 | str r4, [r3] 73 | mov pc, r14 74 | 75 | .LTORG # assembles literal pool 76 | 77 | read_input_sz: 78 | .4byte .-read_input -------------------------------------------------------------------------------- /input_proc/source/main.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include <3ds/services/apt.h> 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define HID_PID 0x10 17 | 18 | // 9.2 HID 19 | //#define HID_PATCH1_LOC 0x101dbc 20 | //#define HID_PATCH2_LOC 0x107924 21 | 22 | // 11.0 HID 23 | #define HID_PATCH1_LOC 0x101de0 24 | #define HID_PATCH2_LOC 0x107acc 25 | #define HID_PATCH3_LOC 0x106a74 26 | #define HID_CAVE_LOC 0x1094B8 27 | 28 | #define HID_DAT_LOC 0x10df00 29 | #define HID_TS_RD_LOC 0x10df04 30 | #define HID_TS_WR_LOC 0x10df08 31 | 32 | u32 protect_remote_memory(Handle hProcess, void* addr, u32 size) 33 | { 34 | return svcControlProcessMemory(hProcess, (u32)addr, (u32)addr, size, 6, 7); 35 | } 36 | 37 | u32 copy_remote_memory(Handle hDst, void* ptrDst, Handle hSrc, void* ptrSrc, u32 size) 38 | { 39 | static u32 done_state = 0; 40 | 41 | u32 ret, i, state; 42 | u32 dmaConfig[20] = { 0 }; 43 | Handle hDma; 44 | 45 | ret = svcFlushProcessDataCache(hSrc, ptrSrc, size); 46 | ret = svcFlushProcessDataCache(hDst, ptrDst, size); 47 | ret = svcStartInterProcessDma(&hDma, hDst, ptrDst, hSrc, ptrSrc, size, dmaConfig); 48 | state = 0; 49 | 50 | if (done_state == 0) 51 | { 52 | ret = svcGetDmaState(&state, hDma); 53 | svcSleepThread(1000000000); 54 | ret = svcGetDmaState(&state, hDma); 55 | done_state = state; 56 | //printf("InterProcessDmaFinishState: %08lx\n", state); 57 | } 58 | 59 | for (i = 0; i < 10000; i++) 60 | { 61 | state = 0; 62 | ret = svcGetDmaState(&state, hDma); 63 | if (state == done_state) 64 | { 65 | break; 66 | } 67 | svcSleepThread(1000000); 68 | } 69 | 70 | if (i >= 10000) 71 | { 72 | //printf("readRemoteMemory time out %08lx\n", state); 73 | return 1; // error 74 | } 75 | 76 | svcCloseHandle(hDma); 77 | ret = svcInvalidateProcessDataCache(hDst, ptrDst, size); 78 | if (ret != 0) 79 | { 80 | return ret; 81 | } 82 | return 0; 83 | 84 | } 85 | 86 | u32 open_current_process() 87 | { 88 | u32 handle = 0; 89 | u32 ret; 90 | u32 hCurrentProcess; 91 | u32 currentPid; 92 | 93 | svcGetProcessId(¤tPid, 0xffff8001); 94 | ret = svcOpenProcess(&handle, currentPid); 95 | if (ret != 0) 96 | { 97 | return 0; 98 | } 99 | hCurrentProcess = handle; 100 | return hCurrentProcess; 101 | } 102 | 103 | u32 open_process(u32 pid) 104 | { 105 | Handle hProcess; 106 | Result r = svcOpenProcess(&hProcess, pid); 107 | if (r != 0) 108 | { 109 | return 0; 110 | } 111 | return hProcess; 112 | } 113 | 114 | s32 killCache_k() 115 | { 116 | __asm__ volatile("cpsid aif"); 117 | __asm__ volatile("mcr p15, 0, r0, c7, c5, 0"); // icache 118 | __asm__ volatile("mcr p15, 0, r0, c7, c14, 0"); // dcache 119 | return 0; 120 | } 121 | 122 | void killCache() 123 | { 124 | svcBackdoor(killCache_k); 125 | } 126 | 127 | u32 branch(u32 base, u32 target) 128 | { 129 | s32 off = (s32)(target - base); 130 | off -= 8; // arm is 2 instructions ahead (8 bytes) 131 | off /= 4; // word offset vs byte offset 132 | 133 | u32 ins = 0xea000000; // branch without link 134 | ins |= *(u32*)&off; 135 | return ins; 136 | } 137 | 138 | Handle target; 139 | Handle self; 140 | 141 | void hook(u32 loc, u32 storage, u32 *hook_code, u32 hook_len) 142 | { 143 | if (protect_remote_memory(target, (void*)(storage & (~0xfff)), 0x1000) != 0) 144 | { 145 | //printf("patch 4 prot failed\n"); 146 | } 147 | 148 | if (copy_remote_memory(target, (void*)storage, self, hook_code, hook_len) != 0) 149 | { 150 | //printf("patch 4 copy failed\n"); 151 | } 152 | 153 | u32 br = branch(loc, storage); 154 | 155 | if (copy_remote_memory(target, (void*)loc, self, &br, 4) != 0) 156 | { 157 | //printf("patch 3 copy failed\n"); 158 | } 159 | } 160 | 161 | void read_input(); 162 | extern u32 read_input_sz; 163 | 164 | bool run = true; 165 | 166 | void input_loop(void* a) 167 | { 168 | Handle hid = open_process(0x10); 169 | Handle self = open_current_process(); 170 | u32 input_loc = 0x10df20; 171 | u32 input[3]; 172 | 173 | acInit(); 174 | u32 *sockbuf = (u32*)memalign(0x1000, 0x10000); 175 | Result res = socInit(sockbuf, 0x10000); 176 | 177 | if(res != 0) 178 | { 179 | acExit(); 180 | return; 181 | } 182 | 183 | struct sockaddr_in addr; 184 | int sockfd; 185 | int byte_count; 186 | char buf[512]; 187 | 188 | addr.sin_family = AF_INET; 189 | addr.sin_port = htons(4950); 190 | addr.sin_addr.s_addr = htonl(INADDR_ANY); 191 | sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 192 | if(sockfd == -1) 193 | { 194 | socExit(); 195 | acExit(); 196 | return; 197 | } 198 | int r = bind(sockfd, (struct sockaddr*) &addr, sizeof(addr)); 199 | if(r == -1) 200 | { 201 | close(sockfd); 202 | socExit(); 203 | acExit(); 204 | return; 205 | } 206 | 207 | while(run) 208 | { 209 | byte_count = recv(sockfd, buf, sizeof buf, 0); 210 | if(byte_count == -1) 211 | { 212 | break; 213 | } 214 | 215 | if(byte_count >= 12) 216 | { 217 | u32 *b = (u32*)buf; 218 | input[0] = b[0]; 219 | input[1] = b[1]; 220 | input[2] = b[2]; 221 | copy_remote_memory(hid, (void*)input_loc, self, &input, 12); 222 | } 223 | } 224 | 225 | socExit(); 226 | acExit(); 227 | } 228 | 229 | int main() 230 | { 231 | //printf("injecting into hid..\n"); 232 | 233 | self = open_current_process(); 234 | 235 | u32 new_loc = HID_DAT_LOC; 236 | 237 | target = open_process(HID_PID); 238 | 239 | u32 test = 0; 240 | 241 | Result r = copy_remote_memory(self, &test, target, (void*)new_loc, 4); 242 | if (r != 0) 243 | { 244 | //printf("copy returned %08lx\n", r); 245 | exit(0); 246 | } 247 | 248 | if (test != 0) 249 | { 250 | //printf("!!!!!!\n"); 251 | } 252 | else 253 | { 254 | u32 f = 0xffffffff; 255 | r = copy_remote_memory(target, (void*)new_loc, self, &f, 4); 256 | if (r != 0) 257 | { 258 | //printf("init copy failed\n"); 259 | } 260 | 261 | if (protect_remote_memory(target, (void*)(HID_PATCH1_LOC & (~0xfff)), 0x1000) != 0) 262 | { 263 | //printf("patch 1 prot failed\n"); 264 | } 265 | 266 | if (copy_remote_memory(target, (void*)HID_PATCH1_LOC, self, &new_loc, 4) != 0) 267 | { 268 | //printf("patch 1 copy failed\n"); 269 | } 270 | 271 | if (protect_remote_memory(target, (void*)(HID_PATCH2_LOC & (~0xfff)), 0x1000) != 0) 272 | { 273 | //printf("patch 2 prot failed\n"); 274 | } 275 | 276 | if (copy_remote_memory(target, (void*)HID_PATCH2_LOC, self, &new_loc, 4) != 0) 277 | { 278 | //printf("patch 2 copy failed\n"); 279 | } 280 | 281 | if (protect_remote_memory(target, (void*)(HID_PATCH3_LOC & (~0xfff)), 0x1000) != 0) 282 | { 283 | //printf("patch 2 prot failed\n"); 284 | } 285 | 286 | hook(HID_PATCH3_LOC, HID_CAVE_LOC, (u32*)&read_input, read_input_sz); 287 | 288 | //printf("hid done\n"); 289 | 290 | killCache(); 291 | 292 | svcCloseHandle(target); 293 | svcCloseHandle(self); 294 | } 295 | 296 | input_loop(NULL); 297 | 298 | svcExitProcess(); 299 | return 0; 300 | } 301 | --------------------------------------------------------------------------------