本论坛为只读模式,仅供查阅,不能注册新用户,不能发帖/回帖,有问题可发邮件 xikug.xp (^) gmail.com
查看: 6307|回复: 16

垃圾进程管理器 [复制链接]

Rank: 2

发表于 2009-8-1 19:06:18 |显示全部楼层
首先是获取系统中存在的进程,用Native API实现的话就是ZwQuerySystemInformation,使用它的SystemProcessesAndThreadsInformation功能获取相应信息,大致的形式如下:
ULONG n = 0x100;
PSYSTEM_PROCESSES sp = new SYSTEM_PROCESSES[n];
while(MySecZwQuerySystemInformation(
SystemProcessesAndThreadsInformation,
sp, n * sizeof(SYSTEM_PROCESSES), 0)
== STATUS_INFO_LENGTH_MISMATCH)
{
delete [] sp;
n=n*2;
sp = new SYSTEM_PROCESSES[n];
}
具体的遍历方法看代码。

下面就是获取相应进程中的模块信息。
我使用的方法是RtlQueryProcessDebugInformation,这个函数声明如下:
NTSTATUS
NTAPI
RtlQueryProcessDebugInformation(
IN ULONG ProcessId,
IN ULONG DebugInfoClassMask,
IN OUT PDEBUG_BUFFER DebugBuffer
);
ProcessId是要察看的相应进程的PID,DebugInfoClassMask是要察看的信息类型,DebugBuffer返回相应信息。
DebugInfoClassMask的取值如下:
PDI_MODULES 0x01 // The loaded modules of the process
PDI_BACKTRACE 0x02 // The heap stack back traces
PDI_HEAPS 0x04 // The heaps of the process
PDI_HEAP_TAGS 0x08 // The heap tags
PDI_HEAP_BLOCKS 0x10 // The heap blocks
PDI_LOCKS 0x20 // The locks created by the process
我们要用到的是第一个PDI_MODULES 0x01,相应的数据结构如下:
typedef struct _DEBUG_BUFFER {
HANDLE SectionHandle;
PVOID SectionBase;
PVOID RemoteSectionBase;
ULONG SectionBaseDelta;
HANDLE EventPairHandle;
ULONG Unknown[2];
HANDLE RemoteThreadHandle;
ULONG InfoClassMask;
ULONG SizeOfInfo;
ULONG AllocatedSize;
ULONG SectionSize;
PVOID ModuleInformation;
PVOID BackTraceInformation;
PVOID HeapInformation;
PVOID LockInformation;
PVOID Reserved[8];
} DEBUG_BUFFER, *PDEBUG_BUFFER;
其中ModuleInformation就是是我们需要的模块信息指针,此指针的第一个ULONG代表DEBUG_MODULE_INFORMATION的个数:
typedef struct _DEBUG_MODULE_INFORMATION { // c.f. SYSTEM_MODULE_INFORMATION
ULONG Reserved[2];
ULONG Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} DEBUG_MODULE_INFORMATION, *PDEBUG_MODULE_INFORMATION;
CHAR ImageName[256]就是我们要的了。

还会用到
PDEBUG_BUFFER
NTAPI
RtlCreateQueryDebugBuffer(
IN ULONG Size,
IN BOOLEAN EventPair
);
给我们分配一个DEBUG_BUFFER的内存空间。

下面是获取进程中的句柄信息。
我使用的方法是ZwQuerySystemInformation的SystemHandleInformation功能+ ZwQueryObject。
我们先用ZwQuerySystemInformation的SystemHandleInformation功能获取系统中所有的句柄信息
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
通过比较ProcessId获取需要的进程句柄,其中Handle是句柄值,Object是句柄所对应的对象地址。
在获得进程所有句柄之后,我们不能直接操作它,除非是本进程的句柄,所以我们还要ZwDuplicateObject复制一个句柄到本进程然后操作之。(我自己用的时候发现只有一个句柄不能Duplicate过来,是LSASS进程中的,不清楚是什么原因,望大牛解释。)
之后就是得到相应对象信息了。ZwQueryObject的ObjectBasicInformation功能得到一些基本信息,下面会用到,ZwQueryObject的ObjectTypeInformation功能得到对象的类型,ZwQueryObject的ObjectNameInformation功能得到对象名字,还有其他很多功能可以察看Native API一书。
上面基本得到了需要的句柄信息,不过我在调试的过程中发现一个问题:当察看服务进程的句柄信息时,整个应用程序就没有响应了。后来查了资料,原来在RING3下用ZwQueryObject获取对象名字信息也就是ObjectNameInformation时,如果对象是一个命名管道,并且已经被以同步的方式打开的话,发起ZwQueryObject的整个进程就会挂起,也就是出现没有响应的情况。但是如果在RING0下使用ZwQueryObject,就不会出现这种情况,所以我的解决方法是碰到File类型的对象就用驱动去取得名字,命名管道的对象一般都是File类型的。
另外还有关闭句柄的方法,就是ZwDuplicateObject将相应句柄以DUPLICATE_CLOSE_SOURCE的方式复制过来,然后CLOSE就能关闭相应句柄。
还有一种方法可以获取句柄信息,就是ZwQuerySystemInformation的SystemHandleInformation功能+SystemObjectInformation功能。不过这种方法有限制,就是必须在系统启动时NtGlobalFlag 的FLG_MAINTAIN_OBJECT_TYPELIST位必须置1,我在我电脑上没有取得成功。


