青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

小默

[zz]內(nèi)核級(jí)HOOK的幾種實(shí)現(xiàn)與應(yīng)用

         實(shí)現(xiàn)內(nèi)核級(jí) HOOK 對(duì)于攔截、分析、跟蹤系統(tǒng)內(nèi)核起著致關(guān)重要的作用。實(shí)現(xiàn)的方法不同意味著應(yīng)用側(cè)重點(diǎn)的不同。如想要攔截 NATIVE API 那么可能常用的就是 HOOK SERVICE TABLE 的方法。如果要分析一些系統(tǒng)調(diào)用,那么可能想到用 HOOK INT 2E 中斷來(lái)實(shí)現(xiàn)。如果想要攔截或跟蹤其他內(nèi)核 DRIVER 的調(diào)用,那么就要用到HOOK PE 的方法來(lái)實(shí)現(xiàn)。這里我們更注重的是實(shí)現(xiàn),原理方面已有不少高手在網(wǎng)上發(fā)表過(guò)文章。大家可以結(jié)合起來(lái)讀。下面以我寫(xiě)的幾個(gè)實(shí)例程序來(lái)講解一下各種方法的實(shí)現(xiàn)。錯(cuò)誤之處還望各位指正。


1、HOOK SERVICE TABLE 方法:
   這種方法對(duì)于攔截 NATIVE API 來(lái)說(shuō)用的比較多。原理就是通過(guò)替換系統(tǒng)導(dǎo)
出的一個(gè) SERVICE TABLE 中相應(yīng)的 NATIVE API 的地址來(lái)達(dá)到攔截的目的。
因?yàn)榇朔椒ㄝ^為簡(jiǎn)單,網(wǎng)上也有不少資料來(lái)介紹。所以這里就不給出實(shí)例程序了。SERVICE TABLE 的結(jié)構(gòu)如下:

typedef struct ServiceDescriptorEntry {
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase;
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
    

2、HOOK INT 2E 方法:
   這種方法對(duì)于跟蹤、分析系統(tǒng)調(diào)用來(lái)說(shuō)用的比較多。原理是通過(guò)替換 IDT
表中的 INT 2E 中斷,使之指向我們自己的中斷服務(wù)處理例程來(lái)實(shí)現(xiàn)的。掌握
此方法需要你對(duì)保護(hù)模式有一定的基礎(chǔ)。下面的程序演示了這一過(guò)程。


/*****************************************************************
文件名        : WssHookInt2e.c
描述          : 系統(tǒng)調(diào)用跟蹤
作者          : sinister
最后修改日期  : 2002-11-02
*****************************************************************/

#include "ntddk.h"
#include "string.h"

#define DWORD unsigned __int32
#define WORD unsigned __int16
#define BYTE unsigned __int8
#define BOOL __int32

#define LOWORD(l)           ((WORD)(l))
#define HIWORD(l)           ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))
#define LOBYTE(w)           ((BYTE)(w))
#define HIBYTE(w)           ((BYTE)(((WORD)(w) >> 8) & 0xFF))

#define MAKELONG(a, b) ((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))

#define SYSTEMCALL 0x2e
#define SYSNAME "System"
#define PROCESSNAMELEN 16

#pragma pack(1)

//定義 IDTR
typedef struct tagIDTR {
        WORD IDTLimit;
        WORD LowIDTbase;
        WORD HiIDTbase;
}IDTR, *PIDTR;

//定義 IDT
typedef struct tagIDTENTRY{
    WORD OffsetLow;
    WORD selector;
    BYTE unused_lo;
    unsigned char unused_hi:5;
    unsigned char DPL:2;
    unsigned char P:1;
    WORD OffsetHigh;
} IDTENTRY, *PIDTENTRY;


#pragma pack()

DWORD    OldInt2eService;
ULONG    ProcessNameOffset;
TCHAR   ProcessName[PROCESSNAMELEN];

static NTSTATUS  MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);
ULONG GetProcessNameOffset();
VOID GetProcessName( PCHAR Name );
VOID InstallNewInt2e();
VOID UninstallNewInt2e();

