天道酬勤 发表于 2024-12-30 21:13:37

利用MmCheckSystemImage拦截驱动加载

```c
#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,(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;
}

```

页: [1]
查看完整版本: 利用MmCheckSystemImage拦截驱动加载