#pragma once #include "../Include/Winheaders.h" #include "../Include/Types.h" #include "../Include/Macro.h" #include "../Include/HandleGuard.h" #include "../../BlackBoneDrv/BlackBoneDef.h" #include #include #include ENUM_OPS( KMmapFlags ); namespace blackbone { // [Original ptr, size] <--> [Mapped ptr] using mapMemoryMap = std::map, ptr_t>; struct MapMemoryResult { ptr_t hostSharedPage; // Shared page address in current process ptr_t targetSharedPage; // Shared page address in target process HANDLE targetPipe; // Hook pipe handle in the target process mapMemoryMap regions; // Mapped regions info }; struct MapMemoryRegionResult { ptr_t originalPtr; // Address of region in the target process ptr_t newPtr; // Address of mapped region in the current process ptr_t removedPtr; // Address of region unmapped because of address conflict uint32_t size; // Size of mapped region uint32_t removedSize; // Size of unmapped region }; class DriverControl { public: BLACKBONE_API DriverControl(); BLACKBONE_API ~DriverControl(); BLACKBONE_API static DriverControl& Instance(); /// /// Try to load driver if it isn't loaded /// /// Path to the driver file /// Status code BLACKBONE_API NTSTATUS EnsureLoaded( const std::wstring& path = L"" ); /// /// Reload driver /// /// Path to the driver file /// Status code BLACKBONE_API NTSTATUS Reload( std::wstring path = L"" ); /// /// Unload driver /// /// Status code BLACKBONE_API NTSTATUS Unload(); /// /// Disable DEP for process /// Has no effect on native x64 processes /// /// Target PID /// Status code BLACKBONE_API NTSTATUS DisableDEP( DWORD pid ); /// /// Change process protection flag /// /// Target PID /// Process protection policy /// Prohibit dynamic code /// Prohibit loading non-microsoft dlls /// Status code BLACKBONE_API NTSTATUS ProtectProcess( DWORD pid, PolicyOpt protection, PolicyOpt dynamicCode = Policy_Keep, PolicyOpt binarySignature = Policy_Keep ); /// /// Change handle access rights /// /// Target PID. /// Handle /// New access /// Status code BLACKBONE_API NTSTATUS PromoteHandle( DWORD pid, HANDLE handle, DWORD access ); /// /// Allocate virtual memory /// /// Tarhet PID /// Desired base. If 0 address is chosed by the system /// Region size /// Allocation type - MEM_RESERVE/MEM_COMMIT /// Memory protection /// Status code BLACKBONE_API NTSTATUS AllocateMem( DWORD pid, ptr_t& base, ptr_t& size, DWORD type, DWORD protection, bool physical = false ); /// /// Free virtual memory /// /// Tarhet PID /// Desired base. If 0 address is chosed by the system /// Region size /// Free type - MEM_RELEASE/MEM_DECOMMIT /// Status code BLACKBONE_API NTSTATUS FreeMem( DWORD pid, ptr_t base, ptr_t size, DWORD type ); /// /// Read process memory /// /// Target PID /// Target base /// Data size /// Buffer address /// Status code BLACKBONE_API NTSTATUS ReadMem( DWORD pid, ptr_t base, ptr_t size, PVOID buffer ); /// /// Write process memory /// /// Target PID /// Target base /// Data size /// Buffer address /// Status code BLACKBONE_API NTSTATUS WriteMem( DWORD pid, ptr_t base, ptr_t size, PVOID buffer ); /// /// Change memory protection /// /// Target PID. /// Regiod base address /// Region size /// New protection /// Status code BLACKBONE_API NTSTATUS ProtectMem( DWORD pid, ptr_t base, ptr_t size, DWORD protection ); /// /// Maps target process memory into current process /// /// Target PID /// Pipe name to use for hook data transfer /// The map sections. /// Results /// Status code BLACKBONE_API NTSTATUS MapMemory( DWORD pid, const std::wstring& pipeName, bool mapSections, MapMemoryResult& result ); /// /// Maps single memory region into current process /// /// Target PID /// Region base address /// Region size /// Mapped region info /// Status code BLACKBONE_API NTSTATUS MapMemoryRegion( DWORD pid, ptr_t base, uint32_t size, MapMemoryRegionResult& result ); /// /// Unmap memory of the target process from current /// /// Target PID /// Status code BLACKBONE_API NTSTATUS UnmapMemory( DWORD pid ); /// /// Unmap single memory region /// If unmapped region size is smaller than the size specified during map, function will return info about /// 2 regions that emerged after unmap /// /// Target PID /// Region base /// Region size /// Unampped region info /// Status code BLACKBONE_API NTSTATUS UnmapMemoryRegion( DWORD pid, ptr_t base, uint32_t size ); /// /// Inject DLL into arbitrary process /// /// Target PID. /// Full qualified dll path. /// Injection type /// Init routine RVA /// Init routine argument /// Unlink module after injection /// Erase PE headers after injection /// Wait for injection /// Status code BLACKBONE_API NTSTATUS InjectDll( DWORD pid, const std::wstring& path, InjectType itype, uint32_t initRVA = 0, const std::wstring& initArg = L"", bool unlink = false, bool erasePE = false, bool wait = true ); /// /// Manually map PE image /// /// Target PID /// Full qualified image path /// Mapping flags /// Init routine RVA /// Init routine argument /// Status code BLACKBONE_API NTSTATUS MmapDll( DWORD pid, const std::wstring& path, KMmapFlags flags, uint32_t initRVA = 0, const std::wstring& initArg = L"" ); /// /// Manually map PE image /// /// Target PID /// Memory location of the image to map /// Image size /// Memory chunk has image layout /// Mapping flags /// Init routine RVA /// Init routine argument /// Status code BLACKBONE_API NTSTATUS MmapDll( DWORD pid, void* address, uint32_t size, bool asImage, KMmapFlags flags, uint32_t initRVA = 0, const std::wstring& initArg = L"" ); /// /// Manually map another system driver into system space /// /// Fully quialified path to the drver /// Status code BLACKBONE_API NTSTATUS MMapDriver( const std::wstring& path ); /// /// Make VAD region appear as PAGE_NO_ACESS to NtQueryVirtualMemory /// /// Target process ID /// Region base /// Region size /// Status code BLACKBONE_API NTSTATUS ConcealVAD( DWORD pid, ptr_t base, uint32_t size ); /// /// Unlink process handle table from HandleListHead /// /// Target process ID /// Status code BLACKBONE_API NTSTATUS UnlinkHandleTable( DWORD pid ); /// /// Enumerate committed, accessible, non-guarded memory regions /// /// Target process ID /// Found regions /// Status code BLACKBONE_API NTSTATUS EnumMemoryRegions( DWORD pid, std::vector& regions ); /// /// Check if driver is loaded /// /// BLACKBONE_API inline bool loaded() const { return _hDriver != INVALID_HANDLE_VALUE; } BLACKBONE_API inline NTSTATUS status() const { return _loadStatus; } private: DriverControl( const DriverControl& ) = delete; DriverControl& operator = (const DriverControl&) = delete; /// /// Load arbitrary driver /// /// Driver service name /// Driver file path /// Status NTSTATUS LoadDriver( const std::wstring& svcName, const std::wstring& path ); /// /// Unload arbitrary driver /// /// Driver service name /// Status NTSTATUS UnloadDriver( const std::wstring& svcName ); /// /// Fill minimum driver registry entry /// /// Driver service name /// Driver path /// Status code LSTATUS PrepareDriverRegEntry( const std::wstring& svcName, const std::wstring& path ); private: FileHandle _hDriver; NTSTATUS _loadStatus = STATUS_NOT_FOUND; }; // Syntax sugar inline DriverControl& Driver() { return DriverControl::Instance(); } }