#pragma once #include "ProcessCore.h" #include "ProcessMemory.h" #include "ProcessModules.h" #include "Threads/Threads.h" #include "RPC/RemoteExec.h" #include "RPC/RemoteHook.h" #include "RPC/RemoteLocalHook.h" #include "../ManualMap/Native/NtLoader.h" #include "../ManualMap/MMap.h" #include "../Include/NativeStructures.h" #include "../Include/CallResult.h" #include "../Misc/InitOnce.h" #include #include namespace blackbone { /// /// Process thread information /// struct ThreadInfo { uint32_t tid = 0; uintptr_t startAddress = 0; bool mainThread = false; }; /// /// Process information /// struct ProcessInfo { uint32_t pid = 0; std::wstring imageName; std::vector threads; bool operator < (const ProcessInfo& other) { return this->pid < other.pid; } }; /// /// Section object information /// struct SectionInfo { ptr_t size = 0; uint32_t attrib = 0; }; /// /// Process handle information /// struct HandleInfo { HANDLE handle = nullptr; uint32_t access = 0; uint32_t flags = 0; ptr_t pObject = 0; std::wstring typeName; std::wstring name; // Object-specific info std::shared_ptr section; }; #define DEFAULT_ACCESS_P PROCESS_QUERY_INFORMATION | \ PROCESS_VM_READ | \ PROCESS_VM_WRITE | \ PROCESS_VM_OPERATION | \ PROCESS_CREATE_THREAD | \ PROCESS_SET_QUOTA | \ PROCESS_TERMINATE | \ PROCESS_SUSPEND_RESUME | \ PROCESS_DUP_HANDLE class Process { public: BLACKBONE_API Process(); BLACKBONE_API ~Process(void); /// /// Attach to existing process /// /// Process ID /// Access mask /// Status code BLACKBONE_API NTSTATUS Attach( DWORD pid, DWORD access = DEFAULT_ACCESS_P ); /// /// Attach to existing process /// /// Process name /// Access mask /// Status code BLACKBONE_API NTSTATUS Attach( const wchar_t* name, DWORD access = DEFAULT_ACCESS_P ); /// /// Attach to existing process /// /// Process handle /// Status code BLACKBONE_API NTSTATUS Attach( HANDLE hProc ); /// /// Create new process and attach to it /// /// Executable path /// Leave process in suspended state. To resume process one should resume its main thread /// If 'suspended' is true, this flag will enforce process initialization via second thread /// Process command line /// Startup directory /// Additional startup params /// Status code BLACKBONE_API NTSTATUS CreateAndAttach( const std::wstring& path, bool suspended = false, bool forceInit = true, const std::wstring& cmdLine = L"", const wchar_t* currentDir = nullptr, STARTUPINFOW* pStartup = nullptr ); /// /// Detach form current process, if any /// /// Status code BLACKBONE_API NTSTATUS Detach(); /// /// Ensure LdrInitializeProcess gets called /// /// Status code BLACKBONE_API NTSTATUS EnsureInit(); /// /// Suspend process /// /// Status code BLACKBONE_API NTSTATUS Suspend(); /// /// Resume process /// /// Status code BLACKBONE_API NTSTATUS Resume(); /// /// Get process ID /// /// Process ID BLACKBONE_API inline DWORD pid() const { return _core.pid(); } /// /// Checks if process still exists /// /// true if process is valid and exists BLACKBONE_API bool valid(); /// /// Terminate process /// /// Exit code /// Stratus code BLACKBONE_API NTSTATUS Terminate( uint32_t code = 0 ); /// /// Enumerate all open handles /// /// Found handles or status code BLACKBONE_API call_result_t> EnumHandles(); /// /// Search for process by executable name /// /// Process name. If empty - function will retrieve all existing processes /// Found processses BLACKBONE_API static std::vector EnumByName( const std::wstring& name ); /// /// Search for process by executable name or by process ID /// /// Target process ID. rocess name. If empty - function will retrieve all existing processes /// Process executable name. If empty - function will retrieve all existing processes /// Found processses /// If set to true, function will retrieve info ablout process threads /// Status code BLACKBONE_API static call_result_t> EnumByNameOrPID( uint32_t pid, const std::wstring& name, bool includeThreads = false ); // // Subroutines // BLACKBONE_API ProcessCore& core() { return _core; } // Core routines and native BLACKBONE_API ProcessMemory& memory() { return _memory; } // Memory manipulations BLACKBONE_API ProcessModules& modules() { return _modules; } // Module management BLACKBONE_API ProcessThreads& threads() { return _threads; } // Threads BLACKBONE_API RemoteHook& hooks() { return _hooks; } // Hooking code remotely BLACKBONE_API RemoteLocalHook& localHooks() { return _localHooks; } // Hooking code locally BLACKBONE_API RemoteExec& remote() { return _remote; } // Remote code execution BLACKBONE_API MMap& mmap() { return _mmap; } // Manual module mapping BLACKBONE_API NtLdr& nativeLdr() { return _nativeLdr; } // Native loader routines // Sugar BLACKBONE_API const Wow64Barrier& barrier() const { return _core._native->GetWow64Barrier(); } private: Process(const Process&) = delete; Process& operator =(const Process&) = delete; private: ProcessCore _core; // Core routines and native subsystem ProcessModules _modules; // Module management ProcessMemory _memory; // Memory manipulations ProcessThreads _threads; // Threads RemoteHook _hooks; // Hooking code remotely RemoteLocalHook _localHooks; // In-process remote hooks RemoteExec _remote; // Remote code execution MMap _mmap; // Manual module mapping NtLdr _nativeLdr; // Native loader routines }; }