_KWAIT_BLOCK使用时遇到的问题

Posted 已注销

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了_KWAIT_BLOCK使用时遇到的问题相关的知识,希望对你有一定的参考价值。

最近在写代码的时候遇到一个问题,就是_KWAIT_BLOCK中的取出来的Kthread取出来的数据是有问题的。

首先了解一下_KWAIT_BLOCK是什么东西,这个结构体是挂在_Kevent下面的Header,这个header只要是可等待对象都会有这个结构体(能够被wiatforsingleobject等待的都是可等待对象),这个header最后一个字段里面有一个双向链表指向这个事件的Kwait_block这个结构体,同时这个结构体会挂在正在等待的线程的KWAIT_BLOCK这个字段上,我们可以通过Kwait_block的thread字段得到是哪个线程在等待这个事件。

typedef struct _KEVENT 
DISPATCHER_HEADER Header;
KEVENT, *PKEVENT, *PRKEVENT;

typedef struct _DISPATCHER_HEADER
union
union
volatile LONG Lock;
LONG LockNV;
DUMMYUNIONNAME;

struct // Events, Semaphores, Gates, etc.
UCHAR Type; // All (accessible via KOBJECT_TYPE)
UCHAR Signalling;
UCHAR Size;
UCHAR Reserved1;
DUMMYSTRUCTNAME;

struct // Timer
UCHAR TimerType;
union
UCHAR TimerControlFlags;
struct
UCHAR Absolute : 1;
UCHAR Wake : 1;
UCHAR EncodedTolerableDelay : TIMER_TOLERABLE_DELAY_BITS;
DUMMYSTRUCTNAME;
;

UCHAR Hand;
union
UCHAR TimerMiscFlags;
struct

#if !defined(KENCODED_TIMER_PROCESSOR)

UCHAR Index : TIMER_EXPIRED_INDEX_BITS;

#else

UCHAR Index : 1;
UCHAR Processor : TIMER_PROCESSOR_INDEX_BITS;

#endif

UCHAR Inserted : 1;
volatile UCHAR Expired : 1;
DUMMYSTRUCTNAME;
DUMMYUNIONNAME;
DUMMYSTRUCTNAME2;

struct // Timer2
UCHAR Timer2Type;
union
UCHAR Timer2Flags;
struct
UCHAR Timer2Inserted : 1;
UCHAR Timer2Expiring : 1;
UCHAR Timer2CancelPending : 1;
UCHAR Timer2SetPending : 1;
UCHAR Timer2Running : 1;
UCHAR Timer2Disabled : 1;
UCHAR Timer2ReservedFlags : 2;
DUMMYSTRUCTNAME;
DUMMYUNIONNAME;

UCHAR Timer2ComponentId;
UCHAR Timer2RelativeId;
DUMMYSTRUCTNAME3;

struct // Queue
UCHAR QueueType;
union
UCHAR QueueControlFlags;
struct
UCHAR Abandoned : 1;
UCHAR DisableIncrement : 1;
UCHAR QueueReservedControlFlags : 6;
DUMMYSTRUCTNAME;
DUMMYUNIONNAME;

UCHAR QueueSize;
UCHAR QueueReserved;
DUMMYSTRUCTNAME4;

struct // Thread
UCHAR ThreadType;
UCHAR ThreadReserved;

union
UCHAR ThreadControlFlags;
struct
UCHAR CycleProfiling : 1;
UCHAR CounterProfiling : 1;
UCHAR GroupScheduling : 1;
UCHAR AffinitySet : 1;
UCHAR Tagged : 1;
UCHAR EnergyProfiling: 1;
UCHAR SchedulerAssist: 1;

#if !defined(_X86_)

UCHAR ThreadReservedControlFlags : 1;

#else

UCHAR Instrumented : 1;

#endif

DUMMYSTRUCTNAME;
DUMMYUNIONNAME;

union
UCHAR DebugActive;

#if !defined(_X86_)

struct
BOOLEAN ActiveDR7 : 1;
BOOLEAN Instrumented : 1;
BOOLEAN Minimal : 1;
BOOLEAN Reserved4 : 3;
BOOLEAN UmsScheduled : 1;
BOOLEAN UmsPrimary : 1;
DUMMYSTRUCTNAME;

#endif

DUMMYUNIONNAME2;
DUMMYSTRUCTNAME5;

struct // Mutant
UCHAR MutantType;
UCHAR MutantSize;
BOOLEAN DpcActive;
UCHAR MutantReserved;
DUMMYSTRUCTNAME6;
DUMMYUNIONNAME;

LONG SignalState; // Object lock
LIST_ENTRY WaitListHead; // Object lock
DISPATCHER_HEADER, *PDISPATCHER_HEADER;

typedef struct _LIST_ENTRY
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;

基本了解要干什么之后,分析一下为什么会出现这个问题

看一下_KWAIT_BLOCK在ddk 7.1的定义,通常为了兼容都会选择比较低的版本。

typedef struct _KWAIT_BLOCK

LIST_ENTRY WaitListEntry;
PKTHREAD Thread;
PVOID Object;
PKWAIT_BLOCK NextWaitBlock;
WORD WaitKey;
UCHAR WaitType;
UCHAR SpareByte;
KWAIT_BLOCK, *PKWAIT_BLOCK;

可以看到如果是x64模式下+0x10的位置就是线程结构体的偏移;但是打开最新的wdk可以看到这个结构体发生了变化。

typedef struct _KWAIT_BLOCK 
LIST_ENTRY WaitListEntry;
UCHAR WaitType;
volatile UCHAR BlockState;
USHORT WaitKey;

#if defined(_WIN64)

LONG SpareLong;

#endif

union
struct _KTHREAD *Thread;
struct _KQUEUE *NotificationQueue;
;

PVOID Object;
PVOID SparePtr;

KWAIT_BLOCK, *PKWAIT_BLOCK, *PRKWAIT_BLOCK;

可以看到在原来的基础上多了一个字段,所以导致+0x10的位置不在是线程结构体了。

最后在网上找到了对比图在win7 sp1之后就发生了变化,对应版本就是nt6.2开始,也就是win8

_KWAIT_BLOCK使用时遇到的问题_#endif

 


 



免责声明:全网优质文章转载,以作为收藏留档之用,文章均不代表本人立场!
请尊重原创作者,如需转载请标注原创作者链接



以上是关于_KWAIT_BLOCK使用时遇到的问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 pyspark 在 Jupyter notebook 中读取 avro 文件时遇到问题

__declspec(dllexport) 和 __declspec(dllimport)的区别

每次我构建我的应用程序时,iOS 模拟器都会崩溃 EXC_BREAKPOINT(code=EXC_i386_BPT,subcode=0x0)

2016年4月3日_JAVA学习笔记

Python2和Python3正则匹配中文时的编码问题

pipe_wait问题_转