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++ 驱动枚举进程。

DriverProtect.h

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif

pragma pack(1)
/*SSDT表*/
typedef struct ServiceDescriptorEntry
{

unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
}ServiceDescriptorEntry_t, *PServiceDescriptorEntry;

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
{

 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;
}

生成了驱动,我们跑到虚拟机上,复制驱动文件和符号到虚拟机

在这里插入图片描述
我们使用的 visualDDK + windbg 通过虚拟机调试
内核映射

在这里插入图片描述
打开windbg , 然后远程连接虚拟机。

在这里插入图片描述
如果windbg 显示 Debuggee is running…,表示没有断点,内核是跑起来的,此时我们加载刚才生成的驱动,instdrv,加载,启动。

在这里插入图片描述
此时观察windbg, DbgPrint打印信息就是枚举驱动的pid和进程名。

在这里插入图片描述
既然已经进入内核了,而且也获取到进程名称和PID了,此时操作内核和杀软是在同一个级别,所以杀软没有任何提示的,当然你就可以进行模块枚举或者hook 内存读写函数或者进程打开函数,然后保护你想保护的进程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值