下面是获取相应的进程信息。
上面讲了通过ZwQuerySystemInformation的SystemProcessesAndThreadsInformation获得进程信息,其中还可以获取每个进程中每个线程的信息
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;
THREAD_STATE State;
KWAIT_REASON WaitReason;
ULONG Reversed;
} SYSTEM_THREADS, *PSYSTEM_THREADS;

typedef struct _SYSTEM_PROCESSES {
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[3];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
SYSTEM_THREADS Threads[1];
} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
SYSTEM_THREADS中的几乎我都添到了线程信息当中。
进程信息我用ZwQueryInformationProcess获取:
ProcessBasicInformation功能获取基本信息,比如优先级之类的;
ProcessTimes功能获取进程时间信息,比如内核运行时间,用户态运行时间;
ProcessVmCounters功能获取内存信息,比如工作集,虚拟内存大小,缺页次数;
ProcessIoCounters获取IO信息,比如读写次数,大小;
ProcessHandleCount获取句柄个数;

另外用GetGuiResources可以获取进程中GDI Handle和User Handle的个数。


下面获取系统信息。
依然是用ZwQuerySystemInformation,只不过这次主角换成了SystemBasicInformation和SystemPerformanceInformation。其中SystemBasicInformation:
typedef struct _SYSTEM_BASIC_INFORMATION {
ULONG Unknown;
ULONG MaximumIncrement;
ULONG PhysicalPageSize;
ULONG NumberOfPhysicalPages;
ULONG LowestPhysicalPage;
ULONG HighestPhysicalPage;
ULONG AllocationGranularity;
ULONG LowestUserAddress;
ULONG HighestUserAddress;
ULONG ActiveProcessors;
UCHAR NumberProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
我们用到其中的PhysicalPageSize得到没页的大小,NumberProcessors得到系统中的CPU个数,NumberOfPhysicalPages得到物理页的个数,所以NumberOfPhysicalPages*PhysicalPageSize就是物理内存大小。

SYSTEM_PERFORMANCE_INFORMATION太长就不贴了,从中我们可以获得可用物理内存大小,系统缓存大小,内核内存的情况,线程切换的情况,I/O的情况,分页的情况等等,具体可以看代码,或者自己看结构添加自己需要的信息。
最后说下CPU利用率的计算方法:
CPU利用率就是某一个时间间隔内,CPU工作的时间占总时间的比例。
首先我们要确定一个时间间隔。我们使用ZwQuerySystemInformation的SystemTimeOfDayInformation获取当前系统时间,并且在前一个纪录点也纪录下那时的系统时间,相减即得。
然后我们可以用ZwQuerySystemInformation的SystemPerformanceInformation功能得到CPU的空闲时间,然后除以时间间隔即可得到CPU的空闲率,相应的CPU利用率也就出来了,相应代码如下:
  1. #define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
  2. SYSTEM_TIME_OF_DAY_INFORMATION stdi;
  3. NTSTATUS status;
  4. double num;
  5. status=MyZwQuerySystemInformation(SystemTimeOfDayInformation,&stdi,sizeof(SYSTEM_TIME_OF_DAY_INFORMATION),0);
  6. if(!NT_SUCCESS(status))
  7. {
  8. AfxMessageBox(L"获取SystemTimeOfDayInformation失败!");
  9. return;
  10. }
  11. SYSTEM_PERFORMANCE_INFORMATION spi;
  12. status=MyZwQuerySystemInformation(SystemPerformanceInformation,&spi,sizeof(SYSTEM_PERFORMANCE_INFORMATION),0);
  13. if(!NT_SUCCESS(status))
  14. {
  15. AfxMessageBox(L"获取SystemPerformanceInformation失败!");
  16. return;
  17. }
  18. if(preIdleTime.QuadPart!=0)
  19. {
  20. IdleTime=Li2Double(spi.IdleTime) - Li2Double(preIdleTime);
  21. SysTime=Li2Double(stdi.CurrentTime) - Li2Double(preSysTime);
  22. IdleTime=IdleTime/SysTime;
  23. num=(double)numOfprocessor;
  24. IdleTime=100.0 - (IdleTime * 100.0)/num + 0.5;
  25. }
  26. preIdleTime=spi.IdleTime;
  27. preSysTime=stdi.CurrentTime;
复制代码


驱动大家用工具先加载好。

MyProcessExplorer.rar

61 KB, 下载次数: 534

ProcessExp.rar

17 KB, 下载次数: 759

Rank: 5Rank: 5

发表于 2009-8-1 19:35:20 |显示全部楼层
这个差太远了! 没一点意思。
你这是在侮辱Process Explorer这个伟大的工具。
发代码可以,拜托不要写着你是什么第三弹ProcessExplorer,

还主要功能都已实现?自己看看Process Explorer里的进程详细信息吧,看看选择列吧。太扯了。这次不扣分都对不起Mark同学

Rank: 1

发表于 2009-8-1 20:03:30 |显示全部楼层
我觉得行,分析也好。应加分

Rank: 3Rank: 3

发表于 2009-8-1 20:15:59 |显示全部楼层
经得起mj骂的男人才是第8个男人
该用户已被删除
发表于 2009-8-1 20:17:02 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
该用户已被删除
发表于 2009-8-1 20:18:54 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

Rank: 9Rank: 9Rank: 9

发表于 2009-8-1 20:49:27 |显示全部楼层
不够深入。。。
悟空,退下,为师一个人就够了

Rank: 5Rank: 5

发表于 2009-8-1 20:53:37 |显示全部楼层
楼主好好看看ProcessExplorer有哪些功能再搞标题党好不~
该用户已被删除
发表于 2009-8-1 21:29:44 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

Rank: 4

发表于 2009-8-1 22:15:36 |显示全部楼层
引用第7楼killvxk于2009-08-01 17:53发表的  :
楼主好好看看ProcessExplorer有哪些功能再搞标题党好不~

同上.

Rank: 2

发表于 2009-8-2 02:35:57 |显示全部楼层
进程信息选择列中可以选择的:
Process Image:
基本上都没做,ImagePath可以在模块信息里面看到

Process Performance:
所有的都可以在进程信息中查看,StartTime我懒得算就没做

ProcessMemory:
大部分都可以在进程信息中看到,有一些比如WS Shareable Bytes,我不知道怎么获取,所以没做

HANDLE:
AccessMask,FileShareFlags没做,其他都有

DLL:
除了Name,Path其他都没做

.Net:
全都没做

StatusBar:
左边的除了Number.NetProcesses不会,其他都可以在系统信息中看到,右边的没懂是什么意思。

还有一些关闭进程的,关闭句柄,关线程,暂停线程的没有加进去
作图我不会,没有作
进程信息中的关于安全的都没做
环境变量的我都没做
进程中的字符串没有做
界面也是奇丑无比

大概就这些了,大家觉得没意义的话,这贴就废了吧,反正我自己也觉得完成度是差很多

Rank: 4

发表于 2009-8-2 11:22:57 |显示全部楼层
大牛太多,标准自然也要高啊,楼主加油

Rank: 2

发表于 2009-8-2 11:23:36 |显示全部楼层
围观,扣分

Rank: 1

发表于 2009-8-3 12:21:01 |显示全部楼层
围观楼主被爆K

Rank: 1

发表于 2009-8-5 12:20:51 |显示全部楼层
看样子,发帖在首行得加一句:“牛们飘过~”。

Rank: 1

发表于 2009-8-9 06:31:53 |显示全部楼层
不明真相的围观群众来也...

Rank: 1

发表于 2010-3-17 11:54:50 |显示全部楼层
感谢国家...给了我这次发言机会...虽然比不上Process.但也是自己分析 的
您需要登录后才可以回帖 登录 | 立即加入

Archiver|手机版|第8个男人 - 论坛为只读模式,仅供查阅

GMT+8, 2019-6-16 11:52 , Processed in 0.031482 second(s), 11 queries .

Design by pvo.cn

© 2011 Pvo Inc.

回顶部