Winapi ZWQuerySystem信息工作不正常

Winapi ZWQuerySystem信息工作不正常,winapi,Winapi,我尝试使用内核模式驱动程序FindProcessidByName,有时ImageName.Buffer变为NULL,因此,当ImageName.Buffer变为NULL时,我找不到进程ID。你知道为什么ImageName.Buffer有时会变为NULL吗,先生 typedef struct _SYSTEM_PROCESS_INFO_L { ULONG NextEntryOffset; ULONG

我尝试使用内核模式驱动程序FindProcessidByName,有时ImageName.Buffer变为NULL,因此,当ImageName.Buffer变为NULL时,我找不到进程ID。你知道为什么ImageName.Buffer有时会变为NULL吗,先生

 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_成功(硬粒)