If you google Pykd you will probably find the projects archived CodePlex site at https://archive.codeplex.com/?p=pykd where you can find a link to it's current website https://githomelab.ru/pykd. The documentation on how to install pykd is wrong or at least misleading in both places. What you really need is Python (2.7 is supposed to work, but didn't for me) and the "pykd bootstrapper".
I got it to work by
.load pykdin Windbg I could execute python scripts with
Windbg Preview doesn't have a writable extension directory (yet?) so unless you want to fight Microsoft App Security it is better to just copy it somewhere else and load it via it's full path.
I will start with a simple example parsing the ActiveProcessList from the processes episode. It primarily uses
pykd.dbgCommand to use pykd as a python wrapper around Windbg commandline commands.
import pykd # Parsing the ProcessList with minimal pykd and lot's of debug output. # def firstNumberInString(string): # meant to get the middle number out of Windbgs: "Evaluate expression: 1104 = 0000000000000450" return [int(s) for s in string.split() if s.isdigit()] if __name__ == "__main__": if not pykd.isWindbgExt(): print("Script cannot be launched outside Windbg") quit(0) # Get PsActiveProcessHead pActiveProcessHead = pykd.getOffset("nt!PsActiveProcessHead") pykd.dprintln("PsActiveProcessHead: @ 0x%08x"%pActiveProcessHead) # Dereference PsActiveProcessHead == Forward link to first process initial_flink = pykd.ptrPtr(pActiveProcessHead) pykd.dprintln("Initial Flink: @ 0x%08x"%initial_flink) # Get structure offsets s = pykd.dbgCommand("? @@(#FIELD_OFFSET(nt!_EPROCESS,ActiveProcessLinks))") offset_eprocess_activeProcesslinks = firstNumberInString(s) pykd.dprintln("Offset EPROCESS-ActiveProcessLinks: " + str(offset_eprocess_activeProcesslinks)) s = pykd.dbgCommand("? @@(#FIELD_OFFSET(nt!_EPROCESS, ImageFileName))") offset_eprocess_imageName = firstNumberInString(s) pykd.dprintln("Offset EPROCESS-ImageName: " + str(offset_eprocess_imageName)) # go through process list and print ImageNames currentEntry = pykd.ptrPtr(pActiveProcessHead) while (currentEntry != pActiveProcessHead): pykd.dprintln("Current Flink: @ 0x%08x"%currentEntry) pCurrentEProcessObject = currentEntry - offset_eprocess_activeProcesslinks pykd.dprintln("Current EPROCESS address: @ 0x%08x"%pCurrentEProcessObject) currentImageName = pykd.loadCStr( pCurrentEProcessObject + offset_eprocess_imageName ) pykd.dprintln("Current ImageName: " + currentImageName) currentEntry = pykd.ptrPtr(pCurrentEProcessObject + offset_eprocess_activeProcesslinks) pykd.dprintln("Done")
While this works totally fine, you get more use out of PyKD if you use it's features. Things like walking through the nt lists become dead simple:
import pykd # Parsing the ProcessList with pykd if __name__ == "__main__": if not pykd.isWindbgExt(): print("Script cannot be launched outside Windbg") quit(0) pActiveProcessList = pykd.getOffset("nt!PsActiveProcessHead") #pActiveProcessList = pykd.module("nt").PsActiveProcessHead processList = pykd.typedVarList(pActiveProcessList, "nt!_EPROCESS", "ActiveProcessLinks" ) for i, process in enumerate(processList): pykd.dprint("Process " + str(i)+":") name=pykd.loadCStr(process.ImageFileName) print(name)