首页
社区
课程
招聘
[求助]PsGetContextThread的问题
发表于: 2016-2-4 16:25 9467

[求助]PsGetContextThread的问题

2016-2-4 16:25
9467
UNICODE_STRING ustr;
									RtlInitUnicodeString(&ustr, L"PsGetContextThread");
									TCONTEXT context = *(PTCONTEXT)inputBuffer;
									PSGETCT  PsGetContextThread = (PSGETCT)MmGetSystemRoutineAddress(&ustr);
									PETHREAD  EThread = NULL;
									if (NULL != PsGetContextThread)
									{
										THREAD_BASIC_INFORMATION tbi;
										RtlInitUnicodeString(&ustr, L"ZwQueryInformationThread");
										PFN_ZwQueryInformationThread ZwQueryInformationThread = (PFN_ZwQueryInformationThread)MmGetSystemRoutineAddress(&ustr);
										if (NULL!=ZwQueryInformationThread)
										{
											ZwQueryInformationThread(context.hThread,
												ThreadBasicInformation,
												&tbi,
												sizeof   (tbi),
												NULL);
											
											Status = PsLookupThreadByThreadId(tbi.ClientId.UniqueThread, &EThread);
											if (EThread != NULL)
											{

												Status = PsGetContextThread(EThread, &context.Context,UserMode);
												DbgPrint("1->EThread:%x\nEax:%x\nEbx:%x\nEcx:%x\nEdx:%x\n",
													EThread,
													context.Context.Eax,
													context.Context.Ebx,
													context.Context.Ecx,
													context.Context.Edx);
												RtlMoveMemory_S(outputBuffer, &context, outputBufferLength);
												if (!NT_SUCCESS(Status))
													DbgPrint("Error Code:%x\n", Status);
											}
											else
											{
												 DbgPrint("Can not get EThread:%x\n", Status);
											}
										}
										else
										{
											DbgPrint("Can not get function addr!2\n");
										}


									}
									else
									{
										DbgPrint("Can not get function addr!\n");
									}

如上述
我在R3Suspend了他 ,之后调用这个函数 FLAG用的是THREAD_GET_CONTEXT  
然后他返回的 STATUS 为C0000005 STATUS_ACCESS_VIOLATION
开始我以为是Flag的问题 我就改成了CONTEXT_FULL 同样是返回C0000005

请问这个是什么问题
小白现在这里谢谢大家了

对了 TCONTEXT 结构为
typedef struct _TCONTEXT
{
        HANDLE hThread;
        CONTEXT Context;
}TCONTEXT, *PTCONTEXT;

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 40
活跃值: (627)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
= =默默问下context.ContextFlags是啥
2016-2-5 04:03
0
雪    币: 26
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
试了几个都没有,会说大大能不能给个栗子
比如说CONTEXT_FULL CONTEXT_CONTROL
2016-2-5 10:13
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
4
PsGetContextThread是这么用的? 难道不是这个样子?

NTSTATUS
PsGetContextThread(
    __in PETHREAD Thread,
    __inout PCONTEXT ThreadContext,
    __in KPROCESSOR_MODE Mode
    )

/*++

Routine Description:

    This function returns the usermode context of the specified thread. This
    function will fail if the specified thread is a system thread. It will
    return the wrong answer if the thread is a non-system thread that does
    not execute in user-mode.

Arguments:

    Thread -       Supplies a pointer to the thread object from
                   which to retrieve context information.

    ThreadContext - Supplies the address of a buffer that will receive
                    the context of the specified thread.

    Mode          - Mode to use for validation checks.

Return Value:

    None.

--*/


看楼主的参数,想调用的应该是这个函数吧:
NTSTATUS
NtGetContextThread(
    __in HANDLE ThreadHandle,
    __inout PCONTEXT ThreadContext
    )

