久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2806|回復: 0
打印 上一主題 下一主題
收起左側

內核編程練習作品->進程守護

[復制鏈接]
跳轉到指定樓層
樓主
ID:71922 發表于 2015-1-10 23:18 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
      剛開始學驅動,成功HOOK NtOpenProces 現在本想試試HOOK NtQuerySystemInformation,沒想打它的結構N多N長,也讓我很驚訝,這個API居然能獲取或者設置超過50多種的信息。

       參考網上的一些代碼,看的我暈頭轉向的..也沒點解釋,而且也沒法編譯...總算搞清楚 進程信息是以鏈表的形式存儲數據的。雖然沒學過鏈表,但也大概有所了解。在做實驗過程中,編譯出錯N次,系統藍屏了N次,總算完成也理解了。
     
      在這個過程中發現一些有趣的事情,例如,網上大部分代碼都是HOOK 這個API來實現進程隱藏,其實還可以惡搞進程信息。最簡單的就是修改要保護進程的PID了。例如:Explorer.exe 的進程PID 是1203,那么我就可以修改成1234,這樣任務管理器也就獲取到假的 PID 。任何對進程操作的前提條件是能獲取到它的PID,現在PID被修改,結束進程自然也無法成功了。原本想修改成其他的進程的PID,例如,任務管理器的PID是1860,它要結束我們要保護的進程1203,那么我們就把 1203修改成它的PID1860,這就變成任務管理器自己結束自己了。可惜,不知道為什么會失敗。嘿嘿,雖然這個失敗了,但是在處理鏈表數據的時候又有新發現,發現破壞鏈表結構,就會實現隱藏所有進程的進程信息,任務管理器看到的是一片空白,目前最新版的XueTr 看到的也是一篇空白,還有冰刃,一查看進程就立即報錯。360任務管理器啟動就立即報錯。但是不知道什么原因居然能產生這種作用!據我所知,冰刃和XueTr貌似不是用常規的方法獲取進程的。所以即使是HOOK NtQuerySystemInformation 移除該進程的所有信息也能被識別出來。那么它們應該不是調用NtQuerySystemInformation這個獲取進程信息才對,現在我無意破壞NtQuerySystemInformation 的鏈表結構,居然能影響到它們,太奇怪了。
以下是截圖。


后來經過自己改進,實現了隱藏指定進程,任務管理器可以顯示其他的進程,冰刃和XueTr就無法獲取進程。不過不穩定,任務管理器有時候會報錯或者會顯示出無名的進程但是PID的值卻非常大。沒法,不知道真正原因,所以這個問題也沒法解決。
以下是成功的時候截的圖:


     嘿嘿,正因為開始我對鏈表不太熟悉,所以在一次實驗中無意破壞了鏈表的結構,就發現這個現象。哈哈~~~,當然也不能說這發現能跟冰刃和XueTr對抗了,因為采用SSDD HOOK,所以它們很容易就能發現。至于360,倒也沒去測試過,首先加載驅動這一步就得費很多心思了。

   以下是SYS完整源碼:方便日后復習之用。

main.h: 用于初始化驅動程序
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// 表示函數運行后 就從內存釋放
#define INITCODE code_sge("INIT")
// 表示內存不足時,可以被置換到硬盤
#define PAGECODE code_seg("PAGE")

#pragma once
#ifdef __cplusplus
extern "C"
{
       #endif
       #include <ntddk.h>
       #ifdef __cplusplus            
}
#endif

/////////////////////////////////////////////////////////////////////

// 保存符號連接 用于卸載驅動是刪除符號連接
UNICODE_STRING SymLinkName;

// 創建設備
NTSTATUS CreateMyDevice(IN PDRIVER_OBJECT pDriverObject, WCHAR MyDeviceName[], WCHAR MySymLinkName[]);
// 派遣函數
NTSTATUS DispatchRoutine(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp);
// 卸載驅動
void UnLoadSys(IN PDRIVER_OBJECT pDriverObject);

// 接收到Ring3傳遞的命令則分析并執行
ULONG CallBack(IN ULONG Ring3_Cmd, IN PIRP pIrp);
/////////////////////////////////////////////////////////////////////

// 創建設備
#pragma INITCODE       // 參數:    驅動對象,所創建的設備名稱,所創建的符號連接名稱
NTSTATUS CreateMyDevice(IN PDRIVER_OBJECT pDriverObject, WCHAR MyDeviceName[], WCHAR MySymLinkName[])
{
        // 創建設備
        UNICODE_STRING DeviceName;
        RtlInitUnicodeString(&DeviceName, MyDeviceName);
                     
        NTSTATUS Status;
        PDEVICE_OBJECT pDevObj;
        Status = IoCreateDevice(pDriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);
        if(!NT_SUCCESS(Status))
        {
              if(Status == STATUS_INSUFFICIENT_RESOURCES)
              {
                   KdPrint(("資源不足!"));
              }
              if(Status == STATUS_OBJECT_NAME_EXISTS)
              {
                   KdPrint(("指定對象名存在!"));
              }
              if(Status == STATUS_OBJECT_NAME_COLLISION)
              {
                   KdPrint(("指定對象名沖突!"));
              }     
              KdPrint(("創建設備失敗!"));
              return Status;  
        }
//        KdPrint(("設備創建成功!"));
        
        pDevObj->Flags |= DO_BUFFERED_IO;
         
        // 創建符號連接
        RtlInitUnicodeString(&SymLinkName, MySymLinkName);
        Status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);
        
        if(!NT_SUCCESS(Status))           // 創建符號連接失敗
        {
                KdPrint(("創建符號連接失敗!"));
                IoDeleteDevice(pDevObj);  // 刪除創建的設備
                return Status;
        }
        return STATUS_SUCCESS;        
}

