#pragma once #include "Imports.h" #include "NativeStructs.h" // Module type typedef enum _ModType { mt_mod32, // 64 bit module mt_mod64, // 32 bit module mt_default, // type is deduced from target process mt_unknown // Failed to detect type } ModType; // Image name resolve flags typedef enum _ResolveFlags { KApiShemaOnly = 1, KSkipSxS = 2, KFullPath = 4, } ResolveFlags; /// /// Module info /// typedef struct _MODULE_DATA { LIST_ENTRY link; // List link PUCHAR baseAddress; // Base image address in target process PUCHAR localBase; // Base image address in system space UNICODE_STRING name; // File name UNICODE_STRING fullPath; // Full file path SIZE_T size; // Size of image ModType type; // Module type enum KMmapFlags flags; // Flags BOOLEAN manual; // Image is manually mapped BOOLEAN initialized; // DllMain was already called } MODULE_DATA, *PMODULE_DATA; /// /// User-mode memory region /// typedef struct _USER_CONTEXT { UCHAR code[0x1000]; // Code buffer union { UNICODE_STRING ustr; UNICODE_STRING32 ustr32; }; wchar_t buffer[0x400]; // Buffer for unicode string // Activation context data union { ACTCTXW actx; ACTCTXW32 actx32; }; HANDLE hCTX; ULONG hCookie; PVOID ptr; // Tmp data union { NTSTATUS status; // Last execution status PVOID retVal; // Function return value ULONG retVal32; // Function return value }; //UCHAR tlsBuf[0x100]; } USER_CONTEXT, *PUSER_CONTEXT; /// /// Manual map context /// typedef struct _MMAP_CONTEXT { PEPROCESS pProcess; // Target process PVOID pWorkerBuf; // Worker thread code buffer HANDLE hWorker; // Worker thread handle PETHREAD pWorker; // Worker thread object LIST_ENTRY modules; // Manual module list PUSER_CONTEXT userMem; // Tmp buffer in user space HANDLE hSync; // APC sync handle PKEVENT pSync; // APC sync object PVOID pSetEvent; // ZwSetEvent address PVOID pLoadImage; // LdrLoadDll address BOOLEAN tlsInitialized; // Static TLS was initialized BOOLEAN noThreads; // No threads should be created } MMAP_CONTEXT, *PMMAP_CONTEXT; /// /// Initialize loader stuff /// /// Any valid system module /// Status code NTSTATUS BBInitLdrData( IN PKLDR_DATA_TABLE_ENTRY pThisModule ); /// /// Get address of a system module /// Either 'pName' or 'pAddress' is required to perform search /// /// Base name of the image (e.g. hal.dll) /// Address inside module /// Found loader entry. NULL if nothing found PKLDR_DATA_TABLE_ENTRY BBGetSystemModule( IN PUNICODE_STRING pName, IN PVOID pAddress ); /// /// Get module base address by name /// /// Target process /// Nodule name to search for /// If TRUE - search in 32-bit PEB /// Found address, NULL if not found PVOID BBGetUserModule( IN PEPROCESS pProcess, IN PUNICODE_STRING ModuleName, IN BOOLEAN isWow64 ); /// /// Unlink user-mode module from Loader lists /// /// Target process /// Module base /// If TRUE - unlink from PEB32 Loader, otherwise use PEB64 /// Status code NTSTATUS BBUnlinkFromLoader( IN PEPROCESS pProcess, IN PVOID pBase, IN BOOLEAN isWow64 ); /// /// Get exported function address /// /// Module base /// Function name or ordinal /// Target process for user module /// Found address, NULL if not found PVOID BBGetModuleExport( IN PVOID pBase, IN PCCHAR name_ord, IN PEPROCESS pProcess, IN PUNICODE_STRING modName ); /// /// Map new user module /// /// Target process /// Image path /// Image buffer /// Image buffer size /// Buffer has image memory layout /// Mapping flags /// Init routine RVA /// Init argument /// Mapped image data /// Status code NTSTATUS BBMapUserImage( IN PEPROCESS pProcess, IN PUNICODE_STRING path, IN PVOID buffer, IN ULONG_PTR size, IN BOOLEAN asImage, IN enum KMmapFlags flags, IN ULONG initRVA, IN PWCH initArg, OUT PMODULE_DATA pImage ); /// /// Resolve import table and load missing dependencies /// /// Target image base /// If TRUE - image is driver /// Target process /// Iamge is 32bit image /// Manual map context /// Status code NTSTATUS BBResolveImageRefs( IN PVOID pImageBase, IN BOOLEAN systemImage, IN PEPROCESS pProcess, IN BOOLEAN wow64Image, IN PMMAP_CONTEXT pContext, IN enum KMmapFlags flags ); /// /// Resolve image name to fully qualified path /// /// Loader context /// Target process. Must be running in the context of this process /// Flags /// Image name to resolve /// Base image name for API SET translation /// Resolved image path /// Status code NTSTATUS BBResolveImagePath( IN PMMAP_CONTEXT pContext, IN PEPROCESS pProcess, IN ResolveFlags flags, IN PUNICODE_STRING path, IN PUNICODE_STRING baseImage, OUT PUNICODE_STRING resolved ); /// /// Find first thread of the target process /// /// Target process. /// Found thread. Thread object reference count is increased by 1 /// Status code NTSTATUS BBLookupProcessThread( IN PEPROCESS pProcess, OUT PETHREAD* ppThread ); /// /// Create new thread in the target process /// /// Thread start address /// Thread argument /// Thread creation flags /// If set to TRUE - wait for thread completion /// Thread exit status /// Status code NTSTATUS BBExecuteInNewThread( IN PVOID pBaseAddress, IN PVOID pParam, IN ULONG flags, IN BOOLEAN wait, OUT PNTSTATUS pExitStatus ); /// /// Queue user-mode APC to the target thread /// /// Target thread /// APC function /// Argument 1 /// Argument 2 /// Argument 3 /// If TRUE - force delivery by issuing special kernel APC /// Status code NTSTATUS BBQueueUserApc( IN PETHREAD pThread, IN PVOID pUserFunc, IN PVOID Arg1, IN PVOID Arg2, IN PVOID Arg3, BOOLEAN bForce ); /// /// Manually map driver into system space /// /// Fully qualified native path to the driver /// Status code NTSTATUS BBMMapDriver( IN PUNICODE_STRING pPath ); PIMAGE_BASE_RELOCATION LdrProcessRelocationBlockLongLong( IN ULONG_PTR VA, IN ULONG SizeOfBlock, IN PUSHORT NextOffset, IN LONGLONG Diff ); NTSTATUS LdrRelocateImage ( IN PVOID NewBase, IN NTSTATUS Success, IN NTSTATUS Conflict, IN NTSTATUS Invalid ); NTSTATUS LdrRelocateImageWithBias( IN PVOID NewBase, IN LONGLONG AdditionalBias, IN NTSTATUS Success, IN NTSTATUS Conflict, IN NTSTATUS Invalid ); PIMAGE_BASE_RELOCATION LdrProcessRelocationBlock( IN ULONG_PTR VA, IN ULONG SizeOfBlock, IN PUSHORT NextOffset, IN LONG_PTR Diff ); PIMAGE_BASE_RELOCATION LdrProcessRelocationBlockLongLong( IN ULONG_PTR VA, IN ULONG SizeOfBlock, IN PUSHORT NextOffset, IN LONGLONG Diff );