登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 143|回复: 0

利用MmCheckSystemImage拦截驱动加载

[复制链接]

31

主题

2

回帖

51

积分

版主

积分
51
发表于 2024-12-30 21:13:37 | 显示全部楼层 |阅读模式
#include <ntifs.h>
#include <ntddk.h>

#define DEVICE_NAME L"\\Device\\test" //Driver Name
#define LINK_NAME L"\\DosDevices\\test" //Link Name
#define IOCTL_BASE    0x800
#define TEMPLATE_CTL_CODE(i) \
    CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_START TEMPLATE_CTL_CODE(1)
#define IOCTL_STOP TEMPLATE_CTL_CODE(2)
#define IOCTL_GETLASTKEY TEMPLATE_CTL_CODE(3)
PDRIVER_OBJECT drvobj;

typedef struct _LDR_DATA_TABLE_ENTRY {
     LIST_ENTRY InLoadOrderLinks;
     LIST_ENTRY InMemoryOrderLinks;
     LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    union {
         LIST_ENTRY HashLinks;
         struct {
            PVOID SectionPointer;
            ULONG CheckSum;
         };
     };
    union {
         struct {
            ULONG TimeDateStamp;
         };
         struct {
            PVOID LoadedImports;
         };
     };
     struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
    PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

#define dprintf DbgPrint


PVOID pfnCheckSystemImage = 0;
int hooked = 0;
int lastkey = 0;

UCHAR fnHeader[] = {0,0,0,0,0,0,0,0,0,0,0,0,0x6a,0x18,0x5f,0x89,0x7d,0xac};
ULONG __stdcall hooked_CheckSystemImage(HANDLE hFile,int a2)
{
    return 0xC0000221;
}
void locate_CheckSystemImage()
{
    PLIST_ENTRY pList = NULL;
    PLDR_DATA_TABLE_ENTRY Ldr = NULL;
    ULONG BaseAddr = 0;
    ULONG Size = 0;
    ULONG i;

    __try
    {
        pList = ( (PLIST_ENTRY)drvobj->DriverSection )->Flink;
        do 
        {
            Ldr = CONTAINING_RECORD(
                pList,
                LDR_DATA_TABLE_ENTRY,
                InLoadOrderLinks);
            if ( Ldr->DllBase ) 
            {
                if ((ULONG)Ldr->DllBase < (ULONG)PsCreateSystemThread)
                {
                    if ((ULONG)Ldr->DllBase + (ULONG)Ldr->SizeOfImage > (ULONG)PsCreateSystemThread)
                    {
                        BaseAddr = (ULONG)Ldr->DllBase;
                        Size = (ULONG)Ldr->SizeOfImage;
                        break;
                    }
                }

            }
            pList = pList->Flink;
        } while ( pList != ((LIST_ENTRY*)drvobj->DriverSection)->Flink );
        dprintf("BaseAddr : %x\n",BaseAddr);
        for (i=BaseAddr;i<BaseAddr+Size-7;i++)
        {
            if (*(PUCHAR)(i) == 0x6a)
            {
                if (RtlCompareMemory(&fnHeader[12],(PUCHAR)i,6) == 6)
                {
                    pfnCheckSystemImage = (PVOID)(i - 12);
                    RtlCopyMemory(fnHeader,pfnCheckSystemImage,12);
                    return;
                }
            }
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    }


}

VOID wpoff()
{
    __asm
    {
        cli;
        push eax;
        mov eax, cr0;
        and eax, 0FFFEFFFFh;
        mov cr0, eax;
        pop eax;
    }
}

VOID wpon()
{
    __asm
    {
        push eax;
        mov eax, cr0;
        or eax, 10000h;
        mov cr0, eax;
        pop eax;
        sti;
    }
}


void hook()
{
    KIRQL oldirql;

    if (hooked) return;
    if (!pfnCheckSystemImage) locate_CheckSystemImage();
    dprintf("pfnCheckSystemImage : %x\n",pfnCheckSystemImage);
    if (!pfnCheckSystemImage) return;
    oldirql = KeRaiseIrqlToDpcLevel();
    wpoff();
    *((PUCHAR)pfnCheckSystemImage)=0xe9;
    *(PULONG)((ULONG)pfnCheckSystemImage+1) = (ULONG)hooked_CheckSystemImage - (ULONG)pfnCheckSystemImage -5;
    wpon();
    KeLowerIrql(oldirql);
    hooked = 1;
    dprintf("hooked\n");
}

void unhook()
{
    KIRQL oldirql;

    if (!hooked) return;
    oldirql = KeRaiseIrqlToDpcLevel();
    wpoff();
    RtlCopyMemory(pfnCheckSystemImage,fnHeader,5);
    wpon();
    KeLowerIrql(oldirql);
    hooked = 0;
    dprintf("unhooked\n");
}
VOID DriverUnload(
    IN PDRIVER_OBJECT DriverObject  
    )
{
    unhook();
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegistryString)
{
    drvobj = DriverObject;
    DriverObject->DriverUnload = (PDRIVER_UNLOAD)DriverUnload;

    hook();
    return STATUS_SUCCESS;
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-1-18 19:00 , Processed in 0.074166 second(s), 27 queries .

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表