2010-09-14 9 views
8

Ich bin eine einfache Kernel-Treiber für meine Anwendung zu schreiben (man denke an eine sehr einfache Anti-Malware-Anwendung.)Wie ZwQueryInformationProcess verwenden, um ProcessImageFileName in einem Kerneltreiber abzurufen?

Ich habe süchtig ZwOpenFile() und verwendet PsGetCurrentProcess() einen Griff an den Anrufer Prozess zu bekommen.

Es gibt eine PEPROCESS Struktur:

PEPROCESS proc = PsGetCurrentProcess(); 

ich ZwQueryInformationProcess() bin mit dem PID und ImageFileName zu erhalten:

DbgPrint("ZwOpenFile Called...\n"); 
DbgPrint("PID: %d\n", PsGetProcessId(proc)); 
DbgPrint("ImageFileName: %.16s\n", PsGetProcessImageFileName(proc)); 

und der Prozess FullPath diese Weise zu erhalten versuchen, (aber ich BSOD):

WCHAR strBuffer[260]; 
UNICODE_STRING str; 

//initialize 
str.Buffer = strBuffer; 
str.Length = 0x0; 
str.MaximumLength = sizeof(strBuffer); 

//note that the seconds arg (27) is ProcessImageFileName 
ZwQueryInformationProcess(proc, 27, &str, sizeof(str), NULL); 

DbgPrint("FullPath: %wZ\n", str.Buffer); 

012 Wie Sie sehen, ist str.Buffer leer oder mit Müll gefüllt. Möglicherweise löst ein Pufferüberlauf beim Füllen der str über ZwQueryInformationProcess() den BSOD aus.

alt text

Jede Hilfe würde geschätzt.

Antwort

6

die MSDN-Dokumentation für diese API anzuzeigen, dass

Wenn die ProcessInformationClass Parameter ProcessImageFileName die Puffer auf dem durch die ProcessInformation Parameter sind groß genug sein sollen, eine UNICODE_STRING Struktur und zu halten, wie die Zeichenfolge selbst. Die Zeichenfolge, die im Pufferelement gespeichert ist, ist der Name des Bildes file.file.

dies mit im Auge, ich schlage vor, Sie versuchen, Ihren Pufferstruktur wie folgt ändern:

Zusätzlich
WCHAR strBuffer[(sizeof(UNICODE_STRING)/sizeof(WCHAR)) + 260]; 
UNICODE_STRING str; 
str = (UNICODE_STRING*)&strBuffer; 

//initialize 
str.Buffer = &strBuffer[sizeof(UNICODE_STRING)/sizeof(WCHAR)]; 
str.Length = 0x0; 
str.MaximumLength = 260 * sizeof(WCHAR); 

//note that the seconds arg (27) is ProcessImageFileName 
ZwQueryInformationProcess(proc, 27, &strBuffer, sizeof(strBuffer), NULL); 

, muss Ihr Code, um den Fehlerfall in den hier beschriebenen Dokumente zu überprüfen und zu handhaben. Dies könnte der Grund sein, warum Sie den BSOD-Trigger-Fall verpasst haben.

Wenn der Puffer zu klein ist, schlägt die Funktion mit dem STATUS_INFO_LENGTH_MISMATCH Fehlercode und der ReturnLength Parameter auf die erforderliche Puffergröße eingestellt ist.

0

ZwQueryInformationProcess braucht ein HANDLE, kein PROCESS! Sie müssen ObOpenObjectByPointer verwenden, um das Handle zuerst zu erhalten.

1

// Deklarieren Sie dieses Codeteil in der Headerdatei, sofern vor der Funktionsdefinition verfügbar.

typedef NTSTATUS (*QUERY_INFO_PROCESS) (
__in HANDLE ProcessHandle, 
__in PROCESSINFOCLASS ProcessInformationClass, 
__out_bcount(ProcessInformationLength) PVOID ProcessInformation, 
__in ULONG ProcessInformationLength, 
__out_opt PULONG ReturnLength 
); 

QUERY_INFO_PROCESS ZwQueryInformationProcess; 

