Skip to content

Commit

Permalink
Vutils
Browse files Browse the repository at this point in the history
  • Loading branch information
vic4key committed Nov 11, 2023
1 parent 20beaaa commit ae63e43
Show file tree
Hide file tree
Showing 9 changed files with 481 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Vutils.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@
<ClInclude Include="3rdparty\UND\include\undname.h" />
<ClInclude Include="3rdparty\WHW\WinHttpWrapper.h" />
<ClInclude Include="include\3rdparty\BI\BigInt.hpp" />
<ClInclude Include="include\3rdparty\CH\cpp-hooking\common.h" />
<ClInclude Include="include\3rdparty\CH\cpp-hooking\hooking.h" />
<ClInclude Include="include\3rdparty\CH\cpp-hooking\iat_hooking.h" />
<ClInclude Include="include\3rdparty\CH\cpp-hooking\inl_hooking.h" />
<ClInclude Include="include\3rdparty\CH\cpp-hooking\invokable.h" />
<ClInclude Include="include\3rdparty\EP\include\easyprint.hpp" />
<ClInclude Include="include\3rdparty\NO\include\base\named_operator.hpp" />
<ClInclude Include="include\3rdparty\NO\include\util\io_helpers.hpp" />
Expand Down Expand Up @@ -401,6 +406,7 @@
<None Include="include\inline\types.inl" />
<None Include="include\inline\spechrs.inl" />
<None Include="include\template\easyprint.tpl" />
<None Include="include\template\fnhooking.tpl" />
<None Include="include\template\handle.tpl" />
<None Include="include\template\math.tpl" />
<None Include="include\template\misc.tpl" />
Expand Down
21 changes: 21 additions & 0 deletions Vutils.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
<Filter Include="Header Files\Third Files\EP">
<UniqueIdentifier>{0e80967e-0e61-4762-98d0-e9774dcee22f}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Files\CH">
<UniqueIdentifier>{09804e65-3ba8-4b2d-ac74-8f7e22ab2be0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\Vutils.h">
Expand Down Expand Up @@ -156,6 +159,21 @@
<ClInclude Include="include\3rdparty\EP\include\easyprint.hpp">
<Filter>Header Files\Third Files\EP</Filter>
</ClInclude>
<ClInclude Include="include\3rdparty\CH\cpp-hooking\common.h">
<Filter>Header Files\Third Files\CH</Filter>
</ClInclude>
<ClInclude Include="include\3rdparty\CH\cpp-hooking\hooking.h">
<Filter>Header Files\Third Files\CH</Filter>
</ClInclude>
<ClInclude Include="include\3rdparty\CH\cpp-hooking\iat_hooking.h">
<Filter>Header Files\Third Files\CH</Filter>
</ClInclude>
<ClInclude Include="include\3rdparty\CH\cpp-hooking\inl_hooking.h">
<Filter>Header Files\Third Files\CH</Filter>
</ClInclude>
<ClInclude Include="include\3rdparty\CH\cpp-hooking\invokable.h">
<Filter>Header Files\Third Files\CH</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Vutils.cpp">
Expand Down Expand Up @@ -358,5 +376,8 @@
<None Include="include\template\easyprint.tpl">
<Filter>Header Files\Template Files</Filter>
</None>
<None Include="include\template\fnhooking.tpl">
<Filter>Header Files\Template Files</Filter>
</None>
</ItemGroup>
</Project>
73 changes: 73 additions & 0 deletions include/3rdparty/CH/cpp-hooking/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* @file common.h
* @author Vic P.
* @brief Header for common use.
*/

#pragma once

#include "invokable.h"

#include <memory>
#include <vu>

/**
* @brief The structure that holds the hooking information of a function.
*/
struct Hooked
{
void* m_function;
void* m_trampoline;
std::shared_ptr<Invokable> m_invoker;

Hooked() : m_function(nullptr), m_trampoline(nullptr) {}

Hooked(const Hooked& right)
{
*this = right;
}

const Hooked& operator=(const Hooked& right)
{
if (this != &right)
{
m_function = right.m_function;
m_trampoline = right.m_trampoline;
m_invoker = right.m_invoker;
}

return *this;
}
};

template <typename T>
struct LibraryT;

template <>
struct LibraryT<std::string>
{
typedef vu::LibraryA self;
};

template <>
struct LibraryT<std::wstring>
{
typedef vu::LibraryW self;
};

/**
* @brief Get the address of an exported function from the given dynamic-link module.
* @param module The module name.
* @param function The function name.
* @returns The address of the function or null.
*/
template<typename StdString>
inline void* get_proc_address(const StdString& module, const StdString& function)
{
if (module.empty() || function.empty())
{
return nullptr;
}

return LibraryT<StdString>::self::quick_get_proc_address(module, function);
}
10 changes: 10 additions & 0 deletions include/3rdparty/CH/cpp-hooking/hooking.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @file hooking.h
* @author Vic P.
* @brief Header for Inline Hooking Manager & IAT Hooking Manager.
*/

#pragma once

#include "inl_hooking.h"
#include "iat_hooking.h"
134 changes: 134 additions & 0 deletions include/3rdparty/CH/cpp-hooking/iat_hooking.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/**
* @file iat_hooking.h
* @author Vic P.
* @brief Header/Implementation for IAT Hooking Manager.
*/

#pragma once

#include "common.h"

#include <vu>

/**
* @brief IAT Hooking Manager.
*/
class IATHookingManager : public vu::SingletonT<IATHookingManager>
{
struct IAT_Hooked : public Hooked {};

std::unordered_map<void*, IAT_Hooked> m_list;

using Entry = vu::IATHookingA::Entry;

vu::IATHookingA& hooker()
{
return vu::IATHookingA::instance();
}

void* get_proc_address(const Entry& entry)
{
Entry temp;

if (!this->hooker().exist(entry.target, entry.module, entry.function, &temp))
{
return nullptr;
}

return temp.original;
}

public:
/**
* @brief Hook a given function.
* @param[in] entry The entry of function that want to hook ({ tartget name, module name, function name }).
* @param[in] hk_function The hooking function.
* @return true if succeeds otherwise return false.
*/
template<typename Function>
bool hook(const Entry& entry, Function&& hk_function)
{
IAT_Hooked hooked;

auto ret = this->hooker().install(entry.target, entry.module, entry.function,
(void*)hk_function, &hooked.m_trampoline);
if (ret != vu::VU_OK)
{
return false;
}

auto function = this->get_proc_address(entry);
if (function == nullptr)
{
return false;
}

using FunctionPtr = decltype(&hk_function);

hooked.m_function = function;
hooked.m_invoker.reset(new Invokable(FunctionPtr(hooked.m_trampoline)));

void* key = hooked.m_function;
m_list[key] = std::move(hooked);

return true;
}

/**
* @brief Unhook a given function that was hooked.
* @param[in] entry The entry of function that want to un-hook ({ tartget name, module name, function name }).
* @return true if succeeds otherwise return false.
*/
bool unhook(const Entry& entry)
{
auto function = this->get_proc_address(entry);
if (function == nullptr)
{
return false;
}

auto it = m_list.find(function);
if (it == m_list.cend())
{
return false;
}

auto ret = this->hooker().uninstall(entry.target, entry.module, entry.function);
if (ret != vu::VU_OK)
{
return false;
}

m_list.erase(it);

return true;
}

/**
* @brief Invoke the original function.
* @param[in] entry The entry of function that want to invoke ({ tartget name, module name, function name }).
* @param[in] args The arguments that pass to the original function.
* @return Based on the result of the original function.
*/
template<typename Return, typename ... Args>
Return invoke(const Entry& entry, Args ... args)
{
auto function = this->get_proc_address(entry);
auto it = m_list.find(function);
if (it == m_list.cend())
{
throw "invoke the function that did not hook";
}

auto& hooked = it->second;

if (std::is_void<Return>::value)
{
hooked.m_invoker->invoke<Return>(std::forward<Args>(args)...);
}
else
{
return hooked.m_invoker->invoke<Return>(std::forward<Args>(args)...);
}
}
};
Loading

0 comments on commit ae63e43

Please sign in to comment.