VOID __fastcall NativeApiCall()
{
    KIRQL OldIrql;
    
    DWORD ServiceID;
    DWORD ProcessId;

    __asm mov ServiceID,eax;


    ProcessId = (DWORD)PsGetCurrentProcessId();
    GetProcessName(ProcessName);

    KeRaiseIrql(HIGH_LEVEL, &OldIrql); // 提升當(dāng)前的 IRQL 級(jí)別防止被中斷


    switch ( ServiceID )
    {
            case 0x20:
                 DbgPrint("NEWINT2E: ProcessName: %s; ProcessID: %d; Native Api: NtCreateFile() \n",ProcessName,ProcessId);
                 break;

            case 0x2b:
                 DbgPrint("NEWINT2E: ProcessName: %s; ProcessID: %d; Native Api: NtCreateSection() \n",ProcessName,ProcessId);                
                 break;


            case 0x30:
                 DbgPrint("NEWINT2E: ProcessName: %s; ProcessID: %d; Native Api: NtCreateToken() \n",ProcessName,ProcessId);                
                 break;
                  
    }

    KeLowerIrql(OldIrql); //恢復(fù)原始 IRQL

}

__declspec(naked) NewInt2eService()
{
    __asm{
        pushad
        pushfd
        push fs
        mov bx,0x30
        mov fs,bx
        push ds
        push es

        sti
        call NativeApiCall; // 調(diào)用記錄函數(shù)
        cli

        pop es
        pop ds
        pop fs
        popfd
        popad

        jmp    OldInt2eService;  //跳到原始 INT 2E 繼續(xù)工作
    }
}

VOID InstallNewInt2e()
{

    IDTR         idtr;
    PIDTENTRY    OIdt;
    PIDTENTRY    NIdt;

    //得到 IDTR 中得段界限與基地址
    __asm {
        sidt idtr;
    }

    //得到IDT基地址
    OIdt = (PIDTENTRY)MAKELONG(idtr.LowIDTbase,idtr.HiIDTbase);

    //保存原來(lái)的 INT 2E 服務(wù)例程
    OldInt2eService = MAKELONG(OIdt[SYSTEMCALL].OffsetLow,OIdt[SYSTEMCALL].OffsetHigh);
    
    NIdt = &(OIdt[SYSTEMCALL]);

    __asm {
        cli
        lea eax,NewInt2eService;  //得到新的 INT 2E 服務(wù)例程偏移
        mov ebx, NIdt;
        mov [ebx],ax;   //INT 2E 服務(wù)例程低 16 位
        shr eax,16      //INT 2E 服務(wù)例程高 16 位
        mov [ebx+6],ax;
        lidt idtr  //裝入新的 IDT
        sti
    }

}

VOID UninstallNewInt2e()
{
    IDTR         idtr;
    PIDTENTRY    OIdt;
    PIDTENTRY    NIdt;

    __asm {
        sidt idtr;
    }

    OIdt = (PIDTENTRY)MAKELONG(idtr.LowIDTbase,idtr.HiIDTbase);

    NIdt = &(OIdt[SYSTEMCALL]);

    _asm {
        cli
        lea eax,OldInt2eService;
        mov ebx, NIdt;
        mov [ebx],ax;
        shr eax,16
        mov [ebx+6],ax;
        lidt idtr
        sti
    }

}




// 驅(qū)動(dòng)入口
NTSTATUS  DriverEntry( IN PDRIVER_OBJECT DriverObject,  IN PUNICODE_STRING RegistryPath )
{
    
    UNICODE_STRING  nameString, linkString;
    PDEVICE_OBJECT  deviceObject;
    NTSTATUS        status;
    HANDLE          hHandle;
    int                i;
    

    //卸載驅(qū)動(dòng)
    DriverObject->DriverUnload = DriverUnload;

    //建立設(shè)備
    RtlInitUnicodeString( &nameString, L"\\Device\\WssHookInt2e" );
    
    status = IoCreateDevice( DriverObject,
                             0,
                             &nameString,
                             FILE_DEVICE_UNKNOWN,
                             0,
                             TRUE,
                             &deviceObject
                           );
                            

    if (!NT_SUCCESS( status ))
        return status;
    

    RtlInitUnicodeString( &linkString, L"\\DosDevices\\WssHookInt2e" );

    status = IoCreateSymbolicLink (&linkString, &nameString);

    if (!NT_SUCCESS( status ))
    {
        IoDeleteDevice (DriverObject->DeviceObject);
        return status;
    }    
    

    for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)    {

          DriverObject->MajorFunction = MydrvDispatch;
    }

      DriverObject->DriverUnload = DriverUnload;

    ProcessNameOffset = GetProcessNameOffset();
    InstallNewInt2e();

  return STATUS_SUCCESS;
}



