• Win64 驱动内核编程-25.X64枚举和隐藏内核模块


    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	%s",(ULONG64)pSystemModuleInformation->Module[i].Base,pDrvName);
    			if( _stricmp(pDrvName,HighlightDrvName)==0 )
    			{
    				printf("		<--------------------");
    				HLed=1;
    			}
    			printf("
    ");
    		}
    	}
    	if(HLed==0)
    		printf("
    [%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隐藏内核模块,摘链问题。也就是要注意结构定义细节就行了。

    #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	%wZ	%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;
    }


     

     

     

  • 相关阅读:
    20199311 2019-2020-2《网络攻防实践》第3周作业
    20199311 2019-2020-2《网络攻防实践》第2周作业
    20199311 2019-2020-2《网络攻防实践》第1周作业
    20199311《网络攻防实践》假期作业
    2019-2020-1 20199311《Linux内核原理与分析》第十二周作业
    2019-2020-1 20199311《Linux内核原理与分析》第十一周作业
    2019-2020-1 20199311《Linux内核原理与分析》第九周作业
    wait函数与waitpid函数
    2019-2020-1 20199311《Linux内核原理与分析》第八周作业
    2019-2020-1 20199311《Linux内核原理与分析》第七周作业
  • 原文地址:https://www.cnblogs.com/csnd/p/12061995.html
Copyright © 2020-2023  润新知