#pragma once #include "../Include/Winheaders.h" #include "RPC/RemoteMemory.h" #include "MemBlock.h" #include #include namespace blackbone { class ProcessMemory : public RemoteMemory { public: BLACKBONE_API ProcessMemory( class Process* process ); BLACKBONE_API ~ProcessMemory(); /// /// Allocate new memory block /// /// Block size /// Memory protection /// Desired base address of new block /// false if caller will be responsible for block deallocation /// Memory block. If failed - returned block will be invalid BLACKBONE_API call_result_t Allocate( size_t size, DWORD protection = PAGE_EXECUTE_READWRITE, ptr_t desired = 0, bool own = true ); /// /// Free memory /// /// Memory address to release. /// Region size /// Release/decommit /// Status BLACKBONE_API NTSTATUS Free( ptr_t pAddr, size_t size = 0, DWORD freeType = MEM_RELEASE ); /// /// Get memory region info /// /// Memory address /// Retrieved info /// Status BLACKBONE_API NTSTATUS Query( ptr_t pAddr, PMEMORY_BASIC_INFORMATION64 pInfo ); /// /// Change memory protection /// /// Memory address /// Region size /// New memory protection flags /// Old protection flags /// Status BLACKBONE_API NTSTATUS Protect( ptr_t pAddr, size_t size, DWORD flProtect, DWORD *pOld = NULL ); /// /// Read data /// /// Memory address to read from /// Size of data to read /// Output buffer /// /// If true, function will try to read all committed pages in range ignoring uncommitted ones. /// Otherwise function will fail if there is at least one non-committed page in region. /// /// Status BLACKBONE_API NTSTATUS Read( ptr_t dwAddress, size_t dwSize, PVOID pResult, bool handleHoles = false ); /// /// Read data /// /// Base address + list of offsets /// Size of data to read /// Output buffer /// /// If true, function will try to read all committed pages in range ignoring uncommitted ones. /// Otherwise function will fail if there is at least one non-committed page in region. /// /// Status BLACKBONE_API NTSTATUS Read( const std::vector& adrList, size_t dwSize, PVOID pResult, bool handleHoles = false ); /// /// Write data /// /// Memory address to write to /// Size of data to write /// Buffer to write /// Status BLACKBONE_API NTSTATUS Write( ptr_t pAddress, size_t dwSize, const void* pData ); /// /// Write data /// /// Base address + list of offsets /// Size of data to write /// Buffer to write /// Status BLACKBONE_API NTSTATUS Write( const std::vector& adrList, size_t dwSize, const void* pData ); /// /// Read data /// /// Address to read from /// Read data template inline call_result_t Read( ptr_t dwAddress ) { auto res = reinterpret_cast(_malloca( sizeof( T ) )); auto status = Read( dwAddress, sizeof( T ), res ); return call_result_t( *res, status ); }; /// /// Read data /// /// Base address + list of offsets /// Read data template inline call_result_t Read( std::vector&& adrList ) { auto res = reinterpret_cast(_malloca( sizeof( T ) )); auto status = Read( std::forward>( adrList ), sizeof( T ), res ); return call_result_t( *res, status ); } /// /// Read data /// /// Address to read from /// Read data /// Status code template inline NTSTATUS Read( ptr_t dwAddress, T& result ) { return Read( dwAddress, sizeof( result ), &result ); }; /// /// Read data /// /// Base address + list of offsets /// Read data /// Status code template inline NTSTATUS Read( std::vector&& adrList, T& result ) { return Read( std::forward>( adrList ), sizeof( result ), &result ); }; /// /// Write data /// /// Size of data to write /// Data to write /// Status template inline NTSTATUS Write( ptr_t dwAddress, const T& data ) { return Write( dwAddress, sizeof( T ), &data ); } /// /// Write data /// /// Base address + list of offset /// Data to write /// Status template inline NTSTATUS Write( std::vector&& adrList, const T& data ) { return Write( std::forward>( adrList ), sizeof( T ), &data ); } /// /// Enumerate valid memory regions /// /// If true - non-allocated regions will be included in list /// Found regions BLACKBONE_API std::vector EnumRegions( bool includeFree = false ); BLACKBONE_API inline class ProcessCore& core() { return _core; } BLACKBONE_API inline class Process* process() { return _process; } private: ProcessMemory( const ProcessMemory& ) = delete; ProcessMemory& operator =( const ProcessMemory& ) = delete; private: class Process* _process; // Owning process object class ProcessCore& _core; // Core routines }; }