Some researches make trace with Temu, some use debuggers: MyNav, ProcessStalker. But, for kernel purpose, as you know, we need to use WinDbg. Big advantage that Windbg works everywhere.
It’s not a secret that kernel researches use Windbg for rootkit hunting and Analyzing. You can find a lot of scripts in KDAR project.
But It’s not comfortable to use Windbg script, so pykd project was born.
Today I would like to present you small overview of pykd and my own script for tracing syscalls.
Let’s start from installing. I can install only version for python 2.7. Another version didn’t work in my Win (It doesn’t work with any VCRedist).
If you installing it from setup packet you already have different examples. If you install only *.pyd file, download it, because documentation on his site is sparse. It’s time to make some experiments.
As any debugger tracer, it’s necessary to insert breakpoints and handle them. Pykd has bp class. Handler must return DEBUG_STATUS_GO or DEBUG_STATUS_GO_HANDLER, to continue execution or stopping.
Next task is monitoring creating process and his child’s. You can find many different ways, but I’d like to control PspInsertProcess and PspProcessDelete. These functions append and remove EPROCESS to\from PsActiveProcessList. In my script I create a BPHandler class which contains handlers for Processes and Syscalls bps. Syscall bps enables when you process with started. For this purpose pykd has typeVar class.
In Syscall handler we needs to get eprocess too. In this case I’d like to show you another command – dbgCommand
If you installing it from setup packet you already have different examples. If you install only *.pyd file, download it, because documentation on his site is sparse. It’s time to make some experiments.
.load pykd.pyd - load extension in WinDbg.
!py name.py – starting script. Don’t forget to set PYTHONPATH because otherwise any dependencies will not work.Have fun? …
As any debugger tracer, it’s necessary to insert breakpoints and handle them. Pykd has bp class. Handler must return DEBUG_STATUS_GO or DEBUG_STATUS_GO_HANDLER, to continue execution or stopping.
Then you should type go() in you script. Pykd set bp only after immediately start.bp( nt.DbgPrint, Handler)
Next task is monitoring creating process and his child’s. You can find many different ways, but I’d like to control PspInsertProcess and PspProcessDelete. These functions append and remove EPROCESS to\from PsActiveProcessList. In my script I create a BPHandler class which contains handlers for Processes and Syscalls bps. Syscall bps enables when you process with
And you can use eprocess like a structure - eprocess.UniqueProcessId.eprocess = typedVar("nt", "_EPROCESS", reg(“eax”)
In Syscall handler we needs to get eprocess too. In this case I’d like to show you another command – dbgCommand
Starting scriptdef GetCurrentProcess(self):
str = dbgCommand(".printf \"%x\n\", poi(poi(fs:[0x124])+0x50)")
return int(str, 16)
f60:nt!NtAlpcConnectPortWake up and see big log file. Result of syscall I’m using for some metamorphic experiments, but it can be used for tracing drivers and so on. Change GetSyscallList function and get another Bp list for your purpose.
f9c:nt!NtAllocateVirtualMemory
f9c:nt!NtAllocateVirtualMemory
f9c:nt!NtAllocateVirtualMemory
Looks pretty simple. But I have few remarks:
Pykd doesn’t show me python exceptions (print debug engine works fine. It’s makes me crazy) Pykd doesn’t call destructor of any classes.( So It doesn’t deleted bp and doesn’t close file, when I stopping it by initial break.) Pykd is slow engine for tracing purposes, But for rootkit hunting it’s really good things.
Another experiment with kernel tracing I will make with Ida and some IoCtl handler.
Good Luck.
P.S. I’m think that windows driver for temu is big. It’s my fault. You can see him for Win 7 from Linux driver developer in Olshanov repository.
1) Starting 0.0.18 pykd has an exception translator to python exception. Many piece of code still use console printing for error reporting. It will be refctored in future versions
ReplyDeleteYou can test pykd exceptions:
addr = 0xDEADBEEF
try:
arr = loadChars( addr, 100 )
except MemoryException:
print "%x - bas address" % addr
2)Destructure is called when ref counter of the object come to 0. For example:
def func():
global b1
b1 = bp( addr, handler1 )
b2 = bp( addr, handler2 )
return
After func returning, b2 object will be destroyed and breakpoint will be removed, but b1 object will be still live.
If you want to remove global object, you can do:
del b1
Also, you can disbale breakpoint by method remove:
b1.remove()
b2.set())
Thank you for interest for the pykd project.
pykd team
Looking start function.
ReplyDeletedef start(name):
handlers = BpHandlers(name)
b1 = bp( addr1, handlers.CreateProcessHandler)
b2 = bp( addr2, handlers.CloseProcessHandler)
go()
del handlers.logs
del handlers.bpobject
del handlers
BpHandler creates 2 objects in constructor. So it doesn't global var. And ref counter should be 0, but...
If we make initial break, through debugging, 2 objects logs and bpobject are still exist.
Try to make init break and delete this strings
del handlers.logs
del handlers.bpobject
But Like I sad, it's working fine if script finished tracing.