
HWSyscalls is a new method to execute indirect syscalls using HWBP, HalosGate and a synthetic trampoline on kernel32 with HWBP.
HWSyscalls は、以下の3つの主要コンポーネントを使用して間接システムコールを実行する新しい手法です。
実行フローを制御するためのハードウェアブレークポイントとベクタード例外ハンドラ。
システムコール番号とアドレスを見つけるために使用される HalosGate。
ハードウェアブレークポイントを使用して kernel32 上に合成トランポリンを作成。
HWSyscalls は、現在の間接システムコール検出に基づく EDR や AV の検出をトリガーせずに間接システムコールを使用したい任意のプロジェクトに追加できる、簡単に組み込めるライブラリとして提供されます。
間接システムコールは、ntdll からシステムコールを呼び出すためにさまざまなバリエーションで使用される一般的な手法ですが、ntdll からシステムコールを呼び出す際の主な問題はその核心にあります。それは、プログラムが以前の DLL を経由せずに ntdll へ直接アクセスするという不自然なアクセスです。 HWSyscalls は、間接システムコールの核となるアイデアに基づいていますが、ハードウェアブレークポイント機能を組み合わせて kernel32 に合成トランポリンを作成し、HalosGate で SSN を取得することで、この問題を解決します。
わかりやすくするために、通常の間接システムコールのフローは次のようになります:

一方、私たちのフローは次のようになります:

スタックをアンワインド可能にするために、HWSyscallExceptionHandler 関数のロジックをいくつかのスタック操作トリックで更新しました。
具体的には、NTAPI 関数を直接呼び出し(そのアドレスは現在 PrepareSyscall 関数で返されます)、NTAPI 関数内で HWBP にヒットし、新しいスタックフレームを作成して、その新しいスタックフレームの戻りアドレスを kernel32(または kernelbase)で見つかる "ADD RSP, 68; RET" ガジェットに設定し、スタック引数もコピーするようにしました。
これにより、スタックは完全にアンワインド可能になり、実際に ntdll から戻る途中で kernel32 を経由します。ブレークポイントや実行フローの操作は一切必要ありません。

詳細については、ブログ投稿をご覧ください (近日公開)。
このプロジェクトを使用するには、HWSyscalls.h をインクルードし、必要なガジェットを見つけて例外ハンドラを初期化するために InitHWSyscalls を呼び出す必要があります。
プログラムの実行終了時に、DeinitHWSyscalls を呼び出して例外ハンドラを削除します。
#include "HWSyscalls.h"
typedef NTSTATUS(WINAPI* NtOpenProcess_t)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN OPTIONAL PCLIENT_ID ClientId);
void main() {
// Initialize the exception handler and find the required gadgets.
if (!InitHWSyscalls())
return;
// ...
// Execute your function!
NtOpenProcess_t pNtOpenProcess = (NtOpenProcess_t)PrepareSyscall((char*)("NtOpenProcess"));
NTSTATUS status = pNtOpenProcess(&targetHandle, PROCESS_ALL_ACCESS, &object, &clientID);
// ...
// Removing the exception handler.
DeinitHWSyscalls();
}
HWSyscalls.h 内の HWSYSCALLS_DEBUG 定義を変更することで、デバッグの冗長表示をオン/オフにできます。
#pragma once
#include <windows.h>
#include <inttypes.h>
#include <stdio.h>
#pragma region Defines
#define HWSYSCALLS_DEBUG 0 // 0 disable, 1 enable
#define UP -32
//...
このプロジェクトをコンパイルするには、Visual Studio 2019 以降が必要です。 このプロジェクトは x64 環境専用に作成されており、最適化なしでコンパイルする必要があることに注意してください。 プロジェクト設定 -> C/C++ -> 最適化 -> 最適化 (無効 /Od) から無効にできます。

Sektor7 には、Halosgate と、彼らの素晴らしい Malware Development Advanced Vol 1 で教えられている HWBP 実装に感謝します。
@Am0nsec と @RtlMateusz には、元の Hellsgate 実装 に感謝します。
Rad9800 には、TamperingSyscalls から得たインスピレーションに感謝します。