-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
391 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
name: Builds | ||
|
||
on: [push, pull_request] | ||
|
||
permissions: | ||
actions: read | ||
contents: read | ||
security-events: write | ||
|
||
jobs: | ||
Windows: | ||
name: Windows latest | ||
runs-on: windows-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
platform: ['x86', 'x64'] | ||
configuration: ['Debug', 'Release'] | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
with: | ||
submodules: recursive | ||
|
||
- name: Initialize CodeQL | ||
uses: github/codeql-action/init@v1 | ||
with: | ||
languages: cpp | ||
|
||
- name: Setup vs prompt | ||
uses: ilammy/msvc-dev-cmd@v1 | ||
|
||
- name: Build | ||
run: msbuild /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }} src\inject.sln | ||
|
||
- name: Perform CodeQL Analysis | ||
uses: github/codeql-action/analyze@v1 | ||
|
||
- name: Upload artifacts | ||
uses: actions/upload-artifact@v2 | ||
with: | ||
name: bin-${{ matrix.platform }}.${{matrix.configuration }} | ||
path: | | ||
src/**/${{ matrix.configuration }}/inject.exe | ||
src/**/${{ matrix.configuration }}/inject.pdb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,13 @@ | ||
# inject | ||
Yet another Windows DLL injector | ||
![Builds](https://github.com/0vercl0k/inject/workflows/Builds/badge.svg) | ||
|
||
## Overview | ||
Yet another Windows DLL injector I wrote to support some work I was doing with [wtf](https://github.com/0vercl0k/wtf). | ||
|
||
<p align='center'> | ||
<img src='pics/inject.gif'> | ||
</p> | ||
|
||
## Authors | ||
|
||
* Axel '[0vercl0k](https://twitter.com/0vercl0k)' Souchet |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
BasedOnStyle: LLVM |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// Axel '0vercl0k' Souchet - March 14 2020 | ||
#include <windows.h> | ||
|
||
#include <cstdint> | ||
#include <cstdio> | ||
#include <filesystem> | ||
#include <memory> | ||
#include <tlhelp32.h> | ||
#include <vector> | ||
|
||
bool InjectDll(const uint32_t ProcessId, const std::filesystem::path &Path) { | ||
const uint32_t ProcessRights = | ||
PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | | ||
PROCESS_VM_WRITE | PROCESS_VM_READ; | ||
const HANDLE Process = OpenProcess(ProcessRights, false, ProcessId); | ||
|
||
if (Process == nullptr) { | ||
return EXIT_FAILURE; | ||
} | ||
|
||
const PVOID RemoteDllPath = VirtualAllocEx( | ||
Process, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); | ||
|
||
if (RemoteDllPath == nullptr) { | ||
printf("VirtualAllocEx failed.\n"); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
const std::string DllPath = Path.string(); | ||
const size_t DllPathLen = DllPath.size() + 1; | ||
SIZE_T BytesWritten; | ||
if (!WriteProcessMemory(Process, RemoteDllPath, DllPath.c_str(), DllPathLen, | ||
&BytesWritten)) { | ||
printf("WriteProcessMemory failed.\n"); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
const HMODULE Kernelbase = GetModuleHandleA("kernelbase"); | ||
if (Kernelbase == nullptr) { | ||
printf("GetModuleHandleA failed.\n"); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
const PVOID LoadLibraryA = PVOID(GetProcAddress(Kernelbase, "LoadLibraryA")); | ||
if (LoadLibraryA == nullptr) { | ||
printf("GetProcAddress failed.\n"); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
DWORD Tid; | ||
const HANDLE Thread = CreateRemoteThread(Process, nullptr, 0, | ||
LPTHREAD_START_ROUTINE(LoadLibraryA), | ||
RemoteDllPath, 0, &Tid); | ||
|
||
if (Thread == NULL) { | ||
printf("CreateRemoteThread failed.\n"); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
WaitForSingleObject(Thread, INFINITE); | ||
|
||
DWORD ExitCode = 0; | ||
GetExitCodeThread(Thread, &ExitCode); | ||
|
||
if (ExitCode == 0) { | ||
printf("/!\\ The thread failed to load the dll.\n"); | ||
} | ||
|
||
CloseHandle(Thread); | ||
VirtualFreeEx(Process, RemoteDllPath, 0, MEM_RELEASE); | ||
CloseHandle(Process); | ||
return ExitCode != 0; | ||
} | ||
|
||
bool Pid2Name(const char *ProcessName, uint32_t &Pid) { | ||
PROCESSENTRY32 Pe32; | ||
HANDLE Snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | ||
if (Snap == INVALID_HANDLE_VALUE) { | ||
return false; | ||
} | ||
|
||
Pe32.dwSize = sizeof(PROCESSENTRY32); | ||
if (!Process32First(Snap, &Pe32)) { | ||
CloseHandle(Snap); | ||
return false; | ||
} | ||
|
||
bool FoundPid = false; | ||
do { | ||
const bool Match = _stricmp(Pe32.szExeFile, ProcessName) == 0; | ||
if (Match) { | ||
if (FoundPid) { | ||
printf("There are several instances of %s, pid %d will be used.\n", | ||
Pe32.szExeFile, Pid); | ||
} else { | ||
FoundPid = true; | ||
Pid = Pe32.th32ProcessID; | ||
} | ||
} | ||
} while (Process32Next(Snap, &Pe32)); | ||
|
||
CloseHandle(Snap); | ||
return FoundPid; | ||
} | ||
|
||
int main(int Argc, const char *Argv[]) { | ||
if (Argc != 3) { | ||
printf("./injectdll <pid | process name> <dll path | dll dir path>\n"); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
uint32_t ProcessId = strtol(Argv[1], nullptr, 0); | ||
if (ProcessId == 0) { | ||
const bool Success = Pid2Name(Argv[1], ProcessId); | ||
if (!Success) { | ||
printf("Pid2Name failed, exiting.\n"); | ||
return EXIT_FAILURE; | ||
} | ||
} | ||
|
||
std::vector<std::filesystem::path> Dlls; | ||
if (std::filesystem::is_directory(Argv[2])) { | ||
const std::filesystem::directory_iterator DirIt(Argv[2]); | ||
for (const auto &DirEntry : DirIt) { | ||
if (DirEntry.path().extension().string() == ".dll") { | ||
Dlls.emplace_back(DirEntry); | ||
} | ||
} | ||
} else { | ||
Dlls.emplace_back(Argv[2]); | ||
} | ||
|
||
for (const std::filesystem::path &Dll : Dlls) { | ||
const std::filesystem::path DllAbsolute = std::filesystem::absolute(Dll); | ||
const bool Succeed = InjectDll(ProcessId, DllAbsolute); | ||
if (!Succeed) { | ||
printf("Error while injecting %ls in %d\n", DllAbsolute.c_str(), | ||
ProcessId); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
printf("Successfully injected %ls in %d\n", DllAbsolute.c_str(), ProcessId); | ||
} | ||
|
||
printf("Done!\n"); | ||
return EXIT_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.31424.327 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inject", "inject.vcxproj", "{CFF27EB6-C404-4E7E-9EE7-72FEDE08E737}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|x64 = Debug|x64 | ||
Debug|x86 = Debug|x86 | ||
Release|x64 = Release|x64 | ||
Release|x86 = Release|x86 | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{CFF27EB6-C404-4E7E-9EE7-72FEDE08E737}.Debug|x64.ActiveCfg = Debug|x64 | ||
{CFF27EB6-C404-4E7E-9EE7-72FEDE08E737}.Debug|x64.Build.0 = Debug|x64 | ||
{CFF27EB6-C404-4E7E-9EE7-72FEDE08E737}.Debug|x86.ActiveCfg = Debug|Win32 | ||
{CFF27EB6-C404-4E7E-9EE7-72FEDE08E737}.Debug|x86.Build.0 = Debug|Win32 | ||
{CFF27EB6-C404-4E7E-9EE7-72FEDE08E737}.Release|x64.ActiveCfg = Release|x64 | ||
{CFF27EB6-C404-4E7E-9EE7-72FEDE08E737}.Release|x64.Build.0 = Release|x64 | ||
{CFF27EB6-C404-4E7E-9EE7-72FEDE08E737}.Release|x86.ActiveCfg = Release|Win32 | ||
{CFF27EB6-C404-4E7E-9EE7-72FEDE08E737}.Release|x86.Build.0 = Release|Win32 | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {8B53551B-C77B-4FDD-8910-6FA2351A8EEE} | ||
EndGlobalSection | ||
EndGlobal |
Oops, something went wrong.