diff --git a/pykd-0.3-2010.sln b/pykd-0.3-2010.sln index f415845..2086949 100644 --- a/pykd-0.3-2010.sln +++ b/pykd-0.3-2010.sln @@ -47,8 +47,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{A7AF EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "snippets", "snippets", "{AAB21DD2-B0EE-493E-8415-5195F18879EB}" ProjectSection(SolutionItems) = preProject + snippets\accessmask.py = snippets\accessmask.py snippets\cr0.py = snippets\cr0.py snippets\cr4.py = snippets\cr4.py + snippets\ctlcode.py = snippets\ctlcode.py + snippets\export.py = snippets\export.py + snippets\iat.py = snippets\iat.py EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "um", "um", "{EEFC9510-DFA7-439E-801E-48FCE72766AD}" diff --git a/snippets/accessmask.py b/snippets/accessmask.py new file mode 100644 index 0000000..5d8daff --- /dev/null +++ b/snippets/accessmask.py @@ -0,0 +1,120 @@ +# +# Access mask parser (c) Ignatich +# + +from pykd import * +import sys +import re + +AccessMask = { + 0x00010000 : 'DELETE', + 0x00020000 : 'READ_CONTROL', + 0x00040000 : 'WRITE_DAC', + 0x00080000 : 'WRITE_OWNER', + 0x00100000 : 'SYNCHRONIZE', + 0x01000000 : 'ACCESS_SYSTEM_SECURITY', + 0x02000000 : 'MAXIMUM_ALLOWED' + } + +GenericMask = { + 0x10000000 : 'GENERIC_ALL', + 0x20000000 : 'GENERIC_EXECUTE', + 0x40000000 : 'GENERIC_WRITE', + 0x80000000 : 'GENERIC_READ' + } + +FileAccessMask = { + 0x0001 : 'FILE_READ_DATA', + 0x0002 : 'FILE_WRITE_DATA', + 0x0004 : 'FILE_APPEND_DATA', + 0x0008 : 'FILE_READ_EA', + 0x0010 : 'FILE_WRITE_EA', + 0x0020 : 'FILE_EXECUTE', + 0x0040 : 'FILE_DELETE_CHILD', + 0x0080 : 'FILE_READ_ATTRIBUTES', + 0x0100 : 'FILE_WRITE_ATTRIBUTES' + } + +ProcessAccessMask = { + 0x0001 : 'PROCESS_TERMINATE', + 0x0002 : 'PROCESS_CREATE_THREAD', + 0x0004 : 'PROCESS_SET_SESSIONID', + 0x0008 : 'PROCESS_VM_OPERATION', + 0x0010 : 'PROCESS_VM_READ', + 0x0020 : 'PROCESS_VM_WRITE', + 0x0040 : 'PROCESS_DUP_HANDLE', + 0x0080 : 'PROCESS_CREATE_PROCESS', + 0x0100 : 'PROCESS_SET_QUOTA', + 0x0200 : 'PROCESS_SET_INFORMATION', + 0x0400 : 'PROCESS_QUERY_INFORMATION', + 0x0800 : 'PROCESS_SUSPEND_RESUME', + 0x1000 : 'PROCESS_QUERY_LIMITED_INFORMATION' + } + +ThreadAccessMask = { + 0x0001 : 'THREAD_TERMINATE', + 0x0002 : 'THREAD_SUSPEND_RESUME', + 0x0004 : 'THREAD_ALERT', + 0x0008 : 'THREAD_GET_CONTEXT', + 0x0010 : 'THREAD_SET_CONTEXT', + 0x0020 : 'THREAD_SET_INFORMATION', + 0x0040 : 'THREAD_QUERY_INFORMATION', + 0x0080 : 'THREAD_SET_THREAD_TOKEN', + 0x0100 : 'THREAD_IMPERSONATE', + 0x0200 : 'THREAD_DIRECT_IMPERSONATION', + 0x0400 : 'THREAD_SET_LIMITED_INFORMATION', + 0x0800 : 'THREAD_QUERY_LIMITED_INFORMATION' + } + +FileMaskSets = [FileAccessMask, AccessMask, GenericMask] +ProcessMaskSets = [ProcessAccessMask, AccessMask, GenericMask] +ThreadMaskSets = [ThreadAccessMask, AccessMask, GenericMask] +GenericMaskSets = [AccessMask, GenericMask] + +def parseMask(mask, maskSets) : + cnt = 0 + for i in range(0, 31) : + bit = 1 << i + for maskSet in maskSets : + if (bit & mask) and bit in maskSet: + if (cnt != 0) : + dprint(" | ") + if (cnt % 4 == 0) : + dprintln("") + dprint("" + maskSet[bit]) + mask &= ~bit + cnt += 1 + return mask + +def main(): + + argc = len(sys.argv) + + if argc == 1 : + dprintln("Syntax: [object type] <;hex mask>;") + dprintln("Supported object types: process, thread, file, generic") + return + + type = (argc > 2 and sys.argv[1]) or "generic" + if argc > 2 : + mask = int(sys.argv[2], 16) + else : + mask = int(sys.argv[1], 16) + + if type == "file" : + mask = parseMask(mask, FileMaskSets) + if type == "process" : + mask = parseMask(mask, ProcessMaskSets) + if type == "thread" : + mask = parseMask(mask, ThreadMaskSets) + elif type == "generic" : + mask = parseMask(mask, GenericMaskSets) + + dprintln("") + + if mask != 0 : + dprintln("Unknown bits: 0x%x" % mask) + +if __name__ == "__main__": + main() + diff --git a/snippets/ctlcode.py b/snippets/ctlcode.py new file mode 100644 index 0000000..ad08491 --- /dev/null +++ b/snippets/ctlcode.py @@ -0,0 +1,116 @@ + +import sys +from pykd import * + +def getDeviceType(devType): + + return { + 0x00000001 : "FILE_DEVICE_BEEP", + 0x00000002 : "FILE_DEVICE_CD_ROM", + 0x00000003 : "FILE_DEVICE_CD_ROM_FILE_SYSTEM", + 0x00000004 : "FILE_DEVICE_CONTROLLER", + 0x00000005 : "FILE_DEVICE_DATALINK", + 0x00000006 : "FILE_DEVICE_DFS", + 0x00000007 : "FILE_DEVICE_DISK", + 0x00000008 : "FILE_DEVICE_DISK_FILE_SYSTEM", + 0x00000009 : "FILE_DEVICE_FILE_SYSTEM", + 0x0000000a : "FILE_DEVICE_INPORT_PORT", + 0x0000000b : "FILE_DEVICE_KEYBOARD", + 0x0000000c : "FILE_DEVICE_MAILSLOT", + 0x0000000d : "FILE_DEVICE_MIDI_IN", + 0x0000000e : "FILE_DEVICE_MIDI_OUT", + 0x0000000f : "FILE_DEVICE_MOUSE", + 0x00000010 : "FILE_DEVICE_MULTI_UNC_PROVIDER", + 0x00000011 : "FILE_DEVICE_NAMED_PIPE", + 0x00000012 : "FILE_DEVICE_NETWORK", + 0x00000013 : "FILE_DEVICE_NETWORK_BROWSER", + 0x00000014 : "FILE_DEVICE_NETWORK_FILE_SYSTEM", + 0x00000015 : "FILE_DEVICE_NULL", + 0x00000016 : "FILE_DEVICE_PARALLEL_PORT", + 0x00000017 : "FILE_DEVICE_PHYSICAL_NETCARD", + 0x00000018 : "FILE_DEVICE_PRINTER", + 0x00000019 : "FILE_DEVICE_SCANNER", + 0x0000001a : "FILE_DEVICE_SERIAL_MOUSE_PORT", + 0x0000001b : "FILE_DEVICE_SERIAL_PORT", + 0x0000001c : "FILE_DEVICE_SCREEN", + 0x0000001d : "FILE_DEVICE_SOUND", + 0x0000001e : "FILE_DEVICE_STREAMS", + 0x0000001f : "FILE_DEVICE_TAPE", + 0x00000020 : "FILE_DEVICE_TAPE_FILE_SYSTEM", + 0x00000021 : "FILE_DEVICE_TRANSPORT", + 0x00000022 : "FILE_DEVICE_UNKNOWN", + 0x00000023 : "FILE_DEVICE_VIDEO", + 0x00000024 : "FILE_DEVICE_VIRTUAL_DISK", + 0x00000025 : "FILE_DEVICE_WAVE_IN", + 0x00000026 : "FILE_DEVICE_WAVE_OUT", + 0x00000027 : "FILE_DEVICE_8042_PORT", + 0x00000028 : "FILE_DEVICE_NETWORK_REDIRECTOR", + 0x00000029 : "FILE_DEVICE_BATTERY", + 0x0000002a : "FILE_DEVICE_BUS_EXTENDER", + 0x0000002b : "FILE_DEVICE_MODEM", + 0x0000002c : "FILE_DEVICE_VDM", + 0x0000002d : "FILE_DEVICE_MASS_STORAGE", + 0x0000002e : "FILE_DEVICE_SMB", + 0x0000002f : "FILE_DEVICE_KS", + 0x00000030 : "FILE_DEVICE_CHANGER", + 0x00000031 : "FILE_DEVICE_SMARTCARD", + 0x00000032 : "FILE_DEVICE_ACPI", + 0x00000033 : "FILE_DEVICE_DVD", + 0x00000034 : "FILE_DEVICE_FULLSCREEN_VIDEO", + 0x00000035 : "FILE_DEVICE_DFS_FILE_SYSTEM", + 0x00000036 : "FILE_DEVICE_DFS_VOLUME", + 0x00000037 : "FILE_DEVICE_SERENUM", + 0x00000038 : "FILE_DEVICE_TERMSRV", + 0x00000039 : "FILE_DEVICE_KSEC", + 0x0000003A : "FILE_DEVICE_FIPS", + 0x0000003B : "FILE_DEVICE_INFINIBAND", + 0x0000003E : "FILE_DEVICE_VMBUS", + 0x0000003F : "FILE_DEVICE_CRYPT_PROVIDER", + 0x00000040 : "FILE_DEVICE_WPD", + 0x00000041 : "FILE_DEVICE_BLUETOOTH", + 0x00000042 : "FILE_DEVICE_MT_COMPOSITE", + 0x00000043 : "FILE_DEVICE_MT_TRANSPORT", + 0x00000044 : "FILE_DEVICE_BIOMETRIC", + 0x00000045 : "FILE_DEVICE_PMI" + }.get( devType, "%#x" % devType ) + +def getMethod(method): + return { + 0: "BUFFERED", + 1: "IN_DIRECT", + 2: "OUT_DIRECT", + 3: "NEITHER" + }[method & 3] + +def getAccess(access): + return { + 0: "FILE_ANY_ACCESS", + 1: "FILE_READ_ACCESS", + 2: "FILE_WRITE_ACCESS", + 3: "3" + }[access & 3] + +def ctlcode( ctl ): + devtype = ( ctl >> 16 ) & 0xFFFF + access = ( ctl >> 14 ) & 3 + function = ( ctl >> 2 ) & 0xFFF + method = ctl & 3 + return "Device type: %s Function: %#x(%d) Method: %s Access: %s" % ( getDeviceType(devtype), function, function, getMethod(method), getAccess(access) ) + +def usage(): + dprintln( "Usage:" ) + dprintln( "!py ctlcode code") + +def main(): + + if not isKernelDebugging(): + dprintln( "This script is for kernel debugging only" ) + + if len(sys.argv) < 2: + usage() + return + + dprintln( ctlcode( expr( sys.argv[1] ) ) ) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/snippets/export.py b/snippets/export.py new file mode 100644 index 0000000..bef1f9a --- /dev/null +++ b/snippets/export.py @@ -0,0 +1,61 @@ +# +# +# + +import sys +import fnmatch +from pykd import * + + +def export( moduleName, mask = "*" ): + + modObj = module( moduleName ) + dprintln( "Module: " + moduleName + " base: %x" % modObj.begin() + " end: %x" % modObj.end() ) + + if isKernelDebugging(): + systemModule = module( "nt" ) + else: + systemModule = module( "ntdll" ) + + + if is64bitSystem(): + ntHeader = systemModule.typedVar( "_IMAGE_NT_HEADERS64", modObj.begin() + ptrDWord( modObj.begin() + 0x3c ) ) + if ntHeader.OptionalHeader.Magic == 0x10b: + systemModule = loadModule( "ntdll32" ) + ntHeader = systemModule.typedVar( "_IMAGE_NT_HEADERS", modObj.begin() + ptrDWord( modObj.begin() + 0x3c ) ) + else: + ntHeader = systemModule.typedVar("_IMAGE_NT_HEADERS", modObj.begin() + ptrDWord( modObj.begin() + 0x3c ) ) + + + dprintln( "Export RVA: %x Size: %x" % ( ntHeader.OptionalHeader.DataDirectory[0].VirtualAddress, ntHeader.OptionalHeader.DataDirectory[0].Size ) ) + dprintln( "========================" ) + + if ntHeader.OptionalHeader.DataDirectory[0].Size == 0: + return + + exportDirAddr = modObj.begin() + ntHeader.OptionalHeader.DataDirectory[0].VirtualAddress; + + namesCount = ptrDWord( exportDirAddr + 0x18 ) + + namesRva = modObj.begin() + ptrDWord( exportDirAddr + 0x20 ) + + for i in range( 0, namesCount ): + exportName = loadCStr( modObj.begin() + ptrDWord( namesRva + 4 * i ) ) + if fnmatch.fnmatch( exportName, mask ): + dprintln( exportName ) + + +if __name__ == "__main__": + + if not isWindbgExt(): + print "script is launch out of windbg" + quit( 0 ) + + if len (sys.argv)<=1: + dprintln( "usage: !py export module_name ( export mask )" ) + elif len( sys.argv ) == 2: + export( sys.argv[1] ) + else: + export( sys.argv[1], sys.argv[2] ) + + diff --git a/snippets/iat.py b/snippets/iat.py new file mode 100644 index 0000000..11a00f3 --- /dev/null +++ b/snippets/iat.py @@ -0,0 +1,69 @@ +# +# +# + +import sys +import fnmatch +from pykd import * + + +def iat( moduleName, mask = "*" ): + + mod = module( moduleName ) + dprintln( "Module: " + moduleName + " base: %x" % mod.begin() + " end: %x" % mod.end() ) + + if isKernelDebugging(): + systemModule = module( "nt" ) + else: + systemModule = module( "ntdll" ) + + + if is64bitSystem(): + ntHeader = systemModule.typedVar( "_IMAGE_NT_HEADERS64", mod.begin() + ptrDWord( mod.begin() + 0x3c ) ) + if ntHeader.OptionalHeader.Magic == 0x10b: + systemModule = loadModule( "ntdll32" ) + ntHeader = systemModule.typedVar( "_IMAGE_NT_HEADERS", mod.begin() + ptrDWord( mod.begin() + 0x3c ) ) + pSize = 4 + else: + pSize = 8 + else: + ntHeader = systemModule.typedVar( "_IMAGE_NT_HEADERS", mod.begin() + ptrDWord( mod.begin() + 0x3c ) ) + pSize = 4 + + + dprintln( "IAT RVA: %x Size: %x" % ( ntHeader.OptionalHeader.DataDirectory[12].VirtualAddress, ntHeader.OptionalHeader.DataDirectory[12].Size ) ) + dprintln( "========================" ) + + if ntHeader.OptionalHeader.DataDirectory[12].Size == 0: + return + + iatAddr = mod.begin() + ntHeader.OptionalHeader.DataDirectory[12].VirtualAddress; + + for i in range( 0, ntHeader.OptionalHeader.DataDirectory[12].Size / pSize ): + + if ( pSize == 4 ): + iatEntry = ptrDWord( iatAddr + i*pSize ) + else: + iatEntry = ptrQWord( iatAddr + i*pSize ) + + if iatEntry != None and iatEntry != 0: + symbolName = findSymbol( iatEntry ) + if fnmatch.fnmatch( symbolName, mask ): + dprintln( symbolName ) + + + + +if __name__ == "__main__": + + if not isWindbgExt(): + print "script is launch out of windbg" + quit( 0 ) + + if len (sys.argv)<=1: + dprintln( "usage: !py import module_name ( symbol name mask )" ) + elif len( sys.argv ) == 2: + iat( sys.argv[1] ) + else: + iat( sys.argv[1], sys.argv[2] ) +