A forum for reverse engineering, OS internals and malware analysis 

Ask your beginner questions here.
 #9767  by lorddoskias
 Sat Nov 19, 2011 10:48 pm
Is there a way to programatically acquire _KPCR's address. I know it is at address fs:[0x1c] so by using inline assembly this can be done, but is there another way to do it without using inline assembly?
 #9770  by lorddoskias
 Sun Nov 20, 2011 1:53 am
Thanks, I just found out this. Now another question:

I'm trying to print the address of PsLoadedModuleList as a PoC to see I can parse the KdVersionBlock. Here is the code I use:
Code: Select all
void printGlobVars() {

	 PKPCR var;
	 PDBGKD_GET_VERSION64 versionBlock;
	 PKDDEBUGGER_DATA64 debugData;


	 //get pointer to the KPCR
     var = __readfsdword(0x1c);

	 versionBlock = var->KdVersionBlock;      <= up to here everything is fine 
	 
	 debugData = versionBlock->DebuggerDataList; <= in visual studio debugger I see that all members have the value 0 

	 DbgPrint("Address of PsLoadedModule list is 0x%p\n", debugData->PsLoadedModuleList); <== so this gives 0x000000
} 
But I think I'm having problems parsing the ULONG64, I'm running inside a 32bit Win 7, but I was left with the impression that irrespective of what the version of the OS is the struct is always of type 64?
 #9779  by nullptr
 Sun Nov 20, 2011 2:51 pm
Try this
Code: Select all
    versionBlock = (PDBGKD_GET_VERSION64)var->KdVersionBlock;
/*
    if (!MmIsAddressValid(versionBlock))
    {
        DbgPrint("invalid address for versionBlock\n");
        return status;
    }  
*/
    debugData = (PKDDEBUGGER_DATA64) ((PLIST_ENTRY64)(versionBlock->DebuggerDataList))->Flink;

    DbgPrint("PsLoadedModuleList: 0x%08X\n", (ULONG)(debugData->PsLoadedModuleList & 0xFFFFFFFF));
 #9780  by lorddoskias
 Sun Nov 20, 2011 3:26 pm
nullptr wrote:Try this
Code: Select all
    versionBlock = (PDBGKD_GET_VERSION64)var->KdVersionBlock;
/*
    if (!MmIsAddressValid(versionBlock))
    {
        DbgPrint("invalid address for versionBlock\n");
        return status;
    }  
*/
    debugData = (PKDDEBUGGER_DATA64) ((PLIST_ENTRY64)(versionBlock->DebuggerDataList))->Flink;

    DbgPrint("PsLoadedModuleList: 0x%08X\n", (ULONG)(debugData->PsLoadedModuleList & 0xFFFFFFFF));
That's quality man, thanks a lot!
 #23742  by g4mbit
 Tue Sep 02, 2014 2:46 pm
I know that this is kind of a old thread, but I believe my question is still relevant.

The code above is valid for x86, but what about x64?
From what I've found so far, you can get the KPCR on x64 this way, since the structure is pretty different:
Code: Select all
PKPCR = (PKPCR) _readgsdword(FIELD_OFFSET(KPCR, Self));
From that point, I could try to get the kdVersionBlock, but I'm getting a bug check 0x3b with access violation (0xc0000005).

How do we get the version block and then the debugger data list?
 #23749  by EP_X0FF
 Tue Sep 02, 2014 6:51 pm
g4mbit wrote:I know that this is kind of a old thread, but I believe my question is still relevant.

The code above is valid for x86, but what about x64?
From what I've found so far, you can get the KPCR on x64 this way, since the structure is pretty different:
Code: Select all
PKPCR = (PKPCR) _readgsdword(FIELD_OFFSET(KPCR, Self));
From that point, I could try to get the kdVersionBlock, but I'm getting a bug check 0x3b with access violation (0xc0000005).

How do we get the version block and then the debugger data list?
Mindless copy-pasting.
PKPCR = (PKPCR) _readgsdword(FIELD_OFFSET(KPCR, Self));

x64 pointers are not 32 bit size.
 #23750  by g4mbit
 Tue Sep 02, 2014 7:59 pm
Yes. That works fine.

But from that point, how do I get to the kdVersionBlock and then the DebuggerDataList, always keeping in mind that I'm trying to do this in x64.

The following code gives me a BS right away.
Code: Select all
PKPCR pKpCR = (PKPCR) _readgsdword(FIELD_OFFSET(KPCR, Self));
PVOID version = pKPCR->KdVersionBlock;