保護ドライブ:コアSSDTフックを取り外します(2)

システムサービス記述子テーブルとして中国名のSSDTの役割、テーブルが2つのAPI関数を接続し、アクションリング3リング0アプリケーション層とコア層であるが、機能は、接続リンクとして、ちょうど大きなインデックステーブルアドレスSSDTを含みませんそれはまた、いくつかの他の有用な情報、ベースアドレス、例えばアドレス・インデックスなどのサービス機能の数が含まれている、コアシステムの一部を達成するために、一般的に使用されるWindows関数アドレステーブルを変更することにより、SSDTフック関数のカーネルレベルであってもよいです監視目的のためにアクションフィルタ、。

その後、我々は手動で解除するドライバの作成を通して一歩一歩になる、以前の研究とは、ドライバを書くことができましたし、指定されたカーネル関数にリンクNtOpenProcessを取り除く方法をステップバイステップでシミュレートするために、ドライブの保護機能を保護ゲーム。

通常の状況下でゲームを開始するには、保護をロードする際に、この保護層を達成するために、SSDTフックで通常ですが、関数は、関数にリンクされていたら、それは仕方によって読み取ら前の元のアドレスで読み取ることができませんオーバーフック関数によって示されるように、関数は、元のアドレスと現在のアドレスが著しい変化を遂げてきた見ることができます。

それでは、どのように動作するには?非常に単純なだけで、私たちに利用できるシステムを使用してMmGetSystemRoutineAddress、次のように元の関数のアドレスを取得する機能、最終テストコードは次のとおりです。

#include <ntddk.h>
extern "C" LONG KerServiceDescriptorTable;

ULONG Get_SSDTAddr(){
    UNICODE_STRING NtOpenProcess;  // 存放函数的Unicode字符串
    ULONG SSDT_Addr;               // 用于存放原始的SSDT地址

    // 将NtOpenProcess字符串以Uncode格式写入到NtProcess变量中
    RtlInitUnicodeString(&NtOpenProcess, L"NtOpenProcess");
    // 获取系统程序地址,取得NtOpenProcess的原始地址
    SSDT_Addr = (ULONG)MmGetSystemRoutineAddress(&NtOpenProcess);
    DbgPrint("原始函数的地址是: %x\n", SSDT_Addr);
    return SSDT_Addr;
}

VOID UnDriver(PDRIVER_OBJECT driver)
{
    DbgPrint(("驱动卸载成功 ! \n"));
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    Get_SSDTAddr();
    DriverObject->DriverUnload = UnDriver;
    return STATUS_SUCCESS;
}

この仮想マシンに戻って手動で観察を確認するドライバをロードし、次に、このドライバ・コードをコンパイルします。

ドライバコードのコンパイルは、上記も実証されていない、効果は同じ、アセンブリコード転記実装プロセスで、その代わりに実装されてもよいです。

#include <ntddk.h>
extern "C" LONG KerServiceDescriptorTable;

ULONG Get_SSDTAddr(){
    UNICODE_STRING NtOpen;         // 存放函数的Unicode字符串
    ULONG SSDT_Addr;                     // 用于存放原始的SSDT地址

    // 将NtOpenProcess字符串以Uncode格式写入到NtProcess变量中
    RtlInitUnicodeString(&NtOpen, L"NtOpenProcess");
    __asm
    {
        lea eax, NtOpen             // 将初始化的NtOpenProcess地址给EAX
        push eax                    // EAX压入堆栈 等待调用
        call DWORD ptr DS:[MmGetSystemRoutineAddress]
        mov SSDT_Addr,eax           // 将结果赋值给变量
    }
    DbgPrint("原始函数的地址是: %x\n", SSDT_Addr);
    return SSDT_Addr;
}

VOID UnDriver(PDRIVER_OBJECT driver)
{
    DbgPrint(("驱动卸载成功 ! \n"));
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    Get_SSDTAddr();
    DriverObject->DriverUnload = UnDriver;
    return STATUS_SUCCESS;
}

111

おすすめ

転載: www.cnblogs.com/LyShark/p/11563775.html