/*++

Routine Description:

    This function returns the usermode context of the specified thread. This
    function will fail if the specified thread is a system thread. It will
    return the wrong answer if the thread is a non-system thread that does
    not execute in user-mode.

Arguments:

    ThreadHandle - Supplies an open handle to the thread object from
                   which to retrieve context information.  The handle
                   must allow THREAD_GET_CONTEXT access to the thread.

    ThreadContext - Supplies the address of a buffer that will receive
                    the context of the specified thread.

Return Value:

    None.

--*/


可惜这个函数没导出,ZwGetContextThread也没导出,所以不能直接这样用
但是PsGetContextThread是导出的,可以直接用,可是楼主好像没搞清楚参数
2016-2-5 11:59
0
雪    币: 26
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
的确是的 我把它手动声明了
昨天中午的确错了,后来自己找到了问题
改成了 现在的代码
麻烦大神再看看
如果我使用 KernelMode就返回C0000005
   如果使用  UserMode  就返回C0000006
2016-2-5 12:54
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
6
你这代码,简直不忍直视。。。
首先,从Handle到Object,只需要ObRefrenceObjectByHandle就可以了,不需要Query再Lookup。。。。
其次,PsGetContextThread的第三个参数也不是你想怎么样就怎么样的,它的主要作用是,当参数是UserMode的时候,它会检查第二个输出缓冲区的地址是不是用户空间的有效地址。明显,虽然你给的context是来自于用户空间的,但是已经经过了映射,所以应该是算做内核空间地址(也就是说,context实际上是一个大于0x80000000的内核地址),这里应该用KernelMode。

还有这句:
RtlMoveMemory_S(outputBuffer, &context, outputBufferLength);


你搞清楚输入输出的缓冲区关系再说吧,而且第三个参数怎么说也应该是sizeof(CONTEXT)吧?

最后给你贴个代码,我只能帮你到这儿了:
NTSTATUS
NtGetContextThread(
    __in HANDLE ThreadHandle,
    __inout PCONTEXT ThreadContext
    )

/*++

Routine Description:

    This function returns the usermode context of the specified thread. This
    function will fail if the specified thread is a system thread. It will
    return the wrong answer if the thread is a non-system thread that does
    not execute in user-mode.

Arguments:

    ThreadHandle - Supplies an open handle to the thread object from
                   which to retrieve context information.  The handle
                   must allow THREAD_GET_CONTEXT access to the thread.

    ThreadContext - Supplies the address of a buffer that will receive
                    the context of the specified thread.

Return Value:

    None.

--*/

{

    KPROCESSOR_MODE Mode;
    NTSTATUS Status;
    PETHREAD Thread;
    PETHREAD CurrentThread;

    PAGED_CODE();

    //
    // Get previous mode and reference specified thread.
    //

    CurrentThread = PsGetCurrentThread ();
    Mode = KeGetPreviousModeByThread (&CurrentThread->Tcb);

    Status = ObReferenceObjectByHandle (ThreadHandle,
                                        THREAD_GET_CONTEXT,
                                        PsThreadType,
                                        Mode,
                                        &Thread,
                                        NULL);

    //
    // If the reference was successful, the check if the specified thread
    // is a system thread.
    //

    if (NT_SUCCESS (Status)) {

        //
        // If the thread is not a system thread, then attempt to get the
        // context of the thread.
        //

        if (IS_SYSTEM_THREAD (Thread) == FALSE) {

            Status = PsGetContextThread (Thread, ThreadContext, Mode);

        } else {
            Status = STATUS_INVALID_HANDLE;
        }

        ObDereferenceObject (Thread);
    }

    return Status;
}
2016-2-5 17:46
0
雪    币: 26
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
谢谢,我已经看了wrk的代码
还有移动内存的第三个参数我是以应用层传递的大小为准
以免导致应用层内存溢出
而且那个context的类型是我自定义的类型
我已经解决了,谢谢你
2016-2-6 01:48
0
游客
登录 | 注册 方可回帖
返回
//