Код демонстрирует технику поиска процессов, открывших указанный файл используя недокумментированное NativeAPI. Немного пошаманив, можно переделать этот код для перебора абсолютно любых типов описателей(handles).
Небольшая проблемка была обнаружена при перечислении описателей одного из процессов TortoiseSVN, почему-то NtQueryObject с флагом ObjectNameInformation не возвращает управление, не знаю баг ли это кода или баг TortoiseSVN, если кто подскажет буду признателен.
ntdll.h
Небольшая проблемка была обнаружена при перечислении описателей одного из процессов TortoiseSVN, почему-то NtQueryObject с флагом ObjectNameInformation не возвращает управление, не знаю баг ли это кода или баг TortoiseSVN, если кто подскажет буду признателен.
ntdll.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | // -------------------------------------------------------------- // This is example, how to listing of processes which use the // specified file // by JKornev <c> http://k0rnev.blogspot.com // -------------------------------------------------------------- #ifndef __NTDLL_H #define __NTDLL_H #include <Windows.h> #define NT_DEF(proc) static Prototype_##proc proc #define NT_BIND(proc) proc = (Prototype_##proc)GetProcAddress(GetModuleHandleA("ntdll"), "" #proc "") // ----------------- Main def typedef LONG NTSTATUS; typedef NTSTATUS *PNTSTATUS; typedef LONG KPRIORITY; #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define OBJECT_TYPE_0 (BYTE)(0) #define OBJECT_TYPE_1 1 #define OBJECT_TYPE_DIRECTORY 2 #define OBJECT_TYPE_SYMBOLICLINK 3 #define OBJECT_TYPE_TOKEN 4 #define OBJECT_TYPE_PROCESS 5 #define OBJECT_TYPE_THREAD 6 #define OBJECT_TYPE_EVENT 7 #define OBJECT_TYPE_8 8 #define OBJECT_TYPE_MUTANT 9 #define OBJECT_TYPE_SEMAPHORE 10 #define OBJECT_TYPE_TIMER 11 #define OBJECT_TYPE_12 12 #define OBJECT_TYPE_WINDOWSTATION 13 #define OBJECT_TYPE_DESKTOP 14 #define OBJECT_TYPE_SECTION 15 #define OBJECT_TYPE_KEY 16 #define OBJECT_TYPE_PORT 17 #define OBJECT_TYPE_18 18 #define OBJECT_TYPE_19 19 #define OBJECT_TYPE_20 20 #define OBJECT_TYPE_21 21 #define OBJECT_TYPE_IOCOMPLETION 22 #define OBJECT_TYPE_FILE (BYTE)(23) typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING; // ----------------- System information class typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, SystemProcessorInformation, // obsolete...delete SystemPerformanceInformation, SystemTimeOfDayInformation, SystemPathInformation, SystemProcessInformation, SystemCallCountInformation, SystemDeviceInformation, SystemProcessorPerformanceInformation, SystemFlagsInformation, SystemCallTimeInformation, SystemModuleInformation, SystemLocksInformation, SystemStackTraceInformation, SystemPagedPoolInformation, SystemNonPagedPoolInformation, SystemHandleInformation, SystemObjectInformation, SystemPageFileInformation, SystemVdmInstemulInformation, SystemVdmBopInformation, SystemFileCacheInformation, SystemPoolTagInformation, SystemInterruptInformation, SystemDpcBehaviorInformation, SystemFullMemoryInformation, SystemLoadGdiDriverInformation, SystemUnloadGdiDriverInformation, SystemTimeAdjustmentInformation, SystemSummaryMemoryInformation, SystemMirrorMemoryInformation, SystemPerformanceTraceInformation, SystemObsolete0, SystemExceptionInformation, SystemCrashDumpStateInformation, SystemKernelDebuggerInformation, SystemContextSwitchInformation, SystemRegistryQuotaInformation, SystemExtendServiceTableInformation, SystemPrioritySeperation, SystemVerifierAddDriverInformation, SystemVerifierRemoveDriverInformation, SystemProcessorIdleInformation, SystemLegacyDriverInformation, SystemCurrentTimeZoneInformation, SystemLookasideInformation, SystemTimeSlipNotification, SystemSessionCreate, SystemSessionDetach, SystemSessionInformation, SystemRangeStartInformation, SystemVerifierInformation, SystemVerifierThunkExtend, SystemSessionProcessInformation, SystemLoadGdiDriverInSystemSpace, SystemNumaProcessorMap, SystemPrefetcherInformation, SystemExtendedProcessInformation, SystemRecommendedSharedDataAlignment, SystemComPlusPackage, SystemNumaAvailableMemory, SystemProcessorPowerInformation, SystemEmulationBasicInformation, SystemEmulationProcessorInformation, SystemExtendedHandleInformation, SystemLostDelayedWriteInformation, SystemBigPoolInformation, SystemSessionPoolTagInformation, SystemSessionMappedViewInformation, SystemHotpatchInformation, SystemObjectSecurityMode, SystemWatchdogTimerHandler, SystemWatchdogTimerInformation, SystemLogicalProcessorInformation, SystemWow64SharedInformation, SystemRegisterFirmwareTableInformationHandler, SystemFirmwareTableInformation, SystemModuleInformationEx, SystemVerifierTriageInformation, SystemSuperfetchInformation, SystemMemoryListInformation, SystemFileCacheInformationEx, MaxSystemInfoClass // MaxSystemInfoClass should always be the last enum } SYSTEM_INFORMATION_CLASS; #if defined(_WIN64) typedef ULONG SYSINF_PAGE_COUNT; #else typedef SIZE_T SYSINF_PAGE_COUNT; #endif typedef struct _SYSTEM_BASIC_INFORMATION { ULONG Reserved; ULONG TimerResolution; ULONG PageSize; SYSINF_PAGE_COUNT NumberOfPhysicalPages; SYSINF_PAGE_COUNT LowestPhysicalPageNumber; SYSINF_PAGE_COUNT HighestPhysicalPageNumber; ULONG AllocationGranularity; ULONG_PTR MinimumUserModeAddress; ULONG_PTR MaximumUserModeAddress; ULONG_PTR ActiveProcessorsAffinityMask; CHAR NumberOfProcessors; } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION; typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { USHORT UniqueProcessId; USHORT CreatorBackTraceIndex; UCHAR ObjectTypeIndex; UCHAR HandleAttributes; USHORT HandleValue; PVOID Object; ULONG GrantedAccess; } SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO; typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG NumberOfHandles; SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; // ----------------- Process information class typedef enum _PROCESSINFOCLASS { ProcessBasicInformation, ProcessQuotaLimits, ProcessIoCounters, ProcessVmCounters, ProcessTimes, ProcessBasePriority, ProcessRaisePriority, ProcessDebugPort, ProcessExceptionPort, ProcessAccessToken, ProcessLdtInformation, ProcessLdtSize, ProcessDefaultHardErrorMode, ProcessIoPortHandlers, // Note: this is kernel mode only ProcessPooledUsageAndLimits, ProcessWorkingSetWatch, ProcessUserModeIOPL, ProcessEnableAlignmentFaultFixup, ProcessPriorityClass, ProcessWx86Information, ProcessHandleCount, ProcessAffinityMask, ProcessPriorityBoost, ProcessDeviceMap, ProcessSessionInformation, ProcessForegroundInformation, ProcessWow64Information, ProcessImageFileName, ProcessLUIDDeviceMapsEnabled, ProcessBreakOnTermination, ProcessDebugObjectHandle, ProcessDebugFlags, ProcessHandleTracing, ProcessIoPriority, ProcessExecuteFlags, ProcessResourceManagement, ProcessCookie, ProcessImageInformation, MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum } PROCESSINFOCLASS; typedef struct _PROCESS_BASIC_INFORMATION32 { NTSTATUS ExitStatus; PVOID PebBaseAddress; ULONG_PTR AffinityMask; KPRIORITY BasePriority; ULONG_PTR UniqueProcessId; ULONG_PTR InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION32; typedef PROCESS_BASIC_INFORMATION32 *PPROCESS_BASIC_INFORMATION32; typedef struct _PROCESS_BASIC_INFORMATION64 { NTSTATUS ExitStatus; PVOID PebBaseAddress; ULONG_PTR AffinityMask; KPRIORITY BasePriority; ULONG_PTR UniqueProcessId; ULONG_PTR InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION64; typedef PROCESS_BASIC_INFORMATION64 *PPROCESS_BASIC_INFORMATION64; // ----------------- Object information class typedef enum _OBJECT_INFORMATION_CLASS { ObjectBasicInformation, ObjectNameInformation, ObjectTypeInformation, ObjectTypesInformation, ObjectHandleFlagInformation, ObjectSessionInformation, MaxObjectInfoClass } OBJECT_INFORMATION_CLASS; typedef struct _OBJECT_NAME_INFORMATION { UNICODE_STRING Name; } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; typedef struct _OBJECT_TYPE_INFORMATION { UNICODE_STRING TypeName; 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 ValidAccessMask; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; ULONG PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; // ----------------- Platform-like def #ifdef _WIN64 typedef PROCESS_BASIC_INFORMATION64 PROCESS_BASIC_INFORMATION; typedef PPROCESS_BASIC_INFORMATION64 PPROCESS_BASIC_INFORMATION; #else typedef PROCESS_BASIC_INFORMATION32 PROCESS_BASIC_INFORMATION; typedef PPROCESS_BASIC_INFORMATION32 PPROCESS_BASIC_INFORMATION; #endif // ----------------- Native API Prototypes typedef NTSTATUS (WINAPI *Prototype_NtQuerySystemInformation)( _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, _Inout_ PVOID SystemInformation, _In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength ); typedef NTSTATUS (WINAPI *Prototype_NtQueryInformationProcess)( _In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength ); typedef NTSTATUS (WINAPI *Prototype_NtQueryObject)( _In_opt_ HANDLE Handle, _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, _Out_opt_ PVOID ObjectInformation, _In_ ULONG ObjectInformationLength, _Out_opt_ PULONG ReturnLength ); #endif |
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | // -------------------------------------------------------------- // This is example, how to listing of processes which use the // specified file // by JKornev <c> http://k0rnev.blogspot.com // -------------------------------------------------------------- #include <stdio.h> #include <Windows.h> #include "ntdll.h" NT_DEF(NtQuerySystemInformation); NT_DEF(NtQueryInformationProcess); NT_DEF(NtQueryObject); typedef void (*enum_proc_callback)(DWORD pid, HANDLE hndl, void *param); bool EnumFileOwners(LPWSTR file_path, enum_proc_callback callback, void *param) { PSYSTEM_HANDLE_INFORMATION phinfo; PSYSTEM_HANDLE_TABLE_ENTRY_INFO pentry; POBJECT_TYPE_INFORMATION pobj_type; POBJECT_NAME_INFORMATION pobj_name; PVOID buf, buf_type[512]; ULONG count, res, size = 512, pid; HANDLE hobj = NULL, hproc = NULL; buf = new BYTE[size]; res = NtQuerySystemInformation(SystemHandleInformation, buf, size, &count); if (res != STATUS_SUCCESS) { if (res == STATUS_INFO_LENGTH_MISMATCH) { size = count; delete[] buf; try { buf = new BYTE[size]; } catch (...) { return 1; } res = NtQuerySystemInformation(SystemHandleInformation, buf, size, &count); if (res != STATUS_SUCCESS) { return 2; } } else { return 3; } } pid = 0; phinfo = (PSYSTEM_HANDLE_INFORMATION)buf; for (int i = 0; i < phinfo->NumberOfHandles; i++) { pentry = (PSYSTEM_HANDLE_TABLE_ENTRY_INFO)&phinfo->Handles[i]; if (pid != pentry->UniqueProcessId) { pid = pentry->UniqueProcessId; if (hproc) { CloseHandle(hproc); } hproc = OpenProcess(PROCESS_DUP_HANDLE, false, pentry->UniqueProcessId); if (!hproc) { continue; } } if (!DuplicateHandle(hproc, (HANDLE)pentry->HandleValue, GetCurrentProcess(), &hobj, 0, false, DUPLICATE_SAME_ACCESS)) { continue; } res = NtQueryObject(hobj, ObjectTypeInformation, &buf_type, sizeof(buf_type), &count); if (res != STATUS_SUCCESS) { CloseHandle(hobj); continue; } pobj_type = (POBJECT_TYPE_INFORMATION)buf_type; if (wcscmp(pobj_type->TypeName.Buffer, L"File")) { CloseHandle(hobj); continue; } res = NtQueryObject(hobj, ObjectNameInformation, &buf_type, sizeof(buf_type), &count); if (res != STATUS_SUCCESS) { CloseHandle(hobj); continue; } pobj_name = (POBJECT_NAME_INFORMATION)buf_type; if (!wcsicmp(pobj_name->Name.Buffer, file_path)) { callback(pentry->UniqueProcessId, (HANDLE)pentry->HandleValue, param); } CloseHandle(hobj); } if (hproc) { CloseHandle(hproc); } return true; } void output_proc_callback(DWORD pid, HANDLE hndl, void *) { printf("PID:%d, Handle:0x%X\n", pid, hndl); } BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) { LUID luid; BOOL bRet=FALSE; if (LookupPrivilegeValue(NULL, lpszPrivilege, &luid)) { TOKEN_PRIVILEGES tp; tp.PrivilegeCount=1; tp.Privileges[0].Luid=luid; tp.Privileges[0].Attributes=(bEnablePrivilege) ? SE_PRIVILEGE_ENABLED: 0; // // Enable the privilege or disable all privileges. // if (AdjustTokenPrivileges(hToken, FALSE, &tp, NULL, (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { // // Check to see if you have proper access. // You may get "ERROR_NOT_ALL_ASSIGNED". // bRet=(GetLastError() == ERROR_SUCCESS); } } return bRet; } int main(int argc, char* argv[]) { PSYSTEM_HANDLE_INFORMATION phinfo; PSYSTEM_HANDLE_TABLE_ENTRY_INFO pentry; NT_BIND(NtQuerySystemInformation); NT_BIND(NtQueryInformationProcess); NT_BIND(NtQueryObject); HANDLE hProcess = GetCurrentProcess(); HANDLE hToken; if (OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken)) { SetPrivilege(hToken, SE_DEBUG_NAME, TRUE); CloseHandle(hToken); } if (!EnumFileOwners(L"\\Device\\HarddiskVolume2\\test.txt", output_proc_callback, NULL)) { printf ("Enum error!\n"); } printf("end"); getchar(); return 0; } |
Комментариев нет:
Отправить комментарий