Python extensions in WinDbg Alin Serdean Senior cloud engineer @cloudbaseit
Jun 28, 2015
Python extensions in WinDbg
Alin SerdeanSenior cloud engineer
@cloudbaseit
About me• Mostly a kernel developer• Past year I have been working
intensely to bring (Open vSwitch)OVS to Hyper-V
• OVS is a production quality, multilayer virtual switch licensed under the open source Apache 2.0 license.
• De facto standard in OpenStack• It is designed to support distribution
across multiple physical servers
OVS use case
OVS features• LACP (IEEE 802.1AX-2008)• Standard 802.1Q VLAN model with
trunking • STP (IEEE 802.1D-1998)• Multiple tunneling protocols (GRE, VXLAN,
IPsec, GRE and VXLAN over IPsec)• Remote configuration protocol with C and
Python bindings• Kernel and user-space forwarding engine
options
Debuggers on WindowsMicrosoft Visual Studio Debugger
- ships along with all versions of VS- good when you have sources- integrated UI- based on CodeView - good for userspace debugging- can be used kernel using the
VisualDDK- less powerful
Debuggers on WindowsSoftICE
- one of the most popular debuggers in the 90s
- Nu-Mega Tech. -> Compuware -> Micro Focus -> no longer maintained
- open source kernel debugger similar to SoftICE named Rasta Ring 0 Debugger (RR0D)
- was designed to run live- Software vendors have put in place a
wide range of countermeasures to protect themselves from people employing SoftICE as a tool to analyse software.
SoftICE mov eax, dword ptr [pIDT+2] ; eax -> IDT add eax, 8 ; eax -> int 1 vector mov ebx, [eax] ; ebx == int 1 vector add eax, 16 ; eax -> int 3 vector mov eax, [eax] ; eax == int 3 vector and eax, 0ffffh ; strip the selector and ebx, 0ffffh ; part of it sub eax, ebx ; find displacement cmp eax, 10h ; jne HackedVector ; if it isn't equal, then chances are SoftICE had tampered with these vectors
Debuggers on Windows• OllyDbg– x86 only– x64 under heavy development– Used for reverse engineering/cracking– Can be used for malware as well– Userspace only
Debuggers on Windows• Interactive Disassembler– Known as IDA– Was sold to DataRescue -> IDA Pro– Orig. author created Hex-Rays– Hex-Rays is back the dev. and
support of IDA– Has support for scripting languages
(IDARuby and IDAPython) through extensions. Latest IDA Pro release IDAPython is preinstalled
– Has support over a variety of Instruction sets
Debuggers on WindowsWinDbg– Well written documentation (MSDN)– Can be used for kernel-memory dumps– Can be used to debug:
• Userspace• Drivers• OS itself!
– x64 support – Has extensions loading them by DLLs (the
ones that starts !)
Debuggers on Windows• WinDbg(contd’)– Has the ability to automatically load PDBs– Has support of multiple scripting
languages• Proprietary looks a bit awful and has to few
commands• Python through the kindness of the following:
– PyDbgExt– PyKd
• Ruby unstable at the moment: – https://github.com/bnagy/rBuggery
– Free to use
Python Extensions• PyDbgExt– Still alpha– Has to be recompiled on 8/8.1– Relies on boost– Highly unstable– No documentation
Python Extensions• PyKd - https://pykd.codeplex.com/– It has installer – It has documentation– It has samples– Microsoft acknowledges it– Used by reverse engineers intensively– Decently stable– Highly maintained
Typical example of Windbg Script !for_each_module " .if(not(wo(dwo(${@#Base}+0x3c)+${@#Base}+46+18) & 0x40)) { r @$t3 = @#End - @#Base; .foreach /s (retn \"C2 C3\") { .foreach (f {s -[1]b @#Base L@$t3 ${retn}}) { .for(r @$t0 = 1; @$t0 < 4; r @$t0 = @$t0 + 1) { r @$t1 = 0; .foreach (g {.catch {u f - @$t0 L@$t0+1}}) { .if($spat(\"${g}\", \"*ret*\") != 0) { r @$t1 = 1 } }; .if(@$t1 == 1) { .printf \"---------------------- size %x\", @$t0; .echo; .catch {u f - @$t0 L@$t0+1} } } } } }"
• The example above is an example to find a specific vulnerability in Windows
• It is used to find ROP gadgets• ROP - Return-oriented programming
allows you to execute code in non-executable memory and code signing.
• The script above bypasses ASLR(Address space layout randomization)
• It searches for the Optional PE Header (DllCharacteristics) then checks for the IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 flag
WinDbg print processr? @$t0=(nt!_LIST_ENTRY*)@@(nt!PsActiveProcessHead).for (r? @$t1 = @$t0->Flink;(@$t1!=@$t0);r?@$t1 = @$t1->Flink){r? @$t2 = #CONTAINING_RECORD(@$t1, nt!_EPROCESS, ActiveProcessLinks)as /x $ProcPid @@(@$t2->UniqueProcessId)as /ma $ProcName @@(@$t2->ImageFileName)as /x $Temp @$t2as /x $Temp2 @@(@$t2->UniqueProcessId).block { .echo ${$Temp} ${$Temp2}}.block {.echo ${$ProcName} with PID ${$ProcPid} }ad $ProcNamead $ProcPidad $Temp}
Same script in PyKdimport sysfrom pykd import *
nt = module( "nt" )
processList = typedVarList( nt.PsActiveProcessHead, "nt!_EPROCESS", "ActiveProcessLinks" )
j = 1
for process in processList:dprint("Process "+str(j)+": ")print "".join( [chr(i) for i in process.ImageFileName if i != 0]
)j += 1
PyKd contd’ Listing all Namespaces of WebServiceMethod
from pykd import *
def dump_soapclientmethod(): # get all SoapClientMethod's soapcliaddrs = pykd.dbgCommand("!dumpheap -mt 0000064283abea38 -short").split("\n")
print "### found %d soap client addresses" % (len(soapcliaddrs))
for addr in soapcliaddrs: # dumpobj to get object properties do = pykd.dbgCommand("!do %(addr)s" % { 'addr': addr }) # get the line for 'action' property actionline = [line for line in do.split('\n') if 'action' in line] # line ends with "<address> action" and we want the <address> actionaddr = actionline[0].split()[-2] # get the string in the retrieved <address> doaction = pykd.dbgCommand("!do -nofields %(addr)s" % {'addr': actionaddr}).split("\n") print "%s -> %s" % (actionaddr, doaction[-2])
• the code above renders an output like:
### found 125 soap client addresses00000001c1755b48 -> String: http://schemas.microsoft.com/sharepoint/soap/List00000001e2085640 -> String: http://schemas.microsoft.com/sharepoint/soap/Copy0000000240fb35c8 -> String: http://schemas.microsoft.com/sharepoint/soap/List00000002419c4158 -> String: http://schemas.microsoft.com/sharepoint/soap/Copy...
Q & A