// Funktion Definition

NTSTATUS GetProcessImageName(HANDLE processId, PUNICODE_STRING ProcessImageName) 
{ 
NTSTATUS status; 
ULONG returnedLength; 
ULONG bufferLength; 
HANDLE hProcess; 
PVOID buffer; 
PEPROCESS eProcess; 
PUNICODE_STRING imageName; 

PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process 

status = PsLookupProcessByProcessId(processId, &eProcess); 

if(NT_SUCCESS(status)) 
{ 
    status = ObOpenObjectByPointer(eProcess,0, NULL, 0,0,KernelMode,&hProcess); 
    if(NT_SUCCESS(status)) 
    { 
    } else { 
     DbgPrint("ObOpenObjectByPointer Failed: %08x\n", status); 
    } 
    ObDereferenceObject(eProcess); 
} else { 
    DbgPrint("PsLookupProcessByProcessId Failed: %08x\n", status); 
} 


if (NULL == ZwQueryInformationProcess) { 

    UNICODE_STRING routineName; 

    RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess"); 

    ZwQueryInformationProcess = 
      (QUERY_INFO_PROCESS) MmGetSystemRoutineAddress(&routineName); 

    if (NULL == ZwQueryInformationProcess) { 
     DbgPrint("Cannot resolve ZwQueryInformationProcess\n"); 
    } 
} 

/* Query the actual size of the process path */ 
status = ZwQueryInformationProcess(hProcess, 
            ProcessImageFileName, 
            NULL, // buffer 
            0, // buffer size 
            &returnedLength); 

if (STATUS_INFO_LENGTH_MISMATCH != status) { 
    return status; 
} 

/* Check there is enough space to store the actual process 
    path when it is found. If not return an error with the 
    required size */ 
bufferLength = returnedLength - sizeof(UNICODE_STRING); 
if (ProcessImageName->MaximumLength < bufferLength) 
{ 
    ProcessImageName->MaximumLength = (USHORT) bufferLength; 
    return STATUS_BUFFER_OVERFLOW; 
} 

/* Allocate a temporary buffer to store the path name */ 
buffer = ExAllocatePoolWithTag(NonPagedPool, returnedLength, 'uLT1'); 

if (NULL == buffer) 
{ 
    return STATUS_INSUFFICIENT_RESOURCES; 
} 

/* Retrieve the process path from the handle to the process */ 
status = ZwQueryInformationProcess(hProcess, 
            ProcessImageFileName, 
            buffer, 
            returnedLength, 
            &returnedLength); 

if (NT_SUCCESS(status)) 
{ 
    /* Copy the path name */ 
    imageName = (PUNICODE_STRING) buffer; 
    RtlCopyUnicodeString(ProcessImageName, imageName); 
} 

/* Free the temp buffer which stored the path */ 
ExFreePoolWithTag(buffer, 'uLT1'); 

return status; 
} 

// Function Call .. dieses Stück Code in PreOperation Anruf schreiben zurück und IRQ sollte PASSIVE_LEVEL

PEPROCESS objCurProcess=NULL; 
HANDLE hProcess; 
UNICODE_STRING fullPath; 

objCurProcess=IoThreadToProcess(Data->Thread);//Note: Date is type of FLT_CALLBACK_DATA which is in PreOperation Callback as argument 

hProcess=PsGetProcessID(objCurProcess); 

fullPath.Length=0; 
fullPath.MaximumLength=520; 
fullPath.Buffer=(PWSTR)ExAllocatePoolWithTag(NonPagedPool,520,'uUT1'); 

GetProcessImageName(hProcess,&fullPath); 

in fullPath variabel ist Vollständiger Prozesspfad. Wenn der Prozess explorer.exe ist, wird der Pfad wie folgt aussehen: -

\Device\HarddiskVolume3\Windows\explorer.exe 

Hinweis: - \ Device \ HarddiskVolume3 Der Pfad kann aufgrund von Machine und unterschiedlichem Volume in der Festplatte geändert werden. Dies ist ein Beispiel in meinem Fall.

Verwandte Themen