【旧文章搬运】ZwQuerySystemInformation枚举进线程信息

原文发表于百度空间,2008-10-15
==========================================================================

很古老的东西了,写一写,权当练手吧.
本来以为没什么难度,很科普很傻瓜的东西,但是写的时候还是遇到一些问题,进程信息正确,得到的线程信息总是不正确,后来分析了一下,发现这个ntdll sdk中定义的进程信息结构和线程信息结构都有点问题,可能它是来自《Win2000 Native API》一书,不适用于Windows XP。后来参考WRK修正了一下。线程信息结构也有问题,和WRK中的一样,但是结果仍然不正确,简单分析了一下,得出结构大小应为0x40,最终还是修正了一下,才有正确结果。
最终确定的进程结构如下:

typedef struct _SYSTEM_PROCESSES {
ULONG NextEntryDelta;
ULONG ThreadCount;
LARGE_INTEGER Reserved1[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR PageDirectoryBase;
VM_COUNTERS VmCounters;
ULONG PrivatePageCount;// add by achillis
IO_COUNTERS IoCounters;
SYSTEM_THREADS Threads[1];
} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;

线程信息结构如下:

typedef struct _SYSTEM_THREADS{
    LARGE_INTEGER KernelTime;
    LARGE_INTEGER UserTime;
    LARGE_INTEGER CreateTime;
    ULONG WaitTime;
    PVOID StartAddress;
    CLIENT_ID ClientId;
    KPRIORITY Priority;
    LONG BasePriority;
    ULONG ContextSwitches;
    ULONG ThreadState;
    ULONG WaitReason;
    ULONG Reversed;//add by achillis
} SYSTEM_THREAD_INFORMATION,*PSYSTEM_THREADS;

红色部分是我增加的,也不知道到底对不对,但是目前为止在我的XP SP2上可以得到正确结果。
枚举进程和线程信息的代码如下:

int ShowProcess(void)
{
NTSTATUS status;
DWORD retlen,truelen;
char *buf=NULL,*p=NULL;
ANSI_STRING ansiStr;
int cnt=0;
PSYSTEM_PROCESSES pSysProcess;
PSYSTEM_THREADS pSysThread;
status=ZwQuerySystemInformation(SystemProcessInformation,NULL,0,&retlen);
truelen=retlen;
status=ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&buf,0,&retlen,MEM_COMMIT,PAGE_READWRITE);
printf("Size of SYSTEM_THREAD:%d\n",sizeof(SYSTEM_THREADS));
p=buf;
status=ZwQuerySystemInformation(SystemProcessInformation,buf,truelen,&retlen);
do
{
   cnt++;
   pSysProcess=(PSYSTEM_PROCESSES)buf;
   RtlUnicodeStringToAnsiString(&ansiStr,&pSysProcess->ProcessName,TRUE);
   printf("Name:%s\n",ansiStr.Buffer);
   RtlFreeAnsiString(&ansiStr);
   printf("ThreadCnt:%d\t",pSysProcess->ThreadCount);
   printf("Priority:%d\t",pSysProcess->BasePriority);
   printf("PID:%4d\t",pSysProcess->ProcessId);
   printf("PPID:%d\n",pSysProcess->InheritedFromProcessId);
   printf("HandleCnt:%d\n",pSysProcess->HandleCount);
   //在每一项SYSTEM_PROCESS结构的最后是一个接一个的SYSTEM_THREAD结构
   //输出每个线程的信息
   if (pSysProcess->ThreadCount&&pSysProcess->ProcessId)
   {
    DWORD i=0;
    pSysThread=pSysProcess->Threads;
    for (;i<pSysProcess->ThreadCount;i++)
    {
     printf("Thread[%d] StartAddr:0x%08x\t",i+1,pSysThread->StartAddress);
     printf("TID:%d\t",pSysThread->ClientId.UniqueThread);
     printf("SwitchCnt:%d\n",pSysThread->ContextSwitchCount);
     pSysThread++;
    }
   }
   //若NextEntryDelta为0,则表明已结束
   if (pSysProcess->NextEntryDelta==0)
   {
    break;
   }
   buf=buf+pSysProcess->NextEntryDelta;
   printf("===============================================================\n");
}while (1);
printf("Total:%d\n",cnt);
status=ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&p,&truelen,MEM_RELEASE);
return 0;
}

写到这儿又想起了经典的Hook ZwQuerySystemInfoamation隐藏进程,其实SYSTEM_PROCESS结构中的NextEntryDelta作为指向下一个结构的偏移量,其作用类似于指针,使整体构成了一个单链表,要隐藏就是从链表中删除一个元素而已,简单的数据结构知识,呵呵~