#pragma PAGECODE
NTSTATUS DispatchRoutine(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp)
{
     ULONG Info = 0;
     
     // 得到當前棧指針
     PIO_STACK_LOCATION Stack;
     Stack = IoGetCurrentIrpStackLocation(pIrp);
     // 區分IRP
     ULONG IRP = 0;
     IRP = Stack->MajorFunction;
     switch(IRP)
     {
          case IRP_MJ_DEVICE_CONTROL:
               {            
                    //得到輸入緩沖區大小
                    ULONG cbin = Stack->Parameters.DeviceIoControl.InputBufferLength;
    //得到輸出緩沖區大小
    ULONG cbout = Stack->Parameters.DeviceIoControl.OutputBufferLength;
    //得到IOCTL碼
    ULONG Ring3_Cmd = Stack->Parameters.DeviceIoControl.IoControlCode;
    // 掉用回調函數,按照指定的信息執行指定動作
    Info = CallBack(Ring3_Cmd, pIrp);
               }
               break;
          case IRP_MJ_CREATE:
               break;
          case IRP_MJ_CLOSE:
               break;
          case IRP_MJ_READ:
               break;                       
     }
     
     // 對相應的IRP進行處理
     pIrp->IoStatus.Information = Info;
     pIrp->IoStatus.Status      = STATUS_SUCCESS;     // 返回成功
     
     // 指示完成此IRP
     IoCompleteRequest(pIrp, IO_NO_INCREMENT);  
     return STATUS_SUCCESS;                             
}

SSDT_HOOK.h:  SSDT HOOK 架構
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 導出SSDT表
typedef struct _ServiceDescriptorTable
{
       PVOID ServiceTableBase;        // SSDT基址
       PVOID ServiceCounterTable;     // 包含SSDT中每個服務被調用次數的計數器,一般由sysenter更新即Ring3轉Ring0中斷
       unsigned int NumberOfServices; // 由ServiceTableBase描述服務的數目
       PVOID ParamTableBase;          // 包含每個系統服務參數字節數表的基地址-系統服務參數表        
}*PServiceDescriptorTable;
extern PServiceDescriptorTable KeServiceDescriptorTable;


#pragma PAGECODE // 要hook的NTAPI服務號,指向原生API,自己的函數地址
int HOOK_API(IN int NtAPI_ID, OUT LONG *Nt_Addr, IN ULONG MyFun)
{
     if(NtAPI_ID>295)
     {
        KdPrint(("NtAPI服務號過大(WIN200:0-295,WINXP:0-283):%d", NtAPI_ID));
        return 1;
     }
     
     if(!MyFun)
     {
        KdPrint(("代替函數地址無效:0x%X", MyFun));
        return 2;
     }
      
     // 獲取NtAPI的在SSDT表的地址
     LONG  *SSDT_NT_Addr = NULL;
     SSDT_NT_Addr = (PLONG)((LONG)(KeServiceDescriptorTable->ServiceTableBase) + NtAPI_ID * 4);
     *Nt_Addr = *SSDT_NT_Addr;            // 取出真正的NtApi地址  

     KdPrint(("函數原地址存放在SSDT的地址:0x%X", SSDT_NT_Addr));
     KdPrint(("讀取該地址獲取真正NtAPI地址:0x%X", *SSDT_NT_Addr));
     KdPrint(("代替函數地址:0x%X", MyFun));
     
     if((LONG)SSDT_NT_Addr<0x80000000 ||(LONG)SSDT_NT_Addr>0x90000000)
     {
        KdPrint(("函數原地址存放在SSDT的地址獲取失敗:0x%X", SSDT_NT_Addr));
        return 3;
     }
     
     if((LONG)*Nt_Addr<0x80000000 ||(LONG)*Nt_Addr>0x90000000)
     {
        KdPrint(("原生函數地址獲取失敗:0x%X", SSDT_NT_Addr));
        return 3;
     }
      
     // 修改SSDT API地址
     __asm                       
     {
        cli
        mov eax, cr0
        and eax, not 10000h
        mov cr0, eax              // 去掉內存保護
     }
     *SSDT_NT_Addr = MyFun;       // 修改存放在SSDT里面的地址
    __asm
{
mov     eax, cr0
or     eax, 10000h
mov     cr0, eax          // 恢復內存保護
sti
}
     return 0;
}
#pragma PAGECODE // 要hook的NTAPI服務號,指向原生API,自己的函數地址
int UnHOOK_API(IN int NtAPI_ID, WCHAR Real_NtAPI_Name[])
{
    if(NtAPI_ID>295)
    {
        KdPrint(("NtAPI服務號過大(WIN200:0-295,WINXP:0-283):%d", NtAPI_ID));
        return 1;
    }
         
     // 獲取NtAPI的在SSDT表的地址
    LONG  *SSDT_NT_Addr = NULL;
    SSDT_NT_Addr = (PLONG)((LONG)(KeServiceDescriptorTable->ServiceTableBase) + NtAPI_ID * 4);
     
     // 獲取原生NtAPI地址
    UNICODE_STRING NtAPI_Name;
    ULONG Real_NtAPI_Addr;

RtlInitUnicodeString(&NtAPI_Name, Real_NtAPI_Name);   
    Real_NtAPI_Addr = (ULONG)MmGetSystemRoutineAddress(&NtAPI_Name);
   
    if(Real_NtAPI_Addr<0x80000000 ||Real_NtAPI_Addr>0x90000000)
    {
        KdPrint(("獲取原生%ws地址失敗:0x%X",Real_NtAPI_Name, Real_NtAPI_Addr));
        return 2;                       
    }
     
     // 恢復SSDT API地址
     __asm                       
     {
        cli
        mov eax, cr0
        and eax, not 10000h
        mov cr0, eax              // 去掉內存保護
     }
     *SSDT_NT_Addr = Real_NtAPI_Addr;       // 修改存放在SSDT里面的地址
    __asm
{
mov     eax, cr0
or     eax, 10000h
mov     cr0, eax          // 恢復內存保護
sti
}
return 0;
     
}

NtQuerySystemInformation_Struct.h:  含義如其名
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __HOOKFUN_H__
#define __HOOKFUN_H__

typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation,              // 0        Y        N
    SystemProcessorInformation,          // 1        Y        N
    SystemPerformanceInformation,        // 2        Y        N
    SystemTimeOfDayInformation,          // 3        Y        N
    SystemNotImplemented1,               // 4        Y        N
    SystemProcessesAndThreadsInformation, // 5       Y        N
    SystemCallCounts,                    // 6        Y        N
    SystemConfigurationInformation,      // 7        Y        N
    SystemProcessorTimes,                // 8        Y        N
    SystemGlobalFlag,                    // 9        Y        Y
    SystemNotImplemented2,               // 10       Y        N
    SystemModuleInformation,             // 11       Y        N
    SystemLockInformation,               // 12       Y        N
    SystemNotImplemented3,               // 13       Y        N
    SystemNotImplemented4,               // 14       Y        N
    SystemNotImplemented5,               // 15       Y        N
    SystemHandleInformation,             // 16       Y        N
    SystemObjectInformation,             // 17       Y        N
    SystemPagefileInformation,           // 18       Y        N
    SystemInstructionEmulationCounts,    // 19       Y        N
    SystemInvalidInfoClass1,             // 20
    SystemCacheInformation,              // 21       Y        Y
    SystemPoolTagInformation,            // 22       Y        N
    SystemProcessorStatistics,           // 23       Y        N
    SystemDpcInformation,                // 24       Y        Y
    SystemNotImplemented6,               // 25       Y        N
    SystemLoadImage,                     // 26       N        Y
    SystemUnloadImage,                   // 27       N        Y
    SystemTimeAdjustment,                // 28       Y        Y
    SystemNotImplemented7,               // 29       Y        N
    SystemNotImplemented8,               // 30       Y        N
    SystemNotImplemented9,               // 31       Y        N
    SystemCrashDumpInformation,          // 32       Y        N
    SystemExceptionInformation,          // 33       Y        N
    SystemCrashDumpStateInformation,     // 34       Y        Y/N
    SystemKernelDebuggerInformation,     // 35       Y        N
    SystemContextSwitchInformation,      // 36       Y        N
    SystemRegistryQuotaInformation,      // 37       Y        Y
    SystemLoadAndCallImage,              // 38       N        Y
    SystemPrioritySeparation,            // 39       N        Y
    SystemNotImplemented10,              // 40       Y        N
    SystemNotImplemented11,              // 41       Y        N
    SystemInvalidInfoClass2,             // 42
    SystemInvalidInfoClass3,             // 43
    SystemTimeZoneInformation,           // 44       Y        N
    SystemLookasideInformation,          // 45       Y        N
    SystemSetTimeSlipEvent,              // 46       N        Y
    SystemCreateSession,                 // 47       N        Y
    SystemDeleteSession,                 // 48       N        Y
    SystemInvalidInfoClass4,             // 49
    SystemRangeStartInformation,         // 50       Y        N
    SystemVerifierInformation,           // 51       Y        Y
    SystemAddVerifier,                   // 52       N        Y
    SystemSessionProcessesInformation    // 53       Y        N
} SYSTEM_INFORMATION_CLASS;

typedef struct _SYSTEM_PROCESSES { // Information Class 5
    ULONG NextEntryDelta;          // 構成結構列的偏移量
    ULONG ThreadCount;             // 線程數目
    ULONG Reserved1[6];
    LARGE_INTEGER CreateTime;      // 創建時間
    LARGE_INTEGER UserTime;        // 用戶模式(Ring3)的CPU時間
    LARGE_INTEGER KernelTime;      // 內核模式(Ring0)的CPU時間
    UNICODE_STRING ProcessName;    // 進程名稱
    KPRIORITY BasePriority;        // 進程優先權
    ULONG ProcessId;               // 進程標識符
    ULONG InheritedFromProcessID;  // 句柄數目
    ULONG HandleCount;             // 句柄數目
    ULONG Reserved2[2];
    VM_COUNTERS VmCounters;        // 虛擬存儲器的結構
    IO_COUNTERS IoCounters;        // IO計數結構
//    SYSTEM_THREADS Therads[1];     // 進程相關線程的結構數組
} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
/*
typedef struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;           //CPU內核模式使用時間;
LARGE_INTEGER UserTime;         //CPU用戶模式使用時間;
LARGE_INTEGER CreateTime;       //線程創建時間;
ULONG     WaitTime;         //等待時間;
PVOID     StartAddress;       //線程開始的虛擬地址;
CLIENT_ID   ClientId;         //線程標識符;
KPRIORITY   Priority;         //線程優先級;
KPRIORITY   BasePriority;       //基本優先級;
ULONG     ContextSwitchCount;   //環境切換數目;
THREAD_STATE State;          //當前狀態;
KWAIT_REASON WaitReason;       //等待原因;
}SYSTEM_THREADS,*PSYSTEM_THREADS;

typedef struct _VM_COUNTERS
{
ULONG PeakVirtualSize;         //虛擬存儲峰值大小;
ULONG VirtualSize;           //虛擬存儲大小;
ULONG PageFaultCount;         //頁故障數目;
ULONG PeakWorkingSetSize;       //工作集峰值大小;
ULONG WorkingSetSize;         //工作集大小;
ULONG QuotaPeakPagedPoolUsage;     //分頁池使用配額峰值;
ULONG QuotaPagedPoolUsage;       //分頁池使用配額;
ULONG QuotaPeakNonPagedPoolUsage;   //非分頁池使用配額峰值;
ULONG QuotaNonPagedPoolUsage;     //非分頁池使用配額;
ULONG PagefileUsage;          //頁文件使用情況;
ULONG PeakPagefileUsage;        //頁文件使用峰值;
}VM_COUNTERS,*PVM_COUNTERS;

typedef struct _IO_COUNTERS
{
LARGE_INTEGER ReadOperationCount;   //I/O讀操作數目;
LARGE_INTEGER WriteOperationCount;   //I/O寫操作數目;
LARGE_INTEGER OtherOperationCount;   //I/O其他操作數目;
LARGE_INTEGER ReadTransferCount;    //I/O讀數據數目;
LARGE_INTEGER WriteTransferCount;   //I/O寫數據數目;
LARGE_INTEGER OtherTransferCount;   //I/O其他操作數據數目;
}IO_COUNTERS,*PIO_COUNTERS;
typedef struct _SYSTEM_PERFORMANCE_INFORMATION
{
LARGE_INTEGER IdleTime;          //CPU空閑時間;
LARGE_INTEGER ReadTransferCount;     //I/O讀操作數目;
LARGE_INTEGER WriteTransferCount;     //I/O寫操作數目;
LARGE_INTEGER OtherTransferCount;     //I/O其他操作數目;
ULONG     ReadOperationCount;     //I/O讀數據數目;
ULONG     WriteOperationCount;     //I/O寫數據數目;
ULONG     OtherOperationCount;     //I/O其他操作數據數目;
ULONG     AvailablePages;       //可獲得的頁數目;
ULONG     TotalCommittedPages;     //總共提交頁數目;
ULONG     TotalCommitLimit;      //已提交頁數目;
ULONG     PeakCommitment;       //頁提交峰值;
ULONG     PageFaults;         //頁故障數目;
ULONG     WriteCopyFaults;       //Copy-On-Write故障數目;
ULONG     TransitionFaults;      //軟頁故障數目;
ULONG     Reserved1;
ULONG     DemandZeroFaults;      //需求0故障數;
ULONG     PagesRead;         //讀頁數目;
ULONG     PageReadIos;         //讀頁I/O操作數;
ULONG     Reserved2[2];
ULONG     PagefilePagesWritten;    //已寫頁文件頁數;
ULONG     PagefilePageWriteIos;    //已寫頁文件操作數;
ULONG     MappedFilePagesWritten;   //已寫映射文件頁數;
ULONG     MappedFileWriteIos;     //已寫映射文件操作數;
ULONG     PagedPoolUsage;       //分頁池使用;
ULONG     NonPagedPoolUsage;     //非分頁池使用;
ULONG     PagedPoolAllocs;       //分頁池分配情況;
ULONG     PagedPoolFrees;       //分頁池釋放情況;
ULONG     NonPagedPoolAllocs;     //非分頁池分配情況;
ULONG     NonPagedPoolFress;     //非分頁池釋放情況;
ULONG     TotalFreeSystemPtes;     //系統頁表項釋放總數;
ULONG     SystemCodePage;       //操作系統代碼頁數;
ULONG     TotalSystemDriverPages;   //可分頁驅動程序頁數;
ULONG     TotalSystemCodePages;    //操作系統代碼頁總數;
ULONG     SmallNonPagedLookasideListAllocateHits; //小非分頁側視列表分配次數;
ULONG     SmallPagedLookasideListAllocateHits;  //小分頁側視列表分配次數;
ULONG     Reserved3;        
ULONG     MmSystemCachePage;     //系統緩存頁數;
ULONG     PagedPoolPage;       //分頁池頁數;
ULONG     SystemDriverPage;     //可分頁驅動頁數;
ULONG     FastReadNoWait;       //異步快速讀數目;
ULONG     FastReadWait;       //同步快速讀數目;
ULONG     FastReadResourceMiss;   //快速讀資源沖突數;
ULONG     FastReadNotPossible;    //快速讀失敗數;
ULONG     FastMdlReadNoWait;     //異步MDL快速讀數目;
ULONG     FastMdlReadWait;      //同步MDL快速讀數目;
ULONG     FastMdlReadResourceMiss;  //MDL讀資源沖突數;
ULONG     FastMdlReadNotPossible;   //MDL讀失敗數;
ULONG     MapDataNoWait;       //異步映射數據次數;
ULONG     MapDataWait;        //同步映射數據次數;
ULONG     MapDataNoWaitMiss;     //異步映射數據沖突次數;
ULONG     MapDataWaitMiss;      //同步映射數據沖突次數;
ULONG     PinMappedDataCount;     //牽制映射數據數目;
ULONG     PinReadNoWait;       //牽制異步讀數目;
ULONG     PinReadWait;        //牽制同步讀數目;
ULONG     PinReadNoWaitMiss;     //牽制異步讀沖突數目;
ULONG     PinReadWaitMiss;      //牽制同步讀沖突數目;
ULONG     CopyReadNoWait;       //異步拷貝讀次數;
ULONG     CopyReadWait;       //同步拷貝讀次數;
ULONG     CopyReadNoWaitMiss;     //異步拷貝讀故障次數;
ULONG     CopyReadWaitMiss;     //同步拷貝讀故障次數;
ULONG     MdlReadNoWait;       //異步MDL讀次數;
ULONG     MdlReadWait;        //同步MDL讀次數;
ULONG     MdlReadNoWaitMiss;     //異步MDL讀故障次數;
ULONG     MdlReadWaitMiss;      //同步MDL讀故障次數;
ULONG     ReadAheadIos;       //向前讀操作數目;
ULONG     LazyWriteIos;       //LAZY寫操作數目;
ULONG     LazyWritePages;       //LAZY寫頁文件數目;
ULONG     DataFlushes;        //緩存刷新次數;
ULONG     DataPages;         //緩存刷新頁數;
ULONG     ContextSwitches;      //環境切換數目;
ULONG     FirstLevelTbFills;     //第一層緩沖區填充次數;
ULONG     SecondLevelTbFills;     //第二層緩沖區填充次數;
ULONG     SystemCall;         //系統調用次數;
}SYSTEM_PERFORMANCE_INFORMATION,*PSYSTEM_PERFORMANCE_INFORMATION;

typedef struct __SYSTEM_PROCESSOR_TIMES
{
LARGE_INTEGER IdleTime;       //空閑時間;
LARGE_INTEGER KernelTime;       //內核模式時間;
LARGE_INTEGER UserTime;       //用戶模式時間;
LARGE_INTEGER DpcTime;        //延遲過程調用時間;
LARGE_INTEGER InterruptTime;     //中斷時間;
ULONG     InterruptCount;     //中斷次數;
}SYSTEM_PROCESSOR_TIMES,*PSYSTEM_PROCESSOR_TIMES;

typedef struct _SYSTEM_PAGEFILE_INFORMATION
{
ULONG NetxEntryOffset;        //下一個結構的偏移量;
ULONG CurrentSize;          //當前頁文件大小;
ULONG TotalUsed;           //當前使用的頁文件數;
ULONG PeakUsed;           //當前使用的頁文件峰值數;
UNICODE_STRING FileName;       //頁文件的文件名稱;
}SYSTEM_PAGEFILE_INFORMATION,*PSYSTEM_PAGEFILE_INFORMATION;

typedef struct _SYSTEM_CACHE_INFORMATION
{
ULONG SystemCacheWsSize;       //高速緩存大小;
ULONG SystemCacheWsPeakSize;     //高速緩存峰值大小;
ULONG SystemCacheWsFaults;      //高速緩存頁故障數目;
ULONG SystemCacheWsMinimum;     //高速緩存最小頁大小;
ULONG SystemCacheWsMaximum;     //高速緩存最大頁大小;
ULONG TransitionSharedPages;     //共享頁數目;
ULONG TransitionSharedPagesPeak;   //共享頁峰值數目;
ULONG Reserved[2];
}SYSTEM_CACHE_INFORMATION,*PSYSTEM_CACHE_INFORMATION;

typedef NTSTATUS (* PZW_QUERY_SYSTEMINFORMATION)(
    IN  SYSTEM_INFORMATION_CLASS SystemInformationClass,
    OUT PVOID SystemInformation,
    IN  ULONG SystemInformationLength,
    OUT PULONG ReturnLength
    );

NTSTATUS NTAPI NewZwQuerySystemInformation(
    IN  SYSTEM_INFORMATION_CLASS SystemInformationClass,
    OUT PVOID SystemInformation,
    IN  ULONG SystemInformationLength,
    OUT PULONG ReturnLength
    );
*/
// =================================================================
// BASIC TYPES
// =================================================================

typedef unsigned char       BYTE,  *PBYTE,  **PPBYTE;
typedef unsigned short      WORD,  *PWORD,  **PPWORD;
typedef unsigned long       DWORD, *PDWORD, **PPDWORD;
typedef unsigned __int64    QWORD, *PQWORD, **PPQWORD;
typedef int                 BOOL,  *PBOOL,  **PPBOOL;
typedef void                                **PPVOID;
#endif  //;
  
HOOK_API.h:  HOOK API 原型定義與替代函數的實現
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "NtQuerySystemInformation_Struct.h"  // NtQuerySystemInformation 函數需要的結構
// 定義NtQuerySystemInformation的原型
extern "C" typedef NTSTATUS __stdcall NTQUERYSYSTEMINFORMATION(
    // 類型信息,大概提供50余種信息探測或設置
    __in SYSTEM_INFORMATION_CLASS SystemInformationClass,
    // 為我們提供需要獲得的信息,或是我們需要設置的系統信息              
    __out_bcount_opt(SystemInformationLength) PVOID SystemInformation,
    // SystemInformation 長度,根據探測的信息類型決定
    __in ULONG SystemInformationLength,
    // 系統返回需要的長度,通常可以設置為NULL
    __out_opt PULONG ReturnLength
);
NTQUERYSYSTEMINFORMATION *RealNtQuerySystemInformation;

// 定義NtOpenProcess的原型
extern "C" typedef NTSTATUS __stdcall NTOPENPROCESS
(
       OUT PHANDLE ProcessHandle,
       IN  ACCESS_MASK AccessMask,
       IN  POBJECT_ATTRIBUTES ObjectAttributes,
       IN  PCLIENT_ID ClientId
);
NTOPENPROCESS *RealNtOpenProcess;      // 定義函數指針 用來指向真正的NtOpenProcess函數地址

///////////////////////////////////////////////////////////////////////////////////////////
                  
ULONG _ProcessPID_Len = 0;
ULONG _ProcessPID[512] = {0};

BOOL _L_HOOK = FALSE;

#pragma PAGECODE
BOOL ScanPID(ULONG PID)
{
     for(ULONG i=0; i<_ProcessPID_Len; i++)
     {
         if(PID == _ProcessPID[ i])
         {
                return TRUE;
         }              
     }
     return FALSE;     
}
// 定義自己的NtOpenProcess 用于檢查其傳遞過來的參數
#pragma PAGECODE
extern "C" NTSTATUS __stdcall MyNtOpenProcess(
                                              OUT     PHANDLE ProcessHandle,
                                              IN      ACCESS_MASK AccessMask,
                                              IN      POBJECT_ATTRIBUTES ObjectAttributes,
                                              IN      PCLIENT_ID ClientId
                                              )
{
        PEPROCESS  EP;
    NTSTATUS     rc;
        HANDLE       PID;
        
        if( (ClientId != NULL) )
        {
        PID = ClientId->UniqueProcess;
        
        // 如果是被保護的PID,則拒絕訪問,并將句柄設置為空
//        if(PID == (HANDLE)_ProcessPID)
            if(ScanPID((ULONG)PID))
        {
        //調試輸出 類似C語言的 Printf
        ProcessHandle = NULL; //這個是關鍵
        rc = STATUS_ACCESS_DENIED; //這個返回值
        
        //PsLookupProcessByProcessId((ULONG)PID,&EP);
        
        EP=PsGetCurrentProcess();
        KdPrint(("【%s】進程想結束要保護的進程 \n",(PTSTR)((ULONG)EP+0x174)));
        }
            else
                rc = RealNtOpenProcess(ProcessHandle, AccessMask, ObjectAttributes, ClientId);
        }
        
        return rc;                                         
}

#pragma PAGECODE
extern "C" NTSTATUS __stdcall MyNtQuerySystemInformation(
    __in SYSTEM_INFORMATION_CLASS SystemInformationClass,              // 獲取信息的類型                              
    __out_bcount_opt(SystemInformationLength) PVOID SystemInformation, // 輸出信息的buf地址
    __in ULONG SystemInformationLength,                                // buf的空間大小
    __out_opt PULONG ReturnLength)                                     // 實際寫入的大小                 
{
  SYSTEM_PROCESSES *lpspi = 0,*lpspia = 0;
  lpspi = (SYSTEM_PROCESSES*)SystemInformation;
  
//  UNICODE_STRING aProcessName;
//  RtlInitUnicodeString(&aProcessName, L"Explorer.exe");
  
  NTSTATUS a = RealNtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);                                         

  if(SystemInformationClass != 5 || !NT_SUCCESS(a))
  {
    return a;
  }

  /*
  // 這個是隱藏所有的進程 但是冰刃、XueTr能檢測出來
  SystemInformation = NULL;
  return STATUS_ACCESS_DENIED;
  */

    if(_L_HOOK)
    {
    // 這個也是隱藏所有的進程 最新版的XueTr無法檢測出來并且也無法顯示正確的進程數等信息 冰刃查看進程會報錯
         int i = 0;   
         while(lpspi->NextEntryDelta != 0)
         {
            i++;
             if(i==2)
             {
                  lpspi->NextEntryDelta = 5;
                 lpspi = (SYSTEM_PROCESSES*)((PUCHAR)lpspi+lpspi->NextEntryDelta);
                 continue;
              }
            lpspi = (SYSTEM_PROCESSES*)((PUCHAR)lpspi+lpspi->NextEntryDelta);            
         }
          return a;
    }  

  //  這個是隱藏指定進程 對冰刃、XueTr無效
  // 如果節點信息有效  
  while(lpspi)
  {
        // 判斷該節點信息是否是我們要保護的進程信息
//         if(RtlEqualUnicodeString(&aProcessName,&lpspi->ProcessName,1))
//         if(lpspi->ProcessId == _ProcessPID)
         if(ScanPID(lpspi->ProcessId))
         {      
              // 如果這條要保護的進程信息是在頭節點                                                            
              if(lpspia == 0)
              {
                  // 有頭結點也有下一個節點 即不是唯一的節點      
                  if(lpspi->NextEntryDelta != 0)                    
                   {
                        // 直接將輸出緩沖區的頭指針指向下一個節點 忽略頭結點的信息                  
                        SystemInformation = (PVOID)((DWORD)SystemInformation + lpspi->NextEntryDelta);
                        // 指針下移
                        lpspi = (SYSTEM_PROCESSES*)((PUCHAR)lpspi+lpspi->NextEntryDelta);
                        continue;                     
                   }
                   else
                   {
                       // 如果只有一個節點且是要隱藏的節點 則將輸出緩沖器置空
                       SystemInformation = NULL;
                   }      
              }
              else         // 如果是中間節點 則表示該進程信息是在中間或尾部
              {
                    // 如果還有下一個節點 說明該進程信息是在中間部分
                    if(lpspi->NextEntryDelta != 0)
                    {
                        // 將該進程信息的上一個指針結構偏移量指向下一個節點 這樣就可以忽略這個進程的指針信息
                        lpspia->NextEntryDelta += lpspi->NextEntryDelta;
                        // 指針移向下一個指針
                        lpspi = (SYSTEM_PROCESSES*)((PUCHAR)lpspi+lpspi->NextEntryDelta);
                        continue;
                    }
                    //尾部結點
                    else
                    {
                        // 如果該進程信息是在尾部 則直接將進程信息的上一個指針結構偏移量指向空,這樣整個鏈表就忽略了這個進程信息鏈表
                        lpspia->NextEntryDelta = 0;
                    }                 
              }                                                            
         }  
  
          // 保存這個與我們要保護進程無關的信息指針~~
         lpspia = lpspi;
         // 如果還有下一個節點
         if(lpspi->NextEntryDelta != 0)
        {
            // 移動到下一個節點 進行判斷該節點的信息是不要移除的信息
            lpspi = (SYSTEM_PROCESSES*)((PUCHAR)lpspi+lpspi->NextEntryDelta);
        }
        else
        {
            // 如果沒有則置空 結束循環
            lpspi = NULL;
//          lpspia->NextEntryDelta = 5;    //加上這個就能隱藏指定進程并且冰刃查看進程會報錯 XT看不到所有的進程 但是能顯示出正確的進程數 任務管理器可能也會報錯

        }

  }
  return a;
}

main.cpp:  主函數
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <main.h>

// 定義Rin3 傳遞下來的指令 因與Ring3定義相同 值必須 >=0x800
#define HOOK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED,FILE_ANY_ACCESS)
#define L_HOOK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED,FILE_ANY_ACCESS)
#define UnHOOK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED,FILE_ANY_ACCESS)

extern "C"
{
       #include <SSDT_HOOK.h>                // SSDT HOOK 框架
       #include <HOOK_API.h>                 // 要HOOK的函數原型及替代函數
}


// 相當于應用程序的main()函數 這是驅動人口函數,凡是驅動被加載均會從這里開始執行
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING B)
{      
       // 注冊派遣函數
       pDriverObject->MajorFunction[IRP_MJ_CREATE]            =    DispatchRoutine;
       pDriverObject->MajorFunction[IRP_MJ_CLOSE]             =    DispatchRoutine;
       pDriverObject->MajorFunction[IRP_MJ_READ]              =    DispatchRoutine;
       pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]    =    DispatchRoutine;
      
       // 設置卸載驅動時要執行的代碼做善后,不設置則無法卸載
       pDriverObject->DriverUnload                            =    UnLoadSys;  
      
       // 創建設備 和 符號連接
       CreateMyDevice(pDriverObject, L"\\Device\\L_Device", L"\\??\\LoveMengx_SSDTHOOK_Driver");
      
       KdPrint(("【加載】驅動完畢。"));
  
///////////////////////////////////////////////////////////////////////////////////      
       LONG NtAPI_Addrs = 0;
       if(!HOOK_API(122, &NtAPI_Addrs, (ULONG)MyNtOpenProcess))
       {
           KdPrint(("NtOpenProcess HOOK 成功~~", NtAPI_Addrs));
           RealNtOpenProcess = (NTOPENPROCESS*)NtAPI_Addrs;
       }
       else
       {
           KdPrint(("HOOK 失敗~~", NtAPI_Addrs));         
       }
       if(!HOOK_API(173, &NtAPI_Addrs, (ULONG)MyNtQuerySystemInformation))
       {
           KdPrint(("NtQuerySystemInformation HOOK 成功~~", NtAPI_Addrs));
           RealNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION*)NtAPI_Addrs;
       }
       else
       {
           KdPrint(("HOOK 失敗~~", NtAPI_Addrs));
       }
              
       return 1;                                                   
}

// 卸載驅動
#pragma PAGECODE
void UnLoadSys(IN PDRIVER_OBJECT pDriverObject)
{            
     // 刪除設備
     PDEVICE_OBJECT pDev;
     pDev =  pDriverObject->DeviceObject;
     IoDeleteDevice(pDev);
     
     // 刪除符號連接
     IoDeleteSymbolicLink(&SymLinkName);

     KdPrint(("【卸載】驅動完畢。"));
     KdPrint(("-----------------------------------"));
}

BOOL HOOKAPI(ULONG Process_PID)
{
    if(Process_PID >65536)
    {
         return FALSE;
    }
    if(!ScanPID(Process_PID))                                    // 檢查是否存在
    {
       _ProcessPID[_ProcessPID_Len] = Process_PID;
       _ProcessPID_Len++;                        
    }
    return TRUE;
}

BOOL UnHOOKAPI()
{
     BOOL Retu = FALSE;
     _ProcessPID_Len = 0;
     
     if(!UnHOOK_API(122, L"NtOpenProcess"))
     {
         Retu = TRUE;
         KdPrint(("NtOpenProcess UnHOOK 成功~~"));        
     }
     else
     {
         Retu = FALSE;
         KdPrint(("NtOpenProcess UnHOOK 失敗~~"));
     }
     
     if(!UnHOOK_API(173, L"NtQuerySystemInformation"))
     {
         Retu = TRUE;
         KdPrint(("NtQuerySystemInformation UnHOOK 成功~~"));  
     }
     else
     {
         Retu = FALSE;
         KdPrint(("NtQuerySystemInformation UnHOOK 失敗~~"));
     }
     return Retu;   
}

int my_atoi(const char* p)
{
bool neg_flag = false;// 符號標記
int res = 0;// 結果
if(p[0] == '+' || p[0] == '-')
neg_flag = (*p++ != '+');
while(isdigit(*p)) res = res*10 + (*p++ - '0');
return neg_flag ?0 -res : res;
}

ULONG CallBack(IN ULONG Ring3_Cmd, IN PIRP pIrp)
{
     // 獲取應用層傳遞下來的數據
     char* InputBuffer =  (char*)pIrp->AssociatedIrp.SystemBuffer;
     char* OutputBuffer = (char*)pIrp->AssociatedIrp.SystemBuffer;
     char Tmp[100] = {0};
     ULONG Info = 0;
     // 分析指令
     switch(Ring3_Cmd)
     {
         case HOOK:
              {
   strcpy(Tmp, InputBuffer);
                   KdPrint(("用戶傳下來的數據 %s   %d", Tmp,my_atoi(Tmp) ));
                   if(HOOKAPI(my_atoi(Tmp)))
                   {
                        strcpy(Tmp, "ADD 完畢~");
                   }
                   else
                   {
                       strcpy(Tmp, "ADD 失敗,PID超過有效范圍~");
                   }  
                   break;
              }
         case UnHOOK:
              {
                   if(UnHOOKAPI())
                   {
                        strcpy(Tmp, "UnHOOK OK");
                   }
                   else
                   {
                        strcpy(Tmp, "UnHOOK Error");
                   }
                   break;
              }
         case L_HOOK:                       // 終極隱藏
                       _L_HOOK = TRUE;
                       strcpy(Tmp, "已經啟動終極隱藏");
              break;   
     }
     strcpy(OutputBuffer, Tmp);
     Info = strlen(Tmp);
     return Info;
}

Exe完整程序源碼
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  

#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"

#include<winioctl.h> //CTL_CODE
#define UHook CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED,FILE_ANY_ACCESS)

BOOL LoadNTDriver(char* lpDriverName,char* lpDriverPathName)
{
BOOL bRet = FALSE;

SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
SC_HANDLE hServiceDDK=NULL;//NT驅動程序的服務句柄

//打開服務控制管理器
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if( hServiceMgr == NULL )  
{
//OpenSCManager失敗
//TRACE( "OpenSCManager() Faild %d ! \n", GetLastError() );
bRet = FALSE;
goto BExit;
}

//創建驅動所對應的服務
hServiceDDK = CreateService( hServiceMgr,
lpDriverName, //驅動程序的在注冊表中的名字  
lpDriverName, // 注冊表驅動程序的 DisplayName 值  
SERVICE_ALL_ACCESS, // 加載驅動程序的訪問權限  
SERVICE_KERNEL_DRIVER,// 表示加載的服務是驅動程序  
SERVICE_DEMAND_START, // 注冊表驅動程序的 Start 值  
SERVICE_ERROR_IGNORE, // 注冊表驅動程序的 ErrorControl 值  
lpDriverPathName, // 注冊表驅動程序的 ImagePath 值  
NULL,  
NULL,  
NULL,  
NULL,  
NULL);  

DWORD dwRtn;
//判斷服務是否失敗
if( hServiceDDK == NULL )  
{  
dwRtn = GetLastError();
if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )  
{  
//由于其他原因創建服務失敗
//TRACE( "CrateService() 失敗 %d ! \n", dwRtn );  
bRet = FALSE;
goto BExit;
}  
else  
{
//服務創建失敗,是由于服務已經創立過
//TRACE( "CrateService() 服務創建失敗,是由于服務已經創立過 ERROR is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" );  
}

// 驅動程序已經加載,只需要打開  
hServiceDDK = OpenService( hServiceMgr, lpDriverName, SERVICE_ALL_ACCESS );  
if( hServiceDDK == NULL )  
{
//如果打開服務也失敗,則意味錯誤
dwRtn = GetLastError();  
//TRACE( "OpenService() 失敗 %d ! \n", dwRtn );  
bRet = FALSE;
goto BExit;
}  
}  

//開啟此項服務
bRet= StartService( hServiceDDK, NULL, NULL );  
if( !bRet )  //開啟服務不成功
{  
//TRACE( "StartService() 失敗 服務可能已經開啟%d ! \n", dwRtn );  
bRet = FALSE;
goto BExit;
}
bRet = TRUE;
//離開前關閉句柄
BExit:
if(hServiceDDK)
{
CloseServiceHandle(hServiceDDK);
}
if(hServiceMgr)
{
CloseServiceHandle(hServiceMgr);
}
return bRet;
}
//卸載驅動程序  
BOOL UnLoadSys( char * szSvrName )  
{
//一定義所用到的變量
BOOL bRet = FALSE;
SC_HANDLE hSCM=NULL;//SCM管理器的句柄,用來存放OpenSCManager的返回值
SC_HANDLE hService=NULL;//NT驅動程序的服務句柄,用來存放OpenService的返回值
SERVICE_STATUS SvrSta;
//二打開SCM管理器
hSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );  
if( hSCM == NULL )  
{
bRet = FALSE;
goto BeforeLeave;
}  

//三打開驅動所對應的服務
hService = OpenService( hSCM, szSvrName, SERVICE_ALL_ACCESS );  

if( hService == NULL )  
{
bRet = FALSE;
goto BeforeLeave;
}  

//四停止驅動程序,如果停止失敗,只有重新啟動才能,再動態加載。  
if( !ControlService( hService, SERVICE_CONTROL_STOP , &SvrSta ) )  
{  
bRet = FALSE;
goto BeforeLeave;
}  

//五動態卸載驅動服務。  
if( !DeleteService( hService ) )  //TRUE//FALSE
{
bRet = FALSE;
goto BeforeLeave;
}  

bRet = TRUE;
//六 離開前關閉打開的句柄
BeforeLeave:
if(hService>0)
{
CloseServiceHandle(hService);
}
if(hSCM>0)
{
CloseServiceHandle(hSCM);
}
return bRet;
}


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
char FilaPath[MAX_PATH] = {0};
char FileName[MAX_PATH] = "UnHook.sys";

if(!strstr(lpCmdLine, "-") || !strstr(lpCmdLine,"<") || !strlen(lpCmdLine))
{
puts("參數格式:指定Nt內核函數的SSDT序列號-Nt內核函數命<");
puts("例如:122-NtOpenProcess<");

return 1;
}

GetModuleFileName(NULL,FilaPath,MAX_PATH);
*(strrchr(FilaPath,'\\')+1) = '\0';
strcat(FilaPath, FileName);


if (!LoadNTDriver(FileName, FilaPath))
{
puts("加載驅動失敗!...");
return 1;
}

Sleep(100);

HANDLE hDevice = NULL;

hDevice = CreateFile("\\\\.\\LoveMengx_UnSSDTHOOK_Driver",
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if (INVALID_HANDLE_VALUE == hDevice)
{
puts("打開驅動失敗...");
return 1;
}

char Buff[1024] = {0};
char Tmp[1024]= {0};
ULONG dwWrite;

DeviceIoControl(hDevice, UHook, Buff, strlen(Buff), Tmp, 1024, &dwWrite, NULL);
if (UnLoadSys(FileName))
{
puts("卸載驅動失敗...");
return 1;
}


puts("完成操作~~");
return 0;
}


                                                                                                             ---  By  L、

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩一区二区三区在线观看 | 国内精品久久久久久久影视简单 | 九九热在线视频 | 国产欧美在线观看 | 成人福利网站 | 久久久久91 | 久久国产精品视频 | a在线视频 | 欧美精品一区二区三区四区五区 | 久久精品国产免费一区二区三区 | 欧美不卡在线 | 成人小视频在线免费观看 | 成年精品 | 国产人成精品一区二区三 | 91久久久久久久 | 亚洲最新在线视频 | 国产精品欧美一区二区三区不卡 | 久久久久久中文字幕 | 最新国产精品 | 国产一区二区三区精品久久久 | 91精品中文字幕一区二区三区 | 91精品国产综合久久久亚洲 | 黑人巨大精品 | 亚洲传媒在线 | 国产精品一区二区福利视频 | 精品一区二区三区视频在线观看 | 国产精品99久久久久久www | av国产在线观看 | 亚洲天堂中文字幕 | 天天草天天干天天 | 理论片午午伦夜理片影院 | 老牛嫩草一区二区三区av | 成人免费在线观看 | 中文字幕av第一页 | 亚洲 中文 欧美 日韩 在线观看 | 精品久久久久久久久久久久久久 | 91精品国产自产精品男人的天堂 | 色.com | 免费影视在线观看 | 久久国产欧美日韩精品 | 国产一区在线免费 |