//處理設(shè)備對(duì)象操作

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0L;
    IoCompleteRequest( Irp, 0 );
    return Irp->IoStatus.Status;
    
}



VOID DriverUnload (IN PDRIVER_OBJECT    pDriverObject)
{
    UNICODE_STRING  nameString;

    UninstallNewInt2e();
    RtlInitUnicodeString( &nameString, L"\\DosDevices\\WssHookInt2e" );    
    IoDeleteSymbolicLink(&nameString);
    IoDeleteDevice(pDriverObject->DeviceObject);

    return;
}



ULONG GetProcessNameOffset()
{
        PEPROCESS curproc;
        int i;
        
        curproc = PsGetCurrentProcess();

        //
        // Scan for 12KB, hopping the KPEB never grows that big!
        //
        for( i = 0; i < 3*PAGE_SIZE; i++ ) {

            if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) {

                return i;
            }
        }

        //
        // Name not found - oh, well
        //
        return 0;
}

VOID GetProcessName( PCHAR Name )
{

        PEPROCESS curproc;
        char *nameptr;
        ULONG i;

        if( ProcessNameOffset ) {

            curproc = PsGetCurrentProcess();
            nameptr = (PCHAR) curproc + ProcessNameOffset;
            strncpy( Name, nameptr, 16 );

        } else {

            strcpy( Name, "???");
        }
}


3、 HOOK PE 方法
    這種方法對(duì)于攔截、分析其他內(nèi)核驅(qū)動(dòng)的函數(shù)調(diào)用來(lái)說(shuō)用的比較多。原理
是根據(jù)替換 PE 格式導(dǎo)出表中的相應(yīng)函數(shù)來(lái)實(shí)現(xiàn)的。此方法中需要用到一些小
技巧。如內(nèi)核模式并沒(méi)有直接提供類似應(yīng)用層的 GetModuleHandl()、GetProcAddress() 等函數(shù)來(lái)獲得模塊的地址。那么我們就需要自己來(lái)編寫(xiě),這
里用到了一個(gè)未公開(kāi)的函數(shù)與結(jié)構(gòu)。ZwQuerySystemInformation 與 SYSTEM_MODULE_INFORMATION 來(lái)實(shí)現(xiàn)得到模塊的基地址。這樣我們就可以根據(jù)
PE 格式來(lái)枚舉導(dǎo)出表中的函數(shù)來(lái)替換了。但這又引出了一個(gè)問(wèn)題,那就是從
WINDOWS 2000 后內(nèi)核數(shù)據(jù)的頁(yè)屬性都是只讀的,不能更改。內(nèi)核模式也沒(méi)有
提供類似應(yīng)用層的 VirtualProtectEx() 等函數(shù)來(lái)修改頁(yè)面屬性。那么也需要
我們自己來(lái)編寫(xiě)。因?yàn)槲覀兪窃趦?nèi)核模式所以我們可以通過(guò)修改 cr0 寄存器的
的寫(xiě)保護(hù)位來(lái)達(dá)到我們的目的。這樣我們所期望的攔截內(nèi)核模式函數(shù)的功能便
得以實(shí)現(xiàn)。此方法需要你對(duì) PE 格式有一定的基礎(chǔ)。下面的程序演示了這一過(guò)程。



/*****************************************************************
文件名        : WssHookPE.c
描述          : 攔截內(nèi)核函數(shù)
作者          : sinister
最后修改日期  : 2002-11-02
*****************************************************************/

#include "ntddk.h"
#include "windef.h"


typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation,
    SystemProcessorInformation,
    SystemPerformanceInformation,
    SystemTimeOfDayInformation,
    SystemNotImplemented1,
    SystemProcessesAndThreadsInformation,
    SystemCallCounts,
    SystemConfigurationInformation,
    SystemProcessorTimes,
    SystemGlobalFlag,
    SystemNotImplemented2,
    SystemModuleInformation,
    SystemLockInformation,
    SystemNotImplemented3,
    SystemNotImplemented4,
    SystemNotImplemented5,
    SystemHandleInformation,
    SystemObjectInformation,
    SystemPagefileInformation,
    SystemInstructionEmulationCounts,
    SystemInvalidInfoClass1,
    SystemCacheInformation,
    SystemPoolTagInformation,
    SystemProcessorStatistics,
    SystemDpcInformation,
    SystemNotImplemented6,
    SystemLoadImage,
    SystemUnloadImage,
    SystemTimeAdjustment,
    SystemNotImplemented7,
    SystemNotImplemented8,
    SystemNotImplemented9,
    SystemCrashDumpInformation,
    SystemExceptionInformation,
    SystemCrashDumpStateInformation,
    SystemKernelDebuggerInformation,
    SystemContextSwitchInformation,
    SystemRegistryQuotaInformation,
    SystemLoadAndCallImage,
    SystemPrioritySeparation,
    SystemNotImplemented10,
    SystemNotImplemented11,
    SystemInvalidInfoClass2,
    SystemInvalidInfoClass3,
    SystemTimeZoneInformation,
    SystemLookasideInformation,
    SystemSetTimeSlipEvent,
    SystemCreateSession,
    SystemDeleteSession,
    SystemInvalidInfoClass4,
    SystemRangeStartInformation,
    SystemVerifierInformation,
    SystemAddVerifier,
    SystemSessionProcessesInformation
} SYSTEM_INFORMATION_CLASS;


typedef struct tagSYSTEM_MODULE_INFORMATION {
    ULONG Reserved[2];
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT Index;
    USHORT Unknown;
    USHORT LoadCount;
    USHORT ModuleNameOffset;
    CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

#define IMAGE_DOS_SIGNATURE        0x5A4D      // MZ
#define IMAGE_NT_SIGNATURE      0x50450000  // PE00
#define IMAGE_NT_SIGNATURE1        0x00004550    // 00EP

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;


typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

//
// Optional header format.
//

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;

    //
    // NT additional fields.
    //

    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

typedef IMAGE_NT_HEADERS32                  IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS32                 PIMAGE_NT_HEADERS;

//
// Section header format.
//

#define IMAGE_SIZEOF_SHORT_NAME              8

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

#define IMAGE_SIZEOF_SECTION_HEADER          40
//
// Export Format
//

typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD   Characteristics;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    DWORD   Name;
    DWORD   Base;
    DWORD   NumberOfFunctions;
    DWORD   NumberOfNames;
    DWORD   AddressOfFunctions;     // RVA from base of image
    DWORD   AddressOfNames;         // RVA from base of image
    DWORD   AddressOfNameOrdinals;  // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

#define BASEADDRLEN 10

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


typedef NTSTATUS (* ZWCREATEFILE)(
  OUT PHANDLE FileHandle,
  IN ACCESS_MASK DesiredAccess,
  IN POBJECT_ATTRIBUTES ObjectAttributes,
  OUT PIO_STATUS_BLOCK IoStatusBlock,
  IN PLARGE_INTEGER AllocationSize  OPTIONAL,
  IN ULONG FileAttributes,
  IN ULONG ShareAccess,
  IN ULONG CreateDisposition,
  IN ULONG CreateOptions,
  IN PVOID EaBuffer  OPTIONAL,
  IN ULONG EaLength
  );

ZWCREATEFILE    OldZwCreateFile;

static NTSTATUS  MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);
VOID DisableWriteProtect( PULONG pOldAttr);
VOID EnableWriteProtect( ULONG ulOldAttr );
FARPROC HookFunction(    PCHAR pModuleBase, PCHAR pHookName, FARPROC pHookFunc );

NTSTATUS  
HookNtCreateFile(
  OUT PHANDLE FileHandle,
  IN ACCESS_MASK DesiredAccess,
  IN POBJECT_ATTRIBUTES ObjectAttributes,
  OUT PIO_STATUS_BLOCK IoStatusBlock,
  IN PLARGE_INTEGER AllocationSize  OPTIONAL,
  IN ULONG FileAttributes,
  IN ULONG ShareAccess,
  IN ULONG CreateDisposition,
  IN ULONG CreateOptions,
  IN PVOID EaBuffer  OPTIONAL,
  IN ULONG EaLength
  );



PCHAR MyGetModuleBaseAddress( PCHAR pModuleName )
{
    PSYSTEM_MODULE_INFORMATION    pSysModule;    

    ULONG            uReturn;
    ULONG            uCount;
    PCHAR            pBuffer = NULL;
    PCHAR            pName    = NULL;
    NTSTATUS        status;
    UINT            ui;

    CHAR            szBuffer[BASEADDRLEN];
    PCHAR            pBaseAddress;
    
    status = ZwQuerySystemInformation( SystemModuleInformation, szBuffer, BASEADDRLEN, &uReturn );

    pBuffer = ( PCHAR )ExAllocatePool( NonPagedPool, uReturn );

    if ( pBuffer )
    {
        status = ZwQuerySystemInformation( SystemModuleInformation, pBuffer, uReturn, &uReturn );

        if( status == STATUS_SUCCESS )
        {
            uCount = ( ULONG )*( ( ULONG * )pBuffer );
            pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );

            for ( ui = 0; ui < uCount; ui++ )
            {
                pName = MyStrchr( pSysModule->ImageName, '\\' );

                if ( !pName )
                {
                    pName = pSysModule->ImageName;
                }

                else {
                    pName++;
                }

                if( !_stricmp( pName, pModuleName ) )
                {
                    pBaseAddress = ( PCHAR )pSysModule->Base;
                    ExFreePool( pBuffer );
                    return pBaseAddress;
                }

                pSysModule ++;
            }
        }

        ExFreePool( pBuffer );
    }

    return NULL;
}


FARPROC HookFunction( PCHAR pModuleBase, PCHAR HookFunName, FARPROC HookFun )
{
    PIMAGE_DOS_HEADER         pDosHdr;
    PIMAGE_NT_HEADERS         pNtHdr;
    PIMAGE_SECTION_HEADER     pSecHdr;
    PIMAGE_EXPORT_DIRECTORY  pExtDir;

    UINT                    ui,uj;
    PCHAR                    FunName;
    DWORD                    *dwAddrName;
    DWORD                    *dwAddrFun;
    FARPROC                    pOldFun;
    ULONG                    uAttrib;


    pDosHdr = ( PIMAGE_DOS_HEADER )pModuleBase;

    if ( IMAGE_DOS_SIGNATURE == pDosHdr->e_magic )
    {
        pNtHdr = ( PIMAGE_NT_HEADERS )( pModuleBase + pDosHdr->e_lfanew );

        if( IMAGE_NT_SIGNATURE  == pNtHdr->Signature ||    IMAGE_NT_SIGNATURE1 == pNtHdr->Signature )
        {
            pSecHdr = ( PIMAGE_SECTION_HEADER )( pModuleBase + pDosHdr->e_lfanew + sizeof( IMAGE_NT_HEADERS ) );

            for ( ui = 0; ui < (UINT)pNtHdr->FileHeader.NumberOfSections; ui++ )
            {
                if ( !strcmp( pSecHdr->Name, ".edata" ) )
                {                
                    pExtDir = ( PIMAGE_EXPORT_DIRECTORY )( pModuleBase + pSecHdr->VirtualAddress );
                    dwAddrName = ( PDWORD )(pModuleBase + pExtDir->AddressOfNames );
                    dwAddrFun = ( PDWORD )(pModuleBase + pExtDir->AddressOfFunctions );

                    for ( uj = 0; uj < (UINT)pExtDir->NumberOfFunctions; uj++ )
                    {
                        FunName = pModuleBase + *dwAddrName;

                        if( !strcmp( FunName, HookFunName ) )
                        {
                            DbgPrint(" HOOK  %s()\n",FunName);
                            DisableWriteProtect( &uAttrib );
                            pOldFun = ( FARPROC )( pModuleBase + *dwAddrFun );
                            *dwAddrFun = ( PCHAR )HookFun - pModuleBase;
                            EnableWriteProtect( uAttrib );
                            return pOldFun;
                        }

                      dwAddrName ++;
                      dwAddrFun ++;
                    }
                }

                pSecHdr++;
            }
        }
    }

    return NULL;
}


// 驅(qū)動(dòng)入口
NTSTATUS  DriverEntry( IN PDRIVER_OBJECT DriverObject,  IN PUNICODE_STRING RegistryPath )
{
    
    UNICODE_STRING  nameString, linkString;
    PDEVICE_OBJECT  deviceObject;
    NTSTATUS        status;
    HANDLE          hHandle;
    PCHAR            pModuleAddress;
    int                i;
    

    //卸載驅(qū)動(dòng)
    DriverObject->DriverUnload = DriverUnload;

    //建立設(shè)備
    RtlInitUnicodeString( &nameString, L"\\Device\\WssHookPE" );
    
    status = IoCreateDevice( DriverObject,
                             0,
                             &nameString,
                             FILE_DEVICE_UNKNOWN,
                             0,
                             TRUE,
                             &deviceObject
                           );
                            

    if (!NT_SUCCESS( status ))
        return status;
    

    RtlInitUnicodeString( &linkString, L"\\DosDevices\\WssHookPE" );

    status = IoCreateSymbolicLink (&linkString, &nameString);

    if (!NT_SUCCESS( status ))
    {
        IoDeleteDevice (DriverObject->DeviceObject);
        return status;
    }    
    
    pModuleAddress = MyGetModuleBaseAddress("ntoskrnl.exe");
    if ( pModuleAddress == NULL)
    {
        DbgPrint(" MyGetModuleBaseAddress()\n");
        return 0;
    }

    OldZwCreateFile = (ZWCREATEFILE)HookFunction( pModuleAddress, "ZwCreateFile",(ZWCREATEFILE)HookNtCreateFile);
    if ( OldZwCreateFile == NULL)
    {
        DbgPrint(" HOOK FAILED\n");
        return 0;
    }

    DbgPrint("HOOK SUCCEED\n");

    for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)    {

          DriverObject->MajorFunction = MydrvDispatch;
    }

      DriverObject->DriverUnload = DriverUnload;
      
  return STATUS_SUCCESS;
}



//處理設(shè)備對(duì)象操作

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0L;
    IoCompleteRequest( Irp, 0 );
    return Irp->IoStatus.Status;
    
}



VOID DriverUnload (IN PDRIVER_OBJECT    pDriverObject)
{
    UNICODE_STRING  nameString;
    PCHAR            pModuleAddress;

    pModuleAddress = MyGetModuleBaseAddress("ntoskrnl.exe");
    if ( pModuleAddress == NULL)
    {
        DbgPrint("MyGetModuleBaseAddress()\n");
        return ;
    }

    OldZwCreateFile = (ZWCREATEFILE)HookFunction( pModuleAddress, "ZwCreateFile",(ZWCREATEFILE)OldZwCreateFile);
    if ( OldZwCreateFile == NULL)
    {
        DbgPrint(" UNHOOK FAILED!\n");
        return ;
    }

    DbgPrint("UNHOOK SUCCEED\n");

    RtlInitUnicodeString( &nameString, L"\\DosDevices\\WssHookPE" );    
    IoDeleteSymbolicLink(&nameString);
    IoDeleteDevice(pDriverObject->DeviceObject);

    return;
}

NTSTATUS  
HookNtCreateFile(
  OUT PHANDLE FileHandle,
  IN ACCESS_MASK DesiredAccess,
  IN POBJECT_ATTRIBUTES ObjectAttributes,
  OUT PIO_STATUS_BLOCK IoStatusBlock,
  IN PLARGE_INTEGER AllocationSize  OPTIONAL,
  IN ULONG FileAttributes,
  IN ULONG ShareAccess,
  IN ULONG CreateDisposition,
  IN ULONG CreateOptions,
  IN PVOID EaBuffer  OPTIONAL,
  IN ULONG EaLength
  )
{
    NTSTATUS    status;

    DbgPrint("Hook ZwCreateFile()\n");

    status = ((ZWCREATEFILE)(OldZwCreateFile))(
               FileHandle,
               DesiredAccess,
               ObjectAttributes,
               IoStatusBlock,
               AllocationSize,
               FileAttributes,
               ShareAccess,
               CreateDisposition,
               CreateOptions,
               EaBuffer,
               EaLength
              );

    return status;
}


VOID DisableWriteProtect( PULONG pOldAttr)
{

     ULONG uAttr;

     _asm
    {
          push eax;
          mov  eax, cr0;
          mov  uAttr, eax;
          and  eax, 0FFFEFFFFh; // CR0 16 BIT = 0
          mov  cr0, eax;
          pop  eax;
    };

     *pOldAttr = uAttr; //保存原有的 CRO 屬性

}

VOID EnableWriteProtect( ULONG uOldAttr )
{

  _asm
  {
       push eax;
       mov  eax, uOldAttr; //恢復(fù)原有 CR0 屬性
       mov  cr0, eax;
       pop  eax;
  };

}

posted on 2009-12-24 20:54 小默 閱讀(573) 評(píng)論(1)  編輯 收藏 引用 所屬分類: Windows

評(píng)論

# re: 內(nèi)核級(jí)HOOK的幾種實(shí)現(xiàn)與應(yīng)用 2009-12-25 19:13 楊彬彬

老土了吧,現(xiàn)在已不用INT 2E 了,那是2000以前的,現(xiàn)在用的是sysenter啦  回復(fù)  更多評(píng)論   

導(dǎo)航

統(tǒng)計(jì)

留言簿(13)

隨筆分類(287)

隨筆檔案(289)

漏洞

搜索

積分與排名

最新評(píng)論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产一区二区观看| 亚洲小说欧美另类社区| 午夜精品久久久久久99热软件| 亚洲精品永久免费精品| 欧美精品久久久久久久久老牛影院| 亚洲国产一成人久久精品| 亚洲欧美国产精品va在线观看| 久久狠狠一本精品综合网| 国产亚洲午夜高清国产拍精品| 国产精品久久久久久久久婷婷| 久久岛国电影| 亚洲狠狠丁香婷婷综合久久久| 欧美福利电影网| 亚洲影视在线播放| 亚洲成人影音| 久久三级福利| 亚洲日本国产| 99热免费精品| 国产亚洲精品一区二区| 国产色视频一区| 欧美性猛交99久久久久99按摩| 欧美一进一出视频| 99精品国产一区二区青青牛奶| 久久亚洲精选| 亚洲影院色无极综合| 欧美中文字幕视频| 亚洲一区三区在线观看| 久久精品国产清自在天天线| 欧美激情视频在线播放 | 亚洲国产裸拍裸体视频在线观看乱了中文 | 一本不卡影院| 久久国产精品99精品国产| 欧美大片一区| 久久亚洲电影| 欧美午夜片欧美片在线观看| 狠狠久久综合婷婷不卡| 国产精品久久久久久久久久久久久久| 欧美刺激午夜性久久久久久久| 欧美吻胸吃奶大尺度电影| 影音先锋亚洲一区| 亚洲成人在线网站| 欧美中文字幕在线观看| 亚洲人体一区| 久久天天躁狠狠躁夜夜爽蜜月| 国产精品毛片a∨一区二区三区|国 | 亚洲丶国产丶欧美一区二区三区 | 亚洲精品资源美女情侣酒店| 亚洲激情av| 亚洲精品在线电影| 久久在线免费观看视频| 久久国产精品电影| 国产精品毛片a∨一区二区三区| 亚洲精品影视在线观看| 国产精品成人免费视频| 小黄鸭精品密入口导航| 亚洲在线日韩| 午夜一区不卡| 欧美日韩国产成人| 欧美精品激情blacked18| 一区二区三区在线看| 曰韩精品一区二区| 久久久精品一品道一区| 免费在线亚洲| 欧美激情精品久久久久| 久久激情视频| 在线成人激情视频| 欧美不卡视频| 欧美.www| 国产精品视频999| 红桃视频成人| 免费高清在线视频一区·| 欧美国产日韩一区二区在线观看| 久久国产精品亚洲va麻豆| 国产午夜精品麻豆| 久久午夜电影网| 麻豆国产va免费精品高清在线| 欧美日韩直播| 激情小说另类小说亚洲欧美| 久久亚洲综合网| 欧美成人影音| 亚洲午夜电影在线观看| 久久久精品动漫| 久久九九精品| 国产精品麻豆欧美日韩ww| 欧美在线999| 亚洲大片在线| 欧美区一区二区三区| 在线播放日韩| 91久久精品国产91久久性色| 欧美日韩国产一区二区| 欧美一级二区| 正在播放欧美一区| 欧美激情精品久久久六区热门| 国产精品美女久久| 噜噜噜久久亚洲精品国产品小说| 中文av字幕一区| 韩国av一区二区三区四区| 亚洲黄色成人| 国产视频在线观看一区二区三区| 欧美成人免费一级人片100| 欧美日韩免费一区| 日韩一区二区福利| 亚洲制服欧美中文字幕中文字幕| 一区二区三区自拍| 亚洲午夜未删减在线观看| 亚洲大片免费看| 亚洲小说春色综合另类电影| 亚洲激情在线观看| 欧美1区2区视频| 国产精品久久久久久久浪潮网站 | 亚洲精品精选| 欧美精品在线一区二区| 欧美中文字幕精品| 欧美精品免费在线| 久久视频精品在线| 亚洲欧美日韩精品久久久久| 极品av少妇一区二区| av成人老司机| 亚洲精品国偷自产在线99热| 亚洲国产精选| 精品白丝av| 亚洲在线成人| 一区二区三区日韩在线观看| 亚洲日本欧美| 亚洲高清在线观看| 亚洲国产精品第一区二区| 国产毛片一区| 久久久欧美一区二区| 欧美日韩中字| 日韩亚洲在线| 国产欧美精品日韩| 久久久精品一区二区三区| 欧美日韩一区在线观看视频| 欧美大尺度在线观看| 韩国一区二区在线观看| 香蕉久久国产| 久久精品最新地址| 国产一区二区三区黄视频| 午夜欧美电影在线观看| 欧美在线你懂的| 国产欧美在线观看| 欧美一级久久久久久久大片| 久久久国产成人精品| 国模套图日韩精品一区二区| 亚洲国产三级| 日韩特黄影片| 欧美日韩国产一区精品一区| 亚洲片区在线| 亚洲色在线视频| 久久精品一区二区| 美国成人毛片| 在线观看亚洲视频| 欧美承认网站| 艳妇臀荡乳欲伦亚洲一区| 亚洲欧美成人| 欧美成人国产| 亚洲电影有码| 亚洲素人一区二区| 国产精品网站在线观看| 欧美一级理论片| 欧美国产日韩视频| 亚洲永久字幕| 激情自拍一区| 欧美人成在线视频| 小嫩嫩精品导航| 亚洲国产成人av| 午夜久久久久| 欧美日韩精品免费在线观看视频| 亚洲最黄网站| 久久综合久久久| 99视频精品全部免费在线| 久久精品国产亚洲a| 亚洲福利视频免费观看| 亚洲一区二区免费在线| 伊人色综合久久天天| 欧美日韩p片| 久久精品国产99精品国产亚洲性色 | 欧美xart系列高清| 亚洲深夜福利网站| 老司机aⅴ在线精品导航| 99精品99| 狠狠色丁香婷婷综合久久片| 欧美精品一卡| 久久天天躁狠狠躁夜夜av| 一区二区三区www| 99成人在线| 国产亚洲精品aa午夜观看| 欧美黄网免费在线观看| 欧美在线黄色| 久久综合伊人| 亚洲一区欧美二区| 91久久夜色精品国产九色| 久久久高清一区二区三区| 99视频有精品| 亚洲国产日韩美| 久久亚洲欧美国产精品乐播| 亚洲午夜在线观看视频在线| 亚洲国产精品黑人久久久| 国产亚洲a∨片在线观看| 欧美日韩在线高清|