2017-01-27 2 views
-1

Ich versuche eine undokumentierte Funktion namens PsGetContextThread zu verwenden, um den Kontext eines Usermode-Threads von einem Treiber abzurufen. Ich weiß, dass dies von usermode möglich ist, aber ich habe meine Gründe dafür vom Kernel und das ist nicht verhandelbar, also bitte nicht ablenken. Jetzt zurück zum Thema, der Code unten, wenn debugged enthält einen gültigen Thread und alles sieht gut aus, aber es gibt ungültige mit Fehlercode C0000005 zurück, die ACCESS_VIOLATION ist, aber ich weiß nicht, wie dieser Code das auslösen könnte und würde einige Hilfe zu schätzen wissen dies aus, da ich schon eine ganze Weile hier feststecke.PsGetContextThread gibt C0000005 (ACCESS_VIOLATION) zurück

Wenn jemand weiß, was als nächstes zu versuchen oder Anregungen, bitte posten Sie unten.

+0

Nur um zu verstehen, was Sie tun: Sie verwenden eine ** undokumentierte ** Funktion, die vom ** Benutzer ** -Modus, ** Kernel ** -Modus aufgerufen werden soll. Und Sie fragen sich, warum es nicht funktioniert? Merken Sie etwas? – Olaf

+1

@Olaf Sie falsch liegen, PsGetContextThread soll nicht von usermode aufgerufen werden ... sein Teil des Kernels exportiert und kann von einem Treiber aufgerufen werden. der Zeiger auf die Funktion ist gültig, es ist der Aufruf selbst, der ACCESS_VIOLATION in der Statusvariablen – Paze

+0

zurückgibt. Ich vermute, das Problem ist, dass Sie eine Kernelmodus-Adresse '& context' übergeben, aber 'UserMode' angeben. Wenn 'UserMode' angegeben wird, prüft' PsGetContextThread' zuerst, dass '& context' ein gültiger Benutzermoduszeiger ist. Versuchen Sie stattdessen 'KernelMode' anzugeben. –

Antwort

0

ja, @HarryJohnston richtig, dass wenn wir UserModePsGetContextThread ist ein gültiger Benutzer-Modus-Zeiger. also müssen wir einen gültigen Benutzermoduszeiger dafür übergeben. wir können es durch Aufruf ZwAllocateVirtualMemory bekommen - diesen Code verwenden - das ist funktioniert

NTSTATUS GetThreadContext(PETHREAD thread, PCONTEXT ctx) 
{ 
#if 0 
    typedef NTSTATUS (NTAPI* GETSETCONTEXTTHREAD)(PETHREAD, PCONTEXT,MODE); 
    static GETSETCONTEXTTHREAD PsGetContextThread; 
    static BOOLEAN bInit; 

    if (!bInit) 
    { 
     STATIC_UNICODE_STRING(aPsGetContextThread, "PsGetContextThread"); 
     PsGetContextThread = (GETSETCONTEXTTHREAD)MmGetSystemRoutineAddress(&aPsGetContextThread); 
     bInit = TRUE; 
    } 

    if (!PsGetContextThread) 
    { 
     return STATUS_PROCEDURE_NOT_FOUND; 
    } 
#endif 

    CONTEXT * BaseAddress = 0; 
    SIZE_T Size = sizeof(CONTEXT); 
    NTSTATUS status = ZwAllocateVirtualMemory(NtCurrentProcess(), (void**)&BaseAddress, 0, &Size, MEM_COMMIT, PAGE_READWRITE); 
    if (0 <= status) 
    { 
     BaseAddress->ContextFlags = ctx->ContextFlags; 
     if (0 <= (status = PsGetContextThread(thread, BaseAddress, UserMode))) 
     { 
      memcpy(ctx, BaseAddress, sizeof(CONTEXT)); 
     } 
     ZwFreeVirtualMemory(NtCurrentProcess(), (void**)&BaseAddress, &Size, MEM_RELEASE); 
    } 

    return status; 
} 

und denken, müssen Sie nicht verwenden MmGetSystemRoutineAddress aber statischen Import PsGetContextThread, aber wenn man sowieso diesen Zeiger in Runtime will bekommen - nicht brauchen Mach das jedes Mal - aber nur einmal. make pointer to funktion static

Verwandte Themen