mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
git-svn-id: https://pykd.svn.codeplex.com/svn@69671 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
b06f995200
commit
4d60699054
176
changelog
176
changelog
@ -1,176 +0,0 @@
|
|||||||
version 0.0.19 28/07/2011
|
|
||||||
|
|
||||||
[+] added : typedVar::data method ( Return raw string object with data stream )
|
|
||||||
[+] added : setMSR routine ( Change MSR value )
|
|
||||||
[+] added : intBase class
|
|
||||||
[+] added : cpuReg class ( representing "live" CPU register )
|
|
||||||
[+] added : printing traceback for !py and !pycmd
|
|
||||||
[+] added : class disasm
|
|
||||||
|
|
||||||
[!] fixed: issue 8657( !pycmd does not allow to define functions )
|
|
||||||
[!] fixed: issue 8655 ( Unnamed structure/unioin not added to fields of typedVarClass )
|
|
||||||
[!] fixed: issue 8927 ( typedVar does not convert enumeration type to int )
|
|
||||||
[!] fixed: issue 9202 ( module object return offset = 0 for non existing symbol )
|
|
||||||
|
|
||||||
version 0.0.18 25/05/2011
|
|
||||||
|
|
||||||
[+] added : rdmsr routine ( Return MSR value )
|
|
||||||
[+] added : typeException, memoryException classes and their translation into python
|
|
||||||
[+] added : typeInfo class
|
|
||||||
[+] added : loadWChars routine
|
|
||||||
[+] added : callback for load/unload modules
|
|
||||||
|
|
||||||
[~] removed : typeClass class
|
|
||||||
|
|
||||||
[!] fixed : issue 8669 ( typedVar() creates an object for a non-existent structure type )
|
|
||||||
[!] fixed : issue 8655 ( Unnamed structure/unioin not added to fields of typedVarClass )
|
|
||||||
|
|
||||||
version 0.0.17 15/04/2011
|
|
||||||
[+] added: isDumpAnalyzing function. Check if it is a dump analyzing or live debuggiv
|
|
||||||
[+] added : loadChars routine. Load raw buffer.
|
|
||||||
[+] added : docstrings for all functions and classes
|
|
||||||
[+] added : checksum() and timestamp() methods for dbgModuleClass
|
|
||||||
[+] added : callbacks for bp class ( breakpoint )
|
|
||||||
|
|
||||||
[~] removed : isSessionStart() function
|
|
||||||
|
|
||||||
[~] updated : typedVarList can parse lists with LIST_ENTRY and lists with links pointing to the head of the next element
|
|
||||||
|
|
||||||
[!] fixed : issue 8470 ( python.exe crashes after first pykd call )
|
|
||||||
[!] fixed : issue 8614 ( go() works incorrectly while process is terminating )
|
|
||||||
[!] fixed : issue 8499 ( !py command crashs with wrong script's path )
|
|
||||||
[!] fixed : issue 8578 ( findModule returns None for WOW64 process )
|
|
||||||
[!] fixed : issue 8493 ( loadPtrs returns dict instead list )
|
|
||||||
[!] fixed : issue 8469 ( dprintln does not work in console mode )
|
|
||||||
|
|
||||||
version 0.0.16 03/03/2011
|
|
||||||
[+] added : isValid() routine; it validates virtual address
|
|
||||||
[+] added : image() and pdb() method for dbgModuleClass class. They return paths to pdb and image files.
|
|
||||||
[+] added : function getTypeClass() - create instance of typeClass by module an type name
|
|
||||||
[+] added : addSynSymbol function adds a synthetic symbol to a module by virtual address
|
|
||||||
[+] added : dbgModuleClass::addSynSymbol method adds a synthetic symbol by offset related to module base
|
|
||||||
[+] added : dbgStackFrameClass::print()
|
|
||||||
[+] added : dbgBreakpointClass::print()
|
|
||||||
[+] added : dbgExtensionClass::print()
|
|
||||||
[+] added : dbgModuleClass::print()
|
|
||||||
[+] added : startProcess routine for live user-mode debugging
|
|
||||||
|
|
||||||
[~] updated : loadArray returns python list, not dict
|
|
||||||
[~] updated : typedVar routine will return None if varibales's address is invalid.
|
|
||||||
[~] updated : loadDump routine returns bool now ( not string )
|
|
||||||
[~] updated : createSession routine is depricated now
|
|
||||||
|
|
||||||
[!] fixed : issue #8336 ( typedVar returns value with wrong type of fields )
|
|
||||||
[!] fixed : infinity loop on x32, if passed into typedVarList() address is not cast to addr64-format. condition in for(): entryAddress != address
|
|
||||||
[!] fixed : issue 8458 ( doubled output in windbg )
|
|
||||||
|
|
||||||
|
|
||||||
version 0.0.15 04/02/2011
|
|
||||||
[+] added : locals() routine; it returns local var for current scope
|
|
||||||
[+] added : typedVarArray routine
|
|
||||||
[~] updated : dbgModuleClass constructor fills symbol cache for optimization
|
|
||||||
[!] fixed : issue #8236 ( dprint/dprintln/print doesn't work with unicode string )
|
|
||||||
[!] fixed : issue #8229 ( loadModuel("some_drv") - out message "IDebugSymbol::Reload failed" )
|
|
||||||
[!] fixed : issue #8239 ( ptrSignByte returns str value )
|
|
||||||
|
|
||||||
|
|
||||||
version 0.0.14 17/01/2011
|
|
||||||
[+] added : __getattribute__ method for dbgModuleClass class to simplify access to module symbols's offsets
|
|
||||||
[+] added : __str__ method for typedVar class, so it can be outputed by print operator
|
|
||||||
[!] bug fixed: issue #8103 ( !py windbg extension imports modules into the global space )
|
|
||||||
[~] changed: eval() renamed to expr()
|
|
||||||
|
|
||||||
|
|
||||||
version 0.0.13 27/12/2010
|
|
||||||
[+] added : go, step, trace routine for control execution
|
|
||||||
[+] added : bp class for control breakpoints
|
|
||||||
[+] added : ptrMWord, ptrSignMWord for reading target's machine word ( 32 or 64 bits ) from memory\
|
|
||||||
[+] added : eval routine for evaluation windbg expression
|
|
||||||
[!] fixed : issue #6782 ( typedVar works very slowly )
|
|
||||||
|
|
||||||
|
|
||||||
version 0.0.12 27/11/2010
|
|
||||||
[+] added : getCurrentPorcess, setCurrentProcess routines
|
|
||||||
[!] fixed: loadModule return None for non existin module with out outputing error message
|
|
||||||
[+] added : getProcessorMode, setProcessorMode routines;
|
|
||||||
[+] added : sample stacks.py
|
|
||||||
[+] added: getThreadList routine; returns thread object's ptr list
|
|
||||||
[!] fixed : loadTypedVar for unnamed union tag ::<unnamed-tag>
|
|
||||||
[!] fixed : loadMemory does not throw exception and return false
|
|
||||||
[!] bug fixed: issue #7727 ( loadUnicodeString returns empty string )
|
|
||||||
[+] added: isKernelDebugging routine
|
|
||||||
[+] added: windbg snippet displaying IAT for module
|
|
||||||
[!] bug fixed: findModule does not work for address < 4GB
|
|
||||||
|
|
||||||
version 0.0.11 22/11/2010
|
|
||||||
[!] bug fixed: issue #7717 ( !py command failed to find standart modules )
|
|
||||||
[!] bug fixed: issue #7718 ( sys.argv[0] does not contain script name )
|
|
||||||
[!] bug fixed: issue #7697 ( raw_input does not work )
|
|
||||||
[+] added: windbgIn windbgOut class for redirecting in/out from stdin/stdout
|
|
||||||
[!] bug fixed: issue #7688 ( dbgIsSessionStart returns false after dbgCreateSession call )
|
|
||||||
|
|
||||||
version 0.0.10 12/11/2010
|
|
||||||
[!] updated: loadUnicodeStr routine returns unicode string ( instead of ansi string )
|
|
||||||
[!] bug fixed: issue #7623 ( memory routines failed to work at wow64 application )
|
|
||||||
[+] added: windbg snippet displaying list of export for module
|
|
||||||
[+] added: loadCStr, loadWStr routine added ( loading c-style string )
|
|
||||||
[!] typedVar routine fixed: loading array of complex type
|
|
||||||
|
|
||||||
version 0.0.9 03/11/2010
|
|
||||||
[+] added: windbg snippet displaying GDT entries
|
|
||||||
[+] added: windbg snippet displaying VMCS structure ( Intel-VT virtualization context )
|
|
||||||
[!] bug fixed: issue #7528 ( loadBytes raises error "did not match C++ signature" )
|
|
||||||
[+] added: windbg snippet displaying CR0 register
|
|
||||||
[+] added: windbg snippet displaying CR4 register
|
|
||||||
[+] added: !py windbg command can work without python script file extension ".py"
|
|
||||||
|
|
||||||
version 0.0.8 27/10/2010
|
|
||||||
[+] added: physical memory read support ( for loadBytes, loadWords etc)
|
|
||||||
[+] added: !pythonpath windbg command - print enviroment var $pythonpath
|
|
||||||
[+] added: !py windbg command uses $pythonpath var for search scripts
|
|
||||||
[+] added: ptrSize routine ( returns pointer's size at the target platform )
|
|
||||||
[!] bug fixed: issue #7164 ( loadTypedVarList can fall in infinite loop )
|
|
||||||
[+] added: sizeof routine ( returns size of type )
|
|
||||||
[+] added: sizeof method for typedVarClass ( return size of var in memory )
|
|
||||||
|
|
||||||
version 0.0.7 20/08/2010
|
|
||||||
|
|
||||||
[+] added: getImplicitThread routine( get address of the current thread )
|
|
||||||
[+] added: setImplicitThread routine ( change current thread context )
|
|
||||||
[+] added: dbgStackFrameClass class ( information about stack frame )
|
|
||||||
[+] added: getCurrentStack routine ( get current stack as collections of dbgStackFrameClass object )
|
|
||||||
[+] added: loadLinkedList routine
|
|
||||||
[+] added: getPdbFile routine
|
|
||||||
[+] added: reloadSymbols
|
|
||||||
[!] bug fixed: issue #6862 ( loadUnicodeString for x64 target does not work )
|
|
||||||
|
|
||||||
version 0.0.6 09/08/2010
|
|
||||||
|
|
||||||
[+] added: dbgExtensionClass class for calling windbg extension command from python script
|
|
||||||
[!] bug fixed: issue #6812 ( windbg ext command !py does not work with full path )
|
|
||||||
[+] added: !pycmd command for windbg extension
|
|
||||||
|
|
||||||
|
|
||||||
version 0.0.5 03/08/2010
|
|
||||||
|
|
||||||
[!] fixed: issue #6769 ( Args parsing is not supporting quoting )
|
|
||||||
[+] added: proclist.py sample
|
|
||||||
[+] added: loadTypedVarList routine
|
|
||||||
[!] fixed: typedVar
|
|
||||||
|
|
||||||
version 0.0.4 29/07/2010
|
|
||||||
|
|
||||||
[+] added: loadUnicodeString routine
|
|
||||||
[+] added: loadAnsiStr routine
|
|
||||||
[+] added: drvobj.py sample
|
|
||||||
[+] fixed: issue #6747 ( windbg script's call parameters passing into python script added )
|
|
||||||
|
|
||||||
|
|
||||||
version 0.0.3 28/07/2010
|
|
||||||
|
|
||||||
[!] bugfix: typedVar
|
|
||||||
[+] routines for loading integer value by pointer ( PtrByte, PtrSignByte, PtrWord ... ) added
|
|
||||||
[+] routines for loading array with sign extending( loadSignBytes, loadSignWords ... ) added
|
|
||||||
[+] routines for loading array ( loadBytes, loadWords ... ) added
|
|
||||||
[+] ssdt.py sample added
|
|
||||||
[+] idt.py sample added
|
|
@ -1,3 +0,0 @@
|
|||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
@ -1,74 +0,0 @@
|
|||||||
|
|
||||||
#
|
|
||||||
# Modules Info
|
|
||||||
#
|
|
||||||
|
|
||||||
import pykd
|
|
||||||
|
|
||||||
moduleList = []
|
|
||||||
|
|
||||||
def reloadModules():
|
|
||||||
|
|
||||||
global moduleList
|
|
||||||
|
|
||||||
|
|
||||||
for m in moduleList: globals()[ m.name().lower() ] = None
|
|
||||||
|
|
||||||
|
|
||||||
if pykd.isKernelDebugging():
|
|
||||||
|
|
||||||
global nt
|
|
||||||
|
|
||||||
nt = pykd.loadModule("nt")
|
|
||||||
|
|
||||||
modules = pykd.typedVarList( nt.PsLoadedModuleList, "nt", "_LDR_DATA_TABLE_ENTRY", "InLoadOrderLinks" )
|
|
||||||
|
|
||||||
moduleList.append( nt )
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
ntdll = pykd.loadModule("ntdll")
|
|
||||||
|
|
||||||
peb = pykd.typedVar( "ntdll", "_PEB", pykd.getCurrentProcess() )
|
|
||||||
|
|
||||||
ldr = pykd.typedVar( "ntdll", "_PEB_LDR_DATA", peb.Ldr )
|
|
||||||
|
|
||||||
modules = pykd.typedVarList( ldr.InLoadOrderModuleList.getAddress(), "ntdll", "_LDR_DATA_TABLE_ENTRY", "InLoadOrderLinks" )
|
|
||||||
|
|
||||||
|
|
||||||
moduleList = []
|
|
||||||
|
|
||||||
for m in modules:
|
|
||||||
|
|
||||||
baseName = str( pykd.loadUnicodeString( m.BaseDllName.getAddress() ) )
|
|
||||||
|
|
||||||
if baseName=="ntoskrnl.exe":
|
|
||||||
continue
|
|
||||||
|
|
||||||
module = pykd.findModule( m.DllBase )
|
|
||||||
|
|
||||||
globals()[ module.name().lower() ] = module
|
|
||||||
|
|
||||||
moduleList.append( module )
|
|
||||||
|
|
||||||
|
|
||||||
def printModuleList():
|
|
||||||
pykd.dprintln( "\n".join( [ str(m) for m in moduleList ] ) )
|
|
||||||
|
|
||||||
|
|
||||||
reloadModules()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
|
|
||||||
#
|
|
||||||
# CPU registers
|
|
||||||
#
|
|
||||||
|
|
||||||
import pykd
|
|
||||||
|
|
||||||
CPU = pykd.getProcessorMode()
|
|
||||||
x86Regs = [ "eax", "ebx", "ecx", "edx", "esi", "edi", "eip", "ebp", "esp" ]
|
|
||||||
amd64Regs = [ "rax", "rbx", "rcx", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rsi", "rdi", "rip", "rbp", "rsp" ]
|
|
||||||
|
|
||||||
|
|
||||||
def reloadRegs():
|
|
||||||
|
|
||||||
""" reload register's values"""
|
|
||||||
|
|
||||||
if CPU == "X86":
|
|
||||||
|
|
||||||
for regName in x86Regs:
|
|
||||||
globals()[regName] = pykd.reg(regName)
|
|
||||||
|
|
||||||
elif CPU == "X64":
|
|
||||||
|
|
||||||
for regName in amd64Regs:
|
|
||||||
globals()[regName] = pykd.reg(regName)
|
|
||||||
|
|
||||||
|
|
||||||
def printRegs():
|
|
||||||
|
|
||||||
""" print CPU registers values"""
|
|
||||||
|
|
||||||
if CPU == "X86":
|
|
||||||
for regName in x86Regs:
|
|
||||||
pykd.dprintln( "%s = %#x( %d )" % ( regName, globals()[regName], globals()[regName] ) )
|
|
||||||
|
|
||||||
elif CPU == "X64":
|
|
||||||
for regName in amd64Regs:
|
|
||||||
pykd.dprintln( "%s = %#x( %d )" % ( regName, globals()[regName], globals()[regName] ) )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
reloadRegs()
|
|
30
pykd.sln
30
pykd.sln
@ -1,30 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
|
||||||
# Visual Studio 2005
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pykd", "pykd\pykd.vcproj", "{C0A12E93-4B76-4B17-B837-37020F957AD2}"
|
|
||||||
ProjectSection(WebsiteProperties) = preProject
|
|
||||||
Debug.AspNetCompiler.Debug = "True"
|
|
||||||
Release.AspNetCompiler.Debug = "False"
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{C0A12E93-4B76-4B17-B837-37020F957AD2}.Release|x64.Build.0 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
@ -1,43 +0,0 @@
|
|||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
from pykd import *
|
|
||||||
|
|
||||||
|
|
||||||
def bpCallback():
|
|
||||||
|
|
||||||
if is64bitSystem():
|
|
||||||
objAttr = typedVar( "ntdll", "_OBJECT_ATTRIBUTES", reg("r8") )
|
|
||||||
else:
|
|
||||||
objAttr = typedVar( "ntdll", "_OBJECT_ATTRIBUTES", ptrPtr(reg("esp") + 0xC) )
|
|
||||||
|
|
||||||
name = loadUnicodeString( objAttr.ObjectName )
|
|
||||||
|
|
||||||
dprintln( "NtCreateFile: " + name )
|
|
||||||
|
|
||||||
return DEBUG_STATUS_GO_HANDLED
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not isWindbgExt():
|
|
||||||
startProcess("notepad.exe")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not isDumpAnalyzing() and not isKernelDebugging():
|
|
||||||
|
|
||||||
nt = loadModule("ntdll")
|
|
||||||
|
|
||||||
b1 = bp( nt.NtCreateFile, bpCallback )
|
|
||||||
|
|
||||||
# wait for user break, exceptions or process exit
|
|
||||||
go()
|
|
||||||
|
|
||||||
dprintln( "stopped" )
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
dprintln( "The debugger must be connected to live usermode process" )
|
|
||||||
|
|
||||||
|
|
218
samples/debug.py
218
samples/debug.py
@ -1,218 +0,0 @@
|
|||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
from PySide.QtCore import *
|
|
||||||
from PySide.QtGui import *
|
|
||||||
|
|
||||||
import pykd
|
|
||||||
|
|
||||||
|
|
||||||
class UpdateEvent( QEvent ):
|
|
||||||
def __init__(self):
|
|
||||||
QEvent.__init__(self, QEvent.Type(QEvent.User + 1))
|
|
||||||
|
|
||||||
|
|
||||||
class GoThread( QThread ):
|
|
||||||
|
|
||||||
def __init__(self, func):
|
|
||||||
QThread.__init__(self)
|
|
||||||
self.start()
|
|
||||||
self.func = func
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.func()
|
|
||||||
app.postEvent( mainForm, UpdateEvent() )
|
|
||||||
self.exit()
|
|
||||||
|
|
||||||
|
|
||||||
class DisasmWidget( QDockWidget ):
|
|
||||||
|
|
||||||
def __init__( self ):
|
|
||||||
QDockWidget.__init__( self )
|
|
||||||
self.setWindowTitle( "Disassembler" )
|
|
||||||
self.textArea = QTextEdit()
|
|
||||||
self.textArea.setReadOnly( True )
|
|
||||||
self.setWidget( self.textArea )
|
|
||||||
|
|
||||||
|
|
||||||
def onUpdate( self ):
|
|
||||||
|
|
||||||
disasm = pykd.disasm()
|
|
||||||
disasmStr = disasm.instruction() + "\n"
|
|
||||||
for i in xrange(50):
|
|
||||||
disasmStr += disasm.next() + "\n"
|
|
||||||
|
|
||||||
self.textArea.setPlainText( disasmStr )
|
|
||||||
|
|
||||||
|
|
||||||
class RegistersWidget( QDockWidget ):
|
|
||||||
|
|
||||||
def __init__( self ):
|
|
||||||
QDockWidget.__init__( self )
|
|
||||||
self.setWindowTitle( "Registers" )
|
|
||||||
self.textArea = QTextEdit()
|
|
||||||
self.setWidget( self.textArea )
|
|
||||||
|
|
||||||
def onUpdate( self ):
|
|
||||||
|
|
||||||
s = ""
|
|
||||||
|
|
||||||
for reg in self.getRegisterSet():
|
|
||||||
s += "%s %x ( %d )\r\n" % ( reg.name(), reg.value(), reg.value() )
|
|
||||||
|
|
||||||
self.textArea.setPlainText( s )
|
|
||||||
|
|
||||||
|
|
||||||
def getRegisterSet(self):
|
|
||||||
regSet=[]
|
|
||||||
try:
|
|
||||||
i = 0
|
|
||||||
while True:
|
|
||||||
reg = pykd.cpuReg(i)
|
|
||||||
regSet.append(reg)
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
except pykd.BaseException:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return regSet
|
|
||||||
|
|
||||||
|
|
||||||
class StackWidget( QDockWidget ):
|
|
||||||
|
|
||||||
def __init__( self ):
|
|
||||||
QDockWidget.__init__( self )
|
|
||||||
self.setWindowTitle( "Stack" )
|
|
||||||
self.textArea = QTextEdit()
|
|
||||||
self.setWidget( self.textArea )
|
|
||||||
|
|
||||||
def onUpdate( self ):
|
|
||||||
|
|
||||||
s = ""
|
|
||||||
|
|
||||||
stackFrames = pykd.getCurrentStack()
|
|
||||||
for frame in stackFrames:
|
|
||||||
s += pykd.findSymbol( frame.instructionOffset ) + " (%x)" % frame.instructionOffset + "\n"
|
|
||||||
|
|
||||||
self.textArea.setPlainText( s )
|
|
||||||
|
|
||||||
|
|
||||||
class MainForm( QMainWindow ):
|
|
||||||
|
|
||||||
updated = Signal()
|
|
||||||
|
|
||||||
def __init__( self ):
|
|
||||||
|
|
||||||
|
|
||||||
QMainWindow.__init__( self, None )
|
|
||||||
self.setWindowTitle("Pykd Debugger Sample")
|
|
||||||
self.setDockNestingEnabled( True )
|
|
||||||
|
|
||||||
self.goThread = None
|
|
||||||
|
|
||||||
|
|
||||||
fileMenu = QMenu( "&File" )
|
|
||||||
fileMenu.addAction( "Open process...", self.onOpenProcess )
|
|
||||||
fileMenu.addAction( "Exit", self.onExit )
|
|
||||||
self.menuBar().addMenu( fileMenu )
|
|
||||||
|
|
||||||
|
|
||||||
debugMenu = QMenu( "Debug" )
|
|
||||||
debugMenu.addAction( "Break", self.onBreak )
|
|
||||||
debugMenu.addAction( "Go", self.onGo )
|
|
||||||
debugMenu.addAction( "Step", self.onStep )
|
|
||||||
self.menuBar().addMenu( debugMenu )
|
|
||||||
|
|
||||||
|
|
||||||
viewMenu = QMenu( "View" )
|
|
||||||
viewMenu.addAction( "Disasm", self.onDisasmShow )
|
|
||||||
viewMenu.addAction( "Regsiters", self.onRegistersShow )
|
|
||||||
viewMenu.addAction( "Stack", self.onStackShow )
|
|
||||||
self.menuBar().addMenu( viewMenu )
|
|
||||||
|
|
||||||
self.disasmWidget = DisasmWidget()
|
|
||||||
self.disasmWidget.setVisible( False )
|
|
||||||
self.addDockWidget( Qt.LeftDockWidgetArea, self.disasmWidget )
|
|
||||||
self.updated.connect(self.disasmWidget.onUpdate )
|
|
||||||
|
|
||||||
self.registersWidget = RegistersWidget()
|
|
||||||
self.registersWidget.setVisible( False )
|
|
||||||
self.addDockWidget( Qt.LeftDockWidgetArea, self.registersWidget )
|
|
||||||
self.updated.connect(self.registersWidget.onUpdate )
|
|
||||||
|
|
||||||
self.stackWidget = StackWidget()
|
|
||||||
self.stackWidget.setVisible( False )
|
|
||||||
self.addDockWidget( Qt.LeftDockWidgetArea, self.stackWidget )
|
|
||||||
self.updated.connect(self.stackWidget.onUpdate )
|
|
||||||
|
|
||||||
self.resize( 800, 600 )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def stopGoThread( self ):
|
|
||||||
|
|
||||||
if self.goThread != None and self.goThread.isRunning():
|
|
||||||
self.goThread.quit()
|
|
||||||
self.goThread.wait(10000)
|
|
||||||
|
|
||||||
|
|
||||||
def event( self, ev ):
|
|
||||||
|
|
||||||
if ev.type() == QEvent.User + 1:
|
|
||||||
self.onUpdate()
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return QMainWindow.event( self, ev )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def onOpenProcess( self ):
|
|
||||||
fileDlg = QFileDialog( self )
|
|
||||||
fileDlg.setNameFilter( self.tr("Executable (*.exe)" ) )
|
|
||||||
|
|
||||||
pykd.startProcess( fileDlg.getOpenFileName()[0] )
|
|
||||||
|
|
||||||
self.goThread = GoThread( pykd.go )
|
|
||||||
|
|
||||||
|
|
||||||
def onBreak( self ):
|
|
||||||
pykd.breakin()
|
|
||||||
|
|
||||||
def onGo( self ):
|
|
||||||
self.stopGoThread()
|
|
||||||
self.goThread = GoThread( pykd.go )
|
|
||||||
|
|
||||||
def onStep( self ):
|
|
||||||
self.stopGoThread()
|
|
||||||
self.goThread = GoThread( pykd.step )
|
|
||||||
|
|
||||||
def onExit( self ):
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def onDisasmShow( self ):
|
|
||||||
self.disasmWidget.setVisible( not self.disasmWidget.isVisible() )
|
|
||||||
|
|
||||||
def onRegistersShow( self ):
|
|
||||||
self.registersWidget.setVisible( not self.registersWidget.isVisible() )
|
|
||||||
|
|
||||||
|
|
||||||
def onStackShow( self ):
|
|
||||||
self.stackWidget.setVisible( not self.stackWidget.isVisible() )
|
|
||||||
|
|
||||||
def onUpdate( self ):
|
|
||||||
self.updated.emit()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
global app
|
|
||||||
global mainForm
|
|
||||||
|
|
||||||
app = QApplication( [] )
|
|
||||||
mainForm = MainForm()
|
|
||||||
mainForm.show()
|
|
||||||
exitres = app.exec_()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,26 +0,0 @@
|
|||||||
"""
|
|
||||||
Print list of all drivers
|
|
||||||
"""
|
|
||||||
|
|
||||||
from pykd import *
|
|
||||||
import ntobj
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
def printDriverFromDir(dirName):
|
|
||||||
lstDrvs = ntobj.getListByDirectoryObject(
|
|
||||||
ntobj.getObjectByName(dirName), ptrPtr( getOffset("nt", "IoDriverObjectType") )
|
|
||||||
)
|
|
||||||
for drv in lstDrvs:
|
|
||||||
cmdDriver = "\t<link cmd=\"!drvobj 0x%x 7\">0x%x</link>" % (drv, drv)
|
|
||||||
dprintln(dirName + "\\" + ntobj.getObjectName(drv) + cmdDriver, True )
|
|
||||||
|
|
||||||
|
|
||||||
if not isKernelDebugging:
|
|
||||||
dprintln( "Script for kernel mode only" )
|
|
||||||
else:
|
|
||||||
printDriverFromDir("\\Driver")
|
|
||||||
printDriverFromDir("\\FileSystem")
|
|
||||||
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
|||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
from pykd import *
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def loadSymbols():
|
|
||||||
|
|
||||||
global nt
|
|
||||||
nt = loadModule( "nt" )
|
|
||||||
|
|
||||||
|
|
||||||
def getObjectInDir( dirObj, objName ):
|
|
||||||
|
|
||||||
|
|
||||||
if objName.find( "\\" ) != -1:
|
|
||||||
( dirSubName, objSubName ) = objName.split("\\", 1)
|
|
||||||
else:
|
|
||||||
dirSubName = objName
|
|
||||||
|
|
||||||
for i in range( 0, 37 ):
|
|
||||||
|
|
||||||
if dirObj.HashBuckets[i] != 0:
|
|
||||||
dirEntry = typedVar( "nt", "_OBJECT_DIRECTORY_ENTRY", dirObj.HashBuckets[i] )
|
|
||||||
|
|
||||||
while dirEntry != 0:
|
|
||||||
|
|
||||||
objHeader = containingRecord( dirEntry.Object, "nt", "_OBJECT_HEADER", "Body" )
|
|
||||||
|
|
||||||
objName = typedVar( "nt", "_OBJECT_HEADER_NAME_INFO", objHeader.getAddress() - objHeader.NameInfoOffset )
|
|
||||||
|
|
||||||
name = loadUnicodeString( objName.Name.getAddress() )
|
|
||||||
|
|
||||||
if name.lower() == dirSubName.lower():
|
|
||||||
|
|
||||||
if objHeader.Type == ptrPtr( nt.ObpDirectoryObjectType ):
|
|
||||||
return getObjectInDir( typedVar( "nt", "_OBJECT_DIRECTORY", dirEntry.Object), objSubName )
|
|
||||||
else:
|
|
||||||
return dirEntry.Object
|
|
||||||
|
|
||||||
if dirEntry.ChainLink != 0:
|
|
||||||
dirEntry = typedVar( "nt", "_OBJECT_DIRECTORY_ENTRY", dirEntry.ChainLink )
|
|
||||||
else:
|
|
||||||
dirEntry = 0
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getObjectByName( objName ):
|
|
||||||
|
|
||||||
if len(objName)==0:
|
|
||||||
return
|
|
||||||
|
|
||||||
if objName[0] != '\\':
|
|
||||||
return
|
|
||||||
|
|
||||||
rootDir = typedVar( "nt", "_OBJECT_DIRECTORY", ptrPtr( nt.ObpRootDirectoryObject ) )
|
|
||||||
|
|
||||||
return getObjectInDir( rootDir, objName[1:] )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def printDrvMajorTable( drvName ):
|
|
||||||
|
|
||||||
objName = "\\Driver\\" + drvName
|
|
||||||
drvObjPtr = getObjectByName( objName )
|
|
||||||
|
|
||||||
if drvObjPtr == None:
|
|
||||||
dprintln( "object not found" )
|
|
||||||
return
|
|
||||||
|
|
||||||
drvObj = typedVar( "nt", "_DRIVER_OBJECT", drvObjPtr )
|
|
||||||
|
|
||||||
|
|
||||||
for i in xrange( 0, len( drvObj.MajorFunction ) ):
|
|
||||||
dprintln( "MajorFunction[%d] = %s" % ( i, findSymbol( drvObj.MajorFunction[i] ) ) )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
if not isWindbgExt():
|
|
||||||
loadDump( sys.argv[1] )
|
|
||||||
|
|
||||||
if isKernelDebugging():
|
|
||||||
loadSymbols();
|
|
||||||
printDrvMajorTable( "afd" )
|
|
||||||
else:
|
|
||||||
dprintln( "not a kernel debugging" )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
"""
|
|
||||||
Using bp class without callback
|
|
||||||
"""
|
|
||||||
|
|
||||||
from pykd import *
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
if not isKernelDebugging():
|
|
||||||
|
|
||||||
if not isWindbgExt():
|
|
||||||
startProcess("calc.exe")
|
|
||||||
|
|
||||||
kernel32 = loadModule("kernel32")
|
|
||||||
|
|
||||||
bpA = bp( kernel32.LoadLibraryA )
|
|
||||||
bpW = bp( kernel32.LoadLibraryW )
|
|
||||||
|
|
||||||
go()
|
|
||||||
dbgCommand("gu")
|
|
||||||
|
|
||||||
dprintln( dbgCommand("!dlls @$retreg") )
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
dprintln("Script for user mode only")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
"""
|
|
||||||
Wait (execute) for load target module
|
|
||||||
"""
|
|
||||||
|
|
||||||
from pykd import *
|
|
||||||
import fnmatch
|
|
||||||
import sys
|
|
||||||
|
|
||||||
class loadHandler(debugEvent):
|
|
||||||
def __init__(self, mask):
|
|
||||||
debugEvent.__init__(self)
|
|
||||||
self.mask = mask
|
|
||||||
|
|
||||||
def onLoadModule(self, module):
|
|
||||||
if fnmatch.fnmatch( module.name(), self.mask ):
|
|
||||||
return DEBUG_STATUS_BREAK
|
|
||||||
return DEBUG_STATUS_NO_CHANGE
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
if len(sys.argv) == 2:
|
|
||||||
loadHandler = loadHandler( sys.argv[1] )
|
|
||||||
go()
|
|
||||||
else:
|
|
||||||
dprintln( "Wait (execute) for load target module\nInvalid command line" )
|
|
||||||
dprintln( "Using" + sys.argv[0] + " <MOD_FILE_NAME>" )
|
|
||||||
dprintln( "\tMOD_FILE_NAME - name of target module with wildcard" )
|
|
@ -1,68 +0,0 @@
|
|||||||
from pykd import *
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def checkInterrupt():
|
|
||||||
|
|
||||||
|
|
||||||
if not is64bitSystem():
|
|
||||||
|
|
||||||
dprintln( "check interrupt handlers...\n" )
|
|
||||||
|
|
||||||
idtr = reg( "idtr" )
|
|
||||||
|
|
||||||
nt = loadModule( "nt" )
|
|
||||||
hal = loadModule( "hal" )
|
|
||||||
|
|
||||||
ErrorCount = 0
|
|
||||||
|
|
||||||
for i in range(0,255):
|
|
||||||
|
|
||||||
idtEntry = typedVar( "nt", "_KIDTENTRY", idtr + i*8 )
|
|
||||||
|
|
||||||
if idtEntry.Selector == 8:
|
|
||||||
|
|
||||||
InterruptHandler = ( idtEntry.ExtendedOffset * 0x10000 ) + idtEntry.Offset
|
|
||||||
|
|
||||||
if InterruptHandler != 0 and not nt.contain( InterruptHandler ) and not hal.contain( InterruptHandler ):
|
|
||||||
|
|
||||||
kinterrupt = containingRecord( InterruptHandler, "nt", "_KINTERRUPT", "DispatchCode" )
|
|
||||||
|
|
||||||
dprintln ( "KINTERRUPT: %(1)x" % { "1" : kinterrupt.getAddress() } )
|
|
||||||
|
|
||||||
if addr64( kinterrupt.DispatchAddress ) != nt.KiInterruptDispatch and addr64( kinterrupt.DispatchAddress ) != nt.KiChainedDispatch:
|
|
||||||
dprintln ( "Threat!!! KINTERRUPT::DispatchAddress PATCHED" )
|
|
||||||
ErrorCount += 1
|
|
||||||
|
|
||||||
if findModule( kinterrupt.ServiceRoutine ) == None:
|
|
||||||
dprintln ( "Threat!!! KINTERRUPT::ServiceRoutine (%(1)x) out of any module" % { "1" : kinterrupt.ServiceRoutine } )
|
|
||||||
ErrorCount += 1
|
|
||||||
|
|
||||||
if not compareMemory( nt.KiInterruptTemplate, InterruptHandler, 98 ):
|
|
||||||
dprintln ( "Threat!!! KINTERRUPT::DispatchCode area PATCHED" )
|
|
||||||
ErrorCount += 1
|
|
||||||
|
|
||||||
dprintln ( "" )
|
|
||||||
|
|
||||||
dprintln( "check end: %(1)d threats" % { "1" : ErrorCount } )
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
dprintln( "x64 is not supported" )
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
if not isWindbgExt():
|
|
||||||
loadDump( sys.argv[1] )
|
|
||||||
|
|
||||||
if isKernelDebugging():
|
|
||||||
checkInterrupt()
|
|
||||||
else:
|
|
||||||
dprintln( "not a kernel debugging" )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
|||||||
"""
|
|
||||||
Print nt!_PORT_MESSAGE header and message dump
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from pykd import *
|
|
||||||
|
|
||||||
# LPC message type
|
|
||||||
LpcMessageType = {
|
|
||||||
1 : "LPC_REQUEST",
|
|
||||||
2 : "LPC_REPLY",
|
|
||||||
3 : "LPC_DATAGRAM",
|
|
||||||
4 : "LPC_LOST_REPLY",
|
|
||||||
5 : "LPC_PORT_CLOSED",
|
|
||||||
6 : "LPC_CLIENT_DIED",
|
|
||||||
7 : "LPC_EXCEPTION",
|
|
||||||
8 : "LPC_DEBUG_EVENT",
|
|
||||||
9 : "LPC_ERROR_EVENT",
|
|
||||||
10 : "LPC_CONNECTION_REQUEST"
|
|
||||||
}
|
|
||||||
|
|
||||||
# diplay format type
|
|
||||||
DispFormatsLength = {
|
|
||||||
"a" : 1, "b" : 1, "yb": 1,
|
|
||||||
"w" : 2, "W" : 2, "u" : 2,
|
|
||||||
"d" : 4, "dc": 4, "yd": 4, "f" : 4,
|
|
||||||
"q" : 8, "D" : 8,
|
|
||||||
"p" : ptrSize(), "ps": ptrSize()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def PrintPortMesage(messageAddr, printFormat="b", use32=False, moduleName="nt"):
|
|
||||||
"""
|
|
||||||
Print _PORT_MESSAGE header and dump of message dump
|
|
||||||
|
|
||||||
Usage: portmsg messageAddr, printFormat[=b], use32[=False], moduleName[=nt]
|
|
||||||
When:
|
|
||||||
messageAddr - address of port message
|
|
||||||
printFormat - string of display format ("d+printFormat").
|
|
||||||
May be: a, b, yb, w, W, u, d, dc, yd, f, q, D, p, ps
|
|
||||||
Display formats overview:
|
|
||||||
<link cmd=\".shell -x rundll32 url.dll,FileProtocolHandler http://msdn.microsoft.com/en-us/library/ff542790(VS.85).aspx\">http://msdn.microsoft.com/en-us/library/ff542790(VS.85).aspx</link>
|
|
||||||
|
|
||||||
use32 - use _PORT_MESSAGE32 (instead of _PORT_MESSAGE) structure (True or False)
|
|
||||||
moduleName - module name with _PORT_MESSAGE structure in symbols
|
|
||||||
"""
|
|
||||||
|
|
||||||
messageTypeName = "_PORT_MESSAGE"
|
|
||||||
if (use32):
|
|
||||||
messageTypeName = "_PORT_MESSAGE32"
|
|
||||||
|
|
||||||
messageHeader = typedVar(moduleName, messageTypeName, messageAddr)
|
|
||||||
if (None == messageHeader):
|
|
||||||
dprintln("ERROR: Getting (" + moduleName + "!" + messageTypeName + " *)(0x%x) failed" % messageAddr )
|
|
||||||
return
|
|
||||||
|
|
||||||
dprintln( "Data length : %3d (0x%02x)" % (messageHeader.u1.s1.DataLength, messageHeader.u1.s1.DataLength) )
|
|
||||||
dprintln( "Total length : %3d (0x%02x)" % (messageHeader.u1.s1.TotalLength, messageHeader.u1.s1.TotalLength) )
|
|
||||||
calcHeaderLen = messageHeader.u1.s1.TotalLength - messageHeader.u1.s1.DataLength
|
|
||||||
headerLen = sizeof(moduleName, messageTypeName)
|
|
||||||
if (calcHeaderLen != headerLen):
|
|
||||||
dprintln( "WARRING: calculated size (%2d (0x%02x)) of LPC-header does not match with symbols information (%2d (0x%02x))" % (calcHeaderLen, calcHeaderLen, headerLen, headerLen) )
|
|
||||||
if (messageHeader.u2.s2.Type in LpcMessageType):
|
|
||||||
dprintln( "Message type : " + LpcMessageType[messageHeader.u2.s2.Type] )
|
|
||||||
else:
|
|
||||||
dprintln( "Message type : %3d (0x%x)" % (messageHeader.u2.s2.Type, messageHeader.u2.s2.Type) )
|
|
||||||
procFindStr = "<link cmd=\"!process 0x%x\">%d(0x%x)</link>" % (messageHeader.ClientId.UniqueProcess, messageHeader.ClientId.UniqueProcess, messageHeader.ClientId.UniqueProcess)
|
|
||||||
dprintln( "Client ID : process= " + procFindStr + ", thread= %d(0x%x)" % (messageHeader.ClientId.UniqueThread, messageHeader.ClientId.UniqueThread), True)
|
|
||||||
dprintln( "View/Callback : %d (0x%x)" % (messageHeader.ClientViewSize, messageHeader.ClientViewSize) )
|
|
||||||
if (printFormat not in DispFormatsLength):
|
|
||||||
dprintln( "WARRING: Unknown (" + printFormat + ") diplay fromat. Use \"b\"" )
|
|
||||||
printFormat = "b"
|
|
||||||
dataAddr = messageHeader.getAddress() + headerLen
|
|
||||||
printCommand = "d" + printFormat + " 0x%x" % dataAddr
|
|
||||||
dataCount = messageHeader.u1.s1.DataLength / DispFormatsLength[printFormat]
|
|
||||||
printCommand += " L 0x%x " % dataCount
|
|
||||||
dprintln( "<link cmd=\"" + printCommand + "\">Dump of message data:</link>", True )
|
|
||||||
dprintln( dbgCommand(printCommand) )
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
argc = len(sys.argv)
|
|
||||||
if (2 == argc):
|
|
||||||
PrintPortMesage(expr(sys.argv[1]))
|
|
||||||
elif (3 == argc):
|
|
||||||
PrintPortMesage(expr(sys.argv[1]), sys.argv[2])
|
|
||||||
elif (4 == argc):
|
|
||||||
PrintPortMesage(expr(sys.argv[1]), sys.argv[2], sys.argv[3] == "True")
|
|
||||||
elif (5 == argc):
|
|
||||||
PrintPortMesage(expr(sys.argv[1]), sys.argv[2], sys.argv[3] == "True", sys.argv[4])
|
|
||||||
else:
|
|
||||||
dprintln(PrintPortMesage.__doc__, True)
|
|
@ -1,33 +0,0 @@
|
|||||||
|
|
||||||
import sys
|
|
||||||
from pykd import *
|
|
||||||
|
|
||||||
|
|
||||||
def processInfo():
|
|
||||||
|
|
||||||
nt = loadModule( "nt" )
|
|
||||||
|
|
||||||
processList = typedVarList( nt.PsActiveProcessHead, "nt", "_EPROCESS", "ActiveProcessLinks" )
|
|
||||||
|
|
||||||
for process in processList:
|
|
||||||
print "".join( [chr(i) for i in process.ImageFileName if i != 0] )
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
if not isWindbgExt():
|
|
||||||
if not loadDump( sys.argv[1] ):
|
|
||||||
dprintln( sys.argv[1] + " - load failed" )
|
|
||||||
return
|
|
||||||
|
|
||||||
if not isKernelDebugging():
|
|
||||||
dprintln( "not a kernel debugging" )
|
|
||||||
return
|
|
||||||
|
|
||||||
processInfo()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
|||||||
"""
|
|
||||||
Prase first param RpcServerRegisterIf[Xxx]
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from pykd import *
|
|
||||||
|
|
||||||
def rpcSrvIf(ifSpec):
|
|
||||||
"""
|
|
||||||
Prase RPC server interface specification
|
|
||||||
|
|
||||||
Usage example:
|
|
||||||
|
|
||||||
kd> ba e 1 rpcrt4!RPC_SERVER::RegisterInterface
|
|
||||||
kd> gc
|
|
||||||
|
|
||||||
And analyze first parameter
|
|
||||||
|
|
||||||
for x86:
|
|
||||||
kd> !py rpcSrvIf poi(@esp+@$ptrsize)
|
|
||||||
or for x64:
|
|
||||||
kd> !py rpcSrvIf @rdx
|
|
||||||
|
|
||||||
P.S. RPC_SERVER::RegisterInterface called from: RpcServerRegisterIf,
|
|
||||||
RpcServerRegisterIf2 and RpcServerRegisterIfEx
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def formatSintaxId(synId):
|
|
||||||
|
|
||||||
def formatGuid(guid):
|
|
||||||
part1 = "%08x-%04x-%04x" % (guid.data1, guid.data2, guid.data3)
|
|
||||||
part2 = "".join( ["%02x" % _byte for _byte in guid.data4] )
|
|
||||||
part3 = "".join( ["%02x" % _byte for _byte in guid.data5] )
|
|
||||||
return part1 + "-" + part2 + "-" + part3
|
|
||||||
|
|
||||||
def formatRpcVer(prcVer):
|
|
||||||
return "v.%d.%d" % (prcVer.MajorVersion, prcVer.MinorVersion)
|
|
||||||
|
|
||||||
return formatGuid(synId.SyntaxGUID) + " " + formatRpcVer(synId.SyntaxVersion)
|
|
||||||
|
|
||||||
# prepare structures for parsing
|
|
||||||
commGuid = typeInfo("rpcSrvIf~_GUID")
|
|
||||||
commGuid.append(ulong_t, "data1")
|
|
||||||
commGuid.append(ushort_t, "data2")
|
|
||||||
commGuid.append(ushort_t, "data3")
|
|
||||||
commGuid.append(uchar_t, "data4", 2)
|
|
||||||
commGuid.append(uchar_t, "data5", 6)
|
|
||||||
# print commGuid
|
|
||||||
|
|
||||||
rpcVersion = typeInfo("rpcSrvIf~_RPC_VERSION")
|
|
||||||
rpcVersion.append(ushort_t, "MajorVersion")
|
|
||||||
rpcVersion.append(ushort_t, "MinorVersion")
|
|
||||||
# print rpcVersion
|
|
||||||
|
|
||||||
rpcSintaxIdentifier = typeInfo("rpcSrvIf~_RPC_SYNTAX_IDENTIFIER")
|
|
||||||
rpcSintaxIdentifier.append(commGuid, "SyntaxGUID")
|
|
||||||
rpcSintaxIdentifier.append(rpcVersion, "SyntaxVersion")
|
|
||||||
# print rpcSintaxIdentifier
|
|
||||||
|
|
||||||
prcDispatchTable = typeInfo("rpcSrvIf~_RPC_DISPATCH_TABLE")
|
|
||||||
prcDispatchTable.append(uint_t, "DispatchTableCount")
|
|
||||||
prcDispatchTable.append(ptr_t, "DispatchTable")
|
|
||||||
prcDispatchTable.append(ptr_t, "Reserved")
|
|
||||||
# print prcDispatchTable
|
|
||||||
|
|
||||||
midlServerInfoHeader = typeInfo("rpcSrvIf~_MIDL_SERVER_INFO_hdr")
|
|
||||||
midlServerInfoHeader.append(ptr_t, "pStubDesc")
|
|
||||||
midlServerInfoHeader.append(ptr_t, "DispatchTable")
|
|
||||||
# print midlServerInfoHeader
|
|
||||||
|
|
||||||
rpcServerInterface = typeInfo("rpcSrvIf~_RPC_SERVER_INTERFACE")
|
|
||||||
rpcServerInterface.append(uint_t, "Length")
|
|
||||||
rpcServerInterface.append(rpcSintaxIdentifier, "InterfaceId")
|
|
||||||
rpcServerInterface.append(rpcSintaxIdentifier, "TransferSyntax")
|
|
||||||
rpcServerInterface.append(ptr_t, "DispatchTable") # -> prcDispatchTable
|
|
||||||
rpcServerInterface.append(uint_t, "RpcProtseqEndpointCount")
|
|
||||||
rpcServerInterface.append(ptr_t, "RpcProtseqEndpoint")
|
|
||||||
rpcServerInterface.append(ptr_t, "DefaultManagerEpv")
|
|
||||||
rpcServerInterface.append(ptr_t, "InterpreterInfo") # -> midlServerInfoHeader
|
|
||||||
rpcServerInterface.append(uint_t, "Flags")
|
|
||||||
# print rpcServerInterface
|
|
||||||
|
|
||||||
# get and print interface header
|
|
||||||
srvIf = rpcServerInterface.load( ifSpec )
|
|
||||||
dprintln("Interface ID : " + formatSintaxId(srvIf.InterfaceId) )
|
|
||||||
dprintln("Transfer Syntax : " + formatSintaxId(srvIf.TransferSyntax) )
|
|
||||||
dprintln("Endpoint count : %d" % srvIf.RpcProtseqEndpointCount )
|
|
||||||
if srvIf.RpcProtseqEndpointCount:
|
|
||||||
protoseqEndp = srvIf.RpcProtseqEndpoint
|
|
||||||
for i in range(0, srvIf.RpcProtseqEndpointCount):
|
|
||||||
dprintln("\t[%02d] protocol is `" % i + loadCStr( ptrPtr(protoseqEndp) ) + "'" )
|
|
||||||
protoseqEndp += ptrSize()
|
|
||||||
dprintln("\t[%02d] endpoint is `" % i + loadCStr( ptrPtr(protoseqEndp) ) + "'" )
|
|
||||||
protoseqEndp += ptrSize()
|
|
||||||
|
|
||||||
dprintln("")
|
|
||||||
|
|
||||||
# query dispatch routines table
|
|
||||||
dspTableSize = prcDispatchTable.load(srvIf.DispatchTable).DispatchTableCount
|
|
||||||
dspTable = midlServerInfoHeader.load(srvIf.InterpreterInfo).DispatchTable
|
|
||||||
dprintln('<exec cmd="dps 0x%x L 0x%x">Routine Table 0x%x, count %d (0x%02x)</exec>\n' %
|
|
||||||
(dspTable, dspTableSize, dspTable, dspTableSize, dspTableSize) ,True)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
if len(sys.argv) == 2:
|
|
||||||
rpcSrvIf( expr(sys.argv[1]) )
|
|
||||||
else:
|
|
||||||
dprintln(rpcSrvIf.__doc__)
|
|
@ -1,70 +0,0 @@
|
|||||||
from pykd import *
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def getServiceAddrWlh(Start, Offset):
|
|
||||||
return Start + (Offset / 16)
|
|
||||||
|
|
||||||
def getServiceAddr2k3(Start, Offset):
|
|
||||||
return Start + (Offset & ~0xf)
|
|
||||||
|
|
||||||
if (ptrWord(getOffset("nt", "NtBuildNumber")) == 3790):
|
|
||||||
getServiceAddr = getServiceAddr2k3
|
|
||||||
else:
|
|
||||||
getServiceAddr = getServiceAddrWlh
|
|
||||||
|
|
||||||
|
|
||||||
def checkSSDT():
|
|
||||||
|
|
||||||
nt = loadModule( "nt" )
|
|
||||||
|
|
||||||
|
|
||||||
if is64bitSystem():
|
|
||||||
|
|
||||||
serviceTableHeader = loadQWords( nt.KeServiceDescriptorTable, 4 )
|
|
||||||
serviceTableStart = serviceTableHeader[0]
|
|
||||||
serviceCount = serviceTableHeader[2]
|
|
||||||
|
|
||||||
dprintln( "ServiceTable start: %(1)x count: %(2)x" % { "1" : serviceTableStart, "2" : serviceCount } )
|
|
||||||
|
|
||||||
serviceTable = loadSignDWords( serviceTableStart, serviceCount )
|
|
||||||
|
|
||||||
for i in range( 0, serviceCount ):
|
|
||||||
|
|
||||||
routineAddress = getServiceAddr(serviceTableStart, serviceTable[i]);
|
|
||||||
dprintln( "[%u] " % i + findSymbol( routineAddress ) )
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
serviceTableHeader = loadDWords( nt.KeServiceDescriptorTable, 4 )
|
|
||||||
serviceTableStart = serviceTableHeader[0]
|
|
||||||
serviceCount = serviceTableHeader[2]
|
|
||||||
|
|
||||||
dprintln( "ServiceTable start: %(1)x count: %(2)x" % { "1" : serviceTableStart, "2" : serviceCount } )
|
|
||||||
|
|
||||||
serviceTable = loadPtrs( serviceTableStart, serviceCount )
|
|
||||||
|
|
||||||
for i in range( 0, serviceCount ):
|
|
||||||
dprintln( "[%u] " % i + findSymbol( serviceTable[i] ) )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
|
|
||||||
while True:
|
|
||||||
|
|
||||||
if not isWindbgExt():
|
|
||||||
if not loadDump( sys.argv[1] ):
|
|
||||||
dprintln( sys.argv[1] + " - load failed" )
|
|
||||||
break
|
|
||||||
|
|
||||||
if not isKernelDebugging():
|
|
||||||
dprintln( "not a kernel debugging" )
|
|
||||||
break
|
|
||||||
|
|
||||||
checkSSDT()
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
import sys
|
|
||||||
from pykd import *
|
|
||||||
|
|
||||||
|
|
||||||
def printStack():
|
|
||||||
|
|
||||||
|
|
||||||
def printThreadStack( threadPtr ):
|
|
||||||
|
|
||||||
setImplicitThread( threadPtr )
|
|
||||||
stackFrames = getCurrentStack()
|
|
||||||
for frame in stackFrames: dprintln( findSymbol( frame.instructionOffset ) + " (%x)" % frame.instructionOffset )
|
|
||||||
dprintln("")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def printUserStack():
|
|
||||||
|
|
||||||
threadList = getThreadList()
|
|
||||||
|
|
||||||
oldMode = getProcessorMode()
|
|
||||||
|
|
||||||
if oldMode == "X64" and loadModule( "wow64" ) != None:
|
|
||||||
setProcessorMode("X86")
|
|
||||||
|
|
||||||
for threadPtr in threadList:
|
|
||||||
printThreadStack( threadPtr )
|
|
||||||
|
|
||||||
setProcessorMode(oldMode)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def printKernelStack():
|
|
||||||
|
|
||||||
process = typedVar( "nt", "_EPROCESS", getCurrentProcess() )
|
|
||||||
|
|
||||||
threadList = typedVarList( process.ThreadListHead.getAddress(), "nt", "_ETHREAD", "ThreadListEntry" )
|
|
||||||
|
|
||||||
oldMode = getProcessorMode()
|
|
||||||
|
|
||||||
if is64bitSystem() and process.Wow64Process != 0:
|
|
||||||
setProcessorMode("X86")
|
|
||||||
|
|
||||||
for thread in threadList:
|
|
||||||
printThreadStack( thread.getAddress() )
|
|
||||||
|
|
||||||
setProcessorMode(oldMode)
|
|
||||||
|
|
||||||
|
|
||||||
if isKernelDebugging():
|
|
||||||
printKernelStack()
|
|
||||||
else:
|
|
||||||
printUserStack()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
while True:
|
|
||||||
|
|
||||||
if not isWindbgExt():
|
|
||||||
if not loadDump( sys.argv[1] ):
|
|
||||||
dprintln( sys.argv[1] + " - load failed" )
|
|
||||||
break
|
|
||||||
|
|
||||||
printStack()
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
#
|
|
||||||
# Add synthetic symbols for module by imports
|
|
||||||
#
|
|
||||||
|
|
||||||
from pykd import *
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def addSymSymbolsByImports(dbgModule):
|
|
||||||
if isKernelDebugging():
|
|
||||||
systemModule = loadModule( "nt" )
|
|
||||||
else:
|
|
||||||
systemModule = loadModule( "ntdll" )
|
|
||||||
|
|
||||||
if is64bitSystem():
|
|
||||||
ntHeader = typedVar( systemModule.name(), "_IMAGE_NT_HEADERS64", dbgModule.begin() + ptrDWord( dbgModule.begin() + 0x3c ) )
|
|
||||||
if ntHeader.OptionalHeader.Magic == 0x10b:
|
|
||||||
systemModule = loadModule( "ntdll32" )
|
|
||||||
ntHeader = typedVar( systemModule.name(), "_IMAGE_NT_HEADERS", dbgModule.begin() + ptrDWord( dbgModule.begin() + 0x3c ) )
|
|
||||||
else:
|
|
||||||
ntHeader = typedVar( systemModule.name(), "_IMAGE_NT_HEADERS", dbgModule.begin() + ptrDWord( dbgModule.begin() + 0x3c ) )
|
|
||||||
|
|
||||||
if ntHeader.OptionalHeader.DataDirectory[12].Size == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
iatAddr = dbgModule.begin() + ntHeader.OptionalHeader.DataDirectory[12].VirtualAddress;
|
|
||||||
|
|
||||||
for i in range( 0, ntHeader.OptionalHeader.DataDirectory[12].Size / ptrSize() ):
|
|
||||||
pIatEtry = iatAddr + i*ptrSize();
|
|
||||||
iatEntry = ptrPtr( pIatEtry )
|
|
||||||
|
|
||||||
if iatEntry != 0:
|
|
||||||
try:
|
|
||||||
symbolName = findSymbol( iatEntry )
|
|
||||||
addSynSymbol(pIatEtry, ptrSize(), "_imp_" + symbolName)
|
|
||||||
except TypeError:
|
|
||||||
dprintln( "Symbol for 0x%x" % iatEntry + " not found" )
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
argc = len(sys.argv)
|
|
||||||
if (2 == argc):
|
|
||||||
addSymSymbolsByImports(findModule(expr(sys.argv[1])))
|
|
||||||
else:
|
|
||||||
dprintln("Invalid command line")
|
|
||||||
dprintln("Usage: " + sys.argv[0] + " module_address")
|
|
@ -1,105 +0,0 @@
|
|||||||
"""
|
|
||||||
Exception watchdog
|
|
||||||
"""
|
|
||||||
|
|
||||||
from pykd import *
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# known exception codes
|
|
||||||
knownExcepCodes = {
|
|
||||||
0xc0000005 : "EXCEPTION_ACCESS_VIOLATION",
|
|
||||||
0x80000002 : "EXCEPTION_DATATYPE_MISALIGNMENT",
|
|
||||||
0x80000003 : "EXCEPTION_BREAKPOINT",
|
|
||||||
0x80000004 : "EXCEPTION_SINGLE_STEP",
|
|
||||||
0xc000008c : "EXCEPTION_ARRAY_BOUNDS_EXCEEDED",
|
|
||||||
0xc000008d : "EXCEPTION_FLT_DENORMAL_OPERAND",
|
|
||||||
0xc000008e : "EXCEPTION_FLT_DIVIDE_BY_ZERO",
|
|
||||||
0xc000008f : "EXCEPTION_FLT_INEXACT_RESULT",
|
|
||||||
0xc0000090 : "EXCEPTION_FLT_INVALID_OPERATION",
|
|
||||||
0xc0000091 : "EXCEPTION_FLT_OVERFLOW",
|
|
||||||
0xc0000092 : "EXCEPTION_FLT_STACK_CHECK",
|
|
||||||
0xc0000093 : "EXCEPTION_FLT_UNDERFLOW",
|
|
||||||
0xc0000094 : "EXCEPTION_INT_DIVIDE_BY_ZERO",
|
|
||||||
0xc0000095 : "EXCEPTION_INT_OVERFLOW",
|
|
||||||
0xc0000096 : "EXCEPTION_PRIV_INSTRUCTION",
|
|
||||||
0xc0000006 : "EXCEPTION_IN_PAGE_ERROR",
|
|
||||||
0xc000001d : "EXCEPTION_ILLEGAL_INSTRUCTION",
|
|
||||||
0xc0000025 : "EXCEPTION_NONCONTINUABLE_EXCEPTION",
|
|
||||||
0xc00000fd : "EXCEPTION_STACK_OVERFLOW",
|
|
||||||
0xc0000026 : "EXCEPTION_INVALID_DISPOSITION",
|
|
||||||
0x80000001 : "EXCEPTION_GUARD_PAGE",
|
|
||||||
0xc0000008 : "EXCEPTION_INVALID_HANDLE",
|
|
||||||
0xc0000194 : "EXCEPTION_POSSIBLE_DEADLOCK",
|
|
||||||
0xc000013a : "CONTROL_C_EXIT"
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExceptionHandler(debugEvent):
|
|
||||||
def __init__(self):
|
|
||||||
self.stopExceptionOccurred = False
|
|
||||||
debugEvent.__init__(self)
|
|
||||||
|
|
||||||
def onException(self, exceptData):
|
|
||||||
|
|
||||||
if exceptData["FirstChance"]:
|
|
||||||
return DEBUG_STATUS_NO_CHANGE
|
|
||||||
|
|
||||||
self.stopExceptionOccurred = True
|
|
||||||
|
|
||||||
dprintln("\n *** shit happens")
|
|
||||||
|
|
||||||
exceptCode = exceptData["Code"]
|
|
||||||
dprint("Exception code : ")
|
|
||||||
if exceptCode in knownExcepCodes:
|
|
||||||
dprintln( knownExcepCodes[exceptCode] )
|
|
||||||
else:
|
|
||||||
dprintln( "0x%08x" % exceptCode )
|
|
||||||
|
|
||||||
dprint("Exception flags : ")
|
|
||||||
exceptFlags = exceptData["Flags"]
|
|
||||||
if exceptFlags:
|
|
||||||
if exceptFlags & NONCONTINUABLE_EXCEPTION:
|
|
||||||
exceptFlags &= ~NONCONTINUABLE_EXCEPTION
|
|
||||||
dprint( "NONCONTINUABLE " )
|
|
||||||
if exceptFlags:
|
|
||||||
dprintln( "| 0x%02x" % exceptFlags)
|
|
||||||
else:
|
|
||||||
dprintln( "" )
|
|
||||||
else:
|
|
||||||
dprintln( "0" )
|
|
||||||
|
|
||||||
dprintln("Exception record : 0x%X" % exceptData["Record"])
|
|
||||||
|
|
||||||
exceptAddr = exceptData["Address"]
|
|
||||||
dprintln("\nException address : 0x%X" % exceptAddr)
|
|
||||||
dprintln( dbgCommand("ln 0x%X" % exceptAddr) )
|
|
||||||
|
|
||||||
if len( exceptData["Parameters"] ):
|
|
||||||
dprintln("Parameters : ")
|
|
||||||
for param in exceptData["Parameters"]:
|
|
||||||
dprintln("\t0x%X" % param)
|
|
||||||
|
|
||||||
dbgCommand( ".reload" )
|
|
||||||
dprintln( "\n " + dbgCommand( "r" ) )
|
|
||||||
dprintln( dbgCommand( "kb" ) )
|
|
||||||
|
|
||||||
return DEBUG_STATUS_BREAK
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
if len(sys.argv) != 1:
|
|
||||||
startComamnd = ""
|
|
||||||
for i in range(1, len(sys.argv)):
|
|
||||||
startComamnd += sys.argv[i] + " "
|
|
||||||
startProcess(startComamnd)
|
|
||||||
|
|
||||||
exceptionHandler = ExceptionHandler()
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
while not exceptionHandler.stopExceptionOccurred:
|
|
||||||
go()
|
|
||||||
|
|
||||||
except WaitEventException:
|
|
||||||
dprintln("none of the targets could generate events")
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user