📄 procinfo.c
字号:
#define _X86_
#include "ntddk.h"
#include <stdio.h>
#include <stdlib.h>
#include "undocnt.h"
HANDLE ghProcess;
BOOLEAN EnableOrDisablePrivilege(ULONG PrivilegeId, BOOLEAN bDisable)
{
HANDLE hToken;
TOKEN_PRIVILEGES PrivilegeSet;
NTSTATUS rc;
rc=NtOpenProcessToken(NtCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken);
if (rc!=STATUS_SUCCESS) {
printf("NtOpenProcessToken failed, rc=%x\n", rc);
return FALSE;
}
memset(&PrivilegeSet, 0, sizeof(PrivilegeSet));
PrivilegeSet.PrivilegeCount=1;
PrivilegeSet.Privileges[0].Luid=RtlConvertUlongToLuid(PrivilegeId);
PrivilegeSet.Privileges[0].Attributes = bDisable?0:SE_PRIVILEGE_ENABLED;
rc=NtAdjustPrivilegesToken(hToken,
FALSE,
&PrivilegeSet,
0,
NULL,
NULL);
NtClose(hToken);
if (rc!=STATUS_SUCCESS) {
printf("NtAdjustPrivilegesToken failed, rc=%x\n", rc);
return FALSE;
}
return TRUE;
}
void DumpBasicInformation()
{
/* No set method for this information class */
PROCESS_BASIC_INFORMATION ProcessBasicInfo;
NTSTATUS rc;
rc=NtQueryInformationProcess(ghProcess,
ProcessBasicInformation,
&ProcessBasicInfo,
sizeof(ProcessBasicInfo),
NULL);
if (rc==STATUS_SUCCESS) {
printf("ProcessBasicInfo.ExitStatus = %x\n", ProcessBasicInfo.ExitStatus);
printf("ProcessBasicInfo.PebBaseAddress = %x\n", ProcessBasicInfo.PebBaseAddress);
printf("ProcessBasicInfo.AffinityMask = %x\n", ProcessBasicInfo.AffinityMask);
printf("ProcessBasicInfo.BasePriority = %x\n", ProcessBasicInfo.BasePriority);
printf("ProcessBasicInfo.UniqueProcessId = %x\n", ProcessBasicInfo.UniqueProcessId);
printf("ProcessBasicInfo.InheritedFromUniqueProcessId = %x\n", ProcessBasicInfo.InheritedFromUniqueProcessId);
} else {
printf("NtQueryInformationProcess failed with infoclass 'ProcessBasicInformation', rc=%x\n", rc);
}
}
void DumpQuotaLimitsInformation()
{
/* Both set and get method for this information class */
QUOTA_LIMITS QuotaLimitsInfo;
NTSTATUS rc;
rc=NtQueryInformationProcess(ghProcess,
ProcessQuotaLimits,
&QuotaLimitsInfo,
sizeof(QuotaLimitsInfo),
NULL);
if (rc==STATUS_SUCCESS) {
printf("QuotaLimitsInfo.PagedPoolLimit = %x\n", QuotaLimitsInfo.PagedPoolLimit);
printf("QuotaLimitsInfo.NonPagedPoolLimit = %x\n", QuotaLimitsInfo.NonPagedPoolLimit);
printf("QuotaLimitsInfo.MinimumWorkingSetSize = %x\n", QuotaLimitsInfo.MinimumWorkingSetSize);
printf("QuotaLimitsInfo.MaximumWorkingSetSize = %x\n", QuotaLimitsInfo.MaximumWorkingSetSize);
printf("QuotaLimitsInfo.PagefileLimit = %x\n", QuotaLimitsInfo.PagefileLimit);
printf("QuotaLimitsInfo.TimeLimit = %I64x\n", QuotaLimitsInfo.TimeLimit.QuadPart);
} else {
printf("NtQueryInformationProcess failed with infoclass 'ProcessQuotaLimits', rc=%x\n", rc);
}
QuotaLimitsInfo.MaximumWorkingSetSize+=4096;
rc=NtSetInformationProcess(ghProcess,
ProcessQuotaLimits,
&QuotaLimitsInfo,
sizeof(QuotaLimitsInfo));
if (rc!=STATUS_SUCCESS) {
printf("NtSetInformationProcess failed with infoclass 'ProcessQuotaLimits', rc=%x\n", rc);
return;
}
rc=NtQueryInformationProcess(ghProcess,
ProcessQuotaLimits,
&QuotaLimitsInfo,
sizeof(QuotaLimitsInfo),
NULL);
if (rc==STATUS_SUCCESS) {
printf("QuotaLimitsInfo.PagedPoolLimit = %x\n", QuotaLimitsInfo.PagedPoolLimit);
printf("QuotaLimitsInfo.NonPagedPoolLimit = %x\n", QuotaLimitsInfo.NonPagedPoolLimit);
printf("QuotaLimitsInfo.MinimumWorkingSetSize = %x\n", QuotaLimitsInfo.MinimumWorkingSetSize);
printf("QuotaLimitsInfo.MaximumWorkingSetSize = %x\n", QuotaLimitsInfo.MaximumWorkingSetSize);
printf("QuotaLimitsInfo.PagefileLimit = %x\n", QuotaLimitsInfo.PagefileLimit);
printf("QuotaLimitsInfo.TimeLimit = %I64x\n", QuotaLimitsInfo.TimeLimit.QuadPart);
} else {
printf("NtQueryInformationProcess failed with infoclass 'ProcessQuotaLimits', rc=%x\n", rc);
}
}
void DumpIoCounters()
{
/*Returns STATUS_NOT_SUPPORTED. This system service seems to be planned initially but
never implemented. System does maintain these IO counters on system wide basis but not
on per process basis*/
/* No set method for this information class */
IO_COUNTERS IoCountersInfo;
NTSTATUS rc;
rc=NtQueryInformationProcess(ghProcess,
ProcessIoCounters,
&IoCountersInfo,
sizeof(IoCountersInfo),
NULL);
if (rc==STATUS_SUCCESS) {
printf("IoCountersInfo.ReadOperationCount = %x\n", IoCountersInfo.ReadOperationCount);
printf("IoCountersInfo.WriteOperationCount = %x\n", IoCountersInfo.WriteOperationCount);
printf("IoCountersInfo.OtherOperationCount = %x\n", IoCountersInfo.OtherOperationCount);
printf("IoCountersInfo.ReadTransferCount = %I64x\n", IoCountersInfo.ReadTransferCount.QuadPart);
printf("IoCountersInfo.WriteTransferCount = %I64x\n", IoCountersInfo.WriteTransferCount.QuadPart);
printf("IoCountersInfo.OtherTransferCount = %I64x\n", IoCountersInfo.OtherTransferCount.QuadPart);
} else {
printf("NtQueryInformationProcess failed with infoclass 'ProcessIoCounters', rc=%x\n", rc);
}
}
void DumpVmCounters()
{
/* No set method for this information class */
VM_COUNTERS VmCountersInfo;
NTSTATUS rc;
rc=NtQueryInformationProcess(ghProcess,
ProcessVmCounters,
&VmCountersInfo,
sizeof(VmCountersInfo),
NULL);
if (rc==STATUS_SUCCESS) {
printf("VmCountersInfo.PeakVirtualSize = %x\n", VmCountersInfo.PeakVirtualSize);
printf("VmCountersInfo.VirtualSize = %x\n", VmCountersInfo.VirtualSize);
printf("VmCountersInfo.PageFaultCount = %x\n", VmCountersInfo.PageFaultCount);
printf("VmCountersInfo.PeakWorkingSetSize = %x\n", VmCountersInfo.PeakWorkingSetSize);
printf("VmCountersInfo.WorkingSetSize = %x\n", VmCountersInfo.WorkingSetSize);
printf("VmCountersInfo.QuotaPeakPagedPoolUsage = %x\n", VmCountersInfo.QuotaPeakPagedPoolUsage);
printf("VmCountersInfo.QuotaPagedPoolUsage = %x\n", VmCountersInfo.QuotaPagedPoolUsage);
printf("VmCountersInfo.QuotaPeakNonPagedPoolUsage = %x\n", VmCountersInfo.QuotaPeakNonPagedPoolUsage);
printf("VmCountersInfo.QuotaNonPagedPoolUsage = %x\n", VmCountersInfo.QuotaNonPagedPoolUsage);
printf("VmCountersInfo.PagefileUsage = %x\n", VmCountersInfo.PagefileUsage);
printf("VmCountersInfo.PeakPagefileUsage = %x\n", VmCountersInfo.PeakPagefileUsage);
} else {
printf("NtQueryInformationProcess failed with infoclass 'ProcessVmCounters', rc=%x\n", rc);
}
}
void DumpProcessTimes()
{
/* No set method for this information class */
KERNEL_USER_TIMES KernelUserTimesInfo;
NTSTATUS rc;
LARGE_INTEGER LocalTime;
rc=NtQueryInformationProcess(ghProcess,
ProcessTimes,
&KernelUserTimesInfo,
sizeof(KernelUserTimesInfo),
NULL);
if (rc==STATUS_SUCCESS) {
TIME_FIELDS TimeFields;
printf("KernelUserTimesInfo.CreateTime = %I64x ", KernelUserTimesInfo.CreateTime.QuadPart);
RtlSystemTimeToLocalTime(&KernelUserTimesInfo.CreateTime, &LocalTime);
RtlTimeToTimeFields(&LocalTime, &TimeFields);
printf("%02d-%02d-%04d, %02d-%02d-%02d\n", TimeFields.Day, TimeFields.Month, TimeFields.Year,
TimeFields.Hour, TimeFields.Minute, TimeFields.Second);
printf("KernelUserTimesInfo.ExitTime = %I64x\n", KernelUserTimesInfo.ExitTime.QuadPart);
printf("KernelUserTimesInfo.KernelTime = %I64x\n", KernelUserTimesInfo.KernelTime.QuadPart);
printf("KernelUserTimesInfo.UserTime = %I64x\n", KernelUserTimesInfo.UserTime.QuadPart);
} else {
printf("NtQueryInformationProcess failed with infoclass 'ProcessTimes', rc=%x\n", rc);
}
}
void DumpBasePriority()
{
/* No get method for this information class */
BASEPRIORITYINFO BasePriorityInfoBuffer;
NTSTATUS rc;
if (!EnableOrDisablePrivilege(SE_INC_BASE_PRIORITY_PRIVILEGE, FALSE)) {
printf("Unable to enable SE_SYSTEMTIME_PRIVILEGE\n");
return;
}
BasePriorityInfoBuffer.BasePriority=LOW_PRIORITY;
rc=NtSetInformationProcess(ghProcess,
ProcessBasePriority,
&BasePriorityInfoBuffer,
sizeof(BasePriorityInfoBuffer));
EnableOrDisablePrivilege(SE_INC_BASE_PRIORITY_PRIVILEGE, TRUE);
if (rc==STATUS_SUCCESS) {
printf("Base Priority set to %x\n", BasePriorityInfoBuffer.BasePriority);
} else {
printf("NtSetInformationProcess failed with infoclass 'ProcessBasePriority', rc=%x\n", rc);
}
}
void DumpRaisePriority()
{
/* No get method for this information class */
RAISEPRIORITYINFO RaisePriorityInfoBuffer;
NTSTATUS rc;
RaisePriorityInfoBuffer.RaisePriority=1;
rc=NtSetInformationProcess(ghProcess,
ProcessRaisePriority,
&RaisePriorityInfoBuffer,
sizeof(RaisePriorityInfoBuffer));
if (rc==STATUS_SUCCESS) {
printf("Priority raised by 1\n");
} else {
printf("NtSetInformationProcess failed with infoclass 'ProcessRaisePriority', rc=%x\n", rc);
}
}
void DumpDebugPort()
{
/* Returns 0 as the debug port if the application is not being debugged and returns
0xFFFFFFFF as the debug port if the application is being debugged */
/* The set method work, however one needs to add the code which can listen on the
debug port and follow the debugging protocol. Otherwise, the process hangs, since
nobody is ready to listen and follow the protocol. Hence the demostration is not
given */
DEBUGPORTINFO DebugPortInfoBuffer;
NTSTATUS rc;
rc=NtQueryInformationProcess(ghProcess,
ProcessDebugPort,
&DebugPortInfoBuffer,
sizeof(DebugPortInfoBuffer),
NULL);
if (rc==STATUS_SUCCESS) {
printf("DebugPortInfoBuffer.hDebugPort = %x\n", DebugPortInfoBuffer.hDebugPort);
} else {
printf("NtQueryInformationProcess failed with infoclass 'ProcessDebugPort', rc=%x\n", rc);
}
}
void DumpExceptionPort()
{
/* The following code fails with STATUS_PORT_ALREADY_SET error, because
CSRSS calls this service to set the exception port for each process. It
is not possible to call it more than once. Although, the follwing code
will work for native applications, one needs to write code to listen
on the port and follow the hard error protocol followed by CSRSS */
EXCEPTIONPORTINFO ExceptionPortInfoBuffer;
NTSTATUS rc;
OBJECT_ATTRIBUTES ObjectAttr;
UNICODE_STRING uPortName;
HANDLE hPort;
RtlInitUnicodeString(&uPortName, L"\\MyPort");
InitializeObjectAttributes(&ObjectAttr, &uPortName, OBJ_CASE_INSENSITIVE, NULL, NULL);
rc=NtCreatePort(&hPort, &ObjectAttr, 0x0, 0x0, 0x00000);
if (rc!=STATUS_SUCCESS) {
printf("NtCreatePort failed, rc=%x\n", rc);
return;
}
ExceptionPortInfoBuffer.hExceptionPort=hPort;
rc=NtSetInformationProcess(ghProcess,
ProcessExceptionPort,
&ExceptionPortInfoBuffer,
sizeof(ExceptionPortInfoBuffer));
if (rc==STATUS_SUCCESS) {
printf("ExceptionPortInfoBuffer.hExceptionPort = %x\n", ExceptionPortInfoBuffer.hExceptionPort);
} else {
printf("NtSetInformationProcess failed with infoclass 'ProcessExceptionPort', rc=%x\n", rc);
}
}
void DumpAccessToken()
{
/* No get method for this information class */
/* Following code fails with an error code STATUS_TOKEN_ALREADY_IN_USE, because this token
is already set for the process, the code will work if some other token is specified */
PROCESS_ACCESS_TOKEN ProcessAccessTokenInfoBuffer;
HANDLE hToken;
NTSTATUS rc;
rc=NtOpenProcessToken(NtCurrentProcess(),
TOKEN_ALL_ACCESS,
&hToken);
if (rc!=STATUS_SUCCESS) {
printf("NtOpenProcessToken failed, rc=%x\n", rc);
return;
}
ProcessAccessTokenInfoBuffer.Token=hToken;
ProcessAccessTokenInfoBuffer.Thread=NtCurrentThread();
if (!EnableOrDisablePrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, FALSE)) {
printf("Unable to get SE_ASSIGNPRIMARYTOKEN_PRIVILEGE privilege\n");
return;
}
rc=NtSetInformationProcess(ghProcess,
ProcessAccessToken,
&ProcessAccessTokenInfoBuffer,
sizeof(ProcessAccessTokenInfoBuffer));
EnableOrDisablePrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE);
if (rc==STATUS_SUCCESS) {
printf("Process access token set\n");
} else {
printf("NtSetInformationProcess failed with infoclass 'ProcessAccessToken', rc=%x\n", rc);
}
}
BOOLEAN IsLDTPresent()
{
PPROCESS_LDT_INFORMATION pProcessLdtInfo;
NTSTATUS rc;
char Buffer[LDT_TABLE_SIZE + sizeof(PROCESS_LDT_INFORMATION) - sizeof(LDT_ENTRY)];
pProcessLdtInfo=(PPROCESS_LDT_INFORMATION)Buffer;
pProcessLdtInfo->Start=0;
pProcessLdtInfo->Length=LDT_TABLE_SIZE;
rc=NtQueryInformationProcess(ghProcess,
ProcessLdtInformation,
Buffer,
sizeof(Buffer),
NULL);
if (rc==STATUS_SUCCESS) {
if (pProcessLdtInfo->Length==0) {
return FALSE;
} else {
return TRUE;
}
} else {
return FALSE;
}
}
void DumpLdtInformation()
{
NTSTATUS rc;
PPROCESS_LDT_INFORMATION pProcessLdtInfo;
char Buffer[LDT_TABLE_SIZE + sizeof(PROCESS_LDT_INFORMATION) - sizeof(LDT_ENTRY)];
printf("IsLDTPresent()=%x\n", IsLDTPresent());
if (!IsLDTPresent()) {
printf("Setting LDT\n");
pProcessLdtInfo=(PPROCESS_LDT_INFORMATION)Buffer;
memset(Buffer, 0, sizeof(Buffer));
pProcessLdtInfo->Start=0;
pProcessLdtInfo->Length=16;
rc=NtSetInformationProcess(ghProcess,
ProcessLdtInformation,
Buffer,
sizeof(Buffer));
if (rc!=STATUS_SUCCESS) {
printf("NtSetInformationProcess failed, rc=%x\n", rc);
return;
}
} else {
printf("LDT already present\n");
}
pProcessLdtInfo=(PPROCESS_LDT_INFORMATION)Buffer;
pProcessLdtInfo->Start=0;
pProcessLdtInfo->Length=LDT_TABLE_SIZE;
rc=NtQueryInformationProcess(ghProcess,
ProcessLdtInformation,
Buffer,
sizeof(Buffer),
NULL);
if (rc==STATUS_SUCCESS) {
ULONG nLdtEntries;
ULONG i;
nLdtEntries=pProcessLdtInfo->Length/sizeof(LDT_ENTRY);
printf("%d entries found in LDT\n", nLdtEntries);
for (i=0; i<nLdtEntries; i++) {
ULONG Base;
ULONG Limit;
ULONG Selector;
Base=((ULONG)pProcessLdtInfo->LdtEntries[i].HighWord.Bits.BaseHi)<<24;
Base|=((ULONG)pProcessLdtInfo->LdtEntries[i].HighWord.Bits.BaseMid)<<16;
Base|=((ULONG)pProcessLdtInfo->LdtEntries[i].BaseLow);
Limit=((ULONG)pProcessLdtInfo->LdtEntries[i].HighWord.Bits.LimitHi)<<16;
Limit|=((ULONG)pProcessLdtInfo->LdtEntries[i].LimitLow);
Selector=i<<3;
Selector|=4;
Selector|=((ULONG)pProcessLdtInfo->LdtEntries[i].HighWord.Bits.Dpl);
printf("Selector %x, Base =%x, Limit=%x\n", Selector, Base, Limit);
}
} else {
printf("NtQueryInformationProcess failed with infoclass 'ProcessLdtInformation', rc=%x\n", rc);
}
}
void DumpLdtSizeInformation()
{
/* No get method for this information class */
/* LDT Size can only be reduced, it can not be increased */
PROCESS_LDT_SIZE ProcessLdtSizeInfo;
NTSTATUS rc;
ProcessLdtSizeInfo.Length=8;
rc=NtSetInformationProcess(ghProcess,
ProcessLdtSize,
&ProcessLdtSizeInfo,
sizeof(ProcessLdtSizeInfo));
if (rc==STATUS_SUCCESS) {
printf("LDT size set to %x\n", ProcessLdtSizeInfo.Length);
} else {
printf("NtSetInformationProcess failed with infoclass 'ProcessLdtSize', rc=%x\n", rc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -