首页 > 其他分享 >线程

线程

时间:2024-05-18 17:32:26浏览次数:17  
标签:0x03c 0y0 Void 0x0b8 线程 进程

3.线程

线程介绍

线程是需要上下文环境的

线程一定绑定在某个进程上的

内核线程只有一个堆栈(在内核中创建线程如果不指定进程的话,默认是绑定在system进程)

R3中线程有2个堆栈,在R3进R0的时候会切换堆栈,这时候用的就不是R3的堆栈而是R0的(R0和R3的上下文环境)

线程没有cr3的概念,只有绑定在哪个进程上面的概念

内核空间是所有进程共享的

R3下,描述线程用的是TEB

R0下,描述线程用的是KTHREAD或者ETHREAD

线程在内核态的时候是可以跑在其他的进程上

线程在WinXP的时候是32个链表

线程在Win7 之后的时候不是32个链表,而是每一个32个链表,放到KPCR

线程在单核情况下本质就是32个链表组成的数组

线程在就绪状态下会插入11号链表中

线程结构

windbg查看进程线程

获得指定进程的线程

!process 0 0

!process 进程地址

 THREAD 88a04538  Cid 0d78.0cb4  Teb: 7ffdd000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Alertable
            86df6b20  SynchronizationTimer
            86e13d58  SynchronizationTimer
            86e65290  SynchronizationTimer

因为是R3(UserMode)的所以有TEB

dt _kthread线程地址

kd> dt _kthread 88a04538
ntdll!_KTHREAD
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 CycleTime        : 0x827a0
   +0x018 HighCycleTime    : 0
   +0x020 QuantumTarget    : 0x11d245d4//总耗时的时间碎片
   +0x028 InitialStack     : 0x838c4ed0 Void//栈底
   +0x02c StackLimit       : 0x838c2000 Void/栈顶
   +0x030 KernelStack      : 0x838c4648 Void/栈保存的切换前的ESP
   +0x034 ThreadLock       : 0//锁
   +0x038 WaitRegister     : _KWAIT_STATUS_REGISTER
   +0x039 Running          : 0 ''//是否在运行中的状态,运行中是1
   +0x03a Alerted          : [2]  ""//可警惕
   +0x03c KernelStackResident : 0y0//线程是否可以扩张
   +0x03c ReadyTransition  : 0y0
   +0x03c ProcessReadyQueue : 0y0
   +0x03c WaitNext         : 0y0
   +0x03c SystemAffinityActive : 0y0
   +0x03c Alertable        : 0y1//唤醒,标注当前线程是否可以被唤醒
   +0x03c GdiFlushActive   : 0y0//GDI是否活动刷新
   +0x03c UserStackWalkActive : 0y0//用户层的堆栈活动
   +0x03c ApcInterruptRequest : 0y0//是否允许apc中断,如果1的话,硬件中断不会触发apc,有成员的时候才会触发apc
   +0x03c ForceDeferSchedule : 0y0
   +0x03c QuantumEndMigrate : 0y0
   +0x03c UmsDirectedSwitchEnable : 0y0
   +0x03c TimerActive      : 0y0
   +0x03c SystemThread     : 0y0//判断自己是否是内核线程,1代表内核线程
   +0x03c Reserved         : 0y000000000000000000 (0)
   +0x03c MiscFlags        : 0n32
   +0x040 ApcState         : _KAPC_STATE//apc状态
   +0x040 ApcStateFill     : [23]  "xE???"
   +0x057 Priority         : 10 ''//优先级,当前线程的优先级的级别
   +0x058 NextProcessor    : 0//根据亲核性,下次切换线程线程跑在哪个核上
   +0x05c DeferredProcessor : 0//如果没有指定下一次泡在那个核上,那么就按照这个默认的
   +0x060 ApcQueueLock     : 0
   +0x064 ContextSwitches  : 0xb//当前线程切换了多少次
   +0x068 State            : 0x5 ''//状态,线程的状态
   +0x069 NpxState         : 0 ''
   +0x06a WaitIrql         : 0 ''//等待相关的
   +0x06b WaitMode         : 1 ''//等待相关的
   +0x06c WaitStatus       : 0n2//等待相关的
   +0x070 WaitBlockList    : 0x88a045f8 _KWAIT_BLOCK//等待相关的
   +0x074 WaitListEntry    : _LIST_ENTRY [ 0x87e7ddbc - 0x80b9e300 ]//等待相关的
   +0x074 SwapListEntry    : _SINGLE_LIST_ENTRY
   +0x07c Queue            : (null) //队列
   +0x080 WaitTime         : 0x390dc
   +0x084 KernelApcDisable : 0n0
   +0x086 SpecialApcDisable : 0n0
   +0x084 CombinedApcDisable : 0
   +0x088 Teb              : 0x7ffdd000 Void//TEB
   +0x090 Timer            : _KTIMER//定时器
   +0x0b8 AutoAlignment    : 0y0
   +0x0b8 DisableBoost     : 0y0
   +0x0b8 EtwStackTraceApc1Inserted : 0y0
   +0x0b8 EtwStackTraceApc2Inserted : 0y0
   +0x0b8 CalloutActive    : 0y0
   +0x0b8 ApcQueueable     : 0y1
   +0x0b8 EnableStackSwap  : 0y1
   +0x0b8 GuiThread        : 0y0
   +0x0b8 UmsPerformingSyscall : 0y0
   +0x0b8 VdmSafe          : 0y0
   +0x0b8 UmsDispatched    : 0y0
   +0x0b8 ReservedFlags    : 0y000000000000000000000 (0)
   +0x0b8 ThreadFlags      : 0n96
   +0x0bc ServiceTable     : 0x84185b00 Void
   +0x0c0 WaitBlock        : [4] _KWAIT_BLOCK
   +0x120 QueueListEntry   : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x128 TrapFrame        : 0x838c4c34 _KTRAP_FRAME
   +0x12c FirstArgument    : 0x00000003 Void
   +0x130 CallbackStack    : (null) 
   +0x130 CallbackDepth    : 0
   +0x134 ApcStateIndex    : 0 ''
   +0x135 BasePriority     : 8 ''
   +0x136 PriorityDecrement : 2 ''
   +0x136 ForegroundBoost  : 0y0010
   +0x136 UnusualBoost     : 0y0000
   +0x137 Preempted        : 0 ''//抢占(windows的抢占机制),标记为1可以抢占其他线程
   +0x138 AdjustReason     : 0 ''
   +0x139 AdjustIncrement  : 0 ''
   +0x13a PreviousMode     : 1 ''
   +0x13b Saturation       : 0 ''
   +0x13c SystemCallNumber : 0x185
   +0x140 FreezeCount      : 0
   +0x144 UserAffinity     : _GROUP_AFFINITY
   +0x150 Process          : 0x88b3f030 _KPROCESS//谁创建了这个线程
   +0x154 Affinity         : _GROUP_AFFINITY
   +0x160 IdealProcessor   : 0
   +0x164 UserIdealProcessor : 0
   +0x168 ApcStatePointer  : [2] 0x88a04578 _KAPC_STATE
   +0x170 SavedApcState    : _KAPC_STATE
   +0x170 SavedApcStateFill : [23]  "???"
   +0x187 WaitReason       : 0x6 ''
   +0x188 SuspendCount     : 0 ''
   +0x189 Spare1           : 0 ''
   +0x18a OtherPlatformFill : 0 ''
   +0x18c Win32Thread      : (null) //win32线程,如果是UI线程,那么会多一个Win32结构体
   +0x190 StackBase        : 0x838c5000 Void
   +0x194 SuspendApc       : _KAPC
   +0x194 SuspendApcFill0  : [1]  "???"
   +0x195 ResourceIndex    : 0 ''
   +0x194 SuspendApcFill1  : [3]  "???"
   +0x197 QuantumReset     : 0x12 ''
   +0x194 SuspendApcFill2  : [4]  "???"
   +0x198 KernelTime       : 0
   +0x194 SuspendApcFill3  : [36]  "???"
   +0x1b8 WaitPrcb         : (null) 
   +0x194 SuspendApcFill4  : [40]  "???"
   +0x1bc LegoData         : (null) 
   +0x194 SuspendApcFill5  : [47]  "???"
   +0x1c3 LargeStack       : 0 ''
   +0x1c4 UserTime         : 0
   +0x1c8 SuspendSemaphore : _KSEMAPHORE
   +0x1c8 SuspendSemaphorefill : [20]  "???"
   +0x1dc SListFaultCount  : 0
   +0x1e0 ThreadListEntry  : _LIST_ENTRY [ 0x88b3f05c - 0x86df4f28 ]//创建这个线程的进程创建的所有线程的列表
   +0x1e8 MutantListHead   : _LIST_ENTRY [ 0x88a04720 - 0x88a04720 ]
   +0x1f0 SListFaultAddress : (null) 
   +0x1f4 ThreadCounters   : (null) 
   +0x1f8 XStateSave       : (null) 

内核态的线程的堆栈

+0x028 InitialStack     : 0x838c4ed0 Void
+0x02c StackLimit       : 0x838c2000 Void
+0x030 KernelStack      : 0x838c4648 Void

内核线程的

为什么这个栈底并不在底部,看下面的KiFastCallEntry

ebp减去了29ch

每一个线程在创建堆栈的时候预留了29c个位置

这预留的29c = trap_frame + 浮点

所以如果要求出整个栈的栈底的话需要InitialStack + 29c

trap_frame 作用:fastcall进内核的时候需要提供一个存储环境的地方

浮点 线程切换的时候使用

KernelStack并不是常用的pop/push的那个ESP,而是线程切换的时候将老线程的esp保存在这个里,线程换恢复再从这里取出,恢复堆栈(类似Linux中的prev ebp

Alerted 可警惕

+0x03a Alerted          : [2]  ""//可警惕

数组是0代表是0环的可警惕,数组是1是3环的可警惕

可警惕的程度代表当线程正处在一种可以被唤醒的假等待

Sleep是死等,SleepEx是带有警惕性的等待

KernelStackResident 线程扩张

默认情况下线程的栈被创建的时候只有12k(0x3000)但是整个太小了,再调用UI的时候不够,需要扩张

而这个KernelStackResident记录了线程是否允许拓张,为1代表可以扩张

Alertable 是否可以唤醒

这个相当于一个开关,当他置为1的时候,不一定可以唤醒,在此情况下加上了可警惕就绝对可以唤醒

ApcState apc状态

kd> dt _kapc_state
ntdll!_KAPC_STATE
   +0x000 ApcListHead      : [2] _LIST_ENTRY
   +0x010 Process          : Ptr32 _KPROCESS//当先线程的上下文环境是谁
   +0x014 KernelApcInProgress : UChar
   +0x015 KernelApcPending : UChar
   +0x016 UserApcPending   : UChar

Process

Process :当前线程的进程所属是谁

假设A进程的0x1234指向的是AB进程的0x1234指向的是B,那么如何正确的让A进程读B进程的地址,也就是如何知道读的是不是B进程

CR3是绑定在进程上的,可以通过改变CR3来让改变线程的上下文环境,让线程跑到其他进程

Priority 线程优先级

线程初始优先级是8

数字越大,优先级越低

标签:0x03c,0y0,Void,0x0b8,线程,进程
From: https://www.cnblogs.com/murkuo/p/18199530

相关文章

  • pyqt5 子线程如何操作主线程GUI
    一.简介在使用pyqt5编写gui时遇到两个问题,会导致界面崩溃,今天就围绕这两个问题来简单说明和改进。1.在主线程中使用while无限循环会导致界面崩溃2.在子线程中操作主线程gui会导致界面崩溃二.步骤说明1.在主线程中使用while无限循环会导致界面崩溃1)错误代码importsysfr......
  • 多线程下使用List中的subList和remove方法产生的 java.util.ConcurrentModificationEx
    在说多线程操作List之前,我们先看下单线程下产生的问题:单线程List<Integer>listA=newArrayList<>();listA.add(1);listA.add(2);listA.add(3);listA.add(4);listA.add(5);listA.add(6);for(Integera:listA){......
  • Java-线程-wait()、notify()和notifyAll()
    0.是什么(What)wait(),notify(),和notifyAll()方法都是Object类的一部分,用于实现线程间的协作。1.为什么(Why)线程的执行顺序是随机的(操作系统随机调度的,抢占式执行),但是有时候,我们希望的是它们能够顺序的执行。所以引入了这几个方法,使得我们能保证一定的顺序。1.1Objec类......
  • 美团面试:如何实现线程任务编排?
    线程任务编排指的是对多个线程任务按照一定的逻辑顺序或条件进行组织和安排,以实现协同工作、顺序执行或并行执行的一种机制。1.线程任务编排VS线程通讯有同学可能会想:那线程的任务编排是不是问的就是线程间通讯啊?线程间通讯我知道了,它的实现方式总共有以下几种方式:Object......
  • 进程、线程和协程之间的区别和联系
    文章目录一、进程二、线程三、进程和线程的区别与联系四、一个形象的例子解释进程和线程的区别五、进程/线程之间的亲缘性六、协程一、进程进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,上级挂靠单......
  • 避免DbContext同时在多个线程调用
    下面这个微软官方文档阐述了,应该避免在多个线程上同时操作同一个DbContext:AvoidingDbContextthreadingissues其中有说到,在使用DbContext的代码中,所有的异步函数应该立即被await,否则会有极大概率抛出InvalidOperationException。这是因为一个DbContext实例不能被多个线程同时......
  • 超线程/同步多线程(HT/SMT)技术
    超线程/同步多线程(HT/SMT)技术虽然现在超线程(Hyper-Threading)被大家广泛接受,并把所有一个物理核心上有多个虚拟核心的技术都叫做超线程,但这其实是Intel的一个营销名称。而实际上这一类技术的(学术/技术)通行名称是同步多线程(SMT,SimultaneousMultithreading)技术。SMT技术初衷是通......
  • Java-线程-synchronized
    0.背景文章目录层级较多,参考我这篇文章来进行展开,方便阅读:博客园SimpleMemory主题如何浮动目录显示参考文章:synchronized底层monitor原理synchronized的底层是基于Java的监视器monitor的。在Java中,monitor(监视器)是用来实现线程同步的一种基本机制。它是一个控制结构,内置......
  • Qt 中用Q_GLOBAL_STATIC来实现线程安全的单例模式
    官方说明:Qt中有个宏Q_GLOBAL_STATIC可以用来创建一个全局静态变量,下面看下官方文档的说明:Q_GLOBAL_STATIC(Type,VariableName)CreatesaglobalandstaticobjectoftypeQGlobalStatic,ofnameVariableNameandthatbehavesasapointertoType.Theobjectcr......
  • Python 内置库 多线程threading使用讲解
    线程基本使用单线程defmain():print("在扔一个苹果")if__name__=="__main__":main()多线程Python提供了thread、threading等模块来进行线程的创建与管理,后者在线程管理能力上更进一步,因此我们通常使用threading模块。创建一个线程需要指定该线程执行的任务(函......