Skip to content

Commit d0510ea

Browse files
committed
Refactor build configuration and update main executable logic for GhostInjector
1 parent a9d0e7f commit d0510ea

5 files changed

Lines changed: 247 additions & 240 deletions

File tree

.github/workflows/build.yml

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ on:
77
branches: [ main, master ]
88
workflow_dispatch:
99

10+
permissions:
11+
contents: write
12+
1013
jobs:
1114
build-windows-msvc:
1215
runs-on: windows-latest
@@ -27,32 +30,93 @@ jobs:
2730
- name: Build
2831
run: |
2932
cmake --build build --config Release
33+
34+
- name: Rename executable
35+
run: move build\Release\ghostinjector-*.exe build\Release\ghostinjector.exe
3036

3137
- name: Check DLL dependencies
3238
shell: pwsh
3339
run: |
3440
Write-Host "=== Executable Info ==="
35-
Get-ChildItem -Path build\Release\ghostinjector-*.exe | ForEach-Object {
41+
Get-ChildItem -Path build\Release\ghostinjector.exe | ForEach-Object {
3642
Write-Host "File: $($_.Name)"
3743
Write-Host "Size: $([math]::Round($_.Length / 1MB, 2)) MB"
3844
Write-Host ""
3945
}
4046
Write-Host "=== Checking for MSVC Runtime Dependencies ==="
41-
Write-Host "Note: This executable requires Visual C++ Redistributable (vcruntime140.dll, msvcp140.dll)"
47+
Write-Host "Note: This executable requires Visual C++ Redistributable (vcruntime140.dll)"
4248
4349
- name: Upload artifact
4450
uses: actions/upload-artifact@v4
4551
with:
4652
name: ghostinjector-windows-x64-msvc
47-
path: build/Release/ghostinjector-*.exe
53+
path: build/Release/ghostinjector.exe
4854
if-no-files-found: error
49-
retention-days: 30
55+
retention-days: 90
56+
57+
- name: Get executable name
58+
id: get-exe-name
59+
shell: pwsh
60+
run: |
61+
$exePath = Get-ChildItem -Path build\Release\ghostinjector.exe | Select-Object -First 1
62+
echo "exe-name=$($exePath.Name)" >> $env:GITHUB_OUTPUT
63+
echo "exe-path=$($exePath.FullName)" >> $env:GITHUB_OUTPUT
64+
65+
- name: Create/Update Latest Release
66+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
67+
uses: softprops/action-gh-release@v2
68+
with:
69+
tag_name: latest
70+
name: Latest Build (Development)
71+
body: |
72+
## 🚀 Latest Development Build
73+
74+
**Commit:** ${{ github.sha }}
75+
**Date:** ${{ github.event.head_commit.timestamp }}
76+
**Message:** ${{ github.event.head_commit.message }}
77+
78+
### ⚠️ Requirements
79+
- Windows 10/11 (64-bit)
80+
- [Visual C++ Redistributable](https://aka.ms/vs/17/release/vc_redist.x64.exe)
81+
82+
### 📥 Download
83+
Download `${{ steps.get-exe-name.outputs.exe-name }}` below
84+
85+
### 📖 Usage
86+
```
87+
ghostinjector.exe <pid> <dll_path1> [dll_path2] ...
88+
```
89+
files: build/Release/ghostinjector.exe
90+
draft: false
91+
prerelease: true
92+
make_latest: true
93+
env:
94+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5095

51-
- name: Create Release (on tag)
52-
if: startsWith(github.ref, 'refs/tags/')
53-
uses: softprops/action-gh-release@v1
96+
- name: Create Release (on version tag)
97+
if: startsWith(github.ref, 'refs/tags/v')
98+
uses: softprops/action-gh-release@v2
5499
with:
55-
files: build/Release/ghostinjector-*.exe
100+
name: Release ${{ github.ref_name }}
101+
body: |
102+
## 📦 Release ${{ github.ref_name }}
103+
104+
### ⚠️ Requirements
105+
- Windows 10/11 (64-bit)
106+
- [Visual C++ Redistributable](https://aka.ms/vs/17/release/vc_redist.x64.exe)
107+
108+
### 📥 Download
109+
Download the executable below
110+
111+
### 📖 Usage
112+
```
113+
ghostinjector.exe <pid> <dll_path1> [dll_path2] ...
114+
```
115+
116+
### ✨ Features
117+
- Support for multiple DLL injection
118+
- Positional arguments support
119+
files: build/Release/ghostinjector.exe
56120
draft: false
57121
prerelease: false
58122
env:

CMakeLists.txt

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
cmake_minimum_required(VERSION 3.10)
2-
project(GhostInjector VERSION 1.0.2 LANGUAGES C CXX)
2+
project(GhostInjector VERSION 1.0.2 LANGUAGES C)
33

4-
set(CMAKE_CXX_STANDARD 11)
5-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6-
set(CMAKE_CXX_EXTENSIONS OFF)
4+
if(MSVC)
5+
string(REPLACE "/MT" "/MD" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
6+
endif()
77

8-
include(FetchContent)
8+
# Set C standard to C99 for the entire project
9+
set(CMAKE_C_STANDARD 99)
10+
set(CMAKE_C_STANDARD_REQUIRED ON)
11+
set(CMAKE_C_EXTENSIONS OFF)
912

10-
# Fetch cxxopts
11-
FetchContent_Declare(
12-
cxxopts
13-
GIT_REPOSITORY https://github.com/jarro2783/cxxopts.git
14-
GIT_TAG v3.2.1
15-
)
16-
FetchContent_MakeAvailable(cxxopts)
13+
if(WIN32)
14+
set(CMAKE_EXECUTABLE_SUFFIX ".exe")
15+
endif()
1716

1817
add_subdirectory(Neptune)
1918
add_subdirectory(NThread)
@@ -22,26 +21,21 @@ add_subdirectory(NThreadOSUtils)
2221
set(GHOSTINJECTOR_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
2322
set(GHOSTINJECTOR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
2423

25-
file(GLOB_RECURSE GHOSTINJECTOR_HEADERS CONFIGURE_DEPENDS ${GHOSTINJECTOR_INCLUDE_DIR}/*.h ${GHOSTINJECTOR_INCLUDE_DIR}/*.hpp)
26-
file(GLOB_RECURSE GHOSTINJECTOR_SOURCES CONFIGURE_DEPENDS ${GHOSTINJECTOR_SOURCE_DIR}/*.c ${GHOSTINJECTOR_SOURCE_DIR}/*.cpp)
24+
file(GLOB_RECURSE GHOSTINJECTOR_HEADERS CONFIGURE_DEPENDS ${GHOSTINJECTOR_INCLUDE_DIR}/*.h)
25+
file(GLOB_RECURSE GHOSTINJECTOR_SOURCES CONFIGURE_DEPENDS ${GHOSTINJECTOR_SOURCE_DIR}/*.c)
2726

2827
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)
2928
set(EXECUTABLE_NAME "${PROJECT_NAME_LOWER}-${PROJECT_VERSION}")
3029

3130
add_executable(${EXECUTABLE_NAME} ${GHOSTINJECTOR_SOURCES})
3231
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${GHOSTINJECTOR_INCLUDE_DIR})
33-
target_link_libraries(${EXECUTABLE_NAME} PRIVATE NThreadOSUtils cxxopts)
34-
35-
# Dynamic linking - will use MSVC runtime DLLs (msvcp140.dll, vcruntime140.dll)
36-
# Removed: -static -static-libgcc -static-libstdc++
32+
target_link_libraries(${EXECUTABLE_NAME} PRIVATE NThreadOSUtils)
3733

3834
target_compile_definitions(${EXECUTABLE_NAME} PRIVATE
39-
LOG_LEVEL_2
35+
LOG_LEVEL_1
4036
NEPTUNE_MODULERULES_HEADER="ntosutils_rules.h"
41-
LOG_FORCE_COLOR
4237
NEPTUNE_ENABLE_MEMMEM
4338
VERSION=${PROJECT_VERSION}
4439
LOG_FILE_PATH=L"ghostinjector.log"
4540
LOG_ON_STDOUT=1
46-
)
47-
41+
)

Neptune

src/main.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/**
2+
* MIT License
3+
*
4+
* Copyright (c) 2025 Serkan Aksoy
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
#include <stdio.h>
26+
#include <stdlib.h>
27+
#include <string.h>
28+
#include <windows.h>
29+
30+
#include "nerror.h"
31+
#include "ntosutils.h"
32+
#include "ntmem.h"
33+
#include "ntosutilswin.h"
34+
35+
void print_usage() {
36+
printf("GhostInjector - DLL Injection tool for Windows processes\n\n");
37+
printf("Examples:\n");
38+
printf(" ghostinjector.exe 1234 mydll.dll\n");
39+
printf(" ghostinjector.exe 5678 first.dll second.dll third.dll\n\n");
40+
printf("Usage:\n");
41+
printf(" ghostinjector.exe <process_id> <dll_path> [dll_path2 ...]\n");
42+
printf(" ghostinjector.exe -h | --help\n");
43+
}
44+
45+
int main(int argc, char *argv[])
46+
{
47+
if (HAS_ERR(neptune_init()))
48+
return EXIT_FAILURE;
49+
50+
if (argc < 3 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
51+
print_usage();
52+
neptune_destroy();
53+
return EXIT_SUCCESS;
54+
}
55+
56+
uint32_t id = atoi(argv[1]);
57+
58+
#ifdef LOG_LEVEL_1
59+
LOG_INFO("Neptune initialized!");
60+
LOG_INFO("ID: %u", id);
61+
LOG_INFO("Number of DLLs to inject: %d", argc - 2);
62+
#endif
63+
64+
if (id == 0) {
65+
#ifdef LOG_LEVEL_1
66+
LOG_ERROR("Invalid id: must be greater than 0");
67+
#endif
68+
neptune_destroy();
69+
return 0x11;
70+
}
71+
72+
HMODULE kernel32 = GetModuleHandleA("kernel32");
73+
if (kernel32 == NULL) {
74+
#ifdef LOG_LEVEL_1
75+
LOG_ERROR("GetModuleHandleA failed");
76+
#endif
77+
neptune_destroy();
78+
return 0x20;
79+
}
80+
81+
FARPROC load_library_func = GetProcAddress(kernel32, "LoadLibraryA");
82+
if (load_library_func == NULL) {
83+
#ifdef LOG_LEVEL_1
84+
LOG_ERROR("GetProcAddress failed");
85+
#endif
86+
neptune_destroy();
87+
return 0x21;
88+
}
89+
90+
#ifdef LOG_LEVEL_1
91+
LOG_INFO("LoadLibraryA=%p", (void *)load_library_func);
92+
#endif
93+
94+
if (HAS_ERR(nosu_attach(id))) {
95+
#ifdef LOG_LEVEL_1
96+
LOG_WARN("nosu_attach failed");
97+
#endif
98+
99+
if (HAS_ERR(nosu_find_thread_and_upgrade(id))) {
100+
#ifdef LOG_LEVEL_1
101+
LOG_ERROR("nosu_find_thread_and_upgrade failed");
102+
#endif
103+
neptune_destroy();
104+
return 0x06;
105+
}
106+
}
107+
108+
for (int i = 2; i < argc; i++) {
109+
const char *dll_path = argv[i];
110+
111+
#ifdef LOG_LEVEL_1
112+
LOG_INFO("Injecting DLL [%d/%d]: %s", i - 1, argc - 2, dll_path);
113+
#endif
114+
115+
size_t dll_path_len = strlen(dll_path);
116+
size_t dll_path_size = dll_path_len + 1;
117+
118+
ntmem_t *ntmem = ntm_create_with_alloc_ex(dll_path_size + 1);
119+
if (ntmem == NULL) {
120+
#ifdef LOG_LEVEL_1
121+
LOG_ERROR("ntm_create failed for %s", dll_path);
122+
#endif
123+
continue;
124+
}
125+
126+
void *local = NTM_LOCAL(ntmem);
127+
memcpy(local, dll_path, dll_path_size);
128+
129+
void *dll_path_addr = ntm_push(ntmem);
130+
if (dll_path_addr == NULL) {
131+
#ifdef LOG_LEVEL_1
132+
LOG_ERROR("ntm_push failed for %s", dll_path);
133+
#endif
134+
ntm_delete(ntmem);
135+
continue;
136+
}
137+
138+
#ifdef LOG_LEVEL_1
139+
LOG_INFO("DLL Path Address(%p)", dll_path_addr);
140+
#endif
141+
142+
void *load_library_ret = ntu_ucall((void *)load_library_func, dll_path_addr);
143+
144+
#ifdef LOG_LEVEL_1
145+
LOG_INFO("LoadLibrary returned: %p", load_library_ret);
146+
if (load_library_ret != NULL) {
147+
LOG_INFO("Successfully injected: %s", dll_path);
148+
} else {
149+
LOG_ERROR("Failed to inject: %s", dll_path);
150+
}
151+
#endif
152+
153+
ntm_delete(ntmem);
154+
}
155+
ntu_destroy();
156+
neptune_destroy();
157+
return EXIT_SUCCESS;
158+
}

0 commit comments

Comments
 (0)