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 内存读写函数或者进程打开函数,而后保护你想保护的进程。

相关文章
相关标签/搜索