Winapi ZWQuerySystem信息工作不正常
我尝试使用内核模式驱动程序FindProcessidByName,有时ImageName.Buffer变为NULL,因此,当ImageName.Buffer变为NULL时,我找不到进程ID。你知道为什么ImageName.Buffer有时会变为NULL吗,先生Winapi ZWQuerySystem信息工作不正常,winapi,Winapi,我尝试使用内核模式驱动程序FindProcessidByName,有时ImageName.Buffer变为NULL,因此,当ImageName.Buffer变为NULL时,我找不到进程ID。你知道为什么ImageName.Buffer有时会变为NULL吗,先生 typedef struct _SYSTEM_PROCESS_INFO_L { ULONG NextEntryOffset; ULONG
typedef struct _SYSTEM_PROCESS_INFO_L
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
ULONG BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
}_SYSTEM_PROCESS_INFO_L, *P_SYSTEM_PROCESS_INFO_L;
HANDLE LSFindProcess(LPSTR name)
{
NTSTATUS durum;
ULONG retsize;
HANDLE hProcid = -1;
P_SYSTEM_PROCESS_INFO_L pi;
durum = ZwQuerySystemInformation(SystemProcessInformation, NULL, NULL, &retsize); // request how much memory size we need.
if (!NT_SUCCESS(durum) && durum !=STATUS_INFO_LENGTH_MISMATCH)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "LS : ZwQuerySystemInformation Failed 1 durum : %p \n",durum);
return -1;
}
PVOID memPtr;
memPtr = ExAllocatePool(PagedPool, retsize);
if (!memPtr)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "LS : ExAllocatePool Failed \n");
return -1;
}
memset(memPtr, 0, retsize);// zero mem
durum = ZwQuerySystemInformation(SystemProcessInformation, memPtr, retsize, NULL);
pi = (P_SYSTEM_PROCESS_INFO_L)memPtr; // parselliyorz
if (!NT_SUCCESS(durum))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "LS : ZwQuerySystemInformation Failed 2 durum : %p \n", durum);
return -1;
}
while (pi->NextEntryOffset)
{
if (pi->ImageName.Buffer) //some process null if I dont use this I am getting BSOD.
{
if (!_stricmp(pi->ImageName.Buffer, name))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "LS : name %ws , pid : %d \n", pi->ImageName.Buffer, pi->ProcessId);
hProcid = pi->ProcessId; // pid
break; // foundedd
}
}
pi = (P_SYSTEM_PROCESS_INFO_L)((unsigned char*)pi + pi->NextEntryOffset);
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "LS : LSFindProcess bitti \n");
return hProcid;
}
您不应该调用ZwQuerySystemInformation,它不容易跨Windows操作系统移植,甚至可能无法在某些操作系统上使用。建议针对您的特定用途使用其他功能 ZWQuerySystem信息工作不正常 这当然是错误的。api工作正常。如果您得到了错误的结果,这只是由于代码中的错误。在具体代码中,spinet存在几个错误 在内核模式下,Zw和Nt api之间存在差异——需要了解需要调用哪个版本,如果两者都被导出(就像在这个具体案例中一样)。如果您知道以前的模式是内核模式,则需要使用Nt版本。如果您不知道在这一点上的前一个模式(在编译时)或前一个模式用户模式-需要使用Zw版本。然而,这是一般性的注意事项,不会总是错误地调用Zw 第一个严重错误-这是调用
ZwQuerySystemInformation
的方式-第一次查询请求的缓冲区大小retsize
(在代码中),第二次已使用此缓冲区大小。但在这两次调用之间,可以在系统中生成新的线程和进程。因此,返回的缓冲区大小可能已经不够大。正确的解决方案-在循环中调用此api,同时它返回STATUS\u INFO\u LENGTH\u MISMATCH
第二个内存必须总是空闲的。尤其是在内核模式下。说代码不完整-没有借口。代码可以是不完整的,也可以是中间的,但分配后的空闲内存始终必须立即插入
还有一个严重错误-while(pi->nexteryoffset)
loop-在这个循环中,我们总是丢失(而不是处理)最后一个条目(最后创建的进程)。我需要改变这个
if(pi->ImageName.Buffer)//如果我不使用这个,那么一些进程将为null
获得BSOD
ImageName
是UNICODE\u字符串
,需要分别使用它。在案例ImageName.Buffer
中,ImageName.Length
也为0。UNICODE\u字符串ImageName代码>是正确的。只有您使用它的方式不正确
_stricmp(pi->ImageName.Buffer,name);/代码>
pi->ImageName.Buffer
是PWSTR
,因此原则上不能与\u stricmp
一起使用。认为你使用C编译器- C++简单地给你错误在这里。但即使在这里使用\u wcsicmp
也是不正确的-同样pi->ImageName
是UNICODE\u字符串
,需要使用RtlEqualUnicodeString(&pi->ImageName,name,TRUE)
其中名称当然必须是PCUNICODE\u字符串
,但不能是PCSTR
或PSTR
甚至PCWSTR
。如果您有PCWSTR name
作为输入,则需要在调用此api之前将其包装为UNICODE\u字符串。代码示例:
NTSTATUS LSFindProcess(PCUNICODE_STRING ImageName, PHANDLE UniqueProcessId)
{
ULONG cb = 0x20000;
PVOID buf;
NTSTATUS status;
do
{
status = STATUS_INSUFFICIENT_RESOURCES;
if (buf = ExAllocatePool(PagedPool, cb))
{
if (0 <= (status = NtQuerySystemInformation(SystemProcessInformation, buf, cb, &cb)))
{
union {
PVOID pv;
PBYTE pb;
PSYSTEM_PROCESS_INFORMATION pspi;
};
pv = buf;
ULONG NextEntryOffset;
goto __0;
do
{
pb += NextEntryOffset;
__0:
if (RtlEqualUnicodeString(&pspi->ImageName, ImageName, TRUE))
{
*UniqueProcessId = pspi->UniqueProcessId;
break;
}
} while (NextEntryOffset = pspi->NextEntryOffset);
}
ExFreePool(buf);
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
return status;
}
NTSTATUS LSFindProcess(PCWSTR ImageName, PHANDLE UniqueProcessId)
{
UNICODE_STRING us;
RtlInitUnicodeString(&us, ImageName);
return LSFindProcess(&us, UniqueProcessId);
}
NTSTATUS LSFindProcess(PCUNICODE_字符串ImageName,幻影UniqueProcessId)
{
ULONG cb=0x20000;
pvoidbuf;
非关税国家地位;
做
{
状态=状态资源不足;
如果(buf=ExAllocatePool(PagedPool,cb))
{
if(0 ImageName,ImageName,TRUE))
{
*UniqueProcessId=pspi->UniqueProcessId;
打破
}
}而(NexteryOffset=pspi->NexteryOffset);
}
ExFreePool(buf);
}
}而(状态==状态信息长度不匹配);
返回状态;
}
NTSTATUS LSFindProcess(PCWSTR ImageName,幻影唯一进程ID)
{
UNICODE_字符串我们;
RTL代码字符串(&us,ImageName);
返回LSFindProcess(&us,UniqueProcessId);
}
谢谢大家,特别是@RbMm感谢大家提供的信息。
完成代码我希望这篇文章能帮助别人
/// <summary>
/// Struct SystemProcessInformation
/// </summary>
typedef struct _SYSTEM_PROCESS_INFO_L
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
ULONG BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
}_SYSTEM_PROCESS_INFO_L, *P_SYSTEM_PROCESS_INFO_L;
/// <summary>
/// Find Process ID By Name , thanks @RbMm
/// </summary>
/// <param name="imagename">Process name </param>
/// <param name="pid">Output Process id</param>
/// <returns>NTSTATUS.</returns>
NTSTATUS LSFindProcessIdByName(IN PCWSTR imagename, OUT PHANDLE pid)
{
NTSTATUS durum = STATUS_UNSUCCESSFUL;
ULONG qmemsize = 0x1024;
PVOID qmemptr = 0;
P_SYSTEM_PROCESS_INFO_L spi;
UNICODE_STRING uimagename;
RtlInitUnicodeString(&uimagename, imagename); // @RbMm
*pid = -1;
do
{
qmemptr = ExAllocatePool(PagedPool, qmemsize); // alloc memory for spi
if (qmemptr == NULL) // check memory is allocated or not.
{
return STATUS_UNSUCCESSFUL;
}
durum = ZwQuerySystemInformation(SystemProcessInformation,qmemptr, qmemsize, NULL);
if (durum == STATUS_INFO_LENGTH_MISMATCH)
{
qmemsize = qmemsize * 2; // increase qmemsize for next memory alloc
ExFreePool(qmemptr); // free memory
}
} while (durum == STATUS_INFO_LENGTH_MISMATCH); // resize memory
spi = (P_SYSTEM_PROCESS_INFO_L)qmemptr;
while(1)
{
if (RtlEqualUnicodeString(&uimagename, &spi->ImageName, TRUE)) // @RbMm
{
*pid = spi->ProcessId;
break;
}
if (spi->NextEntryOffset == 0)
break;
spi = (P_SYSTEM_PROCESS_INFO_L)((unsigned char*)spi + spi->NextEntryOffset); // next info
}
if (!NT_SUCCESS(durum))
{
ExFreePool(qmemptr); // free memory
return STATUS_UNSUCCESSFUL;
}
ExFreePool(qmemptr); // free memory
return STATUS_SUCCESS;
}
//
///结构SystemProcessInformation
///
类型定义结构系统进程信息
{
ULONG NextEntryOffset;
乌龙数;
保留大_整数[3];
大整数创建时间;
大整数用户时间;
大整数核时间;
UNICODE_字符串图像名称;
乌龙优先;
句柄进程ID;
句柄继承自ProcessId;
}_系统流程信息,*P系统流程信息;
///
///通过名称查找进程ID,谢谢@RbMm
///
///进程名称
///输出进程id
///NTSTATUS。
NTSTATUS LSFindProcessIdByName(在PCWSTR imagename中,在幻影pid中)
{
NTSTATUS durum=状态\未成功;
ULONG qmemsize=0x1024;
PVOID qmpptor=0;
系统、流程、信息、spi;
UNICODE_字符串uimagename;
RtlInitUnicodeString(&uimagename,imagename);/@RbMm
*pid=-1;
做
{
qmpptr=ExAllocatePool(PagedPool,qmemsize);//spi的分配内存
if(qmputr==NULL)//检查内存是否已分配。
{
返回状态不成功;
}
durum=ZwQuerySystemInformation(SystemProcessInformation,qmeptr,qmemsize,NULL);
如果(硬粒==状态信息长度不匹配)
{
qmemsize=qmemsize*2;//为下一个内存分配增加qmemsize
ExFreePool(qmputr);//释放内存
}
}while(durum==状态信息长度不匹配);//调整内存大小
spi=(系统、过程、信息)qmemptr;
而(1)
{
if(RtlEqualUnicodeString(&uimagename,&spi->ImageName,TRUE))/@RbMm
{
*pid=spi->ProcessId;
打破
}
如果(spi->NexteryOffset==0)
打破
spi=(系统处理信息)((无符号字符*)spi+spi->NextEntryOffset);//下一步信息
}
如果(!NT_成功(硬粒)