驱动模块隐藏

X64枚举和隐藏内核模块

说明:技术仅供学习使用,如恶意利用,与作者无关!

在 WIN64 上枚举内核模块的人方法:使用 ZwQuerySystemInformation 的第 11 号功能和枚举 KLDR_DATA_TABLE_ENTRY 中的 InLoadOrderLinks 双向链表;隐藏内核模块的通用方法是把指定的驱动对象从 KLDR_DATA_TABLE_ENTRY中的 InLoadOrderLinks 双向链表上摘除。

X64内核模块枚举(注意是在R3)

#include <stdio.h>
#include <Windows.h>

typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)
(
    IN ULONG    SystemInformationClass,
    OUT PVOID    SystemInformation,
    IN ULONG    Length,
    OUT PULONG    ReturnLength
);

typedef unsigned long DWORD;

typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY
{
    ULONG Unknow1;
    ULONG Unknow2;
    ULONG Unknow3;
    ULONG Unknow4;
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT Index;
    USHORT NameLength;
    USHORT LoadCount;
    USHORT ModuleNameOffset;
    char ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;

typedef struct _SYSTEM_MODULE_INFORMATION
{
    ULONG Count;//内核中以加载的模块的个数
    SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;

BOOLEAN EnumKM(char *HighlightDrvName)
{
    ULONG NeedSize, i, ModuleCount, HLed=0, BufferSize = 0x5000;
    PVOID pBuffer = NULL;
    PCHAR pDrvName = NULL;
    NTSTATUS Result;
    PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;
    do
    {
        //分配内存
        pBuffer = malloc( BufferSize );
        if( pBuffer == NULL )
            return 0;
        //查询模块信息
        Result = ZwQuerySystemInformation( 11, pBuffer, BufferSize, &NeedSize );
        if( Result == 0xC0000004L )
        {
            free( pBuffer );
            BufferSize *= 2;
        }
        else if( Result<0 )
        {
            //查询失败则退出
            free( pBuffer );
            return 0;
        }
    }
    while( Result == 0xC0000004L );
    pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;
    //获得模块的总数量
    ModuleCount = pSystemModuleInformation->Count;
    //遍历所有的模块
    for( i = 0; i < ModuleCount; i++ )
    {
        if((ULONG64)(pSystemModuleInformation->Module[i].Base) > (ULONG64)0x8000000000000000)
        {
            pDrvName = pSystemModuleInformation->Module[i].ImageName+pSystemModuleInformation->Module[i].ModuleNameOffset;
            printf("0x%llx\t%s",(ULONG64)pSystemModuleInformation->Module[i].Base,pDrvName);
            if( _stricmp(pDrvName,HighlightDrvName)==0 )
            {
                printf("\t\t<--------------------");
                HLed=1;
            }
            printf("\n");
        }
    }
    if(HLed==0)
        printf("\n[%s] NOT FOUND!",HighlightDrvName);
    free(pBuffer);
    return 1;
}

int main()
{    
    ZwQuerySystemInformation=(ZWQUERYSYSTEMINFORMATION)GetProcAddress(LoadLibraryW(L"ntdll.dll"),"ZwQuerySystemInformation");
    EnumKM("win32k.sys");
    getchar();
    return 0;
}

然后是R0隐藏内核模块,摘链问题。也就是要注意结构定义细节就行了。

R0隐藏代码:

#include <ntddk.h>

#define kprintf        DbgPrint
#define kmalloc(_s)    ExAllocatePoolWithTag(NonPagedPool, _s, 'SYSQ')
#define kfree(_p)    ExFreePool(_p)

NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation 
(
    IN ULONG    SystemInformationClass,
    OUT PVOID    SystemInformation,
    IN ULONG    Length,
    OUT PULONG    ReturnLength
);

typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY
{
    ULONG Unknow1;
    ULONG Unknow2;
    ULONG Unknow3;
    ULONG Unknow4;
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT Index;
    USHORT NameLength;
    USHORT LoadCount;
    USHORT ModuleNameOffset;
    char ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;

typedef struct _SYSTEM_MODULE_INFORMATION
{
    ULONG Count;//内核中以加载的模块的个数
    SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef struct _KLDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY64 InLoadOrderLinks;
    ULONG64 __Undefined1;
    ULONG64 __Undefined2;
    ULONG64 __Undefined3;
    ULONG64 NonPagedDebugInfo;
    ULONG64 DllBase;
    ULONG64 EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG   Flags;
    USHORT  LoadCount;
    USHORT  __Undefined5;
    ULONG64 __Undefined6;
    ULONG   CheckSum;
    ULONG   __padding1;
    ULONG   TimeDateStamp;
    ULONG   __padding2;
}KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;

PDRIVER_OBJECT pDriverObject = NULL;

ULONG64 GetSystemModuleBase(char* lpModuleName)
{
    ULONG NeedSize, i, ModuleCount, BufferSize = 0x5000;
    PVOID pBuffer = NULL;
    PCHAR pDrvName = NULL;
    NTSTATUS Result;
    PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;
    do
    {
        //分配内存
        pBuffer = kmalloc( BufferSize );
        if( pBuffer == NULL )
            return 0;
        //查询模块信息
        Result = ZwQuerySystemInformation( 11, pBuffer, BufferSize, &NeedSize );
        if( Result == STATUS_INFO_LENGTH_MISMATCH )
        {
            kfree( pBuffer );
            BufferSize *= 2;
        }
        else if( !NT_SUCCESS(Result) )
        {
            //查询失败则退出
            kfree( pBuffer );
            return 0;
        }
    }
    while( Result == STATUS_INFO_LENGTH_MISMATCH );
    pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;
    //获得模块的总数量
    ModuleCount = pSystemModuleInformation->Count;
    //遍历所有的模块
    for( i = 0; i < ModuleCount; i++ )
    {
        if((ULONG64)(pSystemModuleInformation->Module[i].Base) > (ULONG64)0x8000000000000000)
        {
            pDrvName = pSystemModuleInformation->Module[i].ImageName+pSystemModuleInformation->Module[i].ModuleNameOffset;
            if( _stricmp(pDrvName,lpModuleName)==0 )
                return (ULONG64)pSystemModuleInformation->Module[i].Base;
        }
    }
    kfree(pBuffer);
    return 0;
}

VOID HideDriver(char *pDrvName)
{
    PKLDR_DATA_TABLE_ENTRY entry=(PKLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
    PKLDR_DATA_TABLE_ENTRY firstentry;
    ULONG64 pDrvBase=0;
    KIRQL OldIrql;
    firstentry = entry;
    pDrvBase = GetSystemModuleBase(pDrvName);
    while((PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink != firstentry)
    {
        if( entry->DllBase==pDrvBase )
        {
            //typedef struct LIST_ENTRY64 {
            //    ULONGLONG Flink;
            //    ULONGLONG Blink;
            //} LIST_ENTRY64;
            //typedef LIST_ENTRY64 *PLIST_ENTRY64;
            //le->Flink->Blink=le->Blink;
            //le->Blink->Flink=le->Flink;
            OldIrql = KeRaiseIrqlToDpcLevel();
            ((LIST_ENTRY64*)(entry->InLoadOrderLinks.Flink))->Blink=entry->InLoadOrderLinks.Blink;
            ((LIST_ENTRY64*)(entry->InLoadOrderLinks.Blink))->Flink=entry->InLoadOrderLinks.Flink;
            entry->InLoadOrderLinks.Flink=0;
            entry->InLoadOrderLinks.Blink=0;
            KeLowerIrql(OldIrql);
            DbgPrint("Remove LIST_ENTRY64 OK!");
            break;
        }
        //kprintf("%llx\t%wZ\t%wZ",entry->DllBase,entry->BaseDllName,entry->FullDllName);
        entry = (PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink;
    }
}

NTSTATUS UnloadDriver(IN PDRIVER_OBJECT DriverObject)
{
    return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath)
{
    DriverObject->DriverUnload = UnloadDriver;
    pDriverObject = DriverObject;
    HideDriver("win32k.sys");    //hidekm64.sys
    return STATUS_SUCCESS;
}

结尾

代码已经贴出,没有很多,就不放下载链接了qwq
如遇任何问题,可以加我QQ:2513881812
喜欢的话不妨打赏一下[滑稽]


   转载规则

请联系作者付费转载。
 上一篇
SuperDriver Project SuperDriver Project
SUPERDRIVER 简介什么是SuperDriver?SuperDriver是一种以内核模式运行的驱动(KMDF),为某些程序提供编程接口,接口主要涉及: 进程操作 进程结束 强制进程结束 *:内存清零 进程隐藏 进程保护
2020-03-12
下一篇 
驱动级强制结束进程 驱动级强制结束进程
驱动级监控进程说明:技术仅供学习使用,如恶意利用,与作者无关!依然已经走到驱动这一层了,那么通常结束掉一个进程不是什么难的事情。同时因为win64 位的各种保护,导致大家慢慢的已经不敢HOOK了,当然这指的是产品。作为学习和破解的话当然可以
2020-03-12
  目录