df001 发表于 2018-2-27 21:52:42

驱动枚举所有进程所有模块,删除指定进程。


环境:   VS2008中配置WDK7600驱动开发环境

包含文件   #include <ntifs.h>   #include <WinDef.h>
需要在 #include <ntddk.h> 之前那么就不会出错

程序大体流程:
PsGetCurrentProcess() 得到本进程EPROCESS
通过EPROCESS +0x174 得到进程名
通过EPROCESS +0x84得到进程ID

   PsLookupProcessByProcessId 通过进程ID 得到 这个ID的 EPROCESS
   MmGetSystemRoutineAddress得到 PsGetProcessPeb的函数地址
   PsGetProcessPeb 通过进程的 EPROCESS得到 进程的PEB 然后再得到PEB的LDR
   保存APC状态(Asynchronous procedure call,异步程序调用)KeStackAttachProcess(EPROCESS , &KAPC);
   通过ldr 得到 内存加载链表InMemoryOrderModuleList 通过它循环遍历模块
   pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink
   pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);   
   pLdrDataEntry 包含有模块的全路径 然后循环得到
   detach进程 KeUnstackDetachProcess
    另外就是 PsLookupProcessByProcessId得到 EPROCESS会增加引用计数 这里减少即可
    ObDereferenceObject(EPROCESS),EPROCESS=null;

通过EPROCESS +0x88得到下一个EPROCESS的ActiveProcessLinks
通过上面这个结构 - 0x88 就得到这个EPROCESS指针
然后循环进行遍历进程

typedef PPEB (__stdcall *PFNPsGetProcessPeb)(PEPROCESS pEProcess);   
typedef ULONG   PPS_POST_PROCESS_INIT_ROUTINE;      <div>
typedef struct _PEB_LDR_DATA {   
    BYTE       Reserved1;   
    PVOID      Reserved2;   
    LIST_ENTRY InMemoryOrderModuleList;   
} PEB_LDR_DATA, *PPEB_LDR_DATA;    </div><div>
typedef struct _RTL_USER_PROCESS_PARAMETERS {   
    BYTE         Reserved1;   
    PVOID          Reserved2;   
    UNICODE_STRING ImagePathName;   
    UNICODE_STRING CommandLine;   
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;   

typedef struct _PEB {   
    BYTE                        Reserved1;   
    BYTE                        BeingDebugged;   
    BYTE                        Reserved2;   
    PVOID                         Reserved3;   
    PPEB_LDR_DATA               Ldr;   
    PRTL_USER_PROCESS_PARAMETERSProcessParameters;   
    BYTE                        Reserved4;   
    PVOID                         Reserved5;   
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;   
    BYTE                        Reserved6;   
    PVOID                         Reserved7;   
    ULONG                         SessionId;   
} PEB, *PPEB;   

typedef struct _LDR_DATA_TABLE_ENTRY      
{      
    LIST_ENTRY InLoadOrderLinks;      
    LIST_ENTRY InMemoryOrderLinks;      
    LIST_ENTRY InInitializationOrderLinks;      
    PVOID DllBase;      
    PVOID EntryPoint;      
    DWORD SizeOfImage;      
    UNICODE_STRING FullDllName;      
    UNICODE_STRING BaseDllName;      
    DWORD Flags;      
    WORD LoadCount;      
    WORD TlsIndex;      
    LIST_ENTRY HashLinks;      
    PVOID SectionPointer;      
    DWORD CheckSum;      
    DWORD TimeDateStamp;      
    PVOID LoadedImports;      
    PVOID EntryPointActivationContext;      
    PVOID PatchInformation;      
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;   </div>

主要功能代码:

NTSTATUS ScanModulebypid(ULONG ulProcessId)   
{   
    //获取进程的EPROCESS结构指针   
    NTSTATUS nStatus;   
    PEPROCESSpEProcess = NULL;   
    nStatus = PsLookupProcessByProcessId((HANDLE)ulProcessId, &pEProcess);   
    if (!NT_SUCCESS(nStatus))   
    {   
      return STATUS_UNSUCCESSFUL;   
    }   

    //查找函数地址      
    UNICODE_STRING uniFunctionName;   
    RtlInitUnicodeString(&uniFunctionName, L"PsGetProcessPeb");   

    //函数指针   
    PFNPsGetProcessPebPsGetProcessPeb = NULL;   

    PsGetProcessPeb = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniFunctionName);   
    if (PsGetProcessPeb == NULL)   
    {   
      KdPrint(("Get PsGetProcessPeb Failed~!\n"));   
      return STATUS_UNSUCCESSFUL;   
    }   

    //获取PEB指针      
    PPEB pPEB = NULL;   
    pPEB = PsGetProcessPeb(pEProcess);   

    if (pPEB == NULL)   
    {   
      KdPrint(("Get pPEB Failed~!\n"));   
      return STATUS_UNSUCCESSFUL;   
    }   

    //保存APC状态APC,即Asynchronous procedure call,异步程序调用
    KAPC_STATE KAPC ={0};   
    //附加到进程   
    KeStackAttachProcess(pEProcess, &KAPC);   

    //是否已经附加到进程   
    BOOLEAN bIsAttached = FALSE;   

    bIsAttached = TRUE;   

    //指向LDR   
    //LDR数据结构   
    PPEB_LDR_DATA pPebLdrData = NULL;   
    pPebLdrData = pPEB->Ldr;   

    //链表头节点、尾节点   
    PLIST_ENTRY pListEntryStart = NULL;   
    PLIST_ENTRY pListEntryEnd = NULL;   
    //头节点、尾节点   
    pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;   


    //开始遍历_LDR_DATA_TABLE_ENTRY   
    //LDR链表入口   
    PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;   
    do      
    {      
      //通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构   

      pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);      

      //输出DLL全路径   
      KdPrint(("%wZ \n", &pLdrDataEntry->FullDllName));   

      pListEntryStart = pListEntryStart->Flink;      

    }while(pListEntryStart != pListEntryEnd);      

    KdPrint(("\n\n"));
    //Detach进程   
    if (bIsAttached != FALSE)   
    {   
      KeUnstackDetachProcess(&KAPC);   
    }   

    //减少引用计数   
    if (pEProcess != NULL)   
    {   
      ObDereferenceObject(pEProcess);   
      pEProcess = NULL;   
    }   

    return STATUS_SUCCESS;   
}   

