• <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>

            旅途

            如果想飛得高,就該把地平線忘掉

            內核級利用通用Hook函數方法檢測進程

            介紹通用Hook的一點思想:
                在系統內核級中,MS的很多信息都沒公開,包括函數的參數數 目,每個參數的類型等。在系統內核中,訪問了大量的寄存器,而很多寄存器的值,是上層調用者提供的。如果值改變系統就會變得不穩定。很可能出現不可想象的 后果。另外有時候對需要Hook的函數的參數不了解,所以不能隨便就去改變它的堆棧,如果不小心也有可能導致藍屏。所以Hook的最佳原則是在自己的 Hook函數中呼叫原函數的時候,所有的寄存器值,堆棧里面的值和Hook前的信息一樣。這樣就能保證在原函數中不會出錯。一般我們自己的Hook的函數 都是寫在C文件里面的。例如Hook的目標函數KiReadyThread。
            那么一般就自己實現一個:
            MyKiReadyThread(...)
            {
                ......
                call KiReadyThread
                ......
            }
            但是用C編譯器編譯出來的代碼會出現一個堆棧幀:
            Push ebp
            mov  ebp,esp
            這就和我們的初衷不改變寄存器的數違背了。所以我們可以自己用匯編來實現MyKiReadyThread。

            _func@0 proc
                pushad        ;保存通用寄存器
                call _cfunc@0  ;這里是在進入原來函數前進行的一些處理。
                popad         ;恢復通用寄存器
                push eax  
                mov eax,[esp+4] ;得到系統在call 目標函數時入棧的返回地址。
                mov ds:_OrgRet,eax ;保存在一個臨時變量中
                pop eax
                mov [esp],retaddr  ;把目標函數的返回地址改成自己的代碼空間的返回地址,使其返回                后能接手繼續的處理
                jmp _OrgDestFunction ;跳到原目標函數中
            retaddr:
                pushad         ;原函數處理完后保存寄存器
                call _HookDestFunction@0 ;再處理
                popad      ;回復寄存器
                jmp ds:_OrgRet ;跳到系統調用目標函數的下一條指令。
            _func@0 endp

            當我們要攔截目標API的時候,只要修改原函數頭5個字節的機器為一個JMP _func就行了。
            然后把原來的5字節保存。在跳入原函數時,恢復那5個字節即可。

            Hook KiReadyThread檢測系統中的進程:
            在線程調度搶占的的時候會調用KiReadyThread,它的原型為
            VOID FASTCALL KiReadyThread (IN PRKTHREAD Thread)
            在進入KiReadyThread時,ecx指向Thread。
            所以完全可以Hook KiReadyThread 然后用ecx的值得到但前線程的進程信息。
            KiReadyThread沒被ntosknrl.exe導出,所以通過硬編碼來。在2000Sp4中地址為0x8043141f

            具體實現:
            ////////////////////////////////
            // 1.cpp
            ////////////////////////////////
            #ifdef __cplusplus
            extern "C" {
            #endif

            #include "ntddk.h"
            #include "string.h"
            #include "ntifs.h"
            #include "stdio.h"

            #define FILE_DEVICE_EVENT  0x8000

            #define IOCTL_PASSBUF \
                CTL_CODE(FILE_DEVICE_EVENT, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)

            void DriverUnload (IN PDRIVER_OBJECT pDriverObject);

            NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);

            void cfunc ();

            void HookDestFunction();
            NTSTATUS DeviceIoControlDispatch(IN  PDEVICE_OBJECT  DeviceObject,
                                             IN  PIRP            pIrp);
            extern void func();

            void ResumeDestFunction();

            const WCHAR devLink[]  = L"\\??\\MyEvent";
            const WCHAR devName[]  = L"\\Device\\MyEvent";
            UNICODE_STRING          devNameUnicd;
            UNICODE_STRING          devLinkUnicd;    

            ULONG OrgDestFunction = (ULONG)0x8043141f; //KiReadyThread

            char JmpMyCode [] = {0xE9,0x00,0x00,0x00,0x00};
            char OrgCode [5];

            char OutBuf[128][16];

            int Count = 0;

            ULONG orgcr0;
            #ifdef __cplusplus
            }
            #endif

            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; //恢復原有 CR0 屬性
                   mov  cr0, eax;
                   pop  eax;
              };

            }

            NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath)
            {
                NTSTATUS                Status;
                PDEVICE_OBJECT            pDevice;

                DbgPrint("DriverEntry called!\n");
                RtlInitUnicodeString (&devNameUnicd, devName );
                RtlInitUnicodeString (&devLinkUnicd, devLink );
                Status = IoCreateDevice ( pDriverObject,
                0,
                     &devNameUnicd,
                FILE_DEVICE_UNKNOWN,
                   0,
                   TRUE,
                   &pDevice );
                    if( !NT_SUCCESS(Status))
                    {
                    DbgPrint(("Can not create device.\n"));
                    return Status;
                }
                   Status = IoCreateSymbolicLink (&devLinkUnicd, &devNameUnicd);
                   if( !NT_SUCCESS(Status))
                   {
                       DbgPrint(("Cannot create link.\n"));
                       return Status;
                   }
                   pDriverObject->DriverUnload  = DriverUnload;
                   pDriverObject->MajorFunction[IRP_MJ_CREATE] =
                pDriverObject->MajorFunction[IRP_MJ_CLOSE] =
                pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =    DeviceIoControlDispatch;
                  
                pDriverObject->DriverUnload = DriverUnload;
                * ( (ULONG*) (JmpMyCode+1) ) = (ULONG)func - (ULONG)OrgDestFunction - 5;
                memcpy(OrgCode,(char*)OrgDestFunction,5);
                HookDestFunction();
                
                return STATUS_SUCCESS;
            }

            void DriverUnload (IN PDRIVER_OBJECT pDriverObject)
            {
                NTSTATUS            status;
                ResumeDestFunction();
                if(pDriverObject->DeviceObject != NULL)

                    {
                       status=IoDeleteSymbolicLink( &devLinkUnicd );
                    if ( !NT_SUCCESS( status ) )
                        {
                                DbgPrint((  "IoDeleteSymbolicLink() failed\n" ));
                        }
                        IoDeleteDevice( pDriverObject->DeviceObject );
                    }
            }

            void DisplayName(PKTHREAD Thread)
            {
                PKPROCESS Process = Thread->ApcState.Process;
                PEPROCESS pEprocess = (PEPROCESS)Process;
                DbgPrint("ImageFileName = %s \n",pEprocess->ImageFileName);
                sprintf(OutBuf[Count++],"%s",pEprocess->ImageFileName);
            }

            void cfunc (void)
            {
                ULONG PKHeader=0;
                __asm
                {
                    mov PKHeader,ecx  //ecx寄存器是KiReadyThread中的PRKTHREAD參數
                }
                ResumeDestFunction();
                
                if ( PKHeader != 0 && Count < 128 )
                {
                    DisplayName((PKTHREAD)PKHeader);    
                }    
            }

            void HookDestFunction()
            {
                DisableWriteProtect(&orgcr0);
                memcpy((char*)OrgDestFunction,JmpMyCode,5);
                EnableWriteProtect(orgcr0);    
            }

            void ResumeDestFunction()
            {
                DisableWriteProtect(&orgcr0);
                memcpy((char*)OrgDestFunction,OrgCode,5);
                EnableWriteProtect(orgcr0);
            }

            NTSTATUS DeviceIoControlDispatch(
                                             IN  PDEVICE_OBJECT  DeviceObject,
                                             IN  PIRP            pIrp
                                           )
            {
                PIO_STACK_LOCATION              irpStack;
                NTSTATUS                        status;
                PVOID                           inputBuffer;
                ULONG                           inputLength;
                PVOID                           outputBuffer;
                ULONG                           outputLength;
                OBJECT_HANDLE_INFORMATION       objHandleInfo;

                status = STATUS_SUCCESS;
                // 取出IOCTL請求代碼
                irpStack = IoGetCurrentIrpStackLocation(pIrp);

                switch (irpStack->MajorFunction)
                {
                case IRP_MJ_CREATE :
                    DbgPrint("Call IRP_MJ_CREATE\n");
                    break;
                case IRP_MJ_CLOSE:
                    DbgPrint("Call IRP_MJ_CLOSE\n");
                    break;
                case IRP_MJ_DEVICE_CONTROL:
                    DbgPrint("IRP_MJ_DEVICE_CONTROL\n");
                    inputLength=irpStack->Parameters.DeviceIoControl.InputBufferLength;
                    outputLength=irpStack->Parameters.DeviceIoControl.OutputBufferLength;
                    switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
                    {
                      case    IOCTL_PASSBUF:
                        {
                            RtlCopyMemory(pIrp->UserBuffer, OutBuf, 20*16);
                            
                            memset(OutBuf,0,128*16);
                            Count = 0;
                            break;
                        }
                        default:
                            break;
                    }

                default:
                    DbgPrint("Call IRP_MJ_UNKNOWN\n");
                    break;
                }
                pIrp->IoStatus.Status = status;
                pIrp->IoStatus.Information = 0;
                IoCompleteRequest (pIrp, IO_NO_INCREMENT);
                return status;
            }

            ////////////////////////////////
            // 1.asm
            ////////////////////////////////
            .386
            .model small

            .data
            _OrgRet dd 0

            .code
            public _func@0
            extrn _cfunc@0:near
            extrn _HookDestFunction@0:near
            extrn _OrgDestFunction:DWORD

            _func@0 proc
                pushad
                call _cfunc@0
                popad
                push eax
                mov eax,[esp+4]
                mov ds:_OrgRet,eax
                pop eax
                mov [esp],retaddr
                jmp _OrgDestFunction
            retaddr:
                pushad
                call _HookDestFunction@0
                popad
                jmp ds:_OrgRet
            _func@0 endp
            END

            //////////////////////////////////////////
            // app.cpp
            //////////////////////////////////////////

            #include <windows.h>
            #include <stdio.h>

            #define FILE_DEVICE_EVENT  0x8000
            #define CTL_CODE( DeviceType, Function, Method, Access ) (                 \

                ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
            )

            #define FILE_ANY_ACCESS                 0
            #define METHOD_BUFFERED                 0
            #define FILE_DEVICE_UNKNOWN             0x00000022

            #define IOCTL_PASSBUF \
                CTL_CODE(FILE_DEVICE_EVENT, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)

            int main()
            {
                   HANDLE      hDevice;    
                    bool        status;
                   ULONG       dwReturn;
                    char        outbuf[129][16];
                    hDevice = NULL;
                    m_hCommEvent = NULL;
                    hDevice = CreateFile( "\\\\.\\MyEvent",
                                GENERIC_READ|GENERIC_WRITE,
                                FILE_SHARE_READ | FILE_SHARE_WRITE,
                                NULL,
                                OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL,
                                NULL);
                    if(hDevice == INVALID_HANDLE_VALUE)
                    {
                       printf("createfile wrong\n");
                       getchar();
                       return 0;
                    }
                while(1)
             {
                    memset(outbuf,0,129*16);
                    status =DeviceIoControl(hDevice,
                                IOCTL_PASSBUF,
                                NULL,
                                0,
                                &outbuf,
                                128*16,
                                &dwReturn,NULL);
                    if( !status)
                    {
                        printf("IO wrong+%d\n", GetLastError());
                        getchar();
                        return 0;
                    }
                    int c=0;
                    while( *((char*)(&outbuf)+c*16) )
                    {
                        //把csrss.exe和自身進程信息跳過,因為會產生有大量的信息。
                        if ( strcmp((char*)(&outbuf)+c*16,"app.exe") && \
                             strcmp((char*)(&outbuf)+c*16,"csrss.exe")  )
                            printf("%s\n",(char*)(&outbuf)+c*16);
                        c++;
                    }
                    Sleep(1);
                }
            }

            試驗結果:
            ......
            TTPlayer.exe
            System
            TTPlayer.exe
            vrvmon.exe
            TTPlayer.exe
            System
            System
            Explorer.EXE
            Explorer.EXE
            Explorer.EXE
            ......
            測試,編譯環境 2000 Sp4 2000 DDK
            沒寫出線程的隱藏進程代碼。不過基本上實現得差不多了,只需要把返回的信息,和Ring3級查詢得到的信息進行適時對比就能查出異常進程了。

            posted on 2007-07-29 13:59 旅途 閱讀(594) 評論(0)  編輯 收藏 引用 所屬分類: 深入windows

            久久婷婷国产麻豆91天堂| 国内精品免费久久影院| 好久久免费视频高清| 久久免费视频网站| 99久久婷婷国产综合精品草原| 国产福利电影一区二区三区久久久久成人精品综合 | segui久久国产精品| 国产亚洲色婷婷久久99精品91| 久久一区二区三区免费| 亚洲va久久久噜噜噜久久狠狠| 伊人久久大香线蕉亚洲五月天 | 久久精品无码午夜福利理论片| 国产99久久久国产精品~~牛 | 国产精品永久久久久久久久久| 亚洲精品乱码久久久久久蜜桃| 亚洲精品无码久久久久去q| 久久国产精品77777| 久久精品亚洲欧美日韩久久| 国产精品毛片久久久久久久| 麻豆av久久av盛宴av| 亚洲午夜久久影院| 久久福利资源国产精品999| 成人资源影音先锋久久资源网| 亚洲人成网站999久久久综合| 国产麻豆精品久久一二三| 亚洲中文字幕无码久久2020| 国产香蕉97碰碰久久人人| 日日狠狠久久偷偷色综合96蜜桃| 狠狠色丁香久久综合五月| 丰满少妇人妻久久久久久| 午夜精品久久久久9999高清| 国产成人综合久久精品尤物| 人妻无码αv中文字幕久久| 青青久久精品国产免费看| 999久久久无码国产精品| 国产精品久久久久久久久软件 | 久久精品国产2020| 精品久久亚洲中文无码| 久久久久综合国产欧美一区二区| 久久久久一区二区三区| 久久久久久免费一区二区三区|