2017-01-27 12 views
-1

私はPsGetContextThreadと呼ばれる文書化されていない関数を使用してドライバからusermodeスレッドのコンテキストを取得しようとしていますが、これはusermodeから可能ですが、私はこれをカーネルから行う理由がありますこれは交渉可能なものではありませんので、そちらに進んでください。今話題に戻って、デバッグ時のコードには有効なスレッドが含まれていて、すべてがうまく見えますが、ACCESS_VIOLATIONのエラーコードC0000005が返されますが、このコードがどのようにトリガできるのか分かりません。これは私がかなり長い間このことに固執していたからです。PsGetContextThread C0000005(ACCESS_VIOLATION)を返す

NTSTATUS GetThreadContext(PETHREAD thread) { 
KPROCESSOR_MODE mode = UserMode; 
CONTEXT context; 
UNICODE_STRING setContextString, getContextString; 
pPsGetContextThread PsGetContextThread; 
NTSTATUS status = STATUS_SUCCESS; 

RtlInitUnicodeString(&getContextString, L"PsGetContextThread"); 
RtlZeroMemory(&context, sizeof(CONTEXT)); 

PsGetContextThread = (pPsGetContextThread)MmGetSystemRoutineAddress(&getContextString); 

context.ContextFlags = CONTEXT_FULL; 
status = PsGetContextThread(thread, &context, mode); 

if (!NT_SUCCESS(status)) { 
    return STATUS_UNSUCCESSFUL; 
} 

return STATUS_SUCCESS; 
} 

誰かが次に試してみたいことが分かっていたり、下記の投稿をしてください。

+0

**あなたは** ** kernel **モードから** user **モードから呼び出されることになっている**文書化されていない**関数を使用します。なぜそれがうまくいかないのだろうか?何か気付く? – Olaf

+1

@Olafあなたは間違っていますが、PsGetContextThreadはusermodeから呼び出されることは想定されていません...カーネルのエクスポートの一部であり、ドライバによって呼び出すことができます。関数へのポインタが有効であり、ACCESS_VIOLATIONをステータス変数 – Paze

+0

に返す呼び出し自体がカーネルモードのアドレス '&context'を渡しているのに' UserMode'を指定していると思われます。 'UserMode'が指定されたとき、' PsGetContextThread'が最初に行うのは '&context'が有効なユーザモードポインタであることをチェックすることです。代わりに 'KernelMode'を指定してみてください。 –

答えて

0

はい、@ HarryJohnston右指定したときUserModePsGetContextThread&contextが有効なユーザーモードポインタであることを確認します。そのために有効なユーザモードポインタを渡す必要があります。

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; 
} 

を動作し、あなたが使用MmGetSystemRoutineAddressが、静的インポートPsGetContextThreadを必要としないと思う、これはですが、とにかく、実行時にこのポインタを取得したい場合 - - このコードを使用する - 私たちは、コールZwAllocateVirtualMemoryによってそれを得ることができる必要はありません毎回これを行う - ただ一回。関数へのポインタを作成するstatic

関連する問題