在64位计算机上从dll调用PNtQuerySystemInformation

时间:2017-03-28 05:57:35

标签: c++ winapi dll process sysinternals

按照程序从我的计算机中检索所有进程信息。通过dll调用相同的应用程序时,无法检索系统进程信息。

// TestSysInternals.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include "ntdll.h"

#include <Winternl.h>

#define VISTA_FILETYPE  25
#define XP_FILETYPE 28



static PNtQuerySystemInformation NtQuerySystemInformation_dynamic = NULL;
static DWORD curPid = 0;
static int nFileHandleType; 
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
int _tmain(int argc, _TCHAR* argv[])
{

    NtQuerySystemInformation_dynamic = (PNtQuerySystemInformation)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), ("NtQuerySystemInformation"));
    //                                   (PNtQuerySystemInformation)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),     _("NtQuerySystemInformation"));
    nFileHandleType = XP_FILETYPE;
    NTSTATUS status;
    DWORD size = sizeof(SYSTEM_HANDLE_INFORMATION);
    PSYSTEM_HANDLE_INFORMATION pSysHandleInformation = (PSYSTEM_HANDLE_INFORMATION)malloc(size);
    DWORD needed = 0;
    int nfound = 0;
    while (!NT_SUCCESS(status = NtQuerySystemInformation_dynamic(SystemHandleInformation, pSysHandleInformation, size, &needed)))
    {
        if (status != STATUS_INFO_LENGTH_MISMATCH
            || needed == 0)
        {
            //DBGLOG("==>Failed Status=%l(%#X) Needed=%lu", status, status, needed);
            goto CLEAN;// some other error
        }
        // The previously supplied buffer wasn't enough.
        size = needed + 1024;
        pSysHandleInformation = (PSYSTEM_HANDLE_INFORMATION)realloc(pSysHandleInformation, size);
    }
    DWORD i;
    for (i = 0; i < pSysHandleInformation->Count; i++)
    {
        DWORD handlePid = pSysHandleInformation->Handles[i].ProcessID;

    }


    CLEAN:
        free(pSysHandleInformation);
        return nfound;
    return 0;
}

标头文件

#ifndef NT_DLL_H_INCLUDED
#define NT_DLL_H_INCLUDED
#include <Winternl.h>
#include <Windows.h>

typedef DWORD(WINAPI *PNtQuerySystemInformation)(DWORD, VOID*, DWORD, ULONG*);

typedef struct _SYSTEM_HANDLE
{
    DWORD   ProcessID;
    BYTE    HandleType;
    BYTE    HandleFlags;
    WORD    HandleNumber;
    DWORD   KernelAddress;
    DWORD   Flags;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
    DWORD           Count;
    SYSTEM_HANDLE   Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

#define NT_SUCCESS_K(Status) ((NTSTATUS)(Status) >= 0)
#define SystemHandleInformation (DWORD)0x10


#endif

通过调试监视检查pSysHandleInformation->Handle数组时,我可以看到以下信息。

enter image description here

根据图片,它为processID值提供了真实的进程ID。但是,当我在dll中放入相同的代码时,processID值得到的确非常大,在我的电脑中不存在,以下是我通过dll运行相同代码时获得的进程id值的屏幕截图。我不知道为什么当通过dll运行相同的代码时,应用程序的行为会有所不同。 非常感谢对这种有线行为的任何想法。

enter image description here

1 个答案:

答案 0 :(得分:1)

该功能已基本过时,您应该在比Win2000 \ XP更新的任何东西上使用GetSystemInfo。难以理解遗留的C代码(这里没有C ++的内容),但是人们可以发现你使用的是SystemHandleInformation类,没有记录,它来自哪里?它应该由SystemProcessInformation。可以通过GetProcessMemoryInfo检索此信息。

SystemProcessInformation的结构将相应:

typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffset;
    BYTE Reserved1[52];
    PVOID Reserved2[3];
    HANDLE UniqueProcessId;
    PVOID Reserved3;
    ULONG HandleCount;
    BYTE Reserved4[4];
    PVOID Reserved5[11];
    SIZE_T PeakPagefileUsage;
    SIZE_T PrivatePageCount;
    LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION;  

要获取进程数,请改用GetProcessHandleCount。