看流星社区

 找回密码
 注册账号
查看: 2152|回复: 0

在PsIsSystemThread中得到线程的是否为系统线程的标志

[复制链接]

该用户从未签到

发表于 2017-6-2 13:31:21 | 显示全部楼层 |阅读模式
一直好奇将一个进程的所有线程的线程标志改成Terminated后,这个进程会自动结束吗?还是这个进程只是被设置成了结束标志,而实际还在运行?想写个程序试验一下,但问题来了,怎么得到线程的标志呢?在PsIsSystemThread中得到线程的是否为系统线程的标志win xp 下的ntoskrnl.exe文件中的PsIsSystemThread的函数:; Attributes: bp-based frame; __stdcall PsIsSystemThread(x)public _PsIsSystemThread@4_PsIsSystemThread@4 proc neararg_0= dword ptr  8mov     edi, edi        ; IoIsSystemThreadpush    ebpmov     ebp, espmov     eax, [ebp+arg_0]mov     eax, [eax+248h]shr     eax, 4and     al, 1pop     ebpretn    4_PsIsSystemThread@4 endpF5一下下:char __stdcall PsIsSystemThread(int a1){  return (*(_DWORD *)(a1 + 0x248) >> 4) & 1;}比较下面来自官方的声明PsIsSystemThread routineThePsIsSystemThreadroutine checks whether a given thread is a system thread.SyntaxC++BOOLEAN PsIsSystemThread(
  _In_PETHREAD Thread
);

ParametersThread[in]Pointer to the thread to be checked.Return valuePsIsSystemThreadreturnsTRUEif the specified thread is a system thread,FALSEotherwise.来源:<http://msdn.microsoft.com/zh-cn/library/ff559945(v=vs.85).aspx>可以猜测a1 + 0x248就是线程权限的标识。我们在xp系统上看一下:nt!_ETHREAD   +0x000 Tcb              : _KTHREAD   +0x1c0 CreateTime       : _LARGE_INTEGER   +0x1c0 NestedFaultCount : Pos 0, 2 Bits   +0x1c0 ApcNeeded        : Pos 2, 1 Bit   +0x1c8 ExitTime         : _LARGE_INTEGER   +0x1c8 LpcReplyChain    : _LIST_ENTRY   +0x1c8 KeyedWaitChain   : _LIST_ENTRY   +0x1d0 ExitStatus       : Int4B   +0x1d0 OfsChain         : Ptr32 Void   +0x1d4 PostBlockList    : _LIST_ENTRY   +0x1dc TerminationPort  : Ptr32 _TERMINATION_PORT   +0x1dc ReaperLink       : Ptr32 _ETHREAD   +0x1dc KeyedWaitValue   : Ptr32 Void   +0x1e0 ActiveTimerListLock : Uint4B   +0x1e4 ActiveTimerListHead : _LIST_ENTRY   +0x1ec Cid              : _CLIENT_ID   +0x1f4 LpcReplySemaphore : _KSEMAPHORE   +0x1f4 KeyedWaitSemaphore : _KSEMAPHORE   +0x208 LpcReplyMessage  : Ptr32 Void   +0x208 LpcWaitingOnPort : Ptr32 Void   +0x20c ImpersonationInfo : Ptr32 _PS_IMPERSONATION_INFORMATION   +0x210 IrpList          : _LIST_ENTRY   +0x218 TopLevelIrp      : Uint4B   +0x21c DeviceToVerify   : Ptr32 _DEVICE_OBJECT   +0x220 ThreadsProcess   : Ptr32 _EPROCESS   +0x224 StartAddress     : Ptr32 Void   +0x228 Win32StartAddress : Ptr32 Void   +0x228 LpcReceivedMessageId : Uint4B   +0x22c ThreadListEntry  : _LIST_ENTRY   +0x234 RundownProtect   : _EX_RUNDOWN_REF   +0x238 ThreadLock       : _EX_PUSH_LOCK   +0x23c LpcReplyMessageId : Uint4B   +0x240 ReadClusterSize  : Uint4B   +0x244 GrantedAccess    : Uint4B   +0x248 CrossThreadFlags : Uint4B   +0x248 Terminated       : Pos 0, 1 Bit   +0x248 DeadThread       : Pos 1, 1 Bit   +0x248 HideFromDebugger : Pos 2, 1 Bit   +0x248 ActiveImpersonationInfo : Pos 3, 1 Bit   +0x248 SystemThread     : Pos 4, 1 Bit   +0x248 HardErrorsAreDisabled : Pos 5, 1 Bit   +0x248 BreakOnTermination : Pos 6, 1 Bit   +0x248 SkipCreationMsg  : Pos 7, 1 Bit   +0x248 SkipTerminationMsg : Pos 8, 1 Bit   +0x24c SameThreadPassiveFlags : Uint4B   +0x24c ActiveExWorker   : Pos 0, 1 Bit   +0x24c ExWorkerCanWaitUser : Pos 1, 1 Bit   +0x24c MemoryMaker      : Pos 2, 1 Bit   +0x250 SameThreadApcFlags : Uint4B   +0x250 LpcReceivedMsgIdValid : Pos 0, 1 Bit   +0x250 LpcExitThreadCalled : Pos 1, 1 Bit   +0x250 AddressSpaceOwner : Pos 2, 1 Bit   +0x254 ForwardClusterOnly : UChar   +0x255 DisablePageFaultClustering : UChar果然,那么我们可以通过在PsIsSystemThread函数中查找特征码的方法来取得线程的标识。如果要保护进程,我们可以将进程的所有线程的线程标志都设置成SystemThread。1. PsIsSystemThread是导出但未声明的函数,只需要声明一下就可以使用了。声明:BOOLEAN PsIsSystemThread(  _In_  PETHREAD Thread);
蓝屏原因:机器上PsIsSystemThread函数的地址并不是函数的真实地址,而是jmp指令,指令的目的地才地函数的真实地址。f8be2520 ff251826bef8    jmp     dword ptr ds:[0F8BE2618h]问题来了,之一:为什么得到的函数地址不是真实地址,是系统本身就是JMP样子的还是被机器上的安全软件给修改成JMP的?验证方法:回复快照,看最原始的系统中这个地方是不是也是JMP?在干净的系统上,uf函数总是能看到真正的地址:lkd> uf PsIsSystemThreadnt!IoIsSystemThread:804ef8a2 8bff            mov     edi,edi804ef8a4 55              push    ebp804ef8a5 8bec            mov     ebp,esp804ef8a7 8b4508          mov     eax,dword ptr [ebp+8]804ef8aa 8b8048020000    mov     eax,dword ptr [eax+248h]804ef8b0 c1e804          shr     eax,4804ef8b3 2401            and     al,1804ef8b5 5d              pop     ebp804ef8b6 c20400          ret     4而在程序中看到的都是JMP地址:BOOLEAN PsIsSystemThread(PETHREAD Thread);dprintf("PsIsSystemThread:0X%08X\n", (PULONG)pPsIsSystemThread);看来系统本身就是JMP地址。通过x nt!PsIsSystemThread看看结果,得到函数真实地址,函数真实地址的地方是不是FF 25而函数的真实地址是804ef8a2lkd> uf PsIsSystemThreadnt!IoIsSystemThread:804ef8a2 8bff            mov     edi,edi804ef8a4 55              push    ebp804ef8a5 8bec            mov     ebp,esp804ef8a7 8b4508          mov     eax,dword ptr [ebp+8]804ef8aa 8b8048020000    mov     eax,dword ptr [eax+248h]804ef8b0 c1e804          shr     eax,4804ef8b3 2401            and     al,1804ef8b5 5d              pop     ebp804ef8b6 c20400          ret     4而程序得到的地址为JMP地址BOOLEAN PsIsSystemThread(PETHREAD Thread);BOOLEAN IoIsSystemThread(PETHREAD Thread);dprintf("PsIsSystemThread:0X%08X\n", (PULONG)pPsIsSystemThread);dprintf("IoIsSystemThread:0X%08X\n", (PULONG)pIoIsSystemThread);

这两个函数的地址分别为:PsIsSystemThread:0XF8C2055CIoIsSystemThread:0XF8C20550lkd> u 0xf8c2055cf8c2055c ff259c06c2f8    jmp     dword ptr ds:[0F8C2069Ch]f8c20562 cc              int     3f8c20563 cc              int     3f8c20564 cc              int     3f8c20565 cc              int     3f8c20566 cc              int     3f8c20567 cc              int     3f8c20568 ff25a806c2f8    jmp     dword ptr ds:[0F8C206A8h]lkd> u f8c20550f8c20550 ff259806c2f8    jmp     dword ptr ds:[0F8C20698h]f8c20556 cc              int     3f8c20557 cc              int     3f8c20558 cc              int     3f8c20559 cc              int     3f8c2055a cc              int     3f8c2055b cc              int     3f8c2055c ff259c06c2f8    jmp     dword ptr ds:[0F8C2069Ch] dword ptr ds:[0F8C2069Ch] = dword ptr ds:[0F8C20698h] = 804ef8a2 http://bbs.pediy.com/showthread.php?t=93742这里的代码好像没有处理FF25所以看雪上楼主的这个程序会蓝屏。改后代码:ULONG GetCrossThreadFlagOffset(){        ULONG Offset = 0;         PUCHAR pPsIsSystemThread;         PULONG pFuncAddr;        PUCHAR pFeature;        if(Offset == 0)         {                pPsIsSystemThread = (PUCHAR)PsIsSystemThread;         }                dprintf("PsIsSystemThread:0X%08X\n", (PULONG)pPsIsSystemThread);        //判断是不是FF 25        if ((*pPsIsSystemThread) != 0xFF || *(pPsIsSystemThread+1) != 0X25)         {                dprintf("pProc is not ff 25.\n");                return Offset;        }        //ff25 9806c2f8    jmp     dword ptr ds:[0F8C20698h]        pFuncAddr = (*(PULONG)(pPsIsSystemThread+2));        dprintf("pFuncAddr:0X%08X\n", (PULONG)pFuncAddr);                pFuncAddr = (PULONG)*pFuncAddr;        dprintf("pFuncAddr:0X%08X\n", (PULONG)pFuncAddr);        pFeature = (PUCHAR)pFuncAddr;        while( *pFeature!=0x8B || *(pFeature+1)!=0x80 )                 pFeature++;         dprintf("Instruction found in address:0X%08X\n",(PULONG)pFeature);         Offset = *(PULONG)(pFeature+2);         dprintf("Offset:0X%08X\n",Offset);         return Offset; }
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 16:30

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表