NTSTATUS ScanProcessModule()
{
    PEPROCESS eprocess,Firsteprocess;
    ULONG ulProcessName;
    ULONG ulProcessID;

    KdPrint(("start ScanProcessModile\n"));
    //__asm int 3;
    eprocess = PsGetCurrentProcess();

    Firsteprocess = eprocess;
    if (eprocess == 0)
    {
      KdPrint(("PsGetCurrentProcess error"));
      return STATUS_SUCCESS;
    }
    while (eprocess != NULL)
    {
      ulProcessName = (ULONG)eprocess + 0x174;      //   +0x174 ImageFileName    : UChar
      ulProcessID = *(ULONG*)((ULONG)eprocess + 0x84);//   +0x084 UniqueProcessId: Ptr32 Void
      KdPrint(("processname = %s,processid = %d \r \n",ulProcessName,ulProcessID));
      //if (!strcmp( (char*)(ULONG*)ulProcessName ,"notepad.exe"))
      //{
            ScanModulebypid(ulProcessID);
      //}
         
                                                      //   +0x088 ActiveProcessLinks : _LIST_ENTRY
      eprocess = (PEPROCESS)(*(ULONG*)((ULONG)eprocess + 0x88) - 0x88);//-0x88是得到 eprocess结构

      if (eprocess == Firsteprocess || (*(LONG*)( (LONG)eprocess + 0x84) ) <0)//如果链表搜索完毕或者进程PID小于0则结束
      {
            break;
      }
    }
    return STATUS_SUCCESS;
}

删除指定进程:
方法1    卸载掉指定进程的NTDLL.dll 模块   (这里以 notepad.exe 为例子)
extern "C"
NTSTATUS   
MmUnmapViewOfSection(   
                     IN PEPROCESS Process,   
                     IN ULONG BaseAddress   
                     );   
