#pragma once #include "../Config.h" #include "../Include/Winheaders.h" #include "../Include/CallResult.h" #include "../Include/Types.h" #include "../PE/PEImage.h" #include "../Misc/Utils.h" #include "Threads/Thread.h" #include #include #include #include namespace std { template <> struct hash < struct pair > { size_t operator()( const pair& value ) const { hash sh; return sh( value.first ) ^ value.second; } }; } namespace blackbone { struct exportData { ptr_t procAddress = 0; // Function address std::wstring forwardModule; // Name of forward module std::string forwardName; // Forwarded function name WORD forwardOrdinal = 0; // Forwarded function ordinal bool isForwarded = false; // Function is forwarded to another module bool forwardByOrd = false; // Forward is done by ordinal }; class ProcessModules { public: using mapModules = std::unordered_map, ModuleDataPtr> ; public: BLACKBONE_API ProcessModules( class Process& proc ); BLACKBONE_API ~ProcessModules(); /// /// Get module by name /// /// Module name /// Module type. 32 bit or 64 bit /// Search type. /// Module data. nullptr if not found BLACKBONE_API ModuleDataPtr GetModule( const std::wstring& name, eModSeachType search = LdrList, eModType type = mt_default ); /// /// Get module by name /// /// Module name. /// Search type. /// Module type. 32 bit or 64 bit /// Import module name. Used only to resolve ApiSchema during manual map /// Module data. nullptr if not found BLACKBONE_API ModuleDataPtr GetModule( std::wstring& name, eModSeachType search = LdrList, eModType type = mt_default, const wchar_t* baseModule = L"" ); /// /// Get module by base address /// /// Module base address /// If true modBase must exactly match module base address /// Search type. /// Module type. 32 bit or 64 bit /// Module data. nullptr if not found BLACKBONE_API ModuleDataPtr GetModule( module_t modBase, bool strict = true, eModSeachType search = LdrList, eModType type = mt_default ); /// /// Get process main module /// /// Module data. nullptr if not found BLACKBONE_API ModuleDataPtr GetMainModule(); /// /// Enumerate all process modules /// /// Search method /// Module list BLACKBONE_API const mapModules& GetAllModules( eModSeachType search = LdrList ); /// /// Get list of manually mapped modules /// /// List of modules BLACKBONE_API mapModules GetManualModules(); /// /// Get export address. Forwarded exports will be automatically resolved if forward module is present /// /// Module to search in /// Function name or ordinal /// Import module name. Only used to resolve ApiSchema during manual map. /// Export info. If failed procAddress field is 0 BLACKBONE_API call_result_t GetExport( const ModuleDataPtr& hMod, const char* name_ord, const wchar_t* baseModule = L"" ); /// /// Get export address. Forwarded exports will be automatically resolved if forward module is present /// /// Module to search in /// Function name or ordinal /// Import module name. Only used to resolve ApiSchema during manual map. /// Export info. If failed procAddress field is 0 BLACKBONE_API call_result_t GetExport( const ModuleData& hMod, const char* name_ord, const wchar_t* baseModule = L"" ); /// /// Get export address. Forwarded exports will be automatically resolved if forward module is present /// /// Module name to search in /// Function name or ordinal /// Export info. If failed procAddress field is 0 BLACKBONE_API call_result_t GetExport( const std::wstring& modName, const char* name_ord ); /// /// Get export from ntdll /// /// Function name or ordinal /// Module type. 32 bit or 64 bit /// Search type. /// Export info. If failed procAddress field is 0 BLACKBONE_API call_result_t GetNtdllExport( const char* name_ord, eModType type = mt_default, eModSeachType search = LdrList ); /// /// Inject image into target process /// /// Full-qualified image path /// Module info. nullptr if failed BLACKBONE_API call_result_t Inject( const std::wstring& path, ThreadPtr pThread = nullptr ); #ifdef COMPILER_MSVC /// /// Inject pure IL image. /// /// NET runtime version to use /// Path to image /// Method to call /// Arguments passed into method /// Return code /// true on success BLACKBONE_API bool InjectPureIL( const std::wstring& netVersion, const std::wstring& netAssemblyPath, const std::wstring& netAssemblyMethod, const std::wstring& netAssemblyArgs, DWORD& returnCode ); #endif /// /// Unload specific module from target process. Can't be used to unload manually mapped modules /// /// Module to unload /// true on success BLACKBONE_API NTSTATUS Unload( const ModuleDataPtr& hMod ); /// /// Unlink module from most loader structures /// /// Module to unlink /// true on success BLACKBONE_API bool Unlink( const ModuleDataPtr& mod ); BLACKBONE_API bool Unlink( const ModuleData& mod ); /// /// Store manually mapped module in module list /// /// Module data /// Module info BLACKBONE_API ModuleDataPtr AddManualModule( const ModuleData& mod ); /// /// Canonicalize paths and set module type to manual if requested /// /// Module data /// Value to set ModuleData::manual to /// Module data BLACKBONE_API ModuleData Canonicalize( const ModuleData& mod, bool manual ); /// /// Remove module from module list /// /// Module file name /// Module type. 32 bit or 64 bit BLACKBONE_API void RemoveManualModule( const std::wstring& filename, eModType mt ); /// /// Ensure module is a valid PE image /// /// Module base address /// true on success BLACKBONE_API bool ValidateModule( module_t base ); /// /// Reset local data /// BLACKBONE_API void reset(); private: ProcessModules( const ProcessModules& ) = delete; ProcessModules operator =(const ProcessModules&) = delete; void UpdateModuleCache( eModSeachType search, eModType type ); private: class Process& _proc; class ProcessMemory& _memory; class ProcessCore& _core; mapModules _modules; // Fast lookup cache CriticalSection _modGuard; // Module guard bool _ldrPatched; // Win7 loader patch flag }; };