From 483688c6010859ae6dcfca364dd57a1ccc1a144f Mon Sep 17 00:00:00 2001 From: Pinwhell <60289470+pinwhell@users.noreply.github.com> Date: Sun, 16 Jun 2024 16:08:16 -0400 Subject: [PATCH 1/8] Organization & Standarization --- .gitignore | 3 + CMakeLists.txt | 32 ++-- include/dll_injector.h | 11 ++ src/CMakeLists.txt | 3 + src/cli/CMakeLists.txt | 2 + src/cli/cli.cpp | 55 +++++++ src/dll-injector/CMakeLists.txt | 3 + src/dll-injector/dll_injector.cc | 246 +++++++++++++++++++++---------- src/injected/CMakeLists.txt | 2 + src/injected/console.cc | 2 +- src/injected/injected.cc | 10 +- 11 files changed, 268 insertions(+), 101 deletions(-) create mode 100644 include/dll_injector.h create mode 100644 src/CMakeLists.txt create mode 100644 src/cli/CMakeLists.txt create mode 100644 src/cli/cli.cpp create mode 100644 src/dll-injector/CMakeLists.txt create mode 100644 src/injected/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 52ea8bc..4d86990 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ build_debug/ build_release/ +.vs/* +out/* +CMakeSettings.json diff --git a/CMakeLists.txt b/CMakeLists.txt index f17ffaf..82675ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,31 +1,19 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.0...3.15) project(dll-injection-skeleton) include(GenerateExportHeader) -add_definitions(-D_WIN32_WINNT=0x0502) +if(WIN32) + add_definitions(-D_WIN32_WINNT=0x0502) +endif() # Common compiler flags -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") - -# dll-injector.exe -set(dll-injector_src - "src/dll-injector/dll_injector.cc" -) - -set(dll-injector_lib - "psapi" -) - -add_executable(dll-injector ${dll-injector_src}) -target_link_libraries(dll-injector ${dll-injector_lib}) - -# injected.dll -set(injected_src - "src/injected/injected.cc" - "src/injected/console.cc" +add_compile_options( + $<$:-Wall> + $<$:/W4> + $<$:-Werror> + $<$:/WX> ) -add_library(injected MODULE ${injected_src}) +add_subdirectory(src) diff --git a/include/dll_injector.h b/include/dll_injector.h new file mode 100644 index 0000000..3b871cc --- /dev/null +++ b/include/dll_injector.h @@ -0,0 +1,11 @@ +#include +#include + +uint64_t getModuleBaseAddress(DWORD processID, const char* dllName); +size_t findPids(const char* programName, size_t resPidsSz, DWORD* outPids); +bool injectDLL(HANDLE hProc, const char* dllFullPath); +bool injectDLL(DWORD procId, const char* dllFullPath); +bool unloadDLL(HANDLE hProc, const char* dllName); +bool unloadDLL(HANDLE hProc, const char* dllName); +bool loadDLL(const char* procName, const char* dllPath); +bool unloadDLL(const char* procName, const char* dllPath); \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..e697749 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(dll-injector) +add_subdirectory(cli) +add_subdirectory(injected) \ No newline at end of file diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt new file mode 100644 index 0000000..6327950 --- /dev/null +++ b/src/cli/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(dll-injector-cli cli.cpp) +target_link_libraries(dll-injector-cli dll-injector) \ No newline at end of file diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp new file mode 100644 index 0000000..99693a7 --- /dev/null +++ b/src/cli/cli.cpp @@ -0,0 +1,55 @@ +#include +#include + +int dll_load(const char* procName, const char* dllPath) +{ + return loadDLL(procName, dllPath) ? 0 : 1; +} + +int dll_unload(const char* procName, const char* dllName) +{ + return unloadDLL(procName, dllName) ? 0 : 1; +} + +void print_usage() +{ + printf( + "usage: dll-injector-cli inject [process name.exe] [dll path]\n" + "usage: dll-injector-cli eject [process name.exe] [dll name]\n"); +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) + { + print_usage(); + return 0; + } + + const char* option = argv[1]; + + if (!strcmp(option, "inject")) + { + if (argc < 4) + { + print_usage(); + return 0; + } + + return dll_load(argv[2], argv[3]); + } + + if (!strcmp(option, "eject")) + { + if (argc < 4) + { + print_usage(); + return 0; + } + + return dll_unload(argv[2], argv[3]); + } + + print_usage(); + return 0; +} \ No newline at end of file diff --git a/src/dll-injector/CMakeLists.txt b/src/dll-injector/CMakeLists.txt new file mode 100644 index 0000000..cedf8df --- /dev/null +++ b/src/dll-injector/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(dll-injector STATIC dll_injector.cc) +target_include_directories(dll-injector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include) +target_link_libraries(dll-injector psapi) \ No newline at end of file diff --git a/src/dll-injector/dll_injector.cc b/src/dll-injector/dll_injector.cc index 50aac57..15c9144 100644 --- a/src/dll-injector/dll_injector.cc +++ b/src/dll-injector/dll_injector.cc @@ -2,33 +2,51 @@ #include #include #include +#include +#include + +HMODULE GetMHandle(DWORD processID, const char* dllName) { + HMODULE hMod = 0; + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processID); + + if (hSnapshot != INVALID_HANDLE_VALUE) { + MODULEENTRY32 moduleEntry; + moduleEntry.dwSize = sizeof(moduleEntry); + + if (Module32First(hSnapshot, &moduleEntry)) { + do { + if (strstr(moduleEntry.szModule, dllName)) { + hMod = moduleEntry.hModule; + break; + } + } while (Module32Next(hSnapshot, &moduleEntry)); + } + CloseHandle(hSnapshot); + } + return hMod; +} -// Name of the program to inject the dll in -static const std::string programName = "gvim.exe"; - -// Name of the dll to inject -static const std::string dllName = "libinjected.dll"; - -DWORD findPid(const std::string& programName) +size_t findPids(const char* programName, size_t resPidsSz, DWORD* outPids) { // Enumerate all processes - DWORD pids[1024]; + size_t resIndex = 0; + DWORD pidsArr[1024]; DWORD temp; - if (!EnumProcesses(pids, sizeof(pids), &temp)) + if (!EnumProcesses(pidsArr, sizeof(pidsArr), &temp)) { - return 1; + return {}; } // Find the first process with the given program name auto noPids = temp / sizeof(DWORD); for (auto i = 0u; i < noPids; i++) { - if (pids[i] == 0) + if (pidsArr[i] == 0) { continue; } - auto tempHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pids[i]); + auto tempHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pidsArr[i]); if (tempHandle == NULL) { continue; @@ -39,89 +57,167 @@ DWORD findPid(const std::string& programName) { TCHAR szProcessName[MAX_PATH]; GetModuleBaseName(tempHandle, tempModule, szProcessName, sizeof(szProcessName) / sizeof(TCHAR)); - if (strcmp(programName.c_str(), szProcessName) == 0) + if (strcmp(programName, szProcessName) == 0) { - return pids[i]; + outPids[resIndex++] = pidsArr[i]; + if ((resIndex < resPidsSz) == false) + break; } } } - return 0; + return resIndex; } -bool injectDLL(DWORD pid) +bool injectDLL(HANDLE hProc, const char* dllFullPath) { - // Get full path of our dll - char fullDllName[1024]; - if (GetFullPathName(dllName.c_str(), sizeof(fullDllName), fullDllName, nullptr) == 0) - { - return false; - } + // Get the address to the function LoadLibraryA in kernel32.dll + auto LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); + if (LoadLibAddr == NULL) + { + return false; + } - // Open process using pid - auto handle = OpenProcess(PROCESS_ALL_ACCESS, false, pid); - if (handle == NULL) - { - return false; - } + // Allocate memory inside the opened process + auto dereercomp = VirtualAllocEx(hProc, NULL, strlen(dllFullPath), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (dereercomp == NULL) + { + return false; + } - // Get the address to the function LoadLibraryA in kernel32.dll - auto LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); - if (LoadLibAddr == NULL) - { - return false; - } + // Write the DLL name to the allocated memory + if (!WriteProcessMemory(hProc, dereercomp, dllFullPath, strlen(dllFullPath), NULL)) + { + return false; + } - // Allocate memory inside the opened process - auto dereercomp = VirtualAllocEx(handle, NULL, strlen(fullDllName), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - if (dereercomp == NULL) - { - return false; - } + // Create a thread in the opened process + auto remoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddr, dereercomp, 0, NULL); + if (remoteThread == NULL) + { + return false; + } - // Write the DLL name to the allocated memory - if (!WriteProcessMemory(handle, dereercomp, fullDllName, strlen(fullDllName), NULL)) - { - return false; - } + // Wait until thread have started (or stopped?) + WaitForSingleObject(remoteThread, INFINITE); - // Create a thread in the opened process - auto remoteThread = CreateRemoteThread(handle, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddr, dereercomp, 0, NULL); - if (remoteThread == NULL) - { - return false; - } + // Free the allocated memory + VirtualFreeEx(hProc, dereercomp, strlen(dllFullPath), MEM_RELEASE); + + // Close the handles + CloseHandle(remoteThread); + CloseHandle(hProc); + + return true; +} + +bool injectDLL(DWORD procId, const char* dllFullPath) +{ + HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, procId); - // Wait until thread have started (or stopped?) - WaitForSingleObject(remoteThread, INFINITE); + if (hProcess == INVALID_HANDLE_VALUE) + return false; - // Free the allocated memory - VirtualFreeEx(handle, dereercomp, strlen(fullDllName), MEM_RELEASE); + bool bInjected = injectDLL(hProcess, dllFullPath); - // Close the handles - CloseHandle(remoteThread); - CloseHandle(handle); + CloseHandle(hProcess); - return true; + return bInjected; } -int main(int argc, char* argv[]) +bool unloadDLL(HANDLE hProc, const char* dllName) { - printf("Finding pid for: %s\n", programName.c_str()); - auto pid = findPid(programName); - if (pid == 0) - { - fprintf(stderr, "Could not find process: %s\n", programName.c_str()); - return 1; - } + DWORD procId = GetProcessId(hProc); - printf("Injecting DLL: %s\n", dllName.c_str()); - if (!injectDLL(pid)) - { - fprintf(stderr, "Could not inject DLL: %s\n", dllName.c_str()); - return 1; - } + printf("PID-%d: Unload %s\n", procId, dllName); - printf("Done!\n"); - return 0; + if (procId == 0) + return false; + + HMODULE hMod = GetMHandle(procId, dllName); + + // Get the address to the function FreeLibrary in kernel32.dll + auto FreeLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "FreeLibrary"); + if (FreeLibAddr == NULL) + { + return false; + } + + // Create a thread in the opened process + auto remoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibAddr, (LPVOID)hMod, 0, NULL); + if (remoteThread == NULL) + { + return false; + } + + // Wait until thread have started (or stopped?) + WaitForSingleObject(remoteThread, INFINITE); + + // Close the handles + CloseHandle(remoteThread); + + return true; +} + +bool unloadDLL(DWORD procId, const char* dllName) +{ + HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, procId); + + if (hProcess == INVALID_HANDLE_VALUE) + return false; + + bool bUnloaded = unloadDLL(hProcess, dllName); + + CloseHandle(hProcess); + + return bUnloaded; +} + +bool loadDLL(const char* procName, const char* dllPath) +{ + DWORD pids[1024]; + size_t nPids = findPids(procName, sizeof(pids), pids); + char fullDllPath[260]; + + if (nPids == 0) + { + printf("Could not find process: %s\n", procName); + return false; + } + + if (!GetFullPathNameA(dllPath, sizeof(fullDllPath), fullDllPath, 0)) + { + printf("Could not find dll: %s\n", dllPath); + return false; + } + + printf("%s Injecting %s\n", procName, fullDllPath); + + for (size_t i = 0; i < nPids; i++) + { + if (!injectDLL(pids[i], fullDllPath)) + printf("%s:%d Could not inject DLL: %s\n", procName, pids[i], fullDllPath); + } + + return true; } + +bool unloadDLL(const char* procName, const char* dllName) +{ + DWORD pids[1024]; + size_t nPids = findPids(procName, sizeof(pids), pids); + + if (nPids == 0) + { + fprintf(stderr, "Could not find process: %s\n", procName); + return false; + } + + for (size_t i = 0; i < nPids; i++) + { + if (!unloadDLL(pids[i], dllName)) + fprintf(stderr, "%s:%d Could not unload DLL: %s\n", procName, pids[i], dllName); + } + + return true; +} \ No newline at end of file diff --git a/src/injected/CMakeLists.txt b/src/injected/CMakeLists.txt new file mode 100644 index 0000000..affd9e6 --- /dev/null +++ b/src/injected/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(injected SHARED injected.cc console.cc) +target_include_directories(injected PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include) \ No newline at end of file diff --git a/src/injected/console.cc b/src/injected/console.cc index 2f75654..1364ad7 100644 --- a/src/injected/console.cc +++ b/src/injected/console.cc @@ -50,6 +50,6 @@ void Console::write(const char* format, ...) vsnprintf(message, sizeof(message), format, args); va_end(args); - WriteConsoleA(consoleHandle, message, strlen(message), nullptr, nullptr); + WriteConsoleA(consoleHandle, message, (DWORD)strlen(message), nullptr, nullptr); } } diff --git a/src/injected/injected.cc b/src/injected/injected.cc index 77b07d3..6e2d571 100644 --- a/src/injected/injected.cc +++ b/src/injected/injected.cc @@ -3,17 +3,21 @@ #include "console.h" -static Console console; +HINSTANCE ghInstance; void injectedMain() { + static Console console; + console.init("Injected DLL"); - console.write("hey its me ur brother"); } -extern "C" __declspec(dllexport) BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + ghInstance = hinstDLL; + (void)lpvReserved; + static std::thread injectedMainThread; switch (fdwReason) From 76eda9d69f2e0f5b76916cce2174cceaa52e2591 Mon Sep 17 00:00:00 2001 From: Pinwhell <60289470+pinwhell@users.noreply.github.com> Date: Sun, 16 Jun 2024 17:35:46 -0400 Subject: [PATCH 2/8] Update README.md --- README.md | 154 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 137 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 42fd46d..8bb6986 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,137 @@ -# DllInjectionSkeleton -Just a very simple dll injection skeleton, including an injector and a dll to inject - - -# Building -This assumes that you have TDM-GCC (GCC 5.1.0), CMake (>= 3.0) and a healthy Bash environment (TDM-GCC and CMake in $PATH): - - $ cd DllInjectorSkeleton - $ ./cmake.sh all - - ### To build debug - $ cd build_debug - $ mingw32-make.exe - - ### To build release - $ cd build_release - $ mingw32-make.exe +# Dll-Injection-Skeleton + +The DLL Injector library provides a simple and efficient way to inject and eject DLLs into and from running processes on Windows. With support for both command-line interface and direct integration through CMake, this tool is ideal for developers needing to modify or debug application behavior dynamically. The library leverages Windows API functions to perform DLL injection and ejection, making it a versatile addition to any developer's toolkit. The CMake integration ensures seamless inclusion in larger projects, allowing immediate access to its functionality through easy linking. + +## Build + +### Prerequisites + +Before building the project, ensure you have the following installed on your system: + +- **CMake**: Version 3.0 or higher. +- **Visual Studio**: Recommended version for Windows development. + +### Steps to Build + +#### 1. Clone the Repository + +Clone the "Dll-Injection-Skeleton" repository from GitHub: +```bash +cd path/to/dll-injection-skeleton +``` + +#### 2. Configure the Build with CMake + +Run CMake to configure the build. Specify the generator appropriate for your installed Visual Studio version (e.g., "Visual Studio 2019"): + +```bash +mkdir build +cd build +cmake -G "Visual Studio 16 2019" .. # Replace with your Visual Studio version +``` + +#### 3. Build the Project + +Open the generated solution file (`dll-injection-skeleton.sln`) in Visual Studio and build the project: + +- Select `Build` > `Build Solution` from the Visual Studio menu. +- Alternatively, build from the command line: +```bash +cmake --build . --config Release +``` +Replace `Release` with `Debug` if you need a debug build. + +#### 4. Running Examples (Optional) + +If you enabled building examples (`DIS_BUILD_EXAMPLES` option), you can run them after building: + +- Navigate to the `build` directory (if not already there). +- Run the built examples by injecting them into any process of your choice using **CLI** (See CLI). + + +## Integration + +To integrate the **Dll-Injection-Skeleton** library into your project, follow these steps: + +### Step 1: Clone the Repository + +Clone the **Dll-Injection-Skeleton** repository from GitHub into your project's directory: +```bash +git clone https://github.com/gurka/DllInjectionSkeleton.git +``` +### Step 2: Include as Subdirectory + +Integrate the library into your CMake project by adding it as a subdirectory in your `CMakeLists.txt` file. Assuming your project's root directory is where you want to include **Dll-Injection-Skeleton**: +```cmake +add_subdirectory(path/to/DllInjectionSkeleton) +``` + +Replace `path/to/DllInjectionSkeleton` with the actual path relative to your project. + +### Step 3: Link to the Library + +Link your project to the **Dll-Injection-Skeleton** library target. For example, if your project is named `MyProject` and you want to link against `dll-injector` target from **Dll-Injection-Skeleton**, modify your `CMakeLists.txt`: +```cmake +target_link_libraries(MyProject PRIVATE dll-injector) +``` + +Make sure to replace `MyProject` with the actual name of your project. + +### Step 4: Build Your Project + +Build your project using CMake and your preferred build tool (e.g., Visual Studio, Ninja, etc.). Ensure that CMake correctly identifies and integrates **Dll-Injection-Skeleton** into your build system. + +### Example CMakeLists.txt + +Here is a simplified example of how your `CMakeLists.txt` might look after integrating **Dll-Injection-Skeleton**: +```cmake +cmake_minimum_required(VERSION 3.0) +project(MyProject) + +# Include Dll-Injection-Skeleton as a subdirectory +add_subdirectory(path/to/DllInjectionSkeleton) + +# Define your project's executable or library +add_executable(MyProject main.cpp) + +# Link your project to Dll-Injection-Skeleton +target_link_libraries(MyProject PRIVATE dll-injector) +``` + +Adjust paths and configurations according to your project's structure and requirements. + + +## Usage & CLI + +### Installation: +Follow instructions in the Build section to build using CMake or download the tool. + +### CLI Usage + +The `dll-injector-cli` tool supports two commands: + +- **Inject Command**: Injects a DLL into a specified process. +```bash +dll-injector-cli inject [process name.exe] [dll path] +``` +- **Eject Command**: Ejects a DLL from a specified process. +```bash +dll-injector-cli eject [process name.exe] [dll name] +``` +### Example Usage + +Examples of using `dll-injector-cli`: +```bash +# Inject DLL into a process +dll-injector-cli inject notepad.exe path/to/mydll.dll + +# Eject DLL from a process +dll-injector-cli eject notepad.exe mydll.dll +``` +Ensure the process is running and accessible to the user. Successful DLL operations depend on correct process and DLL path/name specifications. + +### Notes + +- Ensure appropriate permissions to perform DLL injection and ejection. +- Integrate the `dll-injector` target into your CMake projects for programmatic access to DLL injection capabilities, for more information check **Integration** Section. + From 0a81733ac968d6b40de3f51a59b7e8cc380a3cc6 Mon Sep 17 00:00:00 2001 From: Pinwhell <60289470+pinwhell@users.noreply.github.com> Date: Sun, 16 Jun 2024 17:36:41 -0400 Subject: [PATCH 3/8] Cleanups & Organizations --- .gitignore | 1 + CMakeLists.txt | 18 ++++++++---------- cmake.sh | 20 -------------------- samples/CMakeLists.txt | 1 + {src => samples}/injected/CMakeLists.txt | 0 {src => samples}/injected/console.cc | 0 {src => samples}/injected/console.h | 0 {src => samples}/injected/injected.cc | 0 src/CMakeLists.txt | 1 - 9 files changed, 10 insertions(+), 31 deletions(-) delete mode 100644 cmake.sh create mode 100644 samples/CMakeLists.txt rename {src => samples}/injected/CMakeLists.txt (100%) rename {src => samples}/injected/console.cc (100%) rename {src => samples}/injected/console.h (100%) rename {src => samples}/injected/injected.cc (100%) diff --git a/.gitignore b/.gitignore index 4d86990..3825ade 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build_release/ .vs/* out/* CMakeSettings.json +build/* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 82675ec..f1640a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,18 +2,16 @@ cmake_minimum_required(VERSION 3.0...3.15) project(dll-injection-skeleton) -include(GenerateExportHeader) +set(LOCAL_PROJECT OFF) -if(WIN32) - add_definitions(-D_WIN32_WINNT=0x0502) +if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) + set(LOCAL_PROJECT ON) endif() -# Common compiler flags -add_compile_options( - $<$:-Wall> - $<$:/W4> - $<$:-Werror> - $<$:/WX> -) +option(DIS_BUILD_EXAMPLES "Build examples for Dll Injection Skeleton" ${LOCAL_PROJECT}) add_subdirectory(src) + +if(DIS_BUILD_EXAMPLES) + add_subdirectory(samples) +endif() diff --git a/cmake.sh b/cmake.sh deleted file mode 100644 index 439022f..0000000 --- a/cmake.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -case $1 in - 'all') - mkdir -p build_release && cd build_release && cmake -G "MinGW Makefiles" .. -DCMAKE_BUILD_TYPE=release -DCMAKE_MAKE_PROGRAM=mingw32-make.exe - cd .. - mkdir -p build_debug && cd build_debug && cmake -G "MinGW Makefiles" .. -DCMAKE_BUILD_TYPE=debug -DCMAKE_MAKE_PROGRAM=mingw32-make.exe - ;; - - 'release') - mkdir -p build_release && cd build_release && cmake -G "MinGW Makefiles" .. -DCMAKE_BUILD_TYPE=release -DCMAKE_MAKE_PROGRAM=mingw32-make.exe - ;; - - 'debug') - mkdir -p build_debug && cd build_debug && cmake -G "MinGW Makefiles" .. -DCMAKE_BUILD_TYPE=debug -DCMAKE_MAKE_PROGRAM=mingw32-make.exe - ;; - - *) - echo "Usage: $0 [ all | release | debug ]" - ;; -esac diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt new file mode 100644 index 0000000..942ec34 --- /dev/null +++ b/samples/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(injected) \ No newline at end of file diff --git a/src/injected/CMakeLists.txt b/samples/injected/CMakeLists.txt similarity index 100% rename from src/injected/CMakeLists.txt rename to samples/injected/CMakeLists.txt diff --git a/src/injected/console.cc b/samples/injected/console.cc similarity index 100% rename from src/injected/console.cc rename to samples/injected/console.cc diff --git a/src/injected/console.h b/samples/injected/console.h similarity index 100% rename from src/injected/console.h rename to samples/injected/console.h diff --git a/src/injected/injected.cc b/samples/injected/injected.cc similarity index 100% rename from src/injected/injected.cc rename to samples/injected/injected.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e697749..aea8606 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,2 @@ add_subdirectory(dll-injector) add_subdirectory(cli) -add_subdirectory(injected) \ No newline at end of file From a37a172196551e11eeee8b1faa44748508a5969e Mon Sep 17 00:00:00 2001 From: Pinwhell <60289470+pinwhell@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:08:56 -0400 Subject: [PATCH 4/8] Organizations & Fixups & Revisions --- .gitignore | 3 +- CMakeLists.txt | 6 ++++ include/dll_injector_cli.h | 3 ++ samples/injected/CMakeLists.txt | 5 ++- samples/injected/injected.cc | 2 ++ src/cli/CMakeLists.txt | 13 ++++++-- src/cli/cli.cpp | 55 ++----------------------------- src/cli/dll_injector_cli.cpp | 56 ++++++++++++++++++++++++++++++++ src/dll-injector/dll_injector.cc | 36 +++++++++++++++++--- tests/CMakeLists.txt | 2 ++ tests/cli_test.cpp | 13 ++++++++ 11 files changed, 134 insertions(+), 60 deletions(-) create mode 100644 include/dll_injector_cli.h create mode 100644 src/cli/dll_injector_cli.cpp create mode 100644 tests/CMakeLists.txt create mode 100644 tests/cli_test.cpp diff --git a/.gitignore b/.gitignore index 3825ade..bbe83e5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ build_release/ .vs/* out/* CMakeSettings.json -build/* \ No newline at end of file +build/* +bin/* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f1640a9..4311cb8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.0...3.15) project(dll-injection-skeleton) +set(CMAKE_CXX_STANDARD 17) set(LOCAL_PROJECT OFF) if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) @@ -9,9 +10,14 @@ if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) endif() option(DIS_BUILD_EXAMPLES "Build examples for Dll Injection Skeleton" ${LOCAL_PROJECT}) +option(DIS_ENABLE_TESTING "Build examples for Dll Injection Skeleton" ${LOCAL_PROJECT}) add_subdirectory(src) if(DIS_BUILD_EXAMPLES) add_subdirectory(samples) endif() + +if(DIS_ENABLE_TESTING) + add_subdirectory(tests) +endif() diff --git a/include/dll_injector_cli.h b/include/dll_injector_cli.h new file mode 100644 index 0000000..e18cba1 --- /dev/null +++ b/include/dll_injector_cli.h @@ -0,0 +1,3 @@ +#pragma once + +int dll_injector_main(int argc, const char** argv); \ No newline at end of file diff --git a/samples/injected/CMakeLists.txt b/samples/injected/CMakeLists.txt index affd9e6..6dabc59 100644 --- a/samples/injected/CMakeLists.txt +++ b/samples/injected/CMakeLists.txt @@ -1,2 +1,5 @@ add_library(injected SHARED injected.cc console.cc) -target_include_directories(injected PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include) \ No newline at end of file +target_include_directories(injected PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include) + +add_library(injected_macro_path INTERFACE) +target_compile_definitions(injected_macro_path INTERFACE INJECTED_PATH="${CMAKE_CURRENT_BINARY_DIR}") diff --git a/samples/injected/injected.cc b/samples/injected/injected.cc index 6e2d571..32caf23 100644 --- a/samples/injected/injected.cc +++ b/samples/injected/injected.cc @@ -11,6 +11,8 @@ void injectedMain() console.init("Injected DLL"); console.write("hey its me ur brother"); + + MessageBoxA(NULL, "Hi", NULL, NULL); } BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 6327950..1851dac 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -1,2 +1,11 @@ -add_executable(dll-injector-cli cli.cpp) -target_link_libraries(dll-injector-cli dll-injector) \ No newline at end of file +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../bin) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../bin) + +add_executable(dll-injector-cli dll_injector_cli.cpp cli.cpp) +target_link_libraries(dll-injector-cli dll-injector) + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set_target_properties(dll-injector-cli PROPERTIES OUTPUT_NAME dll-injector-cli-64) +else() + set_target_properties(dll-injector-cli PROPERTIES OUTPUT_NAME dll-injector-cli) +endif() \ No newline at end of file diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 99693a7..4e08c39 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -1,55 +1,6 @@ -#include -#include +#include -int dll_load(const char* procName, const char* dllPath) +int main(int argc, const char* argv[]) { - return loadDLL(procName, dllPath) ? 0 : 1; -} - -int dll_unload(const char* procName, const char* dllName) -{ - return unloadDLL(procName, dllName) ? 0 : 1; -} - -void print_usage() -{ - printf( - "usage: dll-injector-cli inject [process name.exe] [dll path]\n" - "usage: dll-injector-cli eject [process name.exe] [dll name]\n"); -} - -int main(int argc, char* argv[]) -{ - if (argc < 2) - { - print_usage(); - return 0; - } - - const char* option = argv[1]; - - if (!strcmp(option, "inject")) - { - if (argc < 4) - { - print_usage(); - return 0; - } - - return dll_load(argv[2], argv[3]); - } - - if (!strcmp(option, "eject")) - { - if (argc < 4) - { - print_usage(); - return 0; - } - - return dll_unload(argv[2], argv[3]); - } - - print_usage(); - return 0; + return dll_injector_main(argc, argv); } \ No newline at end of file diff --git a/src/cli/dll_injector_cli.cpp b/src/cli/dll_injector_cli.cpp new file mode 100644 index 0000000..70e9093 --- /dev/null +++ b/src/cli/dll_injector_cli.cpp @@ -0,0 +1,56 @@ +#include +#include +#include + +int cli_dll_load(const char* procName, const char* dllPath) +{ + return loadDLL(procName, dllPath) ? 0 : 1; +} + +int cli_dll_unload(const char* procName, const char* dllName) +{ + return unloadDLL(procName, dllName) ? 0 : 1; +} + +void print_usage() +{ + printf( + "usage: dll-injector-cli inject [process name.exe] [dll path]\n" + "usage: dll-injector-cli eject [process name.exe] [dll name]\n"); +} + +int dll_injector_main(int argc, const char** argv) +{ + if (argc < 2) + { + print_usage(); + return 0; + } + + const char* option = argv[1]; + + if (!strcmp(option, "inject")) + { + if (argc < 4) + { + print_usage(); + return 0; + } + + return cli_dll_load(argv[2], argv[3]); + } + + if (!strcmp(option, "eject")) + { + if (argc < 4) + { + print_usage(); + return 0; + } + + return cli_dll_unload(argv[2], argv[3]); + } + + print_usage(); + return 0; +} \ No newline at end of file diff --git a/src/dll-injector/dll_injector.cc b/src/dll-injector/dll_injector.cc index 15c9144..15369db 100644 --- a/src/dll-injector/dll_injector.cc +++ b/src/dll-injector/dll_injector.cc @@ -5,6 +5,19 @@ #include #include +// Function to get a pointer to the filename from a given path +const char* GetFilename(const char* path) { + // Pointers to the last occurrences of '/' and '\' + const char* unix_sep = strrchr(path, '/'); + const char* win_sep = strrchr(path, '\\'); + + // Determine which is the last separator + const char* last_sep = unix_sep > win_sep ? unix_sep : win_sep; + + // If there's no separator, the path itself is the filename + return last_sep ? last_sep + 1 : path; +} + HMODULE GetMHandle(DWORD processID, const char* dllName) { HMODULE hMod = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processID); @@ -26,6 +39,11 @@ HMODULE GetMHandle(DWORD processID, const char* dllName) { return hMod; } +bool IsModuleLoaded(HANDLE hProc, const char* moduleName) +{ + return GetMHandle(GetProcessId(hProc), moduleName) != 0; +} + size_t findPids(const char* programName, size_t resPidsSz, DWORD* outPids) { // Enumerate all processes @@ -71,6 +89,12 @@ size_t findPids(const char* programName, size_t resPidsSz, DWORD* outPids) bool injectDLL(HANDLE hProc, const char* dllFullPath) { + const char* dllName = GetFilename(dllFullPath); + DWORD pid = GetProcessId(hProc); + + if (IsModuleLoaded(hProc, dllName)) + return true; + // Get the address to the function LoadLibraryA in kernel32.dll auto LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); if (LoadLibAddr == NULL) @@ -101,12 +125,14 @@ bool injectDLL(HANDLE hProc, const char* dllFullPath) // Wait until thread have started (or stopped?) WaitForSingleObject(remoteThread, INFINITE); + if (IsModuleLoaded(hProc, dllName)) + printf("PID-%d: Loaded %s\n", pid, dllName); + // Free the allocated memory VirtualFreeEx(hProc, dereercomp, strlen(dllFullPath), MEM_RELEASE); // Close the handles CloseHandle(remoteThread); - CloseHandle(hProc); return true; } @@ -129,7 +155,8 @@ bool unloadDLL(HANDLE hProc, const char* dllName) { DWORD procId = GetProcessId(hProc); - printf("PID-%d: Unload %s\n", procId, dllName); + if (!IsModuleLoaded(hProc, dllName)) + return true; if (procId == 0) return false; @@ -153,6 +180,9 @@ bool unloadDLL(HANDLE hProc, const char* dllName) // Wait until thread have started (or stopped?) WaitForSingleObject(remoteThread, INFINITE); + if (!IsModuleLoaded(hProc, dllName)) + printf("PID-%d: Unloaded %s\n", procId, dllName); + // Close the handles CloseHandle(remoteThread); @@ -191,8 +221,6 @@ bool loadDLL(const char* procName, const char* dllPath) return false; } - printf("%s Injecting %s\n", procName, fullDllPath); - for (size_t i = 0; i < nPids; i++) { if (!injectDLL(pids[i], fullDllPath)) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..c3d901c --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(cli_test cli_test.cpp ../src/cli/dll_injector_cli.cpp) +target_link_libraries(cli_test dll-injector injected_macro_path) \ No newline at end of file diff --git a/tests/cli_test.cpp b/tests/cli_test.cpp new file mode 100644 index 0000000..324f9a8 --- /dev/null +++ b/tests/cli_test.cpp @@ -0,0 +1,13 @@ +#include +#include + +int main(int argc, const char* realArgv[]) +{ + std::filesystem::current_path(INJECTED_PATH); + + const char* argv[]{ + realArgv[0], "eject", "Test.exe", "injected.dll" + }; + + dll_injector_main(sizeof(argv) / sizeof(argv[0]), (const char**)argv); +} \ No newline at end of file From 23461743b739a1ca35454d35bdb9829102f342a9 Mon Sep 17 00:00:00 2001 From: Pinwhell <60289470+pinwhell@users.noreply.github.com> Date: Tue, 18 Jun 2024 11:29:47 -0400 Subject: [PATCH 5/8] Sanity Checks Added --- src/dll-injector/dll_injector.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dll-injector/dll_injector.cc b/src/dll-injector/dll_injector.cc index 15369db..6198a9a 100644 --- a/src/dll-injector/dll_injector.cc +++ b/src/dll-injector/dll_injector.cc @@ -4,6 +4,7 @@ #include #include #include +#include // Function to get a pointer to the filename from a given path const char* GetFilename(const char* path) { @@ -87,9 +88,10 @@ size_t findPids(const char* programName, size_t resPidsSz, DWORD* outPids) return resIndex; } -bool injectDLL(HANDLE hProc, const char* dllFullPath) +bool injectDLL(HANDLE hProc, const char* _dllFullPath) { - const char* dllName = GetFilename(dllFullPath); + std::string dllFullPath = std::filesystem::absolute(_dllFullPath).string(); + const char* dllName = GetFilename(dllFullPath.c_str()); DWORD pid = GetProcessId(hProc); if (IsModuleLoaded(hProc, dllName)) @@ -103,14 +105,14 @@ bool injectDLL(HANDLE hProc, const char* dllFullPath) } // Allocate memory inside the opened process - auto dereercomp = VirtualAllocEx(hProc, NULL, strlen(dllFullPath), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + auto dereercomp = VirtualAllocEx(hProc, NULL, strlen(dllFullPath.c_str()), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (dereercomp == NULL) { return false; } // Write the DLL name to the allocated memory - if (!WriteProcessMemory(hProc, dereercomp, dllFullPath, strlen(dllFullPath), NULL)) + if (!WriteProcessMemory(hProc, dereercomp, dllFullPath.c_str(), strlen(dllFullPath.c_str()), NULL)) { return false; } @@ -129,7 +131,7 @@ bool injectDLL(HANDLE hProc, const char* dllFullPath) printf("PID-%d: Loaded %s\n", pid, dllName); // Free the allocated memory - VirtualFreeEx(hProc, dereercomp, strlen(dllFullPath), MEM_RELEASE); + VirtualFreeEx(hProc, dereercomp, strlen(dllFullPath.c_str()), MEM_RELEASE); // Close the handles CloseHandle(remoteThread); From 23dafd6a837bd2fb6b4de365644571b6ea82946f Mon Sep 17 00:00:00 2001 From: Pinwhell <60289470+pinwhell@users.noreply.github.com> Date: Thu, 20 Jun 2024 07:15:13 -0400 Subject: [PATCH 6/8] Refactors & Cleanups --- src/cli/dll_injector_cli.cpp | 59 ++++++++++++++++++-------------- src/dll-injector/dll_injector.cc | 11 ++---- tests/cli_test.cpp | 2 +- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/cli/dll_injector_cli.cpp b/src/cli/dll_injector_cli.cpp index 70e9093..be54c49 100644 --- a/src/cli/dll_injector_cli.cpp +++ b/src/cli/dll_injector_cli.cpp @@ -1,10 +1,12 @@ #include #include #include +#include +#include -int cli_dll_load(const char* procName, const char* dllPath) +int cli_dll_load(const char* procName, const char* dllPath, bool bRawPath = false) { - return loadDLL(procName, dllPath) ? 0 : 1; + return loadDLL(procName, bRawPath ? dllPath : std::filesystem::absolute(dllPath).string().c_str()) ? 0 : 1; } int cli_dll_unload(const char* procName, const char* dllName) @@ -15,42 +17,49 @@ int cli_dll_unload(const char* procName, const char* dllName) void print_usage() { printf( - "usage: dll-injector-cli inject [process name.exe] [dll path]\n" + "usage: dll-injector-cli inject [process name.exe] [optional raw] [dll path]\n" "usage: dll-injector-cli eject [process name.exe] [dll name]\n"); } int dll_injector_main(int argc, const char** argv) { - if (argc < 2) - { - print_usage(); - return 0; - } - - const char* option = argv[1]; - - if (!strcmp(option, "inject")) - { - if (argc < 4) + try { + if (argc < 2) { print_usage(); return 0; } - return cli_dll_load(argv[2], argv[3]); - } + const char* option = argv[1]; - if (!strcmp(option, "eject")) - { - if (argc < 4) + if (!strcmp(option, "inject")) { - print_usage(); - return 0; + if (argc < 4) + { + print_usage(); + return 0; + } + + return cli_dll_load(argv[2], std::string(argv[3]) == "raw" ? argv[4] : argv[3], std::string(argv[3]) == "raw"); } - return cli_dll_unload(argv[2], argv[3]); - } + if (!strcmp(option, "eject")) + { + if (argc < 4) + { + print_usage(); + return 0; + } + + return cli_dll_unload(argv[2], argv[3]); + } - print_usage(); - return 0; + print_usage(); + return 0; + } + catch (const std::exception& e) + { + std::cerr << e.what() << std::endl; + return -1; + } } \ No newline at end of file diff --git a/src/dll-injector/dll_injector.cc b/src/dll-injector/dll_injector.cc index 15369db..aad4190 100644 --- a/src/dll-injector/dll_injector.cc +++ b/src/dll-injector/dll_injector.cc @@ -207,7 +207,6 @@ bool loadDLL(const char* procName, const char* dllPath) { DWORD pids[1024]; size_t nPids = findPids(procName, sizeof(pids), pids); - char fullDllPath[260]; if (nPids == 0) { @@ -215,16 +214,10 @@ bool loadDLL(const char* procName, const char* dllPath) return false; } - if (!GetFullPathNameA(dllPath, sizeof(fullDllPath), fullDllPath, 0)) - { - printf("Could not find dll: %s\n", dllPath); - return false; - } - for (size_t i = 0; i < nPids; i++) { - if (!injectDLL(pids[i], fullDllPath)) - printf("%s:%d Could not inject DLL: %s\n", procName, pids[i], fullDllPath); + if (!injectDLL(pids[i], dllPath)) + printf("%s:%d Could not inject DLL: %s\n", procName, pids[i], dllPath); } return true; diff --git a/tests/cli_test.cpp b/tests/cli_test.cpp index 324f9a8..7138946 100644 --- a/tests/cli_test.cpp +++ b/tests/cli_test.cpp @@ -6,7 +6,7 @@ int main(int argc, const char* realArgv[]) std::filesystem::current_path(INJECTED_PATH); const char* argv[]{ - realArgv[0], "eject", "Test.exe", "injected.dll" + realArgv[0], "eject", "App.exe", "TestDll.dll" }; dll_injector_main(sizeof(argv) / sizeof(argv[0]), (const char**)argv); From b7450bfd2d3827ae9f90adc5085b64bbe40ec1ed Mon Sep 17 00:00:00 2001 From: Pinwhell <60289470+pinwhell@users.noreply.github.com> Date: Sun, 27 Oct 2024 22:21:03 -0400 Subject: [PATCH 7/8] Installation Capability Added --- CMakeLists.txt | 20 +++++++++++++++++++- cmake/GurkaInjectorConfig.cmake | 1 + src/cli/CMakeLists.txt | 2 +- src/dll-injector/CMakeLists.txt | 7 ++++--- tests/CMakeLists.txt | 2 +- 5 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 cmake/GurkaInjectorConfig.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 4311cb8..e766c3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,20 @@ cmake_minimum_required(VERSION 3.0...3.15) -project(dll-injection-skeleton) +project(GurkaInjector) + +include (CBuildKit) + +option(USE_STATIC_LINKING "Use static linking for the runtime" ON) + +if (USE_STATIC_LINKING) + if (MSVC) + # MSVC specific static linking flag + add_compile_options(/MT$<$:d>) + else() + # GCC/Clang specific static linking flag + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") + endif() +endif() set(CMAKE_CXX_STANDARD 17) set(LOCAL_PROJECT OFF) @@ -21,3 +35,7 @@ endif() if(DIS_ENABLE_TESTING) add_subdirectory(tests) endif() + +install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/GurkaInjectorConfig.cmake + DESTINATION lib/cmake/gurka) diff --git a/cmake/GurkaInjectorConfig.cmake b/cmake/GurkaInjectorConfig.cmake new file mode 100644 index 0000000..0d8c761 --- /dev/null +++ b/cmake/GurkaInjectorConfig.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/gurka-injector-targets.cmake) \ No newline at end of file diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 1851dac..5074fab 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -2,7 +2,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../bin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../bin) add_executable(dll-injector-cli dll_injector_cli.cpp cli.cpp) -target_link_libraries(dll-injector-cli dll-injector) +target_link_libraries(dll-injector-cli gurka::injector) if(CMAKE_SIZEOF_VOID_P EQUAL 8) set_target_properties(dll-injector-cli PROPERTIES OUTPUT_NAME dll-injector-cli-64) diff --git a/src/dll-injector/CMakeLists.txt b/src/dll-injector/CMakeLists.txt index cedf8df..fda0f02 100644 --- a/src/dll-injector/CMakeLists.txt +++ b/src/dll-injector/CMakeLists.txt @@ -1,3 +1,4 @@ -add_library(dll-injector STATIC dll_injector.cc) -target_include_directories(dll-injector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include) -target_link_libraries(dll-injector psapi) \ No newline at end of file +add_library_ns(gurka injector STATIC dll_injector.cc) +target_include_dir_iface(gurka-injector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include include) +target_link_libraries(gurka-injector psapi) +install_target_and_headers (gurka injector) \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c3d901c..c61295c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,2 +1,2 @@ add_executable(cli_test cli_test.cpp ../src/cli/dll_injector_cli.cpp) -target_link_libraries(cli_test dll-injector injected_macro_path) \ No newline at end of file +target_link_libraries(cli_test gurka::injector injected_macro_path) \ No newline at end of file From 9c47f9351cb0c8082a62211c03b6242fe2048ced Mon Sep 17 00:00:00 2001 From: Pinwhell <60289470+pinwhell@users.noreply.github.com> Date: Sun, 27 Oct 2024 23:06:26 -0400 Subject: [PATCH 8/8] Namespacing --- CMakeLists.txt | 3 +++ include/dll_injector.h | 11 ----------- include/dll_injector_cli.h | 3 --- include/gurka/dll_injector.h | 14 ++++++++++++++ include/gurka/dll_injector_cli.h | 5 +++++ src/cli/cli.cpp | 4 +++- src/cli/dll_injector_cli.cpp | 8 +++++--- src/dll-injector/dll_injector.cc | 17 ++++++++++------- tests/cli_test.cpp | 4 +++- 9 files changed, 43 insertions(+), 26 deletions(-) delete mode 100644 include/dll_injector.h delete mode 100644 include/dll_injector_cli.h create mode 100644 include/gurka/dll_injector.h create mode 100644 include/gurka/dll_injector_cli.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e766c3d..5d0d9b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,9 @@ if(DIS_ENABLE_TESTING) add_subdirectory(tests) endif() +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ + DESTINATION include) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/GurkaInjectorConfig.cmake DESTINATION lib/cmake/gurka) diff --git a/include/dll_injector.h b/include/dll_injector.h deleted file mode 100644 index 3b871cc..0000000 --- a/include/dll_injector.h +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -uint64_t getModuleBaseAddress(DWORD processID, const char* dllName); -size_t findPids(const char* programName, size_t resPidsSz, DWORD* outPids); -bool injectDLL(HANDLE hProc, const char* dllFullPath); -bool injectDLL(DWORD procId, const char* dllFullPath); -bool unloadDLL(HANDLE hProc, const char* dllName); -bool unloadDLL(HANDLE hProc, const char* dllName); -bool loadDLL(const char* procName, const char* dllPath); -bool unloadDLL(const char* procName, const char* dllPath); \ No newline at end of file diff --git a/include/dll_injector_cli.h b/include/dll_injector_cli.h deleted file mode 100644 index e18cba1..0000000 --- a/include/dll_injector_cli.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -int dll_injector_main(int argc, const char** argv); \ No newline at end of file diff --git a/include/gurka/dll_injector.h b/include/gurka/dll_injector.h new file mode 100644 index 0000000..289ff8f --- /dev/null +++ b/include/gurka/dll_injector.h @@ -0,0 +1,14 @@ +#include +#include + +namespace gurka { + uint64_t getModuleBaseAddress(DWORD processID, const char* dllName); + size_t findPids(const char* programName, size_t resPidsSz, DWORD* outPids); + bool injectDLL(HANDLE hProc, const char* dllFullPath); + bool injectDLL(DWORD procId, const char* dllFullPath); + bool unloadDLL(HANDLE hProc, const char* dllName); + bool unloadDLL(HANDLE hProc, const char* dllName); + bool loadDLL(const char* procName, const char* dllPath); + bool unloadDLL(DWORD procId, const char* dllName); + bool unloadDLL(const char* procName, const char* dllPath); +} \ No newline at end of file diff --git a/include/gurka/dll_injector_cli.h b/include/gurka/dll_injector_cli.h new file mode 100644 index 0000000..0a914ec --- /dev/null +++ b/include/gurka/dll_injector_cli.h @@ -0,0 +1,5 @@ +#pragma once + +namespace gurka { + int dll_injector_main(int argc, const char** argv); +} \ No newline at end of file diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 4e08c39..f5042de 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -1,4 +1,6 @@ -#include +#include + +using namespace gurka; int main(int argc, const char* argv[]) { diff --git a/src/cli/dll_injector_cli.cpp b/src/cli/dll_injector_cli.cpp index be54c49..eeaa1a4 100644 --- a/src/cli/dll_injector_cli.cpp +++ b/src/cli/dll_injector_cli.cpp @@ -1,9 +1,11 @@ #include -#include -#include +#include +#include #include #include +using namespace gurka; + int cli_dll_load(const char* procName, const char* dllPath, bool bRawPath = false) { return loadDLL(procName, bRawPath ? dllPath : std::filesystem::absolute(dllPath).string().c_str()) ? 0 : 1; @@ -21,7 +23,7 @@ void print_usage() "usage: dll-injector-cli eject [process name.exe] [dll name]\n"); } -int dll_injector_main(int argc, const char** argv) +int gurka::dll_injector_main(int argc, const char** argv) { try { if (argc < 2) diff --git a/src/dll-injector/dll_injector.cc b/src/dll-injector/dll_injector.cc index 528cb8a..7b4bb0d 100644 --- a/src/dll-injector/dll_injector.cc +++ b/src/dll-injector/dll_injector.cc @@ -5,6 +5,9 @@ #include #include #include +#include + +using namespace gurka; // Function to get a pointer to the filename from a given path const char* GetFilename(const char* path) { @@ -45,7 +48,7 @@ bool IsModuleLoaded(HANDLE hProc, const char* moduleName) return GetMHandle(GetProcessId(hProc), moduleName) != 0; } -size_t findPids(const char* programName, size_t resPidsSz, DWORD* outPids) +size_t gurka::findPids(const char* programName, size_t resPidsSz, DWORD* outPids) { // Enumerate all processes size_t resIndex = 0; @@ -88,7 +91,7 @@ size_t findPids(const char* programName, size_t resPidsSz, DWORD* outPids) return resIndex; } -bool injectDLL(HANDLE hProc, const char* _dllFullPath) +bool gurka::injectDLL(HANDLE hProc, const char* _dllFullPath) { std::string dllFullPath = std::filesystem::absolute(_dllFullPath).string(); const char* dllName = GetFilename(dllFullPath.c_str()); @@ -139,7 +142,7 @@ bool injectDLL(HANDLE hProc, const char* _dllFullPath) return true; } -bool injectDLL(DWORD procId, const char* dllFullPath) +bool gurka::injectDLL(DWORD procId, const char* dllFullPath) { HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, procId); @@ -153,7 +156,7 @@ bool injectDLL(DWORD procId, const char* dllFullPath) return bInjected; } -bool unloadDLL(HANDLE hProc, const char* dllName) +bool gurka::unloadDLL(HANDLE hProc, const char* dllName) { DWORD procId = GetProcessId(hProc); @@ -191,7 +194,7 @@ bool unloadDLL(HANDLE hProc, const char* dllName) return true; } -bool unloadDLL(DWORD procId, const char* dllName) +bool gurka::unloadDLL(DWORD procId, const char* dllName) { HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, procId); @@ -205,7 +208,7 @@ bool unloadDLL(DWORD procId, const char* dllName) return bUnloaded; } -bool loadDLL(const char* procName, const char* dllPath) +bool gurka::loadDLL(const char* procName, const char* dllPath) { DWORD pids[1024]; size_t nPids = findPids(procName, sizeof(pids), pids); @@ -225,7 +228,7 @@ bool loadDLL(const char* procName, const char* dllPath) return true; } -bool unloadDLL(const char* procName, const char* dllName) +bool gurka::unloadDLL(const char* procName, const char* dllName) { DWORD pids[1024]; size_t nPids = findPids(procName, sizeof(pids), pids); diff --git a/tests/cli_test.cpp b/tests/cli_test.cpp index 7138946..4cf02ee 100644 --- a/tests/cli_test.cpp +++ b/tests/cli_test.cpp @@ -1,6 +1,8 @@ -#include +#include #include +using namespace gurka; + int main(int argc, const char* realArgv[]) { std::filesystem::current_path(INJECTED_PATH);