windows 驅動實現進程枚舉

由於最近有需求寫windows平臺下的發外掛模塊,須要實現對進程的監控,其中一個線程須要匹配進程名,那麼問題來了,這就須要獲取全部進程名稱。
在用戶層ring3下,枚舉進程的方法主要有:
1.CreateToolhelp32Snapshot 經過快照枚舉,x86和x64,winxp-win10 都可獲取到進程名稱。
2.經過 Psapi.dll,LoadLibrary("PSAPI.DLL"),調用其EnumProcesses()枚舉進程,x86和x64,winxp-win10 都可獲取到進程名稱,可是這個方法會OpenProcess打開進程,在ring3層打開進程,很大機率遇到訪問權限問題,因此慎用。
3.經過Wtsapi32.dll, WTSOpenServer()和WTSEnumerateProcess()函數來枚舉進程,可是這個函數須要首先傳入NetBios名稱,並且要打開服務來執行,就怕遇到獲取不到NetBios名稱或者服務打開失敗的狀況,因此定時枚舉循環進程的話慎用。
4.就是最穩定也最經常使用的方法了,經過ntdll.dll 導出的ZwQuerySystemInformation實現進程枚舉。固然這是在ring3層,須要注意寬字符轉換ANSI, 建議使用這種方法。
以上都是ring3層,用戶層枚舉進程的方法。
但是咱們的遊戲保護,不能在用戶層,否則隨便一個SSDT表修改或者Hook jmp 跳轉,就能夠繞過,必須使用驅動來保護遊戲,不過驅動保護涉及到驅動簽名的問題,不過有國外的大牛寫了驅動僞造簽名的工具,咱們僞造微軟的驅動簽名,而後就能夠悄無聲息的保護遊戲了。
不廢話 vs2010 vc++ 驅動枚舉進程ios

DriverProtect.h c++

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endifwindows

pragma pack(1)

/ SSDT表 /
typedef struct ServiceDescriptorEntry
{api

unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;

}ServiceDescriptorEntry_t, *PServiceDescriptorEntry;ide

pragma pack()

typedef struct _PROCESS_INFO
{函數

ULONG_PTR eprocess;
ULONG pid;
ULONG ppid;
UNICODE_STRING pathName;
UNICODE_STRING ImageFileName;

}PROCESSINFO,*PPROCESSINFO;工具

typedef struct _SYSTEM_THREADS
{spa

LARGE_INTEGER  KernelTime;
 LARGE_INTEGER  UserTime;
 LARGE_INTEGER  CreateTime;
 ULONG    WaitTime;
 PVOID    StartAddress;
 CLIENT_ID   ClientID;
 KPRIORITY   Priority;
 KPRIORITY   BasePriority;
 ULONG    ContextSwitchCount;
 ULONG    ThreadState;
 KWAIT_REASON  WaitReason;
 ULONG    Reserved; //Add

}SYSTEM_THREADS,*PSYSTEM_THREADS;線程

typedef struct _SYSTEM_PROCESSES
{調試

ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;

} _SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;

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;

DriverProtect.cpp

#include "ntddk.h"
#include "ntdef.h"
#include "DriverProtect.h"

#define SystemProcessesAndThreadsInformation 5

extern "C" NTSTATUS ZwQuerySystemInformation(

IN ULONG SystemInformationClass, 
IN OUT PVOID SystemInformation, 
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);

VOID UnLoadDriver(PDRIVER_OBJECT DriverObject)
{

KdPrint(("驅動成功卸載!"));

}

VOID EnmuProcess()
{

ULONG cbBuffer = 0x8000; 
    
    PVOID pBuffer = NULL; 

    NTSTATUS rc; 

    LPWSTR pszProcessName; 

    PSYSTEM_PROCESSES pInfo; 

    do
    {
        pBuffer = ExAllocatePool (NonPagedPool, cbBuffer); 

        if (pBuffer == NULL)
        {
            return;
        }

        rc = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pBuffer, cbBuffer, NULL);

        if ( rc == STATUS_INFO_LENGTH_MISMATCH) //緩衝區不足
        {
            ExFreePool(pBuffer);

            cbBuffer *= 2;
        }
        else if (!NT_SUCCESS(rc))
        {
            ExFreePool(pBuffer);
            return;
        }

    }while (rc == STATUS_INFO_LENGTH_MISMATCH);

    pInfo = (PSYSTEM_PROCESSES)pBuffer;

    while (1)
    {
        pszProcessName = pInfo->ProcessName.Buffer;

        if (pszProcessName == NULL)
        {
            pszProcessName = L"NULL";
        }
        if (pInfo->ProcessId == 0)
        {
            DbgPrint("PID %5d System Idle Process", pInfo->ProcessId);
        }
        else
        {
            DbgPrint("PID %5d %ws/r/n", pInfo->ProcessId, pInfo->ProcessName.Buffer);
        }

        if (pInfo->NextEntryDelta == 0)
        {
            break;
        }

        pInfo = (PSYSTEM_PROCESSES)(((PUCHAR)pInfo) + pInfo->NextEntryDelta);
    }

    ExFreePool(pBuffer);

}

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

DriverObject->DriverUnload = UnLoadDriver;

EnmuProcess();

return STATUS_SUCCESS;

}

生成了驅動,咱們跑到虛擬機上,複製驅動文件和符號到虛擬機。

4444.png

咱們使用的 visualDDK + windbg 經過虛擬機調試
內核映射
33434.png
打開windbg , 而後遠程鏈接虛擬機。
4當斷失斷.png
若是windbg 顯示 Debuggee is running...,表示沒有斷點,內核是跑起來的,此時咱們加載剛纔生成的驅動,instdrv,加載,啓動
444.png
此時觀察windbg, DbgPrint打印信息就是枚舉驅動的pid和進程名
5545.png既然已經進入內核了,並且也獲取到進程名稱和PID了,此時操做內核和殺軟是在同一個級別,因此殺軟沒有任何提示的,固然你就能夠進行模塊枚舉或者hook 內存讀寫函數或者進程打開函數,而後保護你想保護的進程。

相關文章
相關標籤/搜索