While reading Practical Reverse Engineering by Bruce Dang, I came across the following.

Image from Practical Reverse Engineering

  1. Am I correct in my assumption that the procedures return a pointer to the current thread and current process respectively?
  2. In PsCurrentProcess, the offset into the current thread is 0B8h whereas in the comment it is written as 0x70. I do not understand what the author means by this. In an attempt to find out I tried to debug a x64 Windows 10 Kernel.

    enter image description here

    enter image description here

I couldn't find any thing at offsets 70h nor B8h. But I did find a _KPROCESS at offset 220h. Is this what I am looking for?

enter image description here

  1. Will this offset be the same for all Windows 10 x64 systems?
  2. I would like to know about the internals of all these structures. Is there any resource that explains all the important internal data structures in Windows from a reverse engineering stand point.

2 Answers 2


To start with, the offsets are more likely to match the current OS at the time of the book's writing (probably Win7) than Windows 10. That said, a good reference to internal kernel structures over different Windows versions is Geoff Chapell's website: https://www.geoffchappell.com/studies/windows/km/index.htm

For example, looking at KPCR, we can see that at 0x0180 we have KPRCB Prcb;, so 188h is 8 bytes into KPRCB. Checking KPRCB, in turn, we see that offset 8 is KTHREAD *CurrentThread;. So the offset 0B8h should be looked up in the KTHREAD struct. I was able to find on this page the member KAPC_STATE ApcState; at offset 0x70 in x86 version and 0x98 in x64. I'm not sure what OS version is the quoted disassembly coming from, but it looks like there's been some mixup. You should probably submit an errata report on the book's page at Wiley.

In the meantime look at the disassembly of mentioned functions in the kernel you're actually running and then match it against the structs you're printing.

  • Thanks for answering. As adviced, I looked into the dissasembly of the function on my system. The offset to ApcState is 0x98 in x64. It seems to be an array. At an offset x20 into the array is the ApcState.Process. So the effective offset is 98h + 20h = B8. Also after googling a lot I found the terminus project. It shows a nice representation of some internal structures in Windows. Thought you might be interested.
    – Aswin P J
    Oct 4, 2017 at 4:47

most of these structures can be queried with windbg

if you are running in usermode ntdll.pdb has these type information

if you are running in kernelmode ntos/ntkr/ aka nt*.pdb has these type information

you can use a tool like livekd from sysinternals along with windbg to do a local kernel debugging session

following are output from livekd on a win7 x86 machine as far as possible the commands are kept os / version agnostic

the current process can be queried as ? @$proc

kd> ? @$proc
Evaluate expression: -2050188616 = 85cc9ab8

the single question mark ? represents masm expresssion evaluator you can use ?? question marks to turn on c++ expression evaluator

kd> ?? @$proc->UniqueProcessId
void * 0x00000538

the above Current process pid is also represented by @$tpid

kd> ? @$tpid
Evaluate expression: 1336 = 00000538
kd> ?? @$tpid
unsigned int 0x538

the pcr is represented by @$pcr

you can mix and match the expression evaluator the @@() lets you insert a c++ expression into a masm evaluation

kd> ? @$pcr
Evaluate expression: -2097779712 = 82f66c00
kd> ?  @@(@$pcr->PrcbData.CurrentThread)
Evaluate expression: -2048806120 = 85e1b318

in my system PsGetCurrentProcess is as follows

kd> uf nt!PsGetCurrentThread
82e72b99 64a124010000    mov     eax,dword ptr fs:[00000124h]
82e72b9f c3              ret

you can directly get the raw contents of this segment:offset

kd> ? poi(fs:00000124)
Evaluate expression: -2048806120 = 85e1b318

the current thread is denoted by @$thread

kd> ? @$thread
Evaluate expression: -2048806120 = 85e1b318

ApcState is not an array it is a structure

kd> ?? @$thread->Tcb.ApcState
struct _KAPC_STATE
   +0x000 ApcListHead      : [2] _LIST_ENTRY [ 0x85e1b358 - 0x85e1b358 ]
   +0x010 Process          : 0x85cc9ab8 _KPROCESS
   +0x014 KernelApcInProgress : 0 ''
   +0x015 KernelApcPending : 0 ''
   +0x016 UserApcPending   : 0 ''

you can get the offset to Process mention in you post like this

kd> ?? &(@$thread->Tcb.ApcState.Process)
struct _KPROCESS ** 0x85e1b368
kd> ?? *(unsigned long *)&(@$thread->Tcb.ApcState.Process)
unsigned long 0x85cc9ab8

in my system PsGetCurrentProcss is as follows

kd> uf nt!PsGetCurrentProcess
82ec5fce 64a124010000    mov     eax,dword ptr fs:[00000124h]
82ec5fd4 8b4050          mov     eax,dword ptr [eax+50h]
82ec5fd7 c3              ret

raw query

kd> ? poi(30:124)
Evaluate expression: -2048806120 = 85e1b318
kd> ? poi(poi(30:124)+50)
Evaluate expression: -2050188616 = 85cc9ab8

expression query

kd> ? @@(@$prcb->CurrentThread->ApcState.Process)
Evaluate expression: -2050188616 = 85cc9ab8

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.