これは私の元のプロジェクト WTSRM と対応する トーク の続きです。
このプロジェクトは、C++17 を利用して、必要な機能をコンパイル時に簡単に変更できるテンプレートを作成するために書き直されました! これはヘッダーのみのファイルとして実装されているため、自分のプロジェクトに簡単に追加できます。
現在実装されている機能には以下があります:
この動作は次のように設定できます
#define HASHING_ALGORITHM hash_string_fnv1a // constexpr algorithm
namespace config
{
...
//
// configure behaviour
//
inline constexpr unsigned unhooking = system32 | write_process_memory;
inline constexpr auto work_item_load_library = true; // use a work item for LL
//
// configure evasive features
//
inline constexpr auto clear_and_restore_veh = true; // clear and restore veh
inline constexpr auto unregister_dll_notifs = true; // LdrRegisterDllNotification
inline constexpr auto clear_thread_hwbps = true; // clear the hwbps
}
constexpr を利用しているため、使用しない機能はデッドコードとしてプログラムから最適化され、コストがかかりません。
DLL をインポートするには、まず DLL_HASH マクロを使用してハッシュを作成します
DLL_HASH(DBGHELP, L"DBGHELP.DLL")
次に、内部 IAT として機能する module_address_table にそれを追加する必要があります。 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