• 涨姿势系列之——内核环境下花式获得CSRSS进程id


    这个是翻别人的代码时看到的,所以叫涨姿势系列。作者写了一个获取CSRSS进程PID的函数,结果我看了好久才看懂是这么一个作用。先放上代码

     1 HANDLE GetCsrPid()
     2 {
     3     HANDLE Process, hObject;
     4     HANDLE CsrId = (HANDLE)0;
     5     OBJECT_ATTRIBUTES obj;
     6     CLIENT_ID cid;
     7     UCHAR Buff[0x100];
     8     POBJECT_NAME_INFORMATION ObjName = (PVOID)&Buff;
     9     PSYSTEM_HANDLE_INFORMATION_EX Handles;
    10     ULONG r;
    11 
    12     Handles = GetInfoTable(SystemHandleInformation);
    13 
    14     if (!Handles) return CsrId;
    15 
    16     for (r = 0; r < Handles->NumberOfHandles; r++)
    17     {
    18         if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
    19         {
    20             InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
    21 
    22             cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
    23             cid.UniqueThread = 0;
    24 
    25             if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
    26             {
    27                 if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information[r].Handle,NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS)))
    28                 {
    29                     if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL)))
    30                     {
    31                         if (ObjName->Name.Buffer && !wcsncmp(L"\Windows\ApiPort", ObjName->Name.Buffer, 20))
    32                         {
    33                             CsrId = (HANDLE)Handles->Information[r].ProcessId;
    34                         } 
    35                     }
    36 
    37                     ZwClose(hObject);
    38                 }
    39 
    40                 ZwClose(Process);
    41             }
    42         }
    43     }
    44 
    45     ExFreePool(Handles);
    46     return CsrId;
    47 }

    作者干了以下这几件事:执行ZwQuerySystemInfo函数的第16号功能,这个第16号功能就是SystemHandleInformation,作用是获取句柄表。之前没用过这个功能号,MSDN上的页面也找不到了,找不到页面大概是因为这个函数现在已经不被支持了吧(Win8)。搜了半天找到了这个功能的结构

    typedef struct _SYSTEM_HANDLE_INFORMATION_EX 
    {
    ULONG NumberOfHandles;
    SYSTEM_HANDLE_INFORMATION Information[1];
    }SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
    typedef struct _SYSTEM_HANDLE_INFORMATION 
    {
    ULONG ProcessId;
    UCHAR ObjectTypeNumber;
    UCHAR Flags;
    USHORT Handle;
    PVOID Object;
    ACCESS_MASK GrantedAccess;
    }SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

    就是说每个句柄项都被解释成

    • 句柄所属进程的PID
    • 句柄对应对象的类型
    • 句柄值(数字)
    • 句柄对应的对象指针

    这个函数查到句柄后,匹配所有的port对象的句柄。然后把这些句柄dump到本进程(因为只有这样才可以操作句柄),用ZwQueryObject查询port对象的名称,匹配\Windows\ApiPort,而这个port对象正是csrss进程创建的,也就说只有csrss进程的句柄表中才会有这个句柄,这样就实现了查找的csrss进程的目的。

    其实我觉得不需要把句柄复制到自己的进程中了,因为已经有对象的指针了,可以直接获取对象名了。这个做法对我来说比较新鲜,即用句柄来查找进程。

  • 相关阅读:
    SQL语句编写
    触发器
    plot函数中的type中的参数
    【转】R中read.table详解
    7月18日R笔记
    RMySQL在windows下的安装方法
    WinXP下面实现JAVA对R调用 (rJava包设置)
    用R进行文档层次聚类完整实例(tm包)
    R学习之R层次聚类方法(tm包)
    R对term进行层次聚类完整实例(tm包)
  • 原文地址:https://www.cnblogs.com/Ox9A82/p/5553253.html
Copyright © 2020-2023  润新知