#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
);