diff --git a/include/WinStd/Win.h b/include/WinStd/Win.h index c2c9ef30..3c550aec 100644 --- a/include/WinStd/Win.h +++ b/include/WinStd/Win.h @@ -64,10 +64,13 @@ template inline BOOL LookupAccountSidW(_I namespace winstd { + class WINSTD_API win_handle; class WINSTD_API library; + class WINSTD_API process; class WINSTD_API heap; class WINSTD_API actctx_activator; class WINSTD_API user_impersonator; + class WINSTD_API vmemory; } #pragma once @@ -884,6 +887,65 @@ namespace winstd /// \addtogroup WinStdWinAPI /// @{ + /// + /// Windows HANDLE wrapper class + /// + class WINSTD_API win_handle : public handle + { + public: + /// + /// Initializes a new class instance with the object handle set to NULL. + /// + inline win_handle() : handle() {} + + /// + /// Initializes a new class instance with an already available object handle. + /// + /// \param[in] h Initial object handle value + /// + inline win_handle(_In_opt_ handle_type h) : handle(h) {} + + /// + /// Move constructor + /// + /// \param[inout] h A rvalue reference of another object + /// + inline win_handle(_Inout_ win_handle &&h) : handle(std::move(h)) {} + + /// + /// Closes an open object handle. + /// + /// \sa [CloseHandle function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211.aspx) + /// + virtual ~win_handle(); + + /// + /// Move assignment + /// + /// \param[inout] h A rvalue reference of another object + /// + win_handle& operator=(_Inout_ win_handle &&h) + { + if (this != std::addressof(h)) + *(handle*)this = std::move(h); + return *this; + } + + private: + // This class is noncopyable. + win_handle(_In_ const win_handle &h); + win_handle& operator=(_In_ const win_handle &h); + + protected: + /// + /// Closes an open object handle. + /// + /// \sa [CloseHandle function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211.aspx) + /// + virtual void free_internal(); + }; + + /// /// Module handle wrapper /// @@ -926,6 +988,33 @@ namespace winstd }; + /// + /// Process handle wrapper + /// + class WINSTD_API process : public win_handle + { + public: + /// + /// Opens process handle. + /// + /// \sa [OpenProcess function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320.aspx) + /// + /// \return + /// - \c true when succeeds; + /// - \c false when fails. Use `GetLastError()` for failure reason. + /// + inline bool open(_In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwProcessId) + { + handle_type h = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId); + if (h) { + attach(h); + return true; + } else + return false; + } + }; + + /// /// Heap handle wrapper /// @@ -1030,5 +1119,112 @@ namespace winstd BOOL m_cookie; ///< Did impersonation succeed? }; + + /// + /// Memory in virtual address space of a process handle wrapper + /// + class WINSTD_API vmemory : public handle + { + public: + /// + /// Initializes a new class instance with the memory handle set to NULL. + /// + inline vmemory() : + m_proc(NULL), + handle() + { + } + + /// + /// Initializes a new class instance with an already available object handle. + /// + /// \param[in] proc Handle of process the memory belongs to + /// \param[in] h Initial object handle value + /// + inline vmemory(_In_ HANDLE proc, _In_opt_ handle_type h) : + m_proc(proc), + handle(h) + { + } + + /// + /// Move constructor + /// + /// \param[inout] h A rvalue reference of another object + /// + inline vmemory(_Inout_ vmemory &&h) + { + // Transfer process. + m_proc = h.m_proc; + + // Transfer handle. + m_h = h.m_h; + h.m_h = NULL; + } + + /// + /// Frees the memory. + /// + /// \sa [VirtualFreeEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366894.aspx) + /// + virtual ~vmemory(); + + /// + /// Sets a new memory handle for the class + /// + /// When the current object handle of the class is non-NULL, the object is destroyed first. + /// + /// \param[in] proc Handle of process the memory belongs to + /// \param[in] h Initial object handle value + /// + inline void attach(_In_ HANDLE proc, _In_opt_ handle_type h) + { + m_proc = proc; + if (m_h) + free_internal(); + m_h = h; + } + + /// + /// Reserves, commits, or changes the state of a region of memory within the virtual address space of a specified process. The function initializes the memory it allocates to zero. + /// + /// \sa [VirtualAllocEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366890.aspx) + /// + /// \return + /// - \c true when succeeds; + /// - \c false when fails. Use `GetLastError()` for failure reason. + /// + inline bool alloc( + _In_ HANDLE hProcess, + _In_opt_ LPVOID lpAddress, + _In_ SIZE_T dwSize, + _In_ DWORD flAllocationType, + _In_ DWORD flProtect) + { + handle_type h = VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect); + if (h) { + attach(hProcess, h); + return true; + } else + return false; + } + + private: + // This class is noncopyable. + vmemory(_In_ const vmemory &h); + vmemory& operator=(_In_ const vmemory &h); + + protected: + /// + /// Frees the memory. + /// + /// \sa [VirtualFreeEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366894.aspx) + /// + virtual void free_internal(); + + protected: + HANDLE m_proc; ///< Handle of memory's process + }; + /// @} } diff --git a/src/Win.cpp b/src/Win.cpp index e1001876..bae94ccf 100644 --- a/src/Win.cpp +++ b/src/Win.cpp @@ -21,6 +21,23 @@ #include "StdAfx.h" +////////////////////////////////////////////////////////////////////// +// winstd::win_handle +////////////////////////////////////////////////////////////////////// + +winstd::win_handle::~win_handle() +{ + if (m_h) + CloseHandle(m_h); +} + + +void winstd::win_handle::free_internal() +{ + CloseHandle(m_h); +} + + ////////////////////////////////////////////////////////////////////// // winstd::library ////////////////////////////////////////////////////////////////////// @@ -128,3 +145,20 @@ winstd::user_impersonator::~user_impersonator() if (m_cookie) RevertToSelf(); } + + +////////////////////////////////////////////////////////////////////// +// winstd::vmemory +////////////////////////////////////////////////////////////////////// + +winstd::vmemory::~vmemory() +{ + if (m_h) + VirtualFreeEx(m_proc, m_h, 0, MEM_RELEASE); +} + + +void winstd::vmemory::free_internal() +{ + VirtualFreeEx(m_proc, m_h, 0, MEM_RELEASE); +}