Commit 89964e7b authored by ussrhero's avatar ussrhero
Browse files

initial commit

parents
def getModuleInfoProvider():
from localdb.module import getDefaultModuleInfoProvider
return getDefaultModuleInfoProvider()
\ No newline at end of file
import pykd
import argparse
import os
import multiprocessing
import json
from datetime import datetime
import time
from config import getModuleInfoProvider
moduleInfoProvider = None
class DumpStatus:
Error = 0
Success = 1
class DumpModule(object):
def __init__(self, mod):
global moduleInfoProvider
self.name = mod.name()
self.timestamp = mod.timestamp()
moduleInfo = json.loads( moduleInfoProvider.getModuleInfo(self.name) )
self.manufactor = moduleInfo.get("manufactor", "Unknown")
self.desc = moduleInfo.get("desc", "")
self.isDriver = ( mod.begin() & 0x8000000000000000 ) != 0
def getUniqueId(self):
return "%s_%x" % (self.name, self.timestamp)
def buildDumpDesc(name):
global moduleInfoProvider
moduleInfoProvider = getModuleInfoProvider()
return DumpDesc(name)
class DumpDesc(object):
def __init__(self, dumpName):
try:
self.dumpName = dumpName
pykd.loadDump(dumpName)
targetSystem = pykd.targetSystem()
self.modules = [ DumpModule(m) for m in targetSystem.currentProcess().modules() ]
self.desc = pykd.getSystemVersion().buildString
self.status = DumpStatus.Success
except:
print ("error")
self.status = DumpStatus.Error
def ifContainModule(self, mod):
id = mod.getUniqueId()
for module in self.modules:
if module.getUniqueId() == id:
return True
return False
def ifContainModuleName(self, name):
for module in self.modules:
if module.name == name:
return True
return False
def getDumpList(args):
if args.files:
filelist = [ f for f in args.files if os.path.isfile(f) ]
else:
if args.dir:
dirname = os.path.abspath(args.dir)
else:
dirname = os.path.abspath(".")
filelist = [ f for f in os.listdir(dirname) if os.path.isfile(f) ]
return filter( lambda f: os.path.splitext(f)[1].lower() == ".dmp", filelist )
def getUniqueModuleList(dumpDescList, moduleFilter):
uniqueModules = {}
for dump in dumpDescList:
for module in dump.modules:
if moduleFilter == '' or eval(moduleFilter, globals(), { 'manufactor' : module.manufactor, 'isDriver' : module.isDriver} ):
moduleId = module.getUniqueId()
if not moduleId in uniqueModules:
uniqueModules[moduleId] = module
return uniqueModules.values()
def printModuleDiff(dumpDescList, moduleFilter, verbose, rate):
print( "============ Module diff ============")
fullModuleList = getUniqueModuleList(dumpDescList, moduleFilter)
moduleNameList = sorted( set( [ m.name for m in fullModuleList ] ), key = lambda m: m.lower() )
for moduleName in moduleNameList:
moduleRate = len( [ d for d in dumpDescList if d.ifContainModuleName(moduleName) ] ) * 100 / len( dumpDescList )
moduleVariants = [ m for m in fullModuleList if m.name == moduleName ]
if moduleRate < rate:
continue
print( "Module: %s %d variants (in %d%% dumps)" % ( moduleName, len(moduleVariants), moduleRate ) )
for module in moduleVariants:
dumps = [ d for d in dumpDescList if d.ifContainModule(module) ]
print ("\tcount: %d timestamp: %x (%s) manufactor: %s%s" % (len(dumps), module.timestamp,
datetime.utcfromtimestamp(float(module.timestamp)).strftime('%Y/%m/%d'),
module.manufactor, " (%s)" % module.desc if len(module.desc) else "" ) )
if verbose:
if len(dumps) == len(dumpDescList):
print ("\t\tin all dumps")
else:
for dump in dumps:
print ("\t\t%s" % dump.dumpName)
def printOsDiff(dumpDescList, verbose):
print( "============ OS diff ===============")
uniqueSystemDesc = sorted( set( [ d.desc for d in dumpDescList ] ) )
for systemdesc in uniqueSystemDesc:
dumps = [ d for d in dumpDescList if d.desc == systemdesc ]
print ("System: %s in %d dumps" % ( systemdesc, len(dumps) ) )
if verbose:
if len(dumps) == len(dumpDescList):
print ("\t\tin all dumps")
else:
for dump in dumps:
print ("\t\t%s" % dump.dumpName)
def printDiff(args):
t1 = time.time()
print ("Started analyze at %s" % time.strftime("%Y/%m/%d %H:%M", time.localtime(t1)))
dumpList = getDumpList(args);
if args.processNumber == 1:
dumpDescList = map( buildDumpDesc, dumpList )
elif args.processNumber == -1:
dumpDescList = multiprocessing.Pool().map( buildDumpDesc, dumpList )
else:
dumpDescList = multiprocessing.Pool(args.processNumber).map( buildDumpDesc, dumpList )
print ( "parsed %d dumps in %d sec" % ( len(dumpList), time.time() - t1 ) )
print ( "\n" )
if args.moduleFilter:
print ("Module filter: \"%s\"\n" % args.moduleFilter)
printOsDiff( dumpDescList, args.verbose )
print ( "\n" )
printModuleDiff(dumpDescList, args.moduleFilter, args.verbose, args.rate)
def printHeader():
print( "" )
print( "Dump diff" )
print( "" )
def main():
printHeader()
parser = argparse.ArgumentParser(description='Show two dump diff')
parser.add_argument('-f', '--files', metavar='FILE', nargs='+', help='list of dump files')
parser.add_argument('-d', '--dir', metavar='DIRECTORY', help='directory with dump files')
parser.add_argument('-m', '--module', metavar='FILTER', dest = 'moduleFilter', help='module filter', default='not manufactor in ("Microsoft") and isDriver' )
parser.add_argument('-v', '--verbose', help='verbose output', action='store_true', default=False)
parser.add_argument('-r', '--rate', help='filter dump by rate', type=int, default=0)
parser.add_argument('-p', '--processes', help='load dump on multi core', dest='processNumber', type=int, default=-1)
args = parser.parse_args()
if args.rate < 0 or args.rate > 100:
print("rate must be in range [0, 100]")
printDiff(args)
if __name__ == "__main__":
main()
\ No newline at end of file
import json
class DefaultModuleInfoProvider(object):
def __init__(self):
self.moduleDB = json.loads(moduleDB)
self.moduleDB.extend( [ {"name" : name, "manufactor" : "Microsoft"} for name in standardModules ] )
def getModuleInfo(self, moduleName):
return next( ( json.dumps(x) for x in self.moduleDB if x['name'].lower() == moduleName.lower() ),
'{ "name" : "%s", "manufactor" : "Unknown"}' % moduleName )
def getDefaultModuleInfoProvider():
return DefaultModuleInfoProvider()
standardModules = [
'afd', 'atapi', 'ataport', 'ACPI', 'AgileVpn', 'acpiex', 'afunix', 'ahcache',
'bowser', 'nt', 'disk', 'cng', 'Beep', 'BOOTVID', 'blbdrive', 'BATTC', 'BasicDisplay', 'BasicRender',
'bam', 'bthport', 'BTHUSB', 'BthEnum', 'bthpan',
'cdrom', 'classpnp', 'msrpc', 'CLASSPNP', 'CI', 'cm_km', 'crashdmp', 'cdfs', 'CLFS', ' CompositeBus',
'csc', 'compbatt', 'CompositeBus', 'CmBatt', 'CldFlt', 'condrv', 'cdd', 'cldflt', 'cmimcext', 'clipsp',
'dump_atapi', 'dump_dumpata', 'dump_dumpfve', 'dxgkrnl', 'dfsc', 'Dxapi', 'discache', 'dxgmms1',
'dump_diskdump', 'dump_storahci', 'dump_iaStorA', 'dump_dumpstorport', 'dump_stornvme', 'dxgmms2',
'drmk',
'HTTP', 'hal', 'HIDCLASS', 'HIDPARSE', 'hidusb', 'hwpolicy', 'HDAudBus', 'HdAudio',
'EhStorClass',
'fastfat', 'FLTMGR', 'fwpkclnt', 'fileinfo', 'fvevol', 'Fs_Rec', 'fdc', 'filecrypt',
'gpuenergydrv',
'i8042prt', 'iorate',
'kbdhid', 'ksecpkg', 'ksecdd', 'ks','kbdclass', 'kdcom', 'kdnic', 'kd',
'luafv', 'lltdio',
'mrxsmb', 'mrxsmb10', 'mrxsmb20', 'mouhid', 'mpsdrv', 'mountmgr', 'monitor', 'mouclass', 'mup', 'msisadrv',
'Msfs', 'mssmbios', 'mslldp',
'Microsoft_Bluetooth_Legacy_LEEnumerator',
'netbt', 'NETIO', 'ndisuio', 'Ntfs', 'Null', 'netbios', 'ndiswan', 'ndis', 'NDProxy', 'nsiproxy', 'Npfs',
'ndistapi', 'Ndu', 'npsvctrig', 'nwifi', 'ntosext', 'NdisVirtualBus',
'pci', 'pacer', 'parport', 'partmgr', 'PCIIDEX', 'PSHED', 'portcls', 'pciide', 'parvdm', 'peauth',
'pcw', 'pdc',
'rdyboost', 'rdbss', 'raspptp', 'rassstp', 'rasl2tp', 'raspppoe', 'rspndr', 'rdpencdd', 'rdprefmp',
'RDPCDD', 'rdpbus', 'rfcomm', 'rdpvideominiport', 'rdpdr',
'srv', 'srv2', 'srvnet', 'serial', 'serenum', 'secdrv', 'spldr', 'scfilter', 'swenum', 'spaceport',
'storport', 'SCSIPORT', 'storahci', 'storqosflt', 'SgrmAgent',
'tcpip', 'tcpipreg', 'TDI', 'tdx', 'tunnel', 'termdd', 'TSDDD', 'tm',
'usbhub', 'USBD', 'usbuhci', 'usbehci', 'USBPORT', 'usbccgp', 'usbprint', 'umbus', 'USBSTOR',
'usbvideo', 'UEFI', 'usbohci', 'USBXHCI', 'UsbHub3', 'ucx01000',
'volsnap', 'volmgr', 'volmgrx', 'vga', 'VIDEOPRT', 'vdrvroot', 'vmstorfl', 'volume', 'vwififlt',
'vwifibus', 'vwifimp',
'wanarp', 'win32k', 'wfplwfs', 'Wdf01000', 'WMILIB', 'WudfPf', 'watchdog', 'WDFLDR', 'win32kfull',
'win32kbase', 'WindowsTrustedRT', 'WindowsTrustedRTProxy', 'WUDFRd', 'wmiacpi', 'WppRecorder',
'werkernel', 'wdiwifi', 'Wof', 'WpdUpFltr', 'wfplwf', 'wcifs'
]
moduleDB = r'''
[
{"name" : "intelppm", "manufactor" : "Intel", "timestamp" : "5b2a879e"},
{"name" : "intelppm", "manufactor" : "Intel", "timestamp" : "cdd5c2de"},
{"name" : "intelppm", "manufactor" : "Intel", "timestamp" : "96476b72"},
{"name" : "intelppm", "manufactor" : "Intel", "timestamp" : "e0024307"},
{"name" : "intelpep", "manufactor" : "Intel"},
{"name" : "mcupdate_GenuineIntel", "manufactor" : "Intel"},
{"name" : "igdkmd64", "manufactor" : "Intel"},
{"name" : "nvlddmkm", "manufactor" : "NVIDIA"},
{"name" : "iaStorA", "manufactor" : "Intel"},
{"name" : "nvvad64v", "manufactor" : "NVIDIA"},
{"name" : "CEA", "manufactor" : "Microsoft"},
{"name" : "ksthunk", "manufactor" : "Microsoft"},
{"name" : "mmcss", "manufactor" : "Microsoft"},
{"name" : "RTKVHD64", "manufactor" : "Realtek", "desc" : "High Definition Audio Function Driver" },
{"name" : "rt640x64", "manufactor" : "Realtek", "desc" : "8136/8168/8169 NDIS 6.40 64-bit Driver" },
{"name" : "SleepStudyHelper", "manufactor" : "Microsoft" },
{"name" : "1394ohci", "manufactor" : "Microsoft" },
{"name" : "SpbCx", "manufactor" : "Microsoft" },
{"name" : "ASACPI", "manufactor" : "Asus", "timestamp" : "509327da"},
{"name" : "acpipagr", "manufactor" : "Microsoft" },
{"name" : "nvvhci", "manufactor" : "NVIDIA"},
{"name" : "WdNisDrv", "manufactor" : "Windows Defender"}
]
'''
from setuptools import setup
setup(
name='dumpdiff',
packages=['dumpdiff'],
install_requires=[
'pykd',
],
entry_points = {
'console_scripts': ['dumpdiff=dumpdiff.dumpdiff:main'],
}
)
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment