PDA

Visualizza la versione completa : [C] NtQuerySystemInformations and NtQueryObject


daniele_dll
16-01-2006, 19:58
hola

ho la necessità di sviluppare una libreria o comunque del codice che poi in un secondo momento dovrò convertire in C# (ma al momento mi interessa scrivere il codice in C), che si occupi di elencare gli handle aperti tramite l'object manager di windows e di recuperare da li gli handle dei file

per far questo devo usare NtQuerySystemInformations per elencare i vari handle, dopo di che devo ciclare i dati estratti, verificare che ObjectType corrisponda a OB_TYPE_FILE ed infine estrarre le informazioni sul nome del file, tramite NtQueryObject

ho cross-forum-postato anche sul forum di sysinternals.com, dato che mi interessa ricreare le funzionalità di handle (il loro software che fa questo stesso tipo di operazioni)

il thread l'ho aperto a quest'indirizzo
http://www.sysinternals.com/Forum/forum_posts.asp?TID=3577&PN=1

li ci sta già del codice postato, comunque riposto qui anche il codice



LPWSTR GetObjectName(HANDLE hObject)
{
LPWSTR lpwsReturn = NULL;
if(pNTQO != NULL){
DWORD dwSize = sizeof(OBJECT_NAME_INFORMATION);
POBJECT_NAME_INFORMATION pObjectInfo = (POBJECT_NAME_INFORMATION) new BYTE[dwSize];
NTSTATUS ntReturn = pNTQO(hObject, ObjectNameInformation, pObjectInfo, dwSize, &dwSize);
if(ntReturn == STATUS_BUFFER_OVERFLOW){
delete pObjectInfo;
pObjectInfo = (POBJECT_NAME_INFORMATION) new BYTE[dwSize];
ntReturn = pNTQO(hObject, ObjectNameInformation, pObjectInfo, dwSize, &dwSize);
}
if((ntReturn >= STATUS_SUCCESS) && (pObjectInfo->Buffer != NULL))
{
lpwsReturn = (LPWSTR) new BYTE[pObjectInfo->Length + sizeof(WCHAR)];
ZeroMemory(lpwsReturn, pObjectInfo->Length + sizeof(WCHAR));
CopyMemory(lpwsReturn, pObjectInfo->Buffer, pObjectInfo->Length);
}
delete pObjectInfo;
}
return lpwsReturn;
}

int main(int argc, char *argv[])
{
EnableDebugPrivilege();

pNTQO = (tNTQO)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQueryObject");
pNTQSI = (tNTQSI)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQuerySystemInformation");

if(pNTQSI != NULL)
{
DWORD dwSize = sizeof(SYSTEM_HANDLE_INFORMATION);
PSYSTEM_HANDLE_INFORMATION pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) new BYTE[dwSize];
NTSTATUS ntReturn = pNTQSI(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
if(ntReturn == STATUS_INFO_LENGTH_MISMATCH)
{
delete pHandleInfo;
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) new BYTE[dwSize];
ntReturn = pNTQSI(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
}
if(ntReturn == STATUS_SUCCESS)
{
printf(" Found %d Handles. Listing File Handles...\n\n", pHandleInfo->uCount);
printf(" PID\tHandle\tObject Type\tObject Name\n");
for(DWORD dwIdx = 0; dwIdx < pHandleInfo->uCount; dwIdx++)
{
printf("%5d\t%6d\t%ws",
pHandleInfo->Handles[dwIdx].uIdProcess,
pHandleInfo->Handles[dwIdx].Handle,
GetObjectType(pHandleInfo->Handles[dwIdx].ObjectType));

LPWSTR lpwsName = GetObjectName((HANDLE)pHandleInfo->Handles[dwIdx].Handle);
if(lpwsName != NULL)
{
printf("\t%ws", lpwsName);
delete lpwsName;
}

printf("\n", lpwsName);
}
printf("\n\n");
}
else
{
printf("Error while trying to allocate memory for System Handle Information.\n");
}
delete pHandleInfo;
}
else
{
printf("Cannot find NtQuerySystemInformation API... Is this system not Win2K and above?");
}

return 0;
}

ora riscontro principalmente 2 problemi:
- ObjectType è SEMPRE uguale a 28, e la cosa è assurda dato che il valore più alto di OB_TYPE_* corrisponde a 23 ed è OB_TYPE_FILE
- la funzione GetObjectName mi restituisce MOLTO SPESSO un valore null, ed è assurdo, dato che il codice è corretto ma so per certo che mi stampa un'elenco "accorciato" perché il loro software handle (della sysinternals) mi stampa a video molto più roba e se mi faccio stampare a video gli handle anche se ricevo il valore null trovo corrispondenze nell'elenco del software della sysinternals

Prima di arrivare qua ho sudato come un maniale, poi ho trovato il forum di sysinternals ed in un post c'era un codice che serviva a stampare a video tutti gli handle delle socket aperte (TCP e UDP) ... ed ho utilizzato quello come codebase

PS: se volete il codice per intero ditemelo che ve lo spedisco

daniele_dll
17-01-2006, 10:51
uppete ... nessuno ha idee? :stordita:

daniele_dll
18-01-2006, 14:18
posso esultare con un

ALLELUIA!!!

se a qualcuno interessasse la soluzione del problema
http://groups.google.it/group/it.comp.programmare.win32/browse_frm/thread/14dbbdcc9f8f4994/d010a214c87da6c3#d010a214c87da6c3

:unz: :unz: :unz:

ora devo solo convertire TUTTO il codice in C#

daniele_dll
18-01-2006, 15:01
per chi fosse interessato ... per convertire l'handle nel nome del file ...

NtQueryInformationFile

è l'API nativa (conviene comunque usare il wrapper ZwQueryInformationFile anche se teoricamente dovrebbe essere perfettamente uguale)

La dichiarazione è di questo tipo
HANDLE, PVOID, PVOID, DWORD, DWORD

di cui il secondo ed il terzo sono in USCITA mentre tutti gli altri sono in ingresso

- Il primo parametro è l'handle del file
- il secondo non so cosa sia, ma da quanto ho capito non serve se deve semplicemente essere letto solo il nome, la struttura e grande 6 BYTE, tanto che nel codice viene dichiarato come un'array di 3 DWORD
- il terzo è il nome del file nella forma \Device\HarddiskX\path\to\file
- il 4° è la dimensione del buffer
- il 5° è il tipo di richiesta da eseguire, e per leggere semplicemente il nome del file basta passargli 9, ovvero, se avete il DDK, FileNameInformation dell'enum _FILE_INFORMATION_CLASS

Il 3° parametro il codice lo passa come un'array di unsigned char di 1001 elementi, personalmente lo trovo sovra dimensionato dato che oltre 255 caratteri le path non possono essere e considerato che ci sta il nome del device all'inizio anche 300 potrebe andare bene, comunque per salvare capre e cavoli 500 elementi sono + che sufficenti

per completare l'informazione ... questa e le altre api stanno dentro ntdll.dll

daniele_dll
18-01-2006, 22:26
finalmente sono riuscito a fare tutto

domattina posto una pillola sulla cosa dato che immagino che chi dovrà sbatterci la testa contro senza avere il DDK vedrà le stelle al cubo :stordita:

Loading