原文地址:https://www.cnblogs.com/achillis/p/10180184.html

时间: 2024-10-04 21:08:10

【旧文章搬运】ZwQuerySystemInformation枚举进线程信息的相关文章

【旧文章搬运】炉子给的SYSTEM_HANDLE_TYPE有点错误

原文发表于百度空间,2008-12-03========================================================================== 今天写程序,用ZwQuerySystemInformation枚举系统中的文件句柄时出了问题,死活一个都找不到,可是这明显不可能啊?于是用Process Explorer随便找了个文件句柄对象,然后看了它的OBJECT_TYPE,才发现文件句柄的类型索引应为28,而我用的是炉子给的那个SYSTEM_HANDL

【旧文章搬运】ZwQuerySystemInformation枚举内核模块及简单应用

原文发表于百度空间,2008-10-24========================================================================== 简单说,即调用第11号功能,枚举一下内核中已加载的模块.部分代码如下://功能号为11,先获取所需的缓冲区大小ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&needlen);//申请内存ZwAllocateVirtualMemory(NtCu

【旧文章搬运】获取并修改PEB中的映像路径,命令行和当前目录

原文发表于百度空间,2008-7-24 当时对UNICODE_STRING的使用还有点问题,导致最终效果图中字符串被截断了========================================================================== 先从分析PEB开始吧.感觉分析这个东西,首先要把类型定义搞清楚,这个在Windbg里dt _PEB就可以了搞清楚定义主要是为了定位相关变量的偏移.PEB中的ProcessParameters部分就是进程的参数了,里面就有我们感兴

【旧文章搬运】Idle进程相关的一些东西

原文发表于百度空间,2009-05-13========================================================================== Idle进程和System进程一样,也是系统中的一个特殊进程,严格讲它不算是一个进程,但是它有自己的EPROCESS,并有一个IdleThread.若说它算一个进程,它的进程空间.句柄表.Token等却又和System进程一样,即共享了System的内核数据,所以不能以常理对待之.关于Idle进程的两个问题:

【旧文章搬运】遍历EPROCESS中的ActiveProcessLinks枚举进程

原文发表于百度空间,2008-7-25========================================================================== 前面对PEB的相关结构和其中的重要成员进行了分析和学习,现在开始真正进入内核,学习内核中的一些结构.这个EPROCESS结构在ntddk.h中有定义,但是并未给出具体的结构,因此要得到EPROCESS中一些重要的成员变量,只能通过偏移的方法,比如PID,ImageName等.这些偏移可以在Windbg中dt _

【旧文章搬运】分析了一下360安全卫士的HOOK

原文发表于百度空间及看雪论坛,2009-10-08 看雪论坛地址:https://bbs.pediy.com/thread-99128.htm 看时间,09年的国庆节基本上就搞这玩意儿了...========================================================================== 分析了一下360的HOOK,通过直接hook KiFastCallEntry实现对所有系统调用的过滤. 我分析的版本如下:主程序版本: 6.0.1.1003H

【旧文章搬运】Windows中全局钩子DLL的加载过程

原文发表于百度空间,2011-03-24========================================================================== 看雪上别人问的一个问题,顺便在此记录下吧~~ kd> kvn # ChildEBP RetAddr Args to Child 00 0012f7b8 77d2dbfb 0012f81c 00000000 00000008 kernel32!LoadLibraryExW+0x2 (FPO: [Non-Fpo]

.NET获取枚举DescriptionAttribute描述信息性能改进的多种方法

一. DescriptionAttribute的普通使用方式 1.1 使用示例 DescriptionAttribute特性可以用到很多地方,比较常见的就是枚举,通过获取枚举上定义的描述信息在UI上显示,一个简单的枚举定义: public enum EnumGender { None, [System.ComponentModel.Description("男")] Male, [System.ComponentModel.Description("女")] Fem

使用自动化shell脚本查找CPU使用的详细线程信息

项目加了些拦截器代码后,CPU报警,显示CPU使用率超过100%: 想要查找到底是哪些代码消耗的资源过多,从网上找到一篇博文,转载如下: http://blog.csdn.net/guixunlong/article/details/8450897 在知道哪个Java进程CPU占用率过高以后: 1.使用命令 jstack PID 命令打印出CPU占用过高进程的线程栈,例如jstack 12012 > 12012.txt 2.使用top -H -p PID 命令查看对应进程是哪个线程占用CPU过高