NTSTATUS ScanProcessModule()
{
    PEPROCESS eprocess,Firsteprocess;
    ULONG ulProcessName;
    ULONG ulProcessID;

    KdPrint(("start ScanProcessModile\n"));
    //__asm int 3;
    eprocess = PsGetCurrentProcess();

    Firsteprocess = eprocess;
    if (eprocess == 0)
    {
      KdPrint(("PsGetCurrentProcess error"));
      return STATUS_SUCCESS;
    }
            PEPROCESS eprocess2;

    while (eprocess != NULL)
    {
      ulProcessName = (ULONG)eprocess + 0x174;      //   +0x174 ImageFileName    : UChar
      ulProcessID = *(ULONG*)((ULONG)eprocess + 0x84);//   +0x084 UniqueProcessId: Ptr32 Void
      KdPrint(("processname = %s,processid = %d \r \n",ulProcessName,ulProcessID));
         

      if (!strcmp( (char*)(ULONG*)ulProcessName ,"notepad.exe"))
      {
            PsLookupProcessByProcessId((HANDLE)ulProcessID,&eprocess2);
            UNICODE_STRING uniPsGetProcessPeb;
            RtlInitUnicodeString(&uniPsGetProcessPeb,L"PsGetProcessPeb");

            PFNPsGetProcessPeb PsGetProcessPebAddr = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniPsGetProcessPeb);
            if (PsGetProcessPebAddr == NULL)      
            {      
                KdPrint(("Get PsGetProcessPeb Failed~!\n"));      
                return STATUS_UNSUCCESSFUL;      
            }      
            PPEB pPEB = NULL;      
            pPEB = PsGetProcessPebAddr(eprocess2);   
            if (pPEB == NULL)      
            {      
                KdPrint(("Get pPEB Failed~!\n"));      
                return STATUS_UNSUCCESSFUL;      
            }   
            //保存APC状态APC,即Asynchronous procedure call,异步程序调用   
            KAPC_STATE KAPC ={0};      
            //附加到进程      
            KeStackAttachProcess(eprocess2, &KAPC);      

            //是否已经附加到进程      
            BOOLEAN bIsAttached = FALSE;      

            bIsAttached = TRUE;      

            //指向LDR      
            //LDR数据结构      
            PPEB_LDR_DATA pPebLdrData = NULL;      
            pPebLdrData = pPEB->Ldr;      

            //链表头节点、尾节点      
            PLIST_ENTRY pListEntryStart = NULL;      
            PLIST_ENTRY pListEntryEnd = NULL;      
            //头节点、尾节点      
            pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;      


            //开始遍历_LDR_DATA_TABLE_ENTRY      
            //LDR链表入口      
            PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;      
            do      
            {      
                //通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构      

                pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);      

                //输出DLL全路径      
                KdPrint(("%wZ \n", &pLdrDataEntry->FullDllName));      
                UNICODE_STRING uniNtdll;
                RtlInitUnicodeString(&uniNtdll,L"ntdll.dll");

                if (RtlEqualUnicodeString(&pLdrDataEntry->BaseDllName,&uniNtdll,TRUE))
                {
                  MmUnmapViewOfSection(eprocess2,(ULONG)(pLdrDataEntry->DllBase));
                  KdPrint(("卸载 ntdll.dll 完成"));   
                }
                pListEntryStart = pListEntryStart->Flink;      

            }while(pListEntryStart != pListEntryEnd);      

            //Detach进程      
            if (bIsAttached != FALSE)      
            {      
                KeUnstackDetachProcess(&KAPC);      
            }      

            //减少引用计数      
            if (eprocess2 != NULL)      
            {      
                ObDereferenceObject(eprocess2);      
                eprocess2 = NULL;      
            }      
   
      }
         
      //   +0x088 ActiveProcessLinks : _LIST_ENTRY
      eprocess = (PEPROCESS)(*(ULONG*)((ULONG)eprocess + 0x88) - 0x88);//-0x88是得到 eprocess结构

      if (eprocess == Firsteprocess || (*(LONG*)( (LONG)eprocess + 0x84) ) <0)//如果链表搜索完毕或者进程PID小于0则结束
      {
            break;
      }
    }
    return STATUS_SUCCESS;
}

页: [1]
查看完整版本: 驱动枚举所有进程所有模块,删除指定进程。