首页
社区
课程
招聘
[求助] PsGetNextProcessThread 无法调用
发表于: 2018-8-5 22:16 4420

[求助] PsGetNextProcessThread 无法调用

2018-8-5 22:16
4420
求助大神,想在内核中枚举进程的线程,因为 ThreadListHead 偏移不好找,所以用PsResumeProcess定位PsGetNextProcessThread来枚举线程。
代码是这样的:
PEPROCESS pEProcess;
status = PsLookupProcessByProcessId((HANDLE)pid, &pEProcess);
if (NT_SUCCESS(status))
{
    PETHREAD pEThread;
    for (pEThread = PsGetNextProcessThread(pEProcess, NULL); pEThread != NULL; pEThread = PsGetNextProcessThread(pEProcess, pEThread))
    {
        //操作线程...
        pEThread = (PETHREAD)PsGetNextProcessThread(pEProcess, pEThread);
    }
}
但是一旦调用系统立马卡死(Win7 32位),Win10则是直接蓝屏,windbg调试显示 :
Access violation - code c0000005 (!!! second chance !!!)
nt!ObReferenceObjectSafe+0x3:
83ea13f5 8b0a            mov     ecx,dword ptr [edx]
看了看WRK的函数源码,对应 ObReferenceObjectSafe 第一行 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object );

经过测试,单单调用这一句 PsGetNextProcessThread(PsGetCurrentProcess(), NULL); 就会出现问题。这难道是BUG?
可是 PsEnumProcessThreads 、NtTerminateProcess函数都是这样调用的,难道是我调用不对
(经过ida和windbg反汇编,确认PsGetNextProcessThread地址获取正确)

求大神帮忙看看,这到底是什么问题 

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

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 407
活跃值: (1821)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这个问题我也遇到过。不过我当时是用符号获取的PsGetNextProcessThread地址,但是只要调用就爆炸了。后来乖乖的用ZwGetNextThread
2018-8-6 08:51
0
雪    币: 12848
活跃值: (9147)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
3
你确定32位下这玩意是STDCALL?在32位ntos里很多非导出函数会被优化成rax传参、rsi传参之类的奇葩东西
2018-8-6 09:42
0
雪    币: 3586
活跃值: (4729)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
hzqst 你确定32位下这玩意是STDCALL?在32位ntos里很多非导出函数会被优化成rax传参、rsi传参之类的奇葩东西
导出就不会了 没导出就会存在优化 建议写个包装
2018-8-6 16:59
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
hzqst 你确定32位下这玩意是STDCALL?在32位ntos里很多非导出函数会被优化成rax传参、rsi传参之类的奇葩东西
多谢大神指点,问题解决了
2018-8-7 11:48
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
hzqst 你确定32位下这玩意是STDCALL?在32位ntos里很多非导出函数会被优化成rax传参、rsi传参之类的奇葩东西

我发现PsResumeProcess调用PsGetNextProcessThread第一个参数是eax传参,第二个参数竟然是用ebx,然后返回的线程PETHREAD也在ebx里。

NTSTATUS MyEnumProcessPGNPT(PEPROCESS Process)
{
    NTSTATUS Status = STATUS_SUCCESS;
    __asm {
        mov ebx, 0
        jmp Loop
    Work:
        mov eax, ebx
        push eax
        call MySolveThread
        mov[Status], eax
        push ebx
    Loop:
        mov eax, [Process]
        call PsGetNextProcessThread
        mov ebx, eax
        test ebx, ebx
        jnz short Work
    }
    return Status;
}
NTSTATUS MySolveThread(PETHREAD Thread)
{
    //...
}
这个只适用于win7 32位,其他系统可能需要修改
2018-8-7 12:14
0
雪    币: 5734
活跃值: (1737)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
为啥不试试标准方法 枚举线程
2018-8-9 21:55
0
游客
登录 | 注册 方可回帖
返回
//