-1

Following program to retrieve all the process information from my computer. The same application when it is called through a dll, it fails to retrieve system process information.

// 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;
}

Header file

#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

When checkd the pSysHandleInformation->Handles array through debug watch, I could see following information.

enter image description here

As per the picture, it gives real process id for processID value. However, when I put the same code inside a dll, the processID value get really large values that really does not exist in my pc, following is the screenshot of the process id values that i get when I run the same code through dll. I have no idea why application behave differently when the same code is run through dll. Highly appreciate any thought on this wired behavior.

enter image description here

KItis
  • 5,476
  • 19
  • 64
  • 112
  • Show a [mcve] for your dll variant – David Heffernan Mar 28 '17 at 06:19
  • fails - where concrete ? in any case your code extremely ineffective and containing errors. for example `GetFileType(handle);` - are you understand at all what you doing here ? how you defined `SYSTEM_HANDLE_INFORMATION` not visible. what sense in initial allocate sizeof(SYSTEM_HANDLE_INFORMATION); ?... and need **debug** own code but not just write *fail* – RbMm Mar 28 '17 at 06:21
  • @DavidHeffernan, I will post a code sample in a while, RbMm, This is actually a test code, The code inside the if statement is what I am expected to do after process id's are successfully retrieved, but as of now the process id's are not retrieving properly, so I am concentrating on that part only with this test code. I wrote this test application to test this wired behavior. I removed the code that made the confusion, sys handle information is defined in the header file, I have updated the question – KItis Mar 28 '17 at 06:37
  • Don't post a sample. Post a [mcve]. Then we will all be on the same page. – David Heffernan Mar 28 '17 at 06:41
  • your definition of `_SYSTEM_HANDLE` is wrong - this is correct [_SYSTEM_HANDLE_TABLE_ENTRY_INFO](http://processhacker.sourceforge.net/doc/ntexapi_8h_source.html#l01595) and better use [_SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX](http://processhacker.sourceforge.net/doc/ntexapi_8h_source.html#l01864) with other infoclass - [SystemExtendedHandleInformation](http://processhacker.sourceforge.net/doc/ntexapi_8h_source.html#l01268) – RbMm Mar 28 '17 at 06:57
  • also good practice print *processID* in hex - if you do this the first value `3452816845` is really `cdcdcdcd` which already say that you dump uninit buffer – RbMm Mar 28 '17 at 07:01
  • @RbMm, your suggestion worked for me, if you put it as a solution, I will give up vote and accept it as an answer. Thanks lot! – KItis Mar 28 '17 at 10:17

1 Answers1

1

That function is largely outdated, you should use GetSystemInfo on anything newer than Win2000\XP. Hard to tear through legacy C code (there is nothing from C++ here), but one can spot that you use SystemHandleInformation class, that isn't documented, where it got it from? It should by SystemProcessInformation. This information can be retrieved by GetProcessMemoryInfo instead.

Structure for SystemProcessInformation would be accordingly:

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;  

To get count of processes use GetProcessHandleCount instead.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
  • this function absolute not outdated. and `SYSTEM_PROCESS_INFORMATION` absolute not related to retrieve list of handles – RbMm Mar 28 '17 at 06:50
  • @RbMm, well, he uses definitions from old ntdll.h. the "wrong" (as you commented) definition of structure is actually from older version of Microsoft's code. The thing is that all that is undocumented and subject to change in_every_ version of Windows wihout notice. While they list SystemProcessInformation as usable, the SystemHandleInformation isn't even mentioned in documentation. Page for NtQuerySystemInformation is riddled with references to functions that should be used instead of NtQuerySystemInformation – Swift - Friday Pie Mar 28 '17 at 08:45
  • i dont know what is `ntdll.h`, but definition of `_SYSTEM_HANDLE` absolutely wrong and unprofessionally (only look for `DWORD KernelAddress;` - obviously not designed to use in x64). `ubject to change in_every_ version of Windows wihout notice` - but this however until not changed near 17 years. while some "documented" api changed. and list of processes and list of handles is absolute different things. now, how i know for get list of handles only one way - call `NtQuerySystemInformation` with `System[Extended]HandleInformation`. not documented ? so what ? but if need this info ? – RbMm Mar 28 '17 at 08:54
  • @Swift, could you point me to an example where this code usage is demonstrated. Also, is there similar method to get handler's belonging to individual process using this new method you have suggested. – KItis Mar 28 '17 at 09:23
  • This is where I found the usage of `SystemHandleInformation` http://stackoverflow.com/questions/733384/how-to-enumerate-process-handles, in the first answer, the code uses the same method As I am doing. This is a reference form microsoft https://code.msdn.microsoft.com/windowsapps/CppFileHandle-03c8ea0b – KItis Mar 28 '17 at 09:49