该项目被重写是为了利用 C++17 来创建一个模板,使我们能够在编译时轻松更改所需的功能!它实现为仅头文件(header-only),这样你就可以轻松地将其添加到自己的项目中。
目前已实现的一些功能包括:
我们可以如下配置此行为
#define HASHING_ALGORITHM hash_string_fnv1a // constexpr 算法
namespace config
{
...
//
// 配置行为
//
inline constexpr unsigned unhooking = system32 | write_process_memory;
inline constexpr auto work_item_load_library = true; // 使用工作项进行 LL
//
// 配置规避功能
//
inline constexpr auto clear_and_restore_veh = true; // 清除并恢复 veh
inline constexpr auto unregister_dll_notifs = true; // LdrRegisterDllNotification
inline constexpr auto clear_thread_hwbps = true; // 清除硬件断点
}
由于我们使用了 constexpr,未使用的功能不会产生开销,因为它们属于死代码,会被编译器从程序中优化掉。
要导入 DLL,首先我们必须使用 DLL_HASH 宏创建哈希
DLL_HASH(DBGHELP, L"DBGHELP.DLL")
然后我们必须将其添加到 module_address_table 中,该表充当我们的内部 IAT。hash_ 常量由 DLL_HASH 宏创建。对于并非始终加载的非公共 DLL,我们必须指定其名称以便加载它们。
inline addr_struct<decltype(HASHING_ALGORITHM(TOKENIZEA(T))), wchar_t> module_address_table[] =
{
{hash_NTDLL, nullptr,},
{hash_KERNEL32, nullptr,},
{hash_DBGHELP, nullptr, L"DBGHELP.DLL"}
};
要导入函数,首先我们必须使用 HASH_FUNC 宏创建函数名哈希和 typedef
HASH_FUNC(NtUnmapViewOfSection, NTSTATUS, HANDLE, PVOID)
第一个参数是函数名,接下来是返回类型,然后是函数的参数。然后我们需要将其添加到 api_address_table 中,该表将填充当前函数地址
inline addr_struct<decltype(HASHING_ALGORITHM(TOKENIZEA(T))), void> api_address_table[] =
{
{hash_GetProcAddress, nullptr},
{hash_NtUnmapViewOfSection, nullptr},
如果你未能将此函数添加到该表中,程序不会崩溃,但会返回 -1,以提高稳定性。
要使用 API,请使用 API()() 宏,如下所示
API(NtWaitForSingleObject)(NtCurrentProcess(), FALSE, &timeout);
要添加自己的 API 哈希函数,必须使用此模板才能与所需的类型配合使用。
template <typename T>
constexpr auto hash_string_(const T* buffer)
{
TRIVIAL_TYPE_CHECK()
}
感谢以下人士的想法和贡献(排名不分先后) @peterwintrsmith @modexpblog @jonaslyk @JustasMasiulis