Created
June 16, 2017 11:05
-
-
Save ZAYEC77/bb033c90847057bb7c3fefea4d0ae8a7 to your computer and use it in GitHub Desktop.
Output file handle by some processes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include <string> | |
#include <wchar.h> | |
#ifndef UNICODE | |
#define UNICODE | |
#endif | |
#include <windows.h> | |
#include <stdio.h> | |
#define NT_SUCCESS(x) ((x) >= 0) | |
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004 | |
#define SystemHandleInformation 16 | |
#define ObjectBasicInformation 0 | |
#define ObjectNameInformation 1 | |
#define ObjectTypeInformation 2 | |
typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)( | |
ULONG SystemInformationClass, | |
PVOID SystemInformation, | |
ULONG SystemInformationLength, | |
PULONG ReturnLength | |
); | |
typedef NTSTATUS (NTAPI *_NtDuplicateObject)( | |
HANDLE SourceProcessHandle, | |
HANDLE SourceHandle, | |
HANDLE TargetProcessHandle, | |
PHANDLE TargetHandle, | |
ACCESS_MASK DesiredAccess, | |
ULONG Attributes, | |
ULONG Options | |
); | |
typedef NTSTATUS (NTAPI *_NtQueryObject)( | |
HANDLE ObjectHandle, | |
ULONG ObjectInformationClass, | |
PVOID ObjectInformation, | |
ULONG ObjectInformationLength, | |
PULONG ReturnLength | |
); | |
typedef struct _UNICODE_STRING | |
{ | |
USHORT Length; | |
USHORT MaximumLength; | |
PWSTR Buffer; | |
} UNICODE_STRING, *PUNICODE_STRING; | |
typedef struct _SYSTEM_HANDLE | |
{ | |
ULONG ProcessId; | |
BYTE ObjectTypeNumber; | |
BYTE Flags; | |
USHORT Handle; | |
PVOID Object; | |
ACCESS_MASK GrantedAccess; | |
} SYSTEM_HANDLE, *PSYSTEM_HANDLE; | |
typedef struct _SYSTEM_HANDLE_INFORMATION | |
{ | |
ULONG HandleCount; | |
SYSTEM_HANDLE Handles[1]; | |
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; | |
typedef enum _POOL_TYPE | |
{ | |
NonPagedPool, | |
PagedPool, | |
NonPagedPoolMustSucceed, | |
DontUseThisType, | |
NonPagedPoolCacheAligned, | |
PagedPoolCacheAligned, | |
NonPagedPoolCacheAlignedMustS | |
} POOL_TYPE, *PPOOL_TYPE; | |
typedef struct _OBJECT_TYPE_INFORMATION | |
{ | |
UNICODE_STRING Name; | |
ULONG TotalNumberOfObjects; | |
ULONG TotalNumberOfHandles; | |
ULONG TotalPagedPoolUsage; | |
ULONG TotalNonPagedPoolUsage; | |
ULONG TotalNamePoolUsage; | |
ULONG TotalHandleTableUsage; | |
ULONG HighWaterNumberOfObjects; | |
ULONG HighWaterNumberOfHandles; | |
ULONG HighWaterPagedPoolUsage; | |
ULONG HighWaterNonPagedPoolUsage; | |
ULONG HighWaterNamePoolUsage; | |
ULONG HighWaterHandleTableUsage; | |
ULONG InvalidAttributes; | |
GENERIC_MAPPING GenericMapping; | |
ULONG ValidAccess; | |
BOOLEAN SecurityRequired; | |
BOOLEAN MaintainHandleCount; | |
USHORT MaintainTypeList; | |
POOL_TYPE PoolType; | |
ULONG PagedPoolUsage; | |
ULONG NonPagedPoolUsage; | |
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; | |
PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName) | |
{ | |
return GetProcAddress(GetModuleHandleA(LibraryName), ProcName); | |
} | |
int GetProcessHandles(ULONG pid); | |
int GetProcessHandles(ULONG pid) | |
{ | |
_NtQuerySystemInformation NtQuerySystemInformation = | |
(_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation"); | |
_NtDuplicateObject NtDuplicateObject = | |
(_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject"); | |
_NtQueryObject NtQueryObject = | |
(_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject"); | |
NTSTATUS status; | |
PSYSTEM_HANDLE_INFORMATION handleInfo; | |
ULONG handleInfoSize = 0x10000; | |
HANDLE processHandle; | |
ULONG i; | |
if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid))) | |
{ | |
printf("Could not open PID %d! (Don't try to open a system process.)\n", pid); | |
return 1; | |
} | |
handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); | |
/* NtQuerySystemInformation won't give us the correct buffer size, | |
so we guess by doubling the buffer size. */ | |
while ((status = NtQuerySystemInformation( | |
SystemHandleInformation, | |
handleInfo, | |
handleInfoSize, | |
NULL | |
)) == STATUS_INFO_LENGTH_MISMATCH) | |
handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2); | |
/* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */ | |
if (!NT_SUCCESS(status)) | |
{ | |
printf("NtQuerySystemInformation failed!\n"); | |
return 1; | |
} | |
for (i = 0; i < handleInfo->HandleCount; i++) | |
{ | |
SYSTEM_HANDLE handle = handleInfo->Handles[i]; | |
HANDLE dupHandle = NULL; | |
POBJECT_TYPE_INFORMATION objectTypeInfo; | |
PVOID objectNameInfo; | |
UNICODE_STRING objectName; | |
ULONG returnLength; | |
/* Check if this handle belongs to the PID the user specified. */ | |
if (handle.ProcessId != pid) | |
continue; | |
/* Duplicate the handle so we can query it. */ | |
if (!NT_SUCCESS(NtDuplicateObject( | |
processHandle, | |
(HANDLE) handle.Handle, | |
GetCurrentProcess(), | |
&dupHandle, | |
0, | |
0, | |
0 | |
))) | |
{ | |
// printf("[%#x] Error!\n", handle.Handle); | |
continue; | |
} | |
/* Query the object type. */ | |
objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000); | |
if (!NT_SUCCESS(NtQueryObject( | |
dupHandle, | |
ObjectTypeInformation, | |
objectTypeInfo, | |
0x1000, | |
NULL | |
))) | |
{ | |
// printf("[%#x] Error!\n", handle.Handle); | |
CloseHandle(dupHandle); | |
continue; | |
} | |
/* Query the object name (unless it has an access of | |
0x0012019f, on which NtQueryObject could hang. */ | |
if (handle.GrantedAccess == 0x0012019f && (std::wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0)) | |
{ | |
/* We have the type, so display that. */ | |
/* printf( | |
"[%#x] %.*S: (did not get name)\n", | |
handle.Handle, | |
objectTypeInfo->Name.Length / 2, | |
objectTypeInfo->Name.Buffer | |
); */ | |
free(objectTypeInfo); | |
CloseHandle(dupHandle); | |
continue; | |
} | |
objectNameInfo = malloc(0x1000); | |
if (!NT_SUCCESS(NtQueryObject( | |
dupHandle, | |
ObjectNameInformation, | |
objectNameInfo, | |
0x1000, | |
&returnLength | |
))) | |
{ | |
/* Reallocate the buffer and try again. */ | |
objectNameInfo = realloc(objectNameInfo, returnLength); | |
if (!NT_SUCCESS(NtQueryObject( | |
dupHandle, | |
ObjectNameInformation, | |
objectNameInfo, | |
returnLength, | |
NULL | |
))) | |
{ | |
/* We have the type name, so just display that. */ | |
/* printf( | |
"[%#x] %.*S: (could not get name)\n", | |
handle.Handle, | |
objectTypeInfo->Name.Length / 2, | |
objectTypeInfo->Name.Buffer | |
); */ | |
free(objectTypeInfo); | |
free(objectNameInfo); | |
CloseHandle(dupHandle); | |
continue; | |
} | |
} | |
/* Cast our buffer into an UNICODE_STRING. */ | |
objectName = *(PUNICODE_STRING)objectNameInfo; | |
/* Print the information! */ | |
if (objectName.Length && (std::wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0)) | |
{ | |
/* The object has a name. */ | |
/* printf( | |
"[%#x] %.*S: %.*S\n", | |
handle.Handle, | |
objectTypeInfo->Name.Length / 2, | |
objectTypeInfo->Name.Buffer, | |
objectName.Length / 2, | |
objectName.Buffer | |
); */ | |
printf("file pid: %i \n", handle.Handle); | |
printf("file path: %.*S \n", | |
objectName.Length / 2, | |
objectName.Buffer); | |
printf("\n ------------- \n"); | |
} | |
else | |
{ | |
/* Print something else. */ | |
if (std::wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0) | |
{ | |
/* printf( | |
"[%#x] %.*S: (unnamed)\n", | |
handle.Handle, | |
objectTypeInfo->Name.Length / 2, | |
objectTypeInfo->Name.Buffer | |
);*/ | |
} | |
} | |
free(objectTypeInfo); | |
free(objectNameInfo); | |
CloseHandle(dupHandle); | |
} | |
free(handleInfo); | |
CloseHandle(processHandle); | |
return 0; | |
} | |
#include <iostream> | |
#include <windows.h> | |
#include <tlhelp32.h> | |
#include <TlHelp32.h> | |
#include <sstream> | |
#include <map> | |
#include <vector> | |
#include <string.h> | |
#include <stdio.h> | |
#include <tchar.h> | |
#include <stdlib.h> | |
#include "ntstatus.h" | |
#define OBJ_PROTECT_CLOSE 0x00000001 | |
#define OBJ_INHERIT 0x00000002 | |
#define OBJ_AUDIT_OBJECT_CLOSE 0x00000004 | |
#define ObjectNameInformation 1 | |
#define ObjectTypesInformation 3 | |
#define ObjectHandleFlagInformation 4 | |
#define ObjectSessionInformation 5 | |
using namespace std; | |
vector<DWORD> GetProcessList() { | |
vector<DWORD> processes; | |
PROCESSENTRY32 peProcessEntry; | |
TCHAR szBuff[1024]; | |
DWORD dwTemp; | |
HANDLE CONST hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | |
if(INVALID_HANDLE_VALUE == hSnapshot) { | |
return processes; | |
} | |
peProcessEntry.dwSize = sizeof(PROCESSENTRY32); | |
Process32First(hSnapshot, &peProcessEntry); | |
do { | |
TCHAR toFind[] = L"chrome.exe"; | |
if (_tcscmp(peProcessEntry.szExeFile, toFind) == 0) { | |
// cout << peProcessEntry.szExeFile << endl; | |
// cout << peProcessEntry.th32ProcessID << endl; | |
processes.push_back(peProcessEntry.th32ProcessID); | |
} | |
} while(Process32Next(hSnapshot, &peProcessEntry)); | |
CloseHandle(hSnapshot); | |
return processes; | |
} | |
int main (int argc, _TCHAR* argv[]) | |
{ | |
vector<DWORD> processes = GetProcessList(); | |
for (vector<DWORD>::iterator i = processes.begin(); i != processes.end(); i++) { | |
cout << "PID: " << (int)*i << ": "<< endl; | |
GetProcessHandles((ULONG)*i); | |
} | |
// | |
getc(stdin); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment