Geöffnete Dateien durch Prozess Id ermitteln
-
Hallo,
ich möchte gerne die aktuell geöffneten Dateien ermitteln. Bisher bekomme ich sowohl die aktuellen Prozess Ids, mit Hilfe eines Drivers und NtQuerySystemInformation. Außerdem bekomme ich die geöffneten Dateien (bzw. die die gerade bearbeitet werden) mittels ReadDirectoryChanges.
Das Problem ist, dass ich nicht beides zusammen bekomme um z.B. die Anwendung zu ermitteln, die auf eine Datei zugreift. Ich will also die geöffneten Dateien mit Hilfe der Prozess Id ermitteln. Im Prinzip ähnlich wie der ProzessMonitor von Sysinternals.
Kann mir da jemand einen Tipp oder Hinweis geben?
Achso und mit geöffnete Dateien meine ich nicht nur Exe oder DLL, sondern auch z.B. pdf, doc, cpp, etc.
Vielen Dank schonmal,
Marco
-
Nero14 schrieb:
Hallo,
ich möchte gerne die aktuell geöffneten Dateien ermitteln. Bisher bekomme ich sowohl die aktuellen Prozess Ids, mit Hilfe eines Drivers und NtQuerySystemInformation. Außerdem bekomme ich die geöffneten Dateien (bzw. die die gerade bearbeitet werden) mittels ReadDirectoryChanges.
Das Problem ist, dass ich nicht beides zusammen bekomme um z.B. die Anwendung zu ermitteln, die auf eine Datei zugreift. Ich will also die geöffneten Dateien mit Hilfe der Prozess Id ermitteln. Im Prinzip ähnlich wie der ProzessMonitor von Sysinternals.
Kann mir da jemand einen Tipp oder Hinweis geben?
Achso und mit geöffnete Dateien meine ich nicht nur Exe oder DLL, sondern auch z.B. pdf, doc, cpp, etc.
Vielen Dank schonmal,
Marco
Hat niemand eine Idee?

Muss man da vielleicht auch mit dem Treiber nach den aktuell geöffneten Dateien suchen?
-
das geht mit undokumentierten funktionen aus NTDLL. schau mal nach NtQuerySystemInformation und NtQueryObject. ich habe noch code liegen der genau das macht, kann ich sonst nachher posten.
-
Dafür wirst du einen Treiber benötigen. Im Usermode ist es kaum sicher möglich.
Siehe dazu hier
http://www.delphipraxis.net/topic119784_welche+prozess+greift+auf+datei+zu.html&highlight=unlocker
-
@ ascda: Kannst du deine Code mal posten, vielleicht hilft er ja weiter.
Die von dir genannten Funktionen sind mit bekannt, konnten mir aber bei der Namensfindung der Dateien auch nicht helfen. Vielleicht hab ich was übersehen.
Danke!
-
dafür brauchste doch keinen treiber
hier is mein code#ifndef _OPENFILES_H_ #define _OPENFILES_H_ #include <Windows.h> #include <tchar.h> /****************************/ typedef struct OPENFILE_S { TCHAR szFileName[MAX_PATH]; DWORD dwFlags; } OPENFILE_T, *POPENFILE_T; /* * GetNumOpenFiles - Returns the number of open files for a process. * * The function returns the number of open file handles for the specified * process. * * @pid * Identifier of the process to retrieve the number of open files for. * * @return * The number of open files on success, -1 on error. * */ int GetNumOpenFiles( DWORD pid ); /* * GetOpenFiles - Retrieves a list of open files for a process. * * The function retrieves a list of files opened by the specified process. * * @pid * Identifier of the process to retrieve the list of files for. * * @pFiles * Pointer to an array of POPENFILE_T structures that will receive the * information on the opened files. * * @pNumFiles * Maximum number of files to retrieve. * * @return * The function returns 1 on success, -1 on failure. * */ int GetOpenFiles( DWORD pid, POPENFILE_T pFiles, DWORD dwNumFiles ); /* * GetPIDsFromFile - Returns process identifiers of all processes that have * currently opened target file. * * @lpFileName * Name of the file to look up. * * @lpPIDs * Pointer to an array of DWORDs that will receive the process identifiers. * * @dwNumPIDs * Maximum number of entries to store in the buffer pointed to by lpPIDs. * * @return * The function returns the actual number of entries in lpPIDs on success, * -1 on failure. * */ int GetPIDsFromFile( PTCHAR lpFileName, PDWORD lpPIDs, DWORD dwNumPIDs ); /************** private **************/ #define NTSTATUS DWORD #define SYSTEM_INFORMATION_CLASS DWORD #define OBJECT_INFORMATION_CLASS DWORD #define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 #define DUPLICATE_SAME_ATTRIBUTES 0x00000004 #define SystemHandleInformation 0x10 #define ObjectBasicInformation 0x00 #define ObjectNameInformation 0x01 #define ObjectTypeInformation 0x02 typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG ProcessId; UCHAR ObjectTypeNumber; UCHAR Flags; USHORT Handle; PVOID Object; ACCESS_MASK GrantedAccess; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; typedef struct _OBJECT_BASIC_INFORMATION { ULONG Attributes; ACCESS_MASK DesiredAccess; ULONG HandleCount; ULONG ReferenceCount; ULONG PagedPoolUsage; ULONG NonPagedPoolUsage; ULONG Reserved[3]; ULONG NameInformationLength; ULONG TypeInformationLength; ULONG SecurityDescriptorLength; LARGE_INTEGER CreationTime; } OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION; typedef struct _OBJECT_TYPE_INFORMATION { UNICODE_STRING TypeName; ULONG TotalNumberOfHandles; ULONG TotalNumberOfObjects; WCHAR Unused1[8]; ULONG HighWaterNumberOfHandles; ULONG HighWaterNumberOfObjects; WCHAR Unused2[8]; ACCESS_MASK InvalidAttributes; GENERIC_MAPPING GenericMapping; ACCESS_MASK ValidAttributes; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; USHORT MaintainTypeList; DWORD PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; typedef struct _OBJECT_NAME_INFORMATION { UNICODE_STRING Name; WCHAR NameBuffer[0]; } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; typedef NTSTATUS (WINAPI *PFN_NtQuerySystemInformation)( SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG ); typedef NTSTATUS (WINAPI *PFN_NtQueryObject)( HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG); int DeviceToDosPath( PWCHAR lpDevice, PTCHAR lpDosPath, INT nSize ); #endif /* _OPENFILES_H_ */#include "openfiles.h" /* * GetNumOpenFiles - Returns the number of open files for a process. * * The function returns the number of open file handles for the specified * process. * * @pid * Identifier of the process to retrieve the number of open files for. * * @return * The number of open files on success, -1 on error. * */ int GetNumOpenFiles( DWORD pid ) { ULONG *p, n, i, count = 0; PSYSTEM_HANDLE_INFORMATION h; HANDLE hProcess; PFN_NtQuerySystemInformation NtQuerySystemInformation = (PFN_NtQuerySystemInformation) GetProcAddress(LoadLibrary("NTDLL"), "NtQuerySystemInformation"); PFN_NtQueryObject NtQueryObject = (PFN_NtQueryObject) GetProcAddress(LoadLibrary("NTDLL"), "NtQueryObject"); if(!NtQuerySystemInformation || !NtQueryObject) return -1; if(!(hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid))) return -1; n = 0x1000; p = malloc(sizeof(ULONG) * n); while(NtQuerySystemInformation(SystemHandleInformation, p, n * sizeof(*p), 0) == STATUS_INFO_LENGTH_MISMATCH) { free(p); n = n * 2; p = malloc(sizeof(ULONG) * n); } h = (PSYSTEM_HANDLE_INFORMATION)(p + 1); for(i = 0; i < *p; i++) { /* handle belongs to target process */ if(h[i].ProcessId == pid) count++; } CloseHandle(hProcess); free(p); return count; } /* * GetOpenFiles - Retrieves a list of open files for a process. * * The function retrieves a list of files opened by the specified * process. * * @pid * Identifier of the process to retrieve the list of files for. * * @pFiles * Pointer to an array of POPENFILE_T structures that will receive the * information on the opened files. * * @pNumFiles * Maximum number of files to retrieve. * * @return * The function returns the number of entries in pFiles on success, * -1 on failure. * */ int GetOpenFiles( DWORD pid, POPENFILE_T pFiles, DWORD dwNumFiles ) { ULONG *p, n, i, count = 0; PSYSTEM_HANDLE_INFORMATION h; HANDLE hProcess; PFN_NtQuerySystemInformation NtQuerySystemInformation = (PFN_NtQuerySystemInformation) GetProcAddress(LoadLibrary("NTDLL"), "NtQuerySystemInformation"); PFN_NtQueryObject NtQueryObject = (PFN_NtQueryObject) GetProcAddress(LoadLibrary("NTDLL"), "NtQueryObject"); if(!NtQuerySystemInformation || !NtQueryObject) return -1; if(!(hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid))) return -1; n = 0x1000; p = malloc(sizeof(ULONG) * n); while(NtQuerySystemInformation(SystemHandleInformation, p, n * sizeof(*p), 0) == STATUS_INFO_LENGTH_MISMATCH) { free(p); n = n * 2; p = malloc(sizeof(ULONG) * n); } h = (PSYSTEM_HANDLE_INFORMATION)(p + 1); for(i = 0; i < *p; i++) { if(count >= dwNumFiles) break; /* handle belongs to target process */ if(h[i].ProcessId == pid) { HANDLE hObject; OBJECT_BASIC_INFORMATION obi; OBJECT_NAME_INFORMATION *poni; if(!DuplicateHandle(hProcess, (HANDLE)h[i].Handle, GetCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ATTRIBUTES)) continue; NtQueryObject(hObject, ObjectBasicInformation, &obi, sizeof(obi), NULL); n = obi.NameInformationLength == 0 ? MAX_PATH * sizeof(WCHAR) : obi.NameInformationLength; poni = (POBJECT_NAME_INFORMATION)malloc(n); NtQueryObject(hObject, ObjectNameInformation, poni, n, NULL); /* convert from something like \Device\Harddisk0\some_file to dos drive letter path */ if(DeviceToDosPath(poni->Name.Buffer, pFiles[count].szFileName, sizeof(pFiles[count].szFileName))) { pFiles[count].dwFlags = h[i].GrantedAccess; count++; } CloseHandle(hObject); } } CloseHandle(hProcess); free(p); return count; } /* * GetPIDsFromFile - Returns process identifiers of all processes that have * currently opened target file. * * @lpFileName * Name of the file to look up. * * @lpPIDs * Pointer to an array of DWORDs that will receive the process identifiers. * * @dwNumPIDs * Maximum number of entries to store in the buffer pointed to by lpPIDs. * * @return * The function returns the actual number of entries in lpPIDs on success, * -1 on failure. * */ int GetPIDsFromFile( PTCHAR lpFileName, PDWORD lpPIDs, DWORD dwNumPIDs ) { ULONG *p, n, i, count = 0; PSYSTEM_HANDLE_INFORMATION h; HANDLE hProcess; PFN_NtQuerySystemInformation NtQuerySystemInformation = (PFN_NtQuerySystemInformation) GetProcAddress(LoadLibrary("NTDLL"), "NtQuerySystemInformation"); PFN_NtQueryObject NtQueryObject = (PFN_NtQueryObject) GetProcAddress(LoadLibrary("NTDLL"), "NtQueryObject"); if(!NtQuerySystemInformation || !NtQueryObject) return -1; n = 0x1000; p = malloc(sizeof(ULONG) * n); while(NtQuerySystemInformation(SystemHandleInformation, p, n * sizeof(*p), 0) == STATUS_INFO_LENGTH_MISMATCH) { free(p); n = n * 2; p = malloc(sizeof(ULONG) * n); } h = (PSYSTEM_HANDLE_INFORMATION)(p + 1); for(i = 0; i < *p; i++) { HANDLE hObject; OBJECT_BASIC_INFORMATION obi; OBJECT_NAME_INFORMATION *poni; TCHAR szFileName[MAX_PATH]; if(count >= dwNumPIDs) break; if(!(hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, h[i].ProcessId))) continue; if(!DuplicateHandle(hProcess, (HANDLE)h[i].Handle, GetCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ATTRIBUTES)) continue; CloseHandle(hProcess); NtQueryObject(hObject, ObjectBasicInformation, &obi, sizeof(obi), NULL); n = obi.NameInformationLength == 0 ? MAX_PATH * sizeof(WCHAR) : obi.NameInformationLength; poni = (POBJECT_NAME_INFORMATION)malloc(n); NtQueryObject(hObject, ObjectNameInformation, poni, n, NULL); if(DeviceToDosPath(poni->Name.Buffer, szFileName, sizeof(szFileName))) { if(!_tcscmp(lpFileName, szFileName)) lpPIDs[count++] = h[i].ProcessId; } CloseHandle(hObject); } free(p); return count; } /* * DeviceToDosPath - Converts Device Path to Dos Path. * */ int DeviceToDosPath( PWCHAR lpDevice, PTCHAR lpDosPath, INT nSize ) { int i; DWORD dwDrives; WCHAR szDev[MAX_PATH] = {0}, szRet[MAX_PATH], *p; if(!lpDevice) return 0; /* extract device path */ if(wcsncmp(lpDevice, L"\\Device\\", wcslen(L"\\Device\\"))) return 0; p = lpDevice + wcslen(L"\\Device\\"); while(*p != '\\') { if(*p == 0) return 0; p++; } wcsncpy(szDev, lpDevice, p - lpDevice); dwDrives = GetLogicalDrives(); for(i = 0; i < 32; i++) { if((dwDrives >> i) & 0x01) { WCHAR szDosDevice[MAX_PATH], szDrive[3] = L"A:"; szDrive[0] = 'A' + i; QueryDosDeviceW(szDrive, szDosDevice, sizeof(szDosDevice)); if(!wcscmp(szDev, szDosDevice)) { wcscpy(szRet, szDrive); wcsncat(szRet, p, nSize); #ifndef _UNICODE /* convert to single byte */ WideCharToMultiByte(CP_ACP, 0, szRet, wcslen(szRet) * sizeof(WCHAR), lpDosPath, nSize, NULL, NULL); #else wcscpy(lpDosPath, szRet); #endif } } } return 1; } /* example */ #if 0 int main(int argc, char *argv[]) { DWORD dwPIDs[10]; /* open some file */ HANDLE hFile = CreateFile("C:\\WINDOWS\\win.ini", GENERIC_EXECUTE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); /* get number of open files for this process */ DWORD dwNum = GetNumOpenFiles(GetCurrentProcessId()), i; POPENFILE_T pFiles; if(hFile == INVALID_HANDLE_VALUE) { printf("Could not open C:\\WINDOWS\\win.ini\n"); return 0; } /* get a list of all files this process has currently opened */ pFiles = (POPENFILE_T)malloc(sizeof(OPENFILE_T) * dwNum); dwNum = GetOpenFiles(GetCurrentProcessId(), pFiles, dwNum); printf("Process %i has handles for following files:\n\n", GetCurrentProcessId()); for(i = 0; i < dwNum; i++) printf("%s\n", pFiles[i].szFileName); printf("\n"); /* get a list of processes that have currently opened C:\WINDOWS\win.ini */ dwNum = GetPIDsFromFile( _T("C:\\WINDOWS\\win.ini"), dwPIDs, sizeof(dwPIDs) / sizeof(dwPIDs[0]) ); printf("%i processes have currently opened \"C:\\WINDOWS\\win.ini\" :\n\n", dwNum); for(i = 0; i < dwNum; i++) printf("- %i\n", dwPIDs[i]); free(pFiles); CloseHandle(hFile); return 0; } #endif
-
Vielen Dank ascda.

Ich hoffe das bringt es.