diff --git a/.gitignore b/.gitignore index 9ad1e0c..af2bfc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ # CMake generated files out -# nvim Coc clangd lsp -compile_flags.txt - # Visual Studio nuances # Created by https://www.toptal.com/developers/gitignore/api/visualstudio,c++ # Edit at https://www.toptal.com/developers/gitignore?templates=visualstudio,c++ diff --git a/Makefile b/Makefile index 9aa6301..127c510 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,13 @@ PROJECT = sp3 CC = i686-w64-mingw32-gcc -CFLAGS = -std=c99 -masm=intel -Wall -Wextra -Werror -shared +CFLAGS = -std=c99 -masm=intel -pedantic -Wall -Wextra -Werror -shared LD = i686-w64-mingw32-gcc -LDFLAGS = +LDFLAGS = -shared + +ASM = nasm +ASFLAGS = -f win32 BIN = bin BUILD = build @@ -14,33 +17,45 @@ RELEASE = $(OBJ)/release SRC = src OBJ = build SOURCES = $(wildcard $(SRC)/*.c) -OBJECTS = $(patsubst $(SRC)/%.c,$(OBJ)/%.o,$(SOURCES)) - +DBG_OBJECTS = $(patsubst $(SRC)/%.c,$(DEBUG)/%.o,$(SOURCES)) +REL_OBJECTS = $(patsubst $(SRC)/%.c,$(RELEASE)/%.o,$(SOURCES)) INCLUDE = include -INCLUDES = -I$(INCLUDE) +INCLUDES = $(addprefix -I,$(INCLUDE)) -LIB_FILES = -ld3d9 -ld3dx9 -LIBS = $(LIB_FILES) +LIB_FILES = d3d9 d3dx9 +LIBS = $(addprefix -l,$(LIB_FILES)) + +ASM_TARGET = healthDetour +ASM_SRC = $(SRC)/healthDetour.asm +ASM_OBJ = $(OBJ)/healthDetour.o all: debug release debug: $(DEBUG) release: $(PROJECT) -$(DEBUG): CFLAGS+=-g -DDEBUG -$(DEBUG): $(OBJ) $(BIN) $(OBJECTS) - $(CC) $(CFLAGS) $(OBJECTS) $(LIBS) -o $(BIN)/$(PROJECT)_d.dll +$(DEBUG): CFLAGS += -g +$(DEBUG): $(OBJ) $(BIN) $(ASM_OBJ) $(DBG_OBJECTS) + $(LD) $(LDFLAGS) $(ASM_OBJ) $(DBG_OBJECTS) $(LIBS) -o $(BIN)/$(PROJECT)_d.dll + +$(PROJECT): CFLAGS += -O3 -fno-ident -fvisibility=hidden +$(PROJECT): LDFLAGS += -s +$(PROJECT): $(OBJ) $(BIN) $(REL_OBJECTS) + $(LD) $(LDFLAGS) $(ASM_OBJ) $(REL_OBJECTS) $(LIBS) -o $(BIN)/$(PROJECT).dll -$(PROJECT): CFLAGS+=-s -O2 -$(PROJECT): $(OBJ) $(BIN) $(OBJECTS) - $(CC) $(CFLAGS) $(OBJECTS) $(LIBS) -o $(BIN)/$(PROJECT).dll +$(ASM_OBJ): $(OBJ)/%.o: $(SRC)/%.asm + $(ASM) $(ASFLAGS) $^ -o $@ -$(OBJECTS): $(OBJ)/%.o: $(SRC)/%.c +$(DBG_OBJECTS): $(DEBUG)/%.o: $(SRC)/%.c + $(CC) $(CFLAGS) $(INCLUDES) -c $^ -o $@ + +$(REL_OBJECTS): $(RELEASE)/%.o: $(SRC)/%.c $(CC) $(CFLAGS) $(INCLUDES) -c $^ -o $@ $(OBJ): - mkdir -p $@ + mkdir -p $@/debug + mkdir -p $@/release $(BIN): mkdir -p $@ diff --git a/README.md b/README.md index 165754b..3c9c529 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ - Switch from C to CPP: 08/18/2021 - Project completed: 08/19/2021 - Switch from CPP to C: 08/20/2021 +- Project revisited: 12/09/2021 ## Overview & Demonstration The main purpose of this project was to get familiar with the C language while also @@ -40,26 +41,17 @@ Once the DLL is injected, you will have access to the following Hacks: - Numpad 5: Disable Enemies - Numpad 6: Unlock All Doors -## Build Instructions -- WSL - 1. install cmake for windows - ``` - $ ./install_script.sh - ``` -- CMake - 1. install cmake for windows - - Visual Studio 2019 - 1. open the project folder in Visual Studio 2019 - 2. ctrl + shift + b - - Powershell - 1. open Powershell in project directory - ``` - $ cmake -G "Visual Studio 2019" -A Win32 -B "build" - $ cmake --build "build" --config "Release" - ``` +## Build Instructions (Debian) +#### Toolchain +```bash +# Install toolchain for the required compiler +chmod +x ./install-toolchain.sh +sudo ./install-toolchain.sh # Modify it as you please before executing +``` +#### Build +```bash +make # defaults to both release and debug builds +``` ## Known Issues If the user presses F3 while the menu is minimized, it will reset position. - -## Goals -- [ ] ~~Find out how to draw text~~ diff --git a/TODO.md b/TODO.md index 810098d..eb6c876 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,7 @@ -- [ ] Remove inline assembly and change it into .asm - [ ] Refactor Makefile +- [x] Create toolchain script for contribution purposes +- [x] Update README +- [x] Remove inline assembly and change it into .asm - [x] Replace tabs with spaces - [x] Create event.h/c and move handle keyboard to event "namespace" - [x] Create render.h/c and move handle keyboard to render "namespace" diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..074758b --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1,10 @@ +-std=c99 +--target=i686-pc-windows +-I/usr/lib/gcc/i686-w64-mingw32/9.3-win32/include +-I/usr/lib/gcc/i686-w64-mingw32/9.3-win32/include-fixed +-I/usr/lib/gcc/i686-w64-mingw32/9.3-win32/../../../../i686-w64-mingw32/include +-Iinclude +-Wall +-Wextra +-Werror +-pedantic diff --git a/include/mem.h b/include/mem.h index b1349e4..cc7b1fb 100644 --- a/include/mem.h +++ b/include/mem.h @@ -11,7 +11,7 @@ * @param: uintptr_t ptr, unsigned offsets[], size_t size * @rype: uintptr_t */ -uintptr_t FindDMAddress(uintptr_t ptr, unsigned offsets[], size_t size); +uintptr_t FindDynamicAddress(uintptr_t ptr, unsigned offsets[], size_t size); /** * Byte replacement from source to destination. diff --git a/install-toolchain.sh b/install-toolchain.sh new file mode 100644 index 0000000..5096a56 --- /dev/null +++ b/install-toolchain.sh @@ -0,0 +1,17 @@ +# Creator: VPR +# Created: December 9, 2021 +# Updated: December 9, 2021 + +# Gets the required mingw compiler + +set -o pipefail +set -o errexit +set -o nounset +set -o xtrace + +apt update && apt upgrade -y +apt install -y --no-install-recommends \ + mingw-w64 \ + mingw-w64-common \ + mingw-w64-i686-dev \ + mingw-w64-x86-64-dev \ diff --git a/src/d3d9hook.c b/src/d3d9hook.c index 328d4eb..cf6d25d 100644 --- a/src/d3d9hook.c +++ b/src/d3d9hook.c @@ -4,7 +4,7 @@ static HWND g_window; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lpParam) +BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam) { DWORD wndProcId; GetWindowThreadProcessId(handle, &wndProcId); diff --git a/src/hacks.c b/src/hacks.c index 0a14c15..cefe6ae 100644 --- a/src/hacks.c +++ b/src/hacks.c @@ -19,6 +19,8 @@ extern bool bGhostMode; extern bool bShutdown; extern bool bGodMode; +/*void healthDetour(void); // maybe this works?*/ + void hack_GodMode(bool bGodMode) { const char* health_op = (char *)(module_base_addr + offsets_health_base); @@ -29,11 +31,18 @@ void hack_GodMode(bool bGodMode) if (bGodMode) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" Detour((void *)health_op, (void *)healthDetour, health_op_size); +#pragma GCC diagnostic pop + } else { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" Patch((BYTE *)health_op, (BYTE *)health_original, health_op_size); +#pragma GCC diagnostic pop } } @@ -54,13 +63,19 @@ void hack_GhostMode(bool bGhostMode) if (bGhostMode) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" Patch((BYTE *)visibility_op, (BYTE *)visibility_patch, visibility_size); Patch((BYTE *)noise_op, (BYTE *)noise_patch, noise_size); +#pragma GCC diagnostic pop } else { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" Patch((BYTE *)visibility_op, (BYTE *)visibility_original, visibility_size); Patch((BYTE *)noise_op, (BYTE *)noise_original, noise_size); +#pragma GCC diagnostic pop } } @@ -174,11 +189,11 @@ void hack_DisableAlarms(bool bDisableAlarms) unsigned int hack_DisableEnemies(bool bDisableEnemies) { - EntityList* entity_list = *(EntityList **)FindDMAddress(module_base_addr + offsets_entity_list_base, + EntityList* entity_list = *(EntityList **)FindDynamicAddress(module_base_addr + offsets_entity_list_base, offsets_entity_list_pointers, offsets_entity_list_pointers_size); - size_t entity_list_size = *((int *)(FindDMAddress(module_base_addr + offsets_entity_list_base, + size_t entity_list_size = *((int *)(FindDynamicAddress(module_base_addr + offsets_entity_list_base, offsets_entity_list_pointers, offsets_entity_list_pointers_size)) + 1); @@ -206,11 +221,11 @@ unsigned int hack_DisableEnemies(bool bDisableEnemies) unsigned int hack_UnlockAllDoors(void) { - EntityList* _entity_list = *(EntityList **)FindDMAddress(module_base_addr + offsets_entity_list_base, + EntityList* _entity_list = *(EntityList **)FindDynamicAddress(module_base_addr + offsets_entity_list_base, offsets_entity_list_pointers, offsets_entity_list_pointers_size); - size_t size = *((int *)(FindDMAddress(module_base_addr + offsets_entity_list_base, + size_t size = *((int *)(FindDynamicAddress(module_base_addr + offsets_entity_list_base, offsets_entity_list_pointers, offsets_entity_list_pointers_size)) + 1); @@ -239,83 +254,3 @@ unsigned int hack_UnlockAllDoors(void) return n_doors_unlocked; } - -/*void hack_InitializeMenuItems()*/ -/*{*/ - /*strcpy(hackMenu[GOD_MODE].name, "1: God Mode");*/ - /*strcpy(hackMenu[GHOST_MODE].name, "2: Ghost Mode");*/ - /*strcpy(hackMenu[SUPER_WEAPONS].name, "3: Super Weapons");*/ - /*strcpy(hackMenu[DISABLE_ALARMS].name, "4: Disable Alarms");*/ - /*strcpy(hackMenu[DISABLE_ENEMIES].name, "5: Disable Enemies");*/ - /*strcpy(hackMenu[UNLOCK_ALL_DOORS].name, "6: Unlock All Doors");*/ -/*}*/ - -/*void hack_Menu(IDirect3DDevice9* d3dDevice)*/ -/*{*/ - /*resolution = *((Resolution *)(0x0009D2A8));*/ - - /*float factor = 1.0;*/ - /*if (bMaximizeMenu)*/ - /*{*/ - /*// Title Template*/ - /*draw_DrawFilledRect(coordinates.x, coordinates.y, 140, 100, color_DarkGrey, d3dDevice);*/ - /*draw_DrawBorderBox(coordinates.x, coordinates.y, 140, 100, 4, color_Black, d3dDevice);*/ - - /*// Row one*/ - /*int x1 = 20;*/ - /*int y1 = 15;*/ - /*for (int i = 3; i < MAX_MENU_ITEMS; i++)*/ - /*{*/ - /*// If hack is on we display the text colour in green*/ - /*draw_DrawFilledRect(coordinates.x + x1, coordinates.y + y1, 25, 20, hackMenu[i].bEnabled ? color_Green : color_LightGrey, d3dDevice);*/ - /*draw_DrawBorderBox(coordinates.x + x1, coordinates.y + y1, 25, 20, 2, color_Black, d3dDevice);*/ - - /*//used to position the next item below*/ - /*x1 += 40;*/ - /*}*/ - /*// Row two*/ - /*int x2 = 20;*/ - /*int y2 = 55;*/ - /*for (int i = 0; i < MAX_MENU_ITEMS - 3; i++)*/ - /*{*/ - /*// If hack is on we display the text colour in green*/ - /*draw_DrawFilledRect(coordinates.x + x2, coordinates.y + y2, 25, 20, hackMenu[i].bEnabled ? color_Green : color_LightGrey, d3dDevice);*/ - /*draw_DrawBorderBox(coordinates.x + x2, coordinates.y + y2, 25, 20, 2, color_Black, d3dDevice);*/ - - /*//used to position the next item*/ - /*x2 += 40;*/ - /*}*/ - /*}*/ - /*else*/ - /*{*/ - /*factor = 0.25;*/ - /*// Title Template*/ - /*draw_DrawFilledRect(30, 20, (int)(factor*140), (int)(factor*100), color_DarkGrey, d3dDevice);*/ - /*draw_DrawBorderBox(30, 20, (int)(factor*140), (int)(factor*100), 2, color_Black, d3dDevice);*/ - - /*// Row one*/ - /*int x1 = 35;*/ - /*int y1 = 25;*/ - /*for (int i = 3; i < MAX_MENU_ITEMS; i++)*/ - /*{*/ - /*// If hack is on we display the text colour in green*/ - /*draw_DrawFilledRect(x1, y1, (int)(factor*20), (int)(factor*20), hackMenu[i].bEnabled ? color_Green : color_LightGrey, d3dDevice);*/ - /*draw_DrawBorderBox(x1, y1, (int)(factor*20), (int)(factor*20), 1, color_Black, d3dDevice);*/ - - /*//used to position the next item below*/ - /*x1 += (int)(factor*40);*/ - /*}*/ - /*// Row two*/ - /*int x2 = 35;*/ - /*int y2 = 35;*/ - /*for (int i = 0; i < MAX_MENU_ITEMS - 3; i++)*/ - /*{*/ - /*// If hack is on we display the text colour in green*/ - /*draw_DrawFilledRect(x2, y2, (int)(factor*20), (int)(factor*20), hackMenu[i].bEnabled ? color_Green : color_LightGrey, d3dDevice);*/ - /*draw_DrawBorderBox(x2, y2, (int)(factor*20), (int)(factor*20), 1, color_Black, d3dDevice);*/ - - /*//used to position the next item*/ - /*x2 += (int)(factor*40);*/ - /*}*/ - /*}*/ -/*}*/ diff --git a/src/healthDetour.asm b/src/healthDetour.asm new file mode 100644 index 0000000..d11475e --- /dev/null +++ b/src/healthDetour.asm @@ -0,0 +1,17 @@ +segment .text + +global _healthDetour + +_healthDetour: + cmp dword [edi], 0x110E8B50 + je $ + 0x08 + xor eax, eax + mov eax, eax + mov dword [ebx], eax + mov ebx, eax + mov eax, dword [esp + 0x14] + pop esi + mov dword [eax], ebx + pop ebx + pop ecx + ret 0x8 diff --git a/src/main.c b/src/main.c index 788640b..9d487ce 100644 --- a/src/main.c +++ b/src/main.c @@ -56,7 +56,10 @@ DWORD WINAPI MainThread(LPVOID lpReserved) if (GetD3D9Device(d3d9Device, sizeof(d3d9Device))) { - oEndScene = (tEndScene)TrampHook((char*)d3d9Device[42], (char*)hkEndScene, 7); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" + oEndScene = (tEndScene)TrampHook((char *)d3d9Device[42], (char *)hkEndScene, 7); +#pragma GCC diagnostic pop } return TRUE; diff --git a/src/mem.c b/src/mem.c index a1f378a..b5421e7 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1,13 +1,15 @@ #include "mem.h" -uintptr_t FindDMAddress(uintptr_t ptr, unsigned offsets[], size_t size) +uintptr_t FindDynamicAddress(uintptr_t ptr, unsigned offsets[], size_t size) { uintptr_t addr = ptr; for (size_t i = 0; i < size; i++) { - addr = *(uintptr_t*)addr; + addr = *(uintptr_t *)addr; addr += offsets[i]; + + if (!addr) { return 0; } } return addr; @@ -52,7 +54,7 @@ bool Hook(char* src, char* dst, int len) uintptr_t relativeAddress = (uintptr_t)(dst - src - 5); *src = (char)0xE9; - *(uintptr_t*)(src + 1) = (uintptr_t)relativeAddress; + *(uintptr_t *)(src + 1) = (uintptr_t)relativeAddress; DWORD temp; VirtualProtect(src, len, curProtection, &temp); @@ -65,12 +67,12 @@ char* TrampHook(char* src, char* dst, unsigned int len) if (len < 5) return 0; - char* gateway = (char*)VirtualAlloc(0, len + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + char* gateway = (char *)VirtualAlloc(0, len + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); memcpy(gateway, src, len); uintptr_t gateJmpAddy = (uintptr_t)(src - gateway - 5); *(gateway + len) = (char)0xE9; - *(uintptr_t*)(gateway + len + 1) = gateJmpAddy; + *(uintptr_t *)(gateway + len + 1) = gateJmpAddy; if (Hook(src, dst, len)) { @@ -79,43 +81,3 @@ char* TrampHook(char* src, char* dst, unsigned int len) else return NULL; } - -#ifndef __MINGW32__ - void __declspec( naked ) healthDetour(void) - { - __asm - { - cmp dword ptr [edi], 0x110E8B50 - je $ + 0x08 - xor eax, eax - mov eax, eax - mov dword ptr [ebx], eax - mov ebx, eax - mov eax, dword ptr [esp + 0x14] - pop esi - mov dword ptr [eax], ebx - pop ebx - pop ecx - ret 0x8 - } - } -#else - void __declspec() healthDetour(void) - { - __asm__ - ( - "cmp dword ptr [edi], 0X110E8B50\n\t" - "je $ + 0x08\n\t" - "xor eax, eax\n\t" - "mov eax, eax\n\t" - "mov dword ptr [ebx], eax\n\t" - "mov ebx, eax\n\t" - "mov eax, dword ptr [esp + 0x14]\n\t" - "pop esi\n\t" - "mov dword ptr [eax], ebx\n\t" - "pop ebx\n\t" - "pop ecx\n\t" - "ret 0x8\n\t" - ); - } -#endif