Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #/usr/bin/env python
- import getopt
- import struct
- import immutils
- from immlib import *
- copyright="(C) Immunity, Inc."
- DESC = "Dumps Acrobat Reader Cache state"
- class AdobeHeap:
- def __init__(self,AcroPool):
- '''
- AcroManagingPool (hardcoded address depens on version of the AcroRd32.dll)
- From this address it's possible to access all managing structures of their custom heap implementation.
- '''
- self.AcroPool = AcroPool
- self.imm = Debugger()
- self.pAcroCacheList = []
- self.CacheHeadersInfo = []
- self.AcroManagingPool()
- def AcroManagingPool(self):
- self.AcroPool += 0xC #Reserved
- self.mem = self.imm.readMemory(self.AcroPool,128) #Managing structures for AcroCache
- self.lpCacheManaging = struct.unpack("32L",self.mem)
- self.AcroPool += (0x90 - 0xC) #Header of the first AcroBlock
- self.FirstAcroBlock = self.imm.readLong(self.AcroPool)
- def CacheManager(self,addr):
- self.AcroPool = self.imm.readMemory(addr,0x10)
- (pAcroPool,pFreeBlocksList,pAcroCacheList,blocksize) = struct.unpack("4L",self.AcroPool)
- self.imm.log("pAcroPool: 0x%08x pFreeBlocksList: 0x%08x pAcroCacheList: 0x%08x blocksize: 0x%08x" % (pAcroPool,pFreeBlocksList,pAcroCacheList,\
- blocksize), address = pAcroCacheList)
- return pAcroCacheList
- def CacheHeader(self,addr):
- self.AcroPool = self.imm.readMemory(addr,0x18)
- (pCacheManager,allocatedBlocks,flag,blink,flink,size) = struct.unpack("6L",self.AcroPool)
- self.imm.log("CacheManager: 0x%08x AllocatedBlocks: 0x%08x Flags: 0x%08x BLINK: 0x%08x FLINK: 0x%08x Size: 0x%08x" % (pCacheManager,allocatedBlocks\
- ,flag,blink,flink,size), address = addr)
- return flink
- def walkCache(self,addr):
- isAcroBlock = False
- isCache = False
- flag = self.imm.readLong(addr+0x8)
- if flag == 2:
- isAcroBlock = True
- size = self.imm.readLong(addr+0x18)
- elif flag == 0:
- isCache = True
- size = self.imm.readLong(addr+0x14)
- self.imm.log("")
- self.imm.log("***Walking through 0x%08x bytes cache***"%size)
- i = 0
- while 1:
- Flink = self.imm.readLong(addr+0x10)
- AllocatedBlocks = self.imm.readLong(addr+0x04)
- AcroBlockSize = self.imm.readLong(addr+0x14)
- if not Flink:
- self.imm.log("***Walk Done***")
- break
- if isCache:
- self.imm.log("Cache[%d]: 0x%08x | Allocated Blocks: [%d/128]" % (i,addr,AllocatedBlocks), address = addr)
- elif isAcroBlock:
- self.imm.log("AcroBlock: 0x%08x | Size: 0x08%x" % (Flink,AcroBlockSize), address = Flink)
- addr = Flink
- i += 1
- def getCacheManagers(self):
- self.imm.log("")
- self.imm.log("CacheManagers List:")
- i=0
- for x in self.lpCacheManaging:
- self.imm.log("lpCacheManaging[%d]: 0x%08x" % (i,x))
- i += 1
- def getCacheManagersInfo(self):
- self.imm.log("")
- self.imm.log("[Cache Managers Info]")
- for x in self.lpCacheManaging:
- self.pAcroCacheList.append(self.CacheManager(x))
- def getCacheHeaders(self):
- self.imm.log("")
- self.imm.log("[Cache Headers]")
- for x in self.pAcroCacheList:
- try:
- self.CacheHeadersInfo.append(self.CacheHeader(x))
- except:
- pass
- def dumpCache(self):
- self.getCacheManagers()
- self.getCacheManagersInfo()
- self.getCacheHeaders()
- self.pAcroCacheList.pop(0) #unused entry
- for x in self.pAcroCacheList:
- self.walkCache(x)
- def DumpAcroBlocks(self):
- addr = self.FirstAcroBlock
- self.AcroPool = self.imm.readMemory(addr,0x18)
- (pAcroPool,reserved,flag,blink,flink,size) = struct.unpack("6L",self.AcroPool)
- self.walkCache(flink)
- def usage(imm):
- imm.log("!acrocache")
- imm.log(" -c Dump AcroCache state")
- imm.log(" -f CACHEBLOCKADDR Follow CacheBlocks of same size and show allocations count")
- imm.log(" -b Dump AcroBlocks")
- def main(args):
- imm = Debugger()
- pAcroManagingPool = 0x014D38A0 #Acrobat Reader 9.4.0
- try:
- AcroManagingPool = imm.readLong(pAcroManagingPool)
- except:
- return "Couldn't read from AcroManagingPool pointer. Are you on Reader 9.4.0?"
- adobe = AdobeHeap(AcroManagingPool)
- if not args:
- usage(imm)
- try:
- opts, argo = getopt.getopt(args, "bcf:")
- except getopt.GetoptError:
- usage(imm)
- for o,a in opts:
- if o == "-f":
- try:
- adobe.walkCache(int(a, 16))
- except ValueError, msg:
- return "Invalid address: %s" % a
- if o == "-b":
- adobe.DumpAcroBlocks()
- if o == "-c":
- adobe.dumpCache()
- return "done"
- """
- This is just a little script for ImmunityDebugger that will resolve
- exposed COM functions to their relative address. Check usage for some TODO items.
- NOTE: Requires comtypes http://sourceforge.net/projects/comtypes/
- Also comtypes .exe requires MS VC 9.0 redistributables:
- http://www.microsoft.com/downloads/thankyou.aspx?familyId=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&displayLang=en
- You will need to register your activex that you are auditing. Use "regsvr32 activexthing.dll"
- IUf you're doing this on Vista, remember to run regsvr32 from an elevated cmd.exe!
- """
- from ctypes import *
- from ctypes.wintypes import *
- try:
- from comtypes import *
- from comtypes.typeinfo import *
- from comtypes.automation import *
- except ImportError:
- raise Exception("Comtypes library needed")
- from immlib import *
- ole32 = windll.ole32
- kernel32 = windll.kernel32
- class MEMORY_BASIC_INFORMATION(Structure):
- _fields_ = [
- ('BaseAddress', c_void_p),
- ('AllocationBase', c_void_p),
- ('AllocationProtect', c_ulong),
- ('RegionSize', c_ulong),
- ('State', c_ulong),
- ('Protect', c_ulong),
- ('Type', c_ulong),
- ]
- def get_linear_address(address):
- mbi = MEMORY_BASIC_INFORMATION()
- kernel32.VirtualQuery(address,byref(mbi),sizeof(mbi))
- return mbi.AllocationBase
- def enum_type_info_members(p_iref_type_info,p_reftype_attr,p_iunknown,imm, base_addr, mode):
- if p_reftype_attr.cFuncs == 0:
- return
- vtable = 0x0
- code_base = imm.getKnowledge("codebase")
- for i in range(p_reftype_attr.cFuncs):
- func_desc = p_iref_type_info.GetFuncDesc(i)
- method_name = p_iref_type_info.GetNames(func_desc.memid)
- inv_kind = func_desc.invkind
- lpVtbl = cast(p_iunknown, POINTER(POINTER(c_void_p)))
- value = get_linear_address(lpVtbl[0][func_desc.oVft])
- if str(method_name[0]) == "QueryInterface":
- import struct
- address = (((lpVtbl[0][i])-(value+0x1000)))
- address = address + code_base
- #activex = activex.split(".")[0]
- pages = imm.getMemoryPageByOwnerAddress( base_addr ) # workaround
- for page in pages:
- mem = page.getMemory()
- ndx = mem.find( struct.pack("L", address) )
- if ndx != -1:
- vtable = page.getBaseAddress() + ndx
- break
- #imm.log("values %s" % str(method_name[0]))
- if value is not None and lpVtbl[0][i] is not None:
- if func_desc.invkind == INVOKE_FUNC or func_desc.invkind == INVOKE_PROPERTYPUT or func_desc.invkind == INVOKE_PROPERTYPUTREF:
- address = (((lpVtbl[0][i])-(value+0x1000)))
- address = address + code_base
- else:
- if func_desc.invkind == INVOKE_FUNC or func_desc.invkind == INVOKE_PROPERTYPUT or func_desc.invkind == INVOKE_PROPERTYPUTREF:
- try:
- address = imm.readLong( vtable + i*4)
- except Exception:
- address = 0
- imm.log("Method: %s Address: 0x%08x" % (str(method_name[0]),address),address)
- if mode == "label_func":
- imm.setLabel(address, str(method_name[0]) )
- def usage(imm):
- imm.log("This is a helper for RE/bughunting ActiveX controls.")
- imm.log("!activex <name of Control> - this outputs all functions and their addresses.")
- imm.log("!activex <name of Control> break <function name> - set a breakpoint on a function name.")
- imm.log("!activex <name of Control> exec <function name> - call the function internally.")
- imm.log("!activex <name of Control> fuzz <function name> - fuzz this function.")
- imm.log("!activex <name of Control> label - Label all the activex methods.")
- def main(args):
- imm = Debugger()
- imm.log("Args to activex: %s"%repr(args))
- mode=None
- func = None
- try:
- if args[0]:
- activex = args[0]
- if len(args) > 1:
- if args[1]:
- if args[1] == "break":
- mode = "break_on_func"
- func = args[2]
- elif args[1] == "exec":
- mode = "exec_func"
- func = args[2]
- elif args[1] == "fuzz":
- mode = "fuzz_func"
- func = args[2]
- elif args[1] == "label":
- mode = "label_func"
- else:
- activex = args[0]
- else:
- usage(imm)
- return "Usage Information Outputted to log view (Alt-L)"
- except:
- usage(imm)
- return "Usage Information Outputted to Log View (Alt-L)"
- module = imm.getModule(activex)
- if not module:
- return "Module \"%s\" not found. Chech the Executable modules (Alt+E)" % activex
- imm.addKnowledge("codebase",module.getCodebase(),force_add=1)
- tlib = LoadTypeLib(module.getPath())
- ticount = tlib.GetTypeInfoCount()
- i = 0
- while i < ticount:
- p_itype_info = tlib.GetTypeInfo(i)
- if p_itype_info:
- p_type_attr = p_itype_info.GetTypeAttr()
- if p_type_attr.typekind is TKIND_COCLASS:
- for ref in range(p_type_attr.cImplTypes):
- h_ref_type = p_itype_info.GetRefTypeOfImplType(ref)
- if h_ref_type:
- p_iref_type_info = p_itype_info.GetRefTypeInfo(h_ref_type)
- if p_iref_type_info:
- p_reftype_attr = p_iref_type_info.GetTypeAttr()
- imm.log("CLSID: %s " % str(p_type_attr.guid))
- #try:
- p_iunknown = CoCreateInstance(p_type_attr.guid)
- #except:
- # pass
- if p_iunknown:
- enum_type_info_members(p_iref_type_info,p_reftype_attr,p_iunknown,imm, module.getBaseAddress(), mode)
- i+=1
- return "ActiveX Methods Trapped"
- # apitrace PyCommand - (c)Immunity Inc.
- # Justin Seitz <justin@immunityinc.com>
- # TODO:
- # - dereference stack params if the function doesn't contain symbols
- import getopt
- from immlib import *
- NAME = "apitrace"
- def usage(imm):
- imm.log("!%s Hooks all intermodular function calls" % (NAME))
- imm.log(" (excluding Rtl* by default). The -i and -e options")
- imm.log(" specify strings that if found in a function name")
- imm.log(" result in it being included or excluded from the")
- imm.log(" trace")
- imm.log("-i Include pattern")
- imm.log("-e Exclude pattern")
- imm.log(" ")
- imm.log("e.g. !apitrace -i msvcrt -e printf")
- imm.log("The above will hook all calls with msvcrt in the name")
- imm.log("excluding those with printf. So msvcrt.memset will be")
- imm.log("logged but not msvcrt._vsnwprintf")
- class ExportHooks(LoadDLLHook):
- def __init__(self):
- LoadDLLHook.__init__(self)
- self.imm = Debugger()
- self.hooker = InterCallHook()
- def run(self, regs):
- # We gotta new DLL loaded, time to find all it's functions
- # and set breakpoints on them, hopefully to bypass the pain
- # of having to rebuild IATs.
- event = self.imm.getEvent()
- self.imm.log("Module that just got loaded: %s" % event.lpImageName)
- #module = self.imm.getModule( event.lpImageName )
- # Force analysis
- self.imm.analyseCode( module.getCodebase() )
- # Now walk all the functions and set breakpoints on the functions
- # that we can resolve correctly
- function_list = self.imm.getAllFunctions( module.getCodebase() )
- for i in function_list:
- function = self.imm.getFunction( i )
- function_name = self.imm.decodeAddress( i )
- # Now we add all of our breakpoints to the main hook
- self.hooker.add( function_name, i )
- class InterCallHook(LogBpHook):
- def __init__(self):
- LogBpHook.__init__(self)
- self.imm = Debugger()
- def run(self, regs):
- # We have hit the function head, now we decode
- # the function and all of its parameters, quite handy
- call_stack = self.imm.callStack()
- # Now we just do some funky workarounds to make sure
- # we are decoding the information correctly
- main_call = False
- for i in call_stack:
- if i.getProcedure().startswith(" ") == False:
- if main_call == True:
- break
- else:
- main_call == True
- self.imm.log("")
- self.imm.log("Function Call -> %s" % i.getProcedure(), address = regs['EIP'])
- else:
- self.imm.log("%s" % i.getProcedure() )
- def main(args):
- imm = Debugger()
- include_pattern = exclude_pattern = None
- try:
- opts, args = getopt.getopt(args, "i:e:")
- except getopt.GetoptError:
- usage(imm)
- return "Incorrect arguments (Check log window)"
- for o, a in opts:
- if o == "-i":
- include_pattern = a
- elif o == "-e":
- exclude_pattern = a
- else:
- usage(imm)
- return "Incorrect arguments (Check log window)"
- # Find all intermodular commands in the executable
- # and set a logging BP hook on them. Ignore all calls
- # to Rtl* as they need to be instrumented with fast hooks
- module = imm.getModule( imm.getDebuggedName() )
- # We use a LoadDLLHook so that if libraries get added
- # we automagically add the new functions to the global hook
- loaddll_hook = ExportHooks()
- loaddll_hook.add("Generic DLL handler.")
- hooker = InterCallHook()
- if not module.isAnalysed():
- imm.analyseCode( module.getCodebase() )
- call_list = imm.getInterCalls( module.getCodebase() )
- for call in call_list.keys():
- function_name = imm.decodeAddress( int(call_list[call][0][2]) )
- function_suffix = function_name.split(".")[1]
- # Skip any Rtl* calls, we are just splitting a string like kernel32.LoadLibraryA
- if function_suffix.startswith("Rtl"):
- continue
- if exclude_pattern is not None and \
- function_name.find(exclude_pattern) != -1:
- continue
- if include_pattern is not None and \
- function_name.find(include_pattern) == -1:
- continue
- hooker.add( function_name, call_list[call][0][2] )
- imm.log("From: 0x%08x -> To: 0x%08x (decoded: %s) " % \
- (int(call),int(call_list[call][0][2]),function_name))
- return "[*] All intermodular calls found and hooked."
- #!/usr/bin/env python
- #-------------------------------------------------------------------------------
- #
- # By BoB -> Team PEiD
- # http://www.SecretAsHell.com/BobSoft/
- # BobSoft@GMail.Com
- #
- #-------------------------------------------------------------------------------
- #
- # Thanks to JMS for some TLS code used in this script .. ;)
- #
- #-------------------------------------------------------------------------------
- #
- # V1.01
- # Fixed a missing var in getAddressInTlsCallbacks() ..
- #
- #-------------------------------------------------------------------------------
- import immlib
- import pefile
- __VERSION__ = '1.01'
- DESC = "Sets a breakpoint on entrypoint of main module .."
- ProgName = 'BpxEP'
- ProgVers = __VERSION__
- #-------------------------------------------------------------------------------
- def usage(imm):
- imm.log(" ")
- imm.log("%s v%s By BoB -> Team PEiD" % (ProgName, ProgVers),focus=1, highlight=1)
- imm.log("Description:")
- imm.log(" Sets Breakpoint on entrypoint of main module and optionally runs until entrypoint reached ..")
- imm.log(" For use when a packed file fails to stop at entrypoint, EG [MSLRH], UPack ..")
- imm.log(" Debugging these files results in ImmDbg starting at system startup breakpoint ..")
- imm.log(" Also there is ability to place breakpoint at TLS callbacks, this is for packers that")
- imm.log(" run code from TLS callbacks, or unpack from TLS, EG: ASDPack v1.0 ..")
- imm.log(" With ASDPack the target PE File loaded into ImmDbg will run instead of stopping, so ")
- imm.log(" you must set Debugging Options -> Event -> Start at system breakpoint - then run script")
- imm.log(" with -tls and -go params.. ")
- imm.log(" ")
- imm.log("Usage:")
- imm.log(" !%s [-go] [-tls]" % ProgName.lower())
- imm.log(" ")
- imm.log("Options:")
- imm.log(" -go : After setting breakpoint on EP, run (F9)")
- imm.log(" -tls : Set Bpx on TLS callbacks too .. (Uses code by JMS)")
- imm.log(" ")
- return "See log window (Alt-L) for usage .. "
- #-------------------------------------------------------------------------------
- # Some of this TLS code from JMS, thanks :)
- # Returns 0 if no callbacks, else address of first callback ..
- def hasTlsCallbacks(pe, imm):
- addr = 0
- # Maybe no TLS table ?
- if hasattr(pe, "DIRECTORY_ENTRY_TLS"):
- tls_callbacks_table = pe.DIRECTORY_ENTRY_TLS.struct.AddressOfCallBacks
- # Maybe no TLS callbacks pointer?
- if tls_callbacks_table:
- addr = imm.readLong(tls_callbacks_table)
- # Maybe has TLS table, has Callbacks pointer, but points to null .. (Delphi does this)
- if addr != 0:
- return tls_callbacks_table
- return addr
- #-------------------------------------------------------------------------------
- # Returns fixed callback address if imagebase changed ..
- def getAddressInTlsCallbacks(pe, imm, index):
- # This was missing in v.00 .. ;/
- addr = 0
- a = hasTlsCallbacks(pe, imm)
- if a != 0:
- addr = imm.readLong(a + (index * 4)) # Zero-Based index !
- # Maybe relocated ?
- if imm.getModule(imm.getDebuggedName()).getBaseAddress() != pe.OPTIONAL_HEADER.ImageBase:
- # Fix the TLS Callback Virtual Address ..
- addr = (addr - pe.OPTIONAL_HEADER.ImageBase) + imm.getModule(imm.getDebuggedName()).getBaseAddress()
- return addr
- #-------------------------------------------------------------------------------
- def isAddressInTlsCallbacks(pe, imm, addr):
- for i in range(1000):
- TlsAddr = getAddressInTlsCallbacks(pe, imm, i)
- if TlsAddr == addr:
- return True
- if TlsAddr == 0:
- return False
- #-------------------------------------------------------------------------------
- def main(args):
- imm = immlib.Debugger()
- Mod = imm.getModule(imm.getDebuggedName())
- pe = pefile.PE(name=Mod.getPath())
- ep = pe.OPTIONAL_HEADER.AddressOfEntryPoint + Mod.getBaseAddress()
- imm.log(" ")
- imm.log("%s v%s By BoB -> Team PEiD" % (ProgName, ProgVers), highlight=1)
- TlsBpx = False
- RunAfter = False
- if args:
- for i in range(len(args)):
- if (args[i].lower() == "-tls"):
- TlsBpx = not TlsBpx
- if (args[i].lower() == "-go"):
- RunAfter = not RunAfter
- if TlsBpx == True:
- # Do we have a Tls table and callbacks ?
- addr = getAddressInTlsCallbacks(pe, imm, 0)
- if (addr == 0):
- # Stop and display error, else we could be running with -go .. :/
- imm.log("This file has no TLS callbacks ..")
- imm.log(" ")
- return "There were errors, please see log window (Alt-L)"
- count = 0
- while addr != 0:
- imm.setTemporaryBreakpoint(addr)
- count += 1
- imm.log("Set Breakpoint on TLS callback #%d .." % count, address=addr)
- imm.setComment(addr, "TLS callback #%d" % count)
- addr = getAddressInTlsCallbacks(pe, imm, count)
- # Get current EIP in ImmDbg ..
- EIP = imm.getCurrentAddress()
- # User error check .. :)
- if EIP != ep:
- imm.setTemporaryBreakpoint(ep)
- imm.log("Breakpoint set at EntryPoint ..", address=ep)
- imm.setComment(ep, "EntryPoint of \"%s\" .. " % imm.getDebuggedName())
- # Only run if not at EP .. :)
- if RunAfter == True:
- imm.log("Running ..")
- imm.run()
- else:
- imm.log("You are already at entrypoint ..")
- imm.log(" ")
- return "Program entry point"
- imm.log(" ")
- EIP = imm.getCurrentAddress()
- # If we ran then we should be at EP ..
- if EIP == ep:
- if imm.isAnalysed(ep) == 0:
- # Try to analyse code at entrypoint ..
- imm.analyseCode(ep)
- return "Program entry point"
- # Maybe we have hit a TLS Callback ?
- elif isAddressInTlsCallbacks(pe, imm, EIP):
- if imm.isAnalysed(EIP) == 0:
- # Try to analyse code at callback entrypoint ..
- imm.analyseCode(EIP)
- return imm.getComment(EIP)
- else:
- return "Breakpoint set at EntryPoint of \"%s\" .." % imm.getDebuggedName()
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- import immlib
- import getopt
- from libheap import *
- from immlib import LogBpHook
- import libdatatype
- DESC = "Analize a Specific Chunk at a specific moment"
- def usage(imm):
- imm.log("!chunkanalyzehook -a ADDRESS < exp >", focus=1)
- imm.log(" ADDRESS of the place where you want to set a hook")
- imm.log(" < exp > expression to calculate the chunk address")
- imm.log("ex: !chunkanalyzehook -a 0x1006868 EDI - 4")
- FunctionsType = [ "+", "-", "*", "/", "&", "^"]
- # Hook and Dump some Chunks based on the Expression
- class HookAndInform(LogBpHook):
- Functions = { "+": lambda a,b: a+b,
- "-": lambda a,b: a-b,
- "*": lambda a,b: a*c,
- "/": lambda a,b: a/c,
- "&": lambda a,b: a&c,
- "^": lambda a,b: a^c
- }
- def __init__(self, exp, discover = False, nchunks = 3, heap = 0):
- LogBpHook.__init__(self)
- self.Expression = exp
- self.discover = discover
- self.nchunks = nchunks
- self.heap = heap
- def run(self, regs):
- imm = immlib.Debugger()
- accumulator = 0
- second = 0
- func = '+'
- # Calculate the Chunk Address based on the Expression
- for value in self.Expression:
- if value in self.Functions.keys():
- func = value
- else:
- if type(value) == type(0):
- second = value
- elif regs.has_key(value.upper()):
- second = regs[ value.upper() ]
- elif value[0]=='[' and value[-1] ==']' and regs.has_key(value[1:-1].upper()):
- second = imm.readLong( regs[ value[1:-1].upper()] )
- else:
- self.unHook()
- accumulator = self.Functions[func]( accumulator, second)
- imm.log("> Hit Hook 0x%08x, checking chunk: 0x%08x" % (self.address, accumulator), address = accumulator)
- imm.log("=" * 47)
- pheap = PHeap( imm, self.heap )
- plookaddr = 0
- if self.heap:
- plookaddr = pheap.Lookaddr
- hlook = None
- if plookaddr:
- hlook = PHeapLookaside( imm, plookaddr )
- dt = None
- if self.discover:
- dt = libdatatype.DataTypes(imm)
- pheap = PHeap( imm )
- for chk in pheap.getChunks( accumulator, self.nchunks ):
- if chk.size < 0x7F and hlook:
- l = hlook[ chk.size ]
- if not l.isEmpty():
- if chk.addr+8 in l.getList():
- imm.log("- LOOKASIDE -")
- chk.printchunk(uselog = imm.log, dt = dt)
- imm.log("=-" * 0x23 + "=")
- def main(args):
- imm = immlib.Debugger()
- if not args:
- usage(imm)
- return "Wrong Arguments (Check usage on the Log Window)"
- try:
- opts, argo = getopt.getopt(args, "h:n:a:d")
- except getopt.GetoptError:
- return "Wrong Arguments (Check usage on the Log Window)"
- address = None
- expression = argo
- discover = False
- nchunks = 3
- heap = 0
- for o,a in opts:
- if o == '-a':
- try:
- address = int( a, 16 )
- except ValueError:
- usage(imm)
- return "Wrong Address (%s) % " % a
- elif o == '-d':
- discover = True
- elif o == '-n':
- nchunks = int( a, 16 )
- elif o == '-h':
- heap = int( a, 16 )
- imm.log("Expression: %s" % argo)
- if not address and not expression:
- usage( imm )
- return "Wrong usage (Check usage on the Log Window)"
- accumulator = 0
- func = '+'
- regs = {'EIP': 0L, 'ESP': 0L, 'EDI': 0L, 'EAX': 0L, 'EBP': 0L, 'EDX': 0L, 'EBX': 0L, 'ESI': 0L, 'ECX': 0L}
- # normalizing and checking the expression
- for ndx in range(0, len(expression) ):
- value = expression[ndx]
- if value not in FunctionsType:
- if value.upper() in regs.keys():
- expression[ndx] = value.upper()
- elif value[0]=='[' and value[-1] ==']' and regs.has_key(value[1:-1].upper()):
- expression[ndx] = value.upper()
- else:
- try:
- value = int(value, 16)
- expression[ndx] = value
- except ValueError:
- imm.log("Wrong Argument: %s" % value)
- return "Wrong Argument, Hook not setted"
- imm.log("Hooking on expression: '%s'" % str(expression) )
- hook = HookAndInform( expression, discover, nchunks = nchunks, heap = heap )
- hook.add("hook_inform_0x%08x" % address, address)
- return "Hooked on 0x%08x" % address
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- import immlib
- from libheap import *
- import getopt, string
- import immutils
- DESC = "Compare memory with a file (file been a dump from prettyhexprint)"
- NAME = "cmpmemp"
- def usage(imm):
- imm.log("!%s -a ADDR -f FILE_PATH" % NAME)
- imm.log("%s" % DESC)
- def main(args):
- imm = immlib.Debugger()
- address = 0x0
- f_name = None
- try:
- opts, argo = getopt.getopt(args, "a:f:")
- except getopt.GetoptError:
- return "Usage: !cmpmem -a ADDRESS -f FILETOCMP" % str(args)
- for o,a in opts:
- if o == "-a":
- try:
- address = int(a, 16)
- except ValueError, msg:
- return "Invalid heap address: %s" % a
- elif o == "-f":
- f_name = a
- if f_name and address:
- lines = open(f_name).readlines()
- fmem = []
- for line in lines:
- line = line.strip().split(" ")
- for number in line:
- try:
- fmem.append( chr( int(number, 16) ) )
- except ValueError:
- continue
- fmem = fmem
- mem = imm.readMemory(address, len(fmem) )
- for a in range(0, len(fmem)):
- try:
- if fmem[a] != mem[a]:
- imm.log("Unmatched at offset: %d" % a)
- imm.log(" File: %s" % immutils.prettyhexprint( string.joinfields(fmem[ a: a + 8 ], "") ) )
- imm.log(" Mem : %s" % immutils.prettyhexprint( mem[ a: a + 8 ] ) )
- return "Unmatched: Check log window for the dump"
- except IndexError:
- log_str = "Unmatch: Different string sizes= File: %d Memory: %d" % (len(fmem), len(mem))
- imm.log("%s" % log_str)
- return log_str
- imm.log("Match!")
- return "Match!"
- return "No match"
- """pycmd example"""
- DESC="""Find a exported function on the loaded dll"""
- import immlib
- def usage(imm):
- imm.log("!dependencies Find an exported function on the loaded dll")
- imm.log("!dependencies module.function")
- imm.log("ex: !dependencies rpcrt4.rpcserveruseprotseqw")
- def main(args):
- imm=immlib.Debugger()
- if len(args) !=1:
- usage(imm)
- return "Error: Wrong arguments"
- result = imm.findDependecies( [ args[0] ] )
- ret = 0
- for modname in result.keys():
- for mod in result[modname]:
- imm.log("Found: %20s on %s" % (modname, mod.name), address = mod.address)
- ret +=1
- return "Found %d dependencies" % retimport immlib, immutils
- DESC = "Looks for mapped address that can be 'transformed' into opcodes"
- def str2int24_swapped( value ):
- return istr2int( value + "\x00" )
- def usage(imm):
- imm.log("!duality Looks for mapped address that can be 'transformed' into opcodes")
- imm.log("!duality <asm code>")
- def main(args):
- imm = immlib.Debugger()
- found = 0
- searchf = {1:ord, 2: immutils.str2int16_swapped,\
- 3:str2int24_swapped}
- searchm = {1:0xff, 2:0xffff, 3: 0xffffff}
- code = imm.assemble( " ".join(args) )
- mask = len(code)
- currentmask = searchm[mask]
- try:
- what = searchf[ mask ]( code )
- except KeyError:
- return "Error, Code too big"
- imm.log("What: 0x%08x -> %s" % (what, " ".join(args)) )
- imm.getMemoryPages()
- for a in imm.MemoryPages.keys():
- mem = imm.MemoryPages[a]
- size = mem.getSize()
- start = mem.getBaseAddress()
- end = start + size
- ouraddr = ( start & ~currentmask) | what
- if ouraddr > start and ouraddr < end:
- imm.log("Found: 0x%08x %s" % (ouraddr, mem.getSection()), address = ouraddr)
- found+=1
- else:
- ouraddr+= currentmask+1
- if ouraddr > start and ouraddr < end:
- imm.log("Found: 0x%08x (%s)" % ( ouraddr, mem.getSection() ), address = ouraddr)
- found+=1
- return "Addresses founded: %d (Check the Log Window)" % foundimport immlib
- import immutils
- NAME = "findantidep"
- DESC="""Find address to bypass software DEP"""
- def usage(imm):
- imm.log("!%s" % NAME)
- imm.log("%s" % DESC)
- def tAddr(addr):
- buf = immutils.int2str32_swapped(addr)
- return "\\x%02x\\x%02x\\x%02x\\x%02x" % ( ord(buf[0]) , ord(buf[1]), ord(buf[2]), ord(buf[3]) )
- def main(args):
- imm=immlib.Debugger()
- addylist = []
- mod = imm.getModule("ntdll.dll")
- if not mod:
- return "Error: Ntdll.dll not found!"
- # Finding the first ADDRESS
- ret = imm.searchCommands("MOV AL,1\nRET")
- if not ret:
- return "Error: Sorry, the first addy cannot be found"
- for a in ret:
- addylist.append( "0x%08x: %s" % (a[0], a[2]) )
- ret = imm.comboBox("Please, choose the First Address [sets AL to 1]", addylist)
- firstaddy = int(ret[0:10], 16)
- imm.log("First Address: 0x%08x" % firstaddy, address = firstaddy)
- # Finding the Second ADDRESS
- ret = imm.searchCommandsOnModule(mod.getBase(), "CMP AL,0x1\n PUSH 0x2\n POP ESI\n" )
- if not ret:
- return "Error: Sorry, the second addy cannot be found"
- secondaddy = ret[0][0]
- imm.log( "Second Address %x" % secondaddy , address= secondaddy)
- # Finding the Third ADDRESS
- ret = imm.inputBox("Insert the Asm code to search for")
- ret = imm.searchCommands(ret)
- if not ret:
- return "Error: Sorry, the third address cannot be found"
- addylist = []
- for a in ret:
- addylist.append( "0x%08x: %s" % (a[0], a[2]) )
- ret = imm.comboBox("Please, choose the Third return Address [jumps to shellcode]", addylist)
- thirdaddy = int(ret[0:10], 16)
- imm.log( "Third Address: 0x%08x" % thirdaddy, thirdaddy )
- imm.log( 'stack = "%s\\xff\\xff\\xff\\xff%s\\xff\\xff\\xff\\xff" + "A" * 0x54 + "%s" + shellcode ' %\
- ( tAddr(firstaddy), tAddr(secondaddy), tAddr(thirdaddy) ) )
- import immlib
- import immutils
- import libdatatype
- NAME = "finddatatype"
- def usage(imm):
- imm.log("!%s" % NAME)
- imm.log("!%s ADDRESS SIZE" % NAME)
- imm.log("Attempts to find the type of the data spanning")
- imm.log("ADDRESS to ADDRESS + SIZE")
- return "Usage: !%s ADDRESS SIZE" % NAME
- def main(args):
- imm = immlib.Debugger()
- if not args:
- return usage( imm )
- if len( args ) != 2:
- return usage( imm )
- addr = int(args[0], 16)
- size = int(args[1], 16)
- dt = libdatatype.DataTypes(imm)
- mem = imm.readMemory( addr, size )
- if not mem:
- return "Error: Couldn't read anything at address: 0x%08x" % addr
- ret = dt.Discover( mem, addr, what = 'all' )
- imm.log( "Found: %d data types" % len(ret) )
- for obj in ret:
- t = "obj: %d" % obj.size
- if obj.data:
- msg = obj.Print()
- imm.log( "obj: %s: %s %d" % (obj.name, msg, obj.getSize() ), address = obj.address)
- return "Found: %d data types" % len(ret)
- """
- (c) Immunity, Inc. 2004-2008
- U{Immunity Inc.<http://www.immunityinc.com>}
- findloop
- """
- from immlib import *
- from immutils import *
- import getopt
- DESC=""" Find natural loops given a function start address """
- def usage(imm):
- imm.log("!findloop -a <address>")
- imm.log("-a (function start address)")
- imm.log("-h This help")
- def main(args):
- imm = Debugger()
- try:
- opts,argo = getopt.getopt(args, "a:")
- except:
- return usage(imm)
- for o,a in opts:
- if o == "-a":
- loops = imm.findLoops(int(a,16))
- for loop in loops:
- imm.log("LOOP! from:0x%08x, to:0x%08x"%(loop[0],loop[1]),loop[0])
- func = imm.getFunction(int(a,16))
- bbs = func.getBasicBlocks()
- #find first and last node
- first = 0xffffffff
- last = 0
- for node in loop[2]:
- if node < first: first = node
- if node > last: last = node
- #mark loop nodes, but NOT change anything if there's any kind of comment
- for node in loop[2]:
- imm.log(" Loop node:0x%08x"%node,node)
- for bb in bbs:
- if bb.getStart() == node:
- instrs = bb.getInstructions(imm)
- for op in instrs:
- if not imm.getComment(op.getAddress()) and op.getAddress() != node:
- if node == last and op.getAddress() == instrs[-1].getAddress():
- #last instruction of last node
- imm.setComment(op.getAddress(), "/")
- else:
- imm.setComment(op.getAddress(), "|")
- if not imm.getComment(node):
- if node == first:
- imm.setComment(node, "\ Loop 0x%08X Node"%(loop[0]))
- else:
- imm.setComment(node, "| Loop 0x%08X Node"%(loop[0]))
- return "Done!"
- if o =="-h":
- return usage(imm)
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- TODO:
- Fix the Offset in order to actually point to the address where the ID was found. (This is just a really beta version of this script)
- """
- __VERSION__ = '1.0'
- import immlib
- import getopt
- import struct
- DESC = """Find a Packer/Cryptor on a Module (Note: It might take some times due to the amount of signature on our db)"""
- def usage(imm):
- imm.log("!findpacker [-f] -m filename/module Get the RPC information of a loaded dll or for all loaded DLL's",focus=1)
- imm.log(" -m filename/module File or Module to search for")
- imm.log(" -f When set, it look in the file instead of the loaded module")
- imm.log(" ex: !findpacker -m notepad")
- imm.log("NOTE: It might take some times due to the amount of signature on our db")
- def main(args):
- imm = immlib.Debugger()
- if not args:
- usage(imm)
- return "No args"
- try:
- opts, argo = getopt.getopt(args, "m:f")
- except getopt.GetoptError:
- usage(imm)
- return "Bad heap argument %s" % args[0]
- module = None
- OnMemory = 1
- for o,a in opts:
- if o == "-m":
- module = a
- elif o == '-f':
- OnMemory = 0
- if not module:
- usage(imm)
- return "No module provided, see the Log Window for details of usage"
- try:
- ret = imm.findPacker( module, OnMemory = OnMemory)
- except Exception, msg:
- return "Error: %s" % msg
- if not ret:
- return "No Packer found"
- for (addr, name) in ret:
- imm.log("Packer found!: %s at 0x%08x" % (name, addr), address = addr)
- return "Packers found on %s: %d" % (module, len(ret))
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- DESC="""Analize the heap pattern of a executed function"""
- import immlib
- import immutils
- import struct
- from immlib import LogBpHook
- from libheap import *
- import libdatatype
- import getopt
- # RtlAllocateHeap Hook class
- ALLOCLABEL = "Alloc Hook"
- class RtlAllocateHeapHook(LogBpHook):
- def __init__(self, address):
- LogBpHook.__init__(self)
- #self.Heap = heap
- self.hookaddr = address
- self.Called = []
- def run(self,regs):
- """This will be executed when hooktype happens"""
- imm = immlib.Debugger()
- readaddr=""
- size=""
- res=imm.readMemory( regs['EBP'] + 8, 0xc)
- if len(res) != 0xc or not res:
- imm.log("RtlAllocateHeap: ESP seems to broken, unable to get args")
- return 0x0
- (heap, flags, size) = struct.unpack("LLL", res)
- #imm.log("RtlAllocateHeap(0x%08x, 0x%08x, 0x%08x)" % (heap, flags, size))
- called = imm.getKnowledge( "heap_%08x" % self.hookaddr )
- if not called:
- called = []
- try:
- callstack = imm.readLong( regs['EBP'] + 4)
- except Exception:
- callstack = 0x0
- called.append( (1, callstack, heap, flags, size, regs['EAX'] ) )
- imm.addKnowledge("heap_%08x" % self.hookaddr, called, force_add = 0x1)
- # RtlFreeHeap Hook class
- FREELABEL = "Free Hook"
- class RtlFreeHeapHook(LogBpHook):
- def __init__(self, address):
- LogBpHook.__init__(self)
- self.hookaddr = address
- def run(self,regs):
- """This will be executed when hooktype happens"""
- imm = immlib.Debugger()
- readaddr=""
- size=""
- res=imm.readMemory( regs['ESP'] + 4, 0xc)
- if len(res) != 0xc:
- imm.log("RtlFreeHeap: ESP seems to broken, unable to get args")
- return 0x0
- (heap, flags, size) = struct.unpack("LLL", res)
- called = imm.getKnowledge( "heap_%08x" % self.hookaddr )
- if not called:
- called = []
- try:
- callstack = imm.readLong( regs['EBP'] + 4)
- except Exception:
- callstack = 0x0
- called.append( (0, callstack, heap, flags, size) )
- imm.addKnowledge("heap_%08x" % self.hookaddr, called, force_add = 0x1)
- class EndHook(LogBpHook):
- def __init__( self, retaddr ):
- LogBpHook.__init__(self)
- self.retaddr = retaddr
- def run(self, regs):
- imm = immlib.Debugger()
- called = imm.getKnowledge("heap_%08x" % self.retaddr)
- (ahook, fhook) = imm.getKnowledge("end_%08x" % self.retaddr)
- ahook.UnHook()
- fhook.UnHook()
- win = imm.createTable("Function Sniffing", ["Address", "Data"] )
- memleak = {}
- freelist = {}
- win.Log("Dumping the Heap Flow")
- if called:
- for res in called:
- if res[0] == 1:
- type, callstack, heap, flag, size, ret = res
- memleak[ ret ] = (callstack, heap, flag, size, ret)
- win.Log("Alloc(0x%08x, 0x%08x, 0x%08x) -> 0x%08x" %\
- ( heap, flag, size, ret ), address = callstack )
- elif res[0] == 0:
- type, callstack, heap, flag, size = res
- if memleak.has_key( size):
- del memleak[ size ]
- else:
- freelist[ size ] = (callstack, heap, flag, size)
- win.Log("Free (0x%08x, 0x%08x, 0x%08x)" %\
- ( heap, flag, size ), address = callstack )
- win.Log("Chunk freed but not allocated on this heap flow")
- pheap = PHeap( imm )
- dt = libdatatype.DataTypes(imm)
- for a in freelist.keys():
- (callstack, heap, flag, base) = freelist[a]
- win.Log("Free (0x%08x, 0x%08x, 0x%08x)" %\
- ( heap, flag, base ), address = callstack )
- win.Log("Memleak detected")
- for a in memleak.keys():
- (callstack, heap, flag, size, ret) = memleak[a]
- win.Log("Alloc(0x%08x, 0x%08x, 0x%08x) -> 0x%08x" %\
- ( heap, flag, size, ret ), address = callstack )
- chk = pheap.getChunks( ret - 8, 1)[0]
- chk.printchunk( uselog = win.Log, dt = dt )
- imm.log("Funsniff finished, check the newly created window")
- self.UnHook()
- # Function Hook class
- class FunctionHook(LogBpHook):
- def __init__( self, allocaddr, freeaddr, continuos = False):
- LogBpHook.__init__(self)
- #self.threadid = threadid
- self.allocaddr = allocaddr
- self.freeaddr = freeaddr
- self.continuos = continuos
- def run(self, regs):
- """This will be executed when hooktype happens"""
- imm = immlib.Debugger()
- # We will probably gonna need the threadid. Gather it through getEvent()
- readaddr=""
- size=""
- retaddr = imm.readLong( regs['EBP'] + 4)
- for a in regs:
- imm.log("%s:%08x" % (a, regs[a]))
- if not retaddr:
- self.UnHook()
- imm.log("Unhooking, wrong ESP")
- return
- endhook = EndHook( retaddr )
- endhook.add("EndHook_%x" % retaddr, retaddr)
- ahook = RtlAllocateHeapHook( retaddr)
- ahook.add( "Alloc_%08x"% retaddr, self.allocaddr)
- fhook = RtlFreeHeapHook( retaddr)
- fhook.add( "Free_%08x" % retaddr, self.freeaddr)
- imm.addKnowledge("end_%08x" % retaddr, (ahook, fhook) )
- imm.log("o Sniffing the selected Function", address = regs['EIP'])
- if not self.continuos:
- self.UnHook()
- def getRet(imm, allocaddr, max_opcodes = 500):
- addr = allocaddr
- for a in range(0, max_opcodes):
- op = imm.disasmForward( addr )
- if op.isRet():
- if op.getImmConst() == 0xc:
- op = imm.disasmBackward( addr, 3)
- return op.getAddress()
- addr = op.getAddress()
- return 0x0
- def usage(imm):
- imm.log( "!funsniff -a ADDRESS (-c) Analize the heap pattern of a executed function" )
- imm.log( " -a ADDRESS Address of Function to fingerprint")
- imm.log( " -c Continuos")
- def main(args):
- imm = immlib.Debugger()
- address = 0x0
- continuos = False
- if not args:
- usage(imm)
- return "Wrong Arguments (Check usage on the Log Window)"
- try:
- opts, argo = getopt.getopt(args, "a:c")
- except getopt.GetoptError:
- return "Wrong Arguments (Check usage on the Log Window)"
- for o,a in opts:
- if o == '-a':
- try:
- address = int( a, 16 )
- except ValueError:
- usage(imm)
- return "Wrong Address (%s) % " % a
- elif o == '-c':
- continuos = True
- if not address:
- return "Wrong Arguments (Check usage on the Log Window)"
- allocaddr = imm.getAddress("ntdll.RtlAllocateHeap" )
- freeaddr = imm.getAddress("ntdll.RtlFreeHeap" )
- allocaddr = getRet(imm, allocaddr, 800)
- if not allocaddr or not freeaddr:
- imm.log("Error, couldn't find the address of allocateHeap or freeHeap")
- return "Error resolving Address"
- imm.log("Func Sniffing starting")
- imm.log("o Setting the first hook")
- hook = FunctionHook( allocaddr, freeaddr )
- hook.add( "Func_%08x" % address, address)
- return "Hook set"
- import immlib
- from libevent import ExceptionEvent
- DESC = "Get a log of current debugevent"
- NAME = "getevent"
- def usage(imm):
- imm.log("!%s" % NAME)
- imm.log("%s" % DESC)
- def main(args):
- imm=immlib.Debugger()
- evento = imm.getEvent()
- if evento:
- if isinstance(evento, ExceptionEvent):
- for a in evento.Exception:
- imm.log("Exception: %s (0x%08x)" % (a.getType(), a.ExceptionCode), focus = 1)
- imm.log("Exception address: 0x%08x" % a.ExceptionAddress)
- imm.log("Exception num param: %d" % a.NumberParameters)
- for value in a.ExceptionInformation:
- imm.log(hex(value))
- else:
- imm.log("Last event type: 0x%08x (%s) " % (evento.dwDebugEventCode, str(evento) ) )
- return "Works"
- else:
- return "Cannot handle this exception"
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- Additional feature of iterating through all DLL's added by Justin Seitz <jms@bughunter.ca>
- """
- import immlib
- import getopt
- import struct
- DESC = """Get the RPC information of a loaded dll"""
- def usage(imm):
- imm.log("!getrpc filename|all Get the RPC information of a loaded dll or for all loaded DLL's",focus=1)
- def get_rpc_info(imm,mod,module_name):
- codeaddr = mod.getBase()
- size = mod.getSize()
- mem = imm.readMemory(codeaddr, size)
- ndx = 0
- offset = ndx
- Found = 0
- while 1:
- offset = mem[ndx:].find("\x04\x5d\x88\x8a")
- if offset == -1:
- break
- offset -= 0x18
- try:
- length = struct.unpack("L", mem[ndx+offset : ndx+offset+4])[0]
- if length == 0x44:
- Found += 1
- addr = codeaddr + ndx + offset
- imm.log("RPC SERVER INTERFACE found at: 0x%08x" % addr, address = addr)
- hu= struct.unpack("LHH", mem[ndx+offset+4 : ndx+offset+0xc])
- hu2 = struct.unpack("!HLH", mem[ndx+offset+0xc : ndx+offset+0x14])
- uuid = "%08x-%04x-%04x-%04x-%08x%04x" % (hu[0], hu[1], hu[2], hu2[0], hu2[1], hu2[2])
- major,minor = struct.unpack("HH", mem[ndx+offset+0x14 : ndx+offset+0x18])
- imm.log("RPC UUID: %s (v%d.%d)" % (uuid, major, minor))
- imm.gotodisasmWindow(addr)
- imm.setComment(offset + codeaddr, "Length")
- imm.setComment(offset + codeaddr+4, "Interface UUID: %s (v%d.%d)" % (uuid, major, minor))
- imm.setComment(offset + codeaddr+0x18, "Transfer syntax")
- imm.setComment(offset + codeaddr+0x2c, "Dispatch Table")
- imm.setComment(offset + codeaddr+0x30, "RpcProtseqEndpointCount")
- imm.setComment(offset + codeaddr+0x34, "RpcProtseqEndpoint")
- imm.setComment(offset + codeaddr+0x38, "Default Manager")
- imm.setComment(offset + codeaddr+0x3c, "Interpreter Info")
- imm.setComment(offset + codeaddr+0x40, "Flags")
- interpreter_info = struct.unpack("L", mem[ndx+offset+0x3c : ndx+offset+0x3c+4] )[0]
- function_list_addr = imm.readLong( interpreter_info + 4)
- dispatch_table = struct.unpack("L", mem[ndx+offset+0x2c : ndx+offset+0x2c+4] )[0]
- number = imm.readLong( dispatch_table )
- function_ptr = imm.readLong( dispatch_table + 4 )
- for a in range(0, number):
- func = imm.readLong(function_list_addr+a*4)
- imm.log("Function[%d]: 0x%08x" % (a , func), address = func, focus=1)
- for a in range(0, number):
- func = imm.readLong(function_ptr+a*4)
- imm.log("Function pointer [%d]: 0x%08x" % (a , func), address = function_ptr+a*4)
- except Exception, msg:
- pass
- ndx += offset+0x20
- del mem
- if Found:
- imm.log("Module: %s END ===============================================================================" % module_name)
- return "Found %d interfaces on %s" % (Found, module_name)
- else:
- return "No interface found on %s" % module_name
- def main(args):
- imm = immlib.Debugger()
- module_exists = False
- if not args:
- usage(imm)
- return "Incorrect number of arguments (No args)"
- if len(args) != 1:
- usage(imm)
- return "Incorrect number of arguments"
- if args[0].lower() == "all":
- mod_list = imm.getAllModules()
- for mod in mod_list.iteritems():
- module = imm.getModule(mod[0])
- sys_dll = module.getIssystemdll()
- if sys_dll == 0:
- imm.setStatusBar("Fetching RPC information for: %s" % mod[0])
- get_rpc_info(imm,module,mod[0])
- module_exists = True
- else:
- mod = imm.getModule(args[0])
- if mod:
- module_exists = True
- imm.setStatusBar("Fetching RPC information for: %s" % args[0])
- get_rpc_info(imm,mod,args[0])
- if module_exists == False:
- return "Module not found"
- else:
- return "Module information outputted, check the Log."
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- DESC="""gflags"""
- import getopt
- import immlib
- import libregistry
- def usage(imm):
- imm.log("!gflags -[a|d|c] -m module Enable and Disable Global Flags", focus=1)
- imm.log("-m module Module to set the global flags")
- imm.log("-a tag Set a Flag")
- imm.log("-d tag Unset a Flag")
- imm.log("-c Clear Flags")
- imm.log("tags: ")
- for tag in libregistry.GFlagsTags:
- r = libregistry.GFlagsRef[tag]
- imm.log( " %s - %s" % ( tag, r[0] ) )
- def main(args):
- imm = immlib.Debugger()
- try:
- opts, argo = getopt.getopt(args, "m:a:d:c", ["module=", "add=", "delete=", "clear"])
- except getopt.GetoptError:
- usage(imm)
- return "Wrong Argument (Check Log Window)"
- add_f = []
- delete_f = []
- clear_f = False
- module = ""
- for o,a in opts:
- if o in ('-a', "--add"):
- add_f.append( a )
- elif o in ('-d', "--delete"):
- delete_f.append( a )
- elif o in ('-c', "--clear"):
- clear_f = True
- elif o in ('-m', "--module"):
- module = a
- gf = libregistry.GFlags( module)
- if not clear_f:
- if add_f:
- curr = 0
- for tag in add_f:
- try:
- r = gf.GetReferencebyName( tag )
- except Exception, msg:
- usage(imm)
- return "Error: %s" % str(msg)
- curr = curr | r[1]
- gf.Set( curr )
- imm.log("Global Flags added")
- if delete_f:
- curr = 0
- for tag in delete_f:
- try:
- r = gf.GetReferencebyName( tag )
- except Exception, msg:
- usage(imm)
- return "Error: %s" % str(msg)
- curr = curr | r[1]
- gf.UnSet( curr )
- imm.log("Global Flags Deleted")
- else:
- gf.Clear()
- return "Global Flag cleared"
- if not clear_f:
- try:
- ret = gf.Print()
- except Exception:
- return "GlobalFlag not found"
- if module:
- txt = "Current Flags for module %s" % module
- else:
- txt = "Current Global Flags:"
- imm.log(txt)
- for (tag, r) in ret:
- imm.log(" %s: %s" % (tag, r[0]))
- return "Done"
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- import immlib
- import getopt
- from libheap import *
- import libdatatype
- DESC= "Immunity Heap Dump"
- def usage(imm):
- imm.log("!heap Heap dump of currents heaps")
- imm.log("!heap [-h HEAP_ADDR] [-s] [-r] [-f] [-c]")
- imm.log(" -h HEAPADDR Set the heap address to inspect")
- imm.log(" -a CHUNKADDR Set the begging of a chunk to partially inspect")
- imm.log(" -s Save heap's state")
- imm.log(" -r Dump heap using restored value (in case of a broken chunk)")
- imm.log(" -f Inspect the FreeList only")
- imm.log(" -c Inspect the chunks only")
- imm.log(" -k Shows the first 16 bytes of a chunk")
- imm.log(" -d Inspect data on Chunks")
- imm.log(" -q Dont show FreeList information")
- imm.log(" -l Inspect all the Low Fragmentation Information")
- imm.log(" -t PACK_SIZE Filter by Packed Size ( Real Size / 8 )")
- imm.log(" -u Inspect LFH UserBlocks")
- imm.log(" -z Inspect LFH Chunks", focus = 1 )
- def main(args):
- imm = immlib.Debugger()
- window = None
- if not args:
- imm.log("### Immunity's Heapdump ###")
- for hndx in imm.getHeapsAddress():
- imm.log("Heap: 0x%08x" % hndx, address = hndx, focus = 1)
- return "Heap command successful"
- # options:
- # -h HEAP
- # -s (save heap's state)
- # -r (restore in case of broken heap)
- # -f dump just the freelist
- # -c dump just chunks
- # -d discover
- try:
- opts, argo = getopt.getopt(args, "h:lsurfcqknzda:t:")
- except getopt.GetoptError:
- #imm.setStatusBar("Bad heap argument %s" % args[0])
- usage(imm)
- return "Bad heap argument %s" % args[0]
- heap = 0x0
- save = False
- restore = False
- freelist = False
- chunksflags = False
- chunkdisplay = 0
- opennewwindow = False
- discover = None
- chunkaddress = None
- LFH = False
- userblock = False
- lfhchunk = False
- showf = True
- fsize = -1
- for o,a in opts:
- if o == "-h":
- try:
- heap = int(a, 16)
- except ValueError, msg:
- return "Invalid heap address: %s" % a
- if o == "-a":
- try:
- chunkaddress = int(a, 16)
- except ValueError, msg:
- return "Invalid chunk address: %s" % a
- if o == "-t":
- try:
- fsize = int(a, 16)
- except ValueError, msg:
- return "Incorrect filter size : %s" % a
- elif o == "-s":
- save = True
- elif o == "-r":
- restore = True
- elif o == "-f":
- freelist = True
- elif o == "-c":
- chunksflags = True
- elif o == "-k":
- chunkdisplay = SHOWCHUNK_FULL
- elif o == "-n":
- opennewwindow = True
- elif o == "-d":
- discover = libdatatype.DataTypes(imm)
- elif o == '-l':
- LFH = True
- elif o == '-u':
- userblock = True
- elif o == '-z':
- lfhchunk = True
- elif o == '-q':
- showf = False
- if heap and ( heap in imm.getHeapsAddress() ):
- tag = "heap_%08x" % heap
- if not opennewwindow:
- window = imm.getKnowledge(tag)
- if window and not window.isValidHandle():
- imm.forgetKnowledge(tag)
- del window
- window = None
- if not window:
- imm.log( "%s %s " % (str(type(tag)), str(type(heap))) )
- window = imm.createTable("Heap dump 0x%08x" % heap, ["Address", "Chunks"] )
- imm.addKnowledge(tag, window, force_add = 1)
- # in case none of them are select, dump *
- if showf and (not chunksflags and not freelist):
- chunksflags = True
- freelist = True
- pheap = imm.getHeap( heap, restore )
- if save:
- imm.addKnowledge("saved_heap_%08x" % pheap.address , pheap, force_add = 1)
- window.Log("### Immunity's Heapdump ###")
- window.Log("Dumping heap: 0x%08x" % heap, address = heap, focus = 1 )
- window.Log("Flags: 0x%08x Forceflags: 0x%08x" % (pheap.Flags, pheap.ForceFlags), address = heap)
- window.Log("Total Free Size: 0x%08x VirtualMemoryThreshold: 0x%08x" % (pheap.TotalFreeSize, pheap.VirtualMemoryThreshold), address = heap)
- if showf:
- for a in range(0, len(pheap.Segments)):
- if not pheap.Segments[a]:
- break
- window.Log("Segment[%d]: 0x%08x" % (a, pheap.Segments[a].BaseAddress) )
- if freelist:
- if pheap.HeapCache:
- pheap.printHeapCache(uselog = window.Log)
- if hasattr(pheap, 'FreeListInUseLong'):
- pheap.printFreeListInUse(uselog = window.Log )
- pheap.printFreeList( uselog = window.Log)
- if hasattr(pheap, "Lookaside"):
- if pheap.Lookaside:
- pheap.printLookaside( uselog = window.Log )
- if chunksflags:
- for chunk in pheap.chunks:
- chunk.printchunk(uselog = window.Log, option = chunkdisplay, dt = discover)
- if userblock or lfhchunk:
- LFH = True
- if LFH and pheap.LFH:
- if not userblock and not lfhchunk:
- userblock = True
- lfhchunk = True
- window.Log("~" * 0x47)
- if pheap.LFH.LocalData:
- for seginfo in pheap.LFH.LocalData.SegmentInfo:
- subseg_list = seginfo.SubSegment
- for subseg in subseg_list:
- if fsize == -1 or subseg.BlockSize == fsize:
- if userblock:
- window.Log("UserBlock size: 0x%04x %-8s: 0x%08x offset: %08x Depth: %x (0x%08x)" % (subseg.BlockSize, subseg.type, subseg.UserBlocks, subseg.Offset, subseg.Depth, subseg.Next), address = subseg.UserBlocks)
- if lfhchunk:
- for chk in subseg.chunks:
- chk.printchunk(uselog = window.Log, option = chunkdisplay, dt = discover)
- window.Log("=-" * 0x23 + "=")
- return "Heap 0x%x dumped" % heap
- elif chunkaddress:
- tag = "chunks_%08x" % chunkaddress
- if not opennewwindow:
- window = imm.getKnowledge(tag)
- if not window:
- window = imm.createTable("Heap dump 0x%08x" % chunkaddress, ["Address", "Chunks"] )
- imm.addKnowledge(tag, window, force_add = 1)
- pheap = PHeap( imm )
- window.Log("### Immunity's Heapdump ###")
- window.Log("Dumping Chunks from address: 0x%08x" % chunkaddress, address = chunkaddress, focus = 1 )
- for chunk in pheap.getChunks( chunkaddress ):
- chunk.printchunk(uselog = window.Log, option = chunkdisplay, dt = discover)
- window.Log("=-" * 0x23 + "=")
- return "Heap 0x%x dumped" % heap
- else:
- imm.log("Error: A proper heap needs to be defined")
- return "Error: A proper heap needs to be defined"
- #!/usr/bin/env python
- #-------------------------------------------------------------------------------
- #
- # By BoB -> Team PEiD
- # http://www.PEiD.info/BobSoft/
- # BobSoft@GMail.Com
- #
- #-------------------------------------------------------------------------------
- import immlib
- import getopt
- import random
- import ctypes
- #-------------------------------------------------------------------------------
- __VERSION__ = '1.00'
- ProgName = 'HideDebug'
- ProgVers = __VERSION__
- DESC = "Patches lots of anti-debug protection .. (try \"!usage %s\" for details)" % ProgName.lower()
- #-------------------------------------------------------------------------------
- Docs = """
- Loosely based on patch.py (c) Immunity inc .. :)
- Patches:
- o IsDebuggerPresent (With Poly-patch code, as too easy to detect Xor EAX, EAX)
- o ZwQueryInformationProcess
- o CheckRemoteDebuggerPresent
- o PEB.IsDebugged
- o PEB.ProcessHeap.Flag
- o PEB.NtGlobalFlag
- o PEB.Ldr 0xFEEEFEEE filling
- o GetTickCount (With poly-patch code, as too easy to detect Mov EAX, xxxxxxxx)
- o ZwQuerySystemInformation (Used by CreateToolHelp32Snapshot / Process32First / Process32Next and others)
- o FindWindowA
- o FindWindowW
- o FindWindowExA
- o FindWindowExW
- o EnumWindows
- Types:
- o Anti-Debug Types:
- IsDebuggerPresent
- ZwQueryInformationProcess
- CheckRemoteDebuggerPresent
- PEB (All PEB patches are done)
- GetTickCount
- All_Debug - Applies ALL Debug detect patches ..
- o Anti-Process-finding Types:
- ZwQuerySystemInformation (All other process apis use this)
- All_Process - Applies the debugger-process finding Api patch ..
- o Anti-Window-finding Types:
- FindWindowA
- FindWindowW
- FindWindowExA
- FindWindowExW
- EnumWindows
- All_Window - Applies ALL debugger-window finding Api patches ..
- <dodgy excuse>
- Sorry for any weird code, I've only been using Python for 2 weeks .. :)
- </dodgy excuse>
- Description:
- Most of the functions are patched to return Debugger Found = False ..
- The PEB patches are to the various flags in PEB used by anti-debug ..
- Patch for ZwQueryInformationProcess is if DebugPort is checked, returns not debugged ..
- Patch for GetTickCount is to return same number everytime ..
- Patch for ZwQuerySystemInformation is to replace all ImmunityDebugger.exe with SVCHost.EXE ..
- Patch for Window finding apis call Api and if "ID" is classname then return not found ..
- Maybe ToDo:
- o Patch CreateThread ?
- """
- #-------------------------------------------------------------------------------
- # Show usage ..
- def usage(imm):
- imm.log(" ")
- imm.log("%s v%s By BoB -> Team PEiD" % (ProgName, ProgVers),focus=1, highlight=1)
- imm.log("Description:")
- imm.log(" Patches many different flags and apis used to detect debuggers ..")
- imm.log(" Different combinations of patches will defeat most protections, ")
- imm.log(" and some common anti-debug apis are patched with poly code ")
- imm.log(" to avoid detection by packers like RL!Pack .. ")
- imm.log(" All apis return usual valid data, the patches do not affect normal use .. ")
- imm.log(" EG: FindWindowA('NotePad.EXE', Null) will work same if patched or not..")
- imm.log(" ")
- imm.log("Usage:")
- imm.log(" !%s <Type>" % ProgName.lower())
- imm.log(" ")
- imm.log("Type can be ..")
- imm.log(" Debugger-Detect Types:")
- imm.log(" . IsDebuggerPresent - Patches the Kernel32 Api to return false ..")
- imm.log(" . CheckRemoteDebuggerPresent - Patches the Kernel32 Api ..")
- imm.log(" . ZwQueryInformationProcess - Patches the NtDll Api only for getting DebugPort ..")
- imm.log(" . GetTickCount - Patches the Kernel32 Api to always return same value ..")
- imm.log(" . Peb - Patches PEB.IsDebugged, PEB.ProcessHeap.Flag, PEB.NtGlobalFlag and fill bytes ..")
- imm.log(" . All_Debug - Applies patches for all of the above .. ")
- imm.log(" ")
- imm.log(" Debugger-Detect by Process Types: ")
- imm.log(" . ZwQuerySystemInformation - Patches the NtDll Api to remove ImmDbg from list ..")
- imm.log(" . All_Process - Applies all process patches above .. ")
- imm.log(" ")
- imm.log(" Debugger-Detect by Window Types: (User32.DLL must be loaded)")
- imm.log(" . FindWindowA - Reports false if process looks for ImmDbg win classname ..")
- imm.log(" . FindWindowW - Reports false if process looks for ImmDbg win classname ..")
- imm.log(" . FindWindowExA - Reports false if process looks for ImmDbg win classname ..")
- imm.log(" . FindWindowExW - Reports false if process looks for ImmDbg win classname ..")
- imm.log(" . EnumWindows - Own callback function calls user callback if not ImmDbg HWnd ..")
- imm.log(" . All_Window - Applies all window patches above .. ")
- imm.log(" ")
- return "See log window (Alt-L) for usage .. "
- #-------------------------------------------------------------------------------
- # Misc functions ..
- #-------------------------------------------------------------------------------
- #-------------------------------------------------------------------------------
- # Write Poly instructions to patch an EAX = Dword-Value instruction onto an Api ..
- def Poly_ReturnDW(imm, Value):
- I = random.randint(1, 3)
- if I == 1:
- if random.randint(1, 2) == 1:
- # 7 bytes ..
- return imm.assemble( "Sub EAX, EAX\n Add EAX, 0x%08x" % Value )
- else:
- # 7 bytes ..
- return imm.assemble( "Sub EAX, EAX\n Sub EAX, -0x%08x" % Value )
- if I == 2:
- # 6 bytes
- return imm.assemble( "Push 0x%08x\n Pop EAX\n" % Value )
- if I == 3:
- if random.randint(1, 2) == 1:
- # 7 bytes with optimized instruction ..
- return imm.assemble( "XChg EAX, EDI\n DB 0xBF\n DD 0x%08x\n XChg EAX, EDI" % Value )
- else:
- # 8 bytes cos not optimized ..
- return imm.assemble( "XChg EAX, EDI\n Mov EDI, 0x%08x\n XChg EAX, EDI" % Value )
- #-------------------------------------------------------------------------------
- # Write Poly instructions to patch a simple EAX = 0 onto an Api ..
- def Poly_Return0(imm):
- I = random.randint(1, 4)
- if I == 1:
- # 2 bytes
- return imm.assemble( "Sub EAX, EAX" )
- if I == 2:
- if random.randint(1, 2) == 1:
- # 6 bytes
- return imm.assemble( "Push 0\n Pop EAX" )
- else:
- # 3 bytes
- return imm.assemble( "DB 0x6A, 0x00\n Pop EAX" )
- if I == 3:
- # 4 bytes
- return imm.assemble( "XChg EAX, EDI\n Sub EDI, EDI\n XChg EAX, EDI" )
- if I == 4:
- return Poly_ReturnDW(imm, 0)
- #-------------------------------------------------------------------------------
- # Debug Detection Patches ..
- #-------------------------------------------------------------------------------
- #-------------------------------------------------------------------------------
- # Clear various debug flags in PEB ..
- def Patch_PEB(imm):
- PEB = imm.getPEBAddress()
- # Just incase .. ;)
- if PEB == 0:
- imm.log( "No PEB to patch .. !?" )
- return
- imm.log( "Patching PEB.IsDebugged ..", address = PEB + 0x02 )
- imm.writeMemory(PEB + 0x02, imm.assemble( "db 0" ) )
- a = imm.readLong(PEB + 0x18)
- a += 0x10
- imm.log( "Patching PEB.ProcessHeap.Flag ..", address = a )
- imm.writeLong( a, 0 )
- imm.log( "Patching PEB.NtGlobalFlag ..", address = PEB + 0x68 )
- imm.writeLong(PEB + 0x68, 0)
- # Patch PEB_LDR_DATA 0xFEEEFEEE fill bytes .. (about 3000 of them ..)
- a = imm.readLong(PEB + 0x0C)
- imm.log("Patching PEB.LDR_DATA filling ..", address = a)
- while a != 0:
- a += 1
- try:
- b = imm.readLong(a)
- c = imm.readLong(a + 4)
- # Only patch the filling runs ..
- if (b == 0xFEEEFEEE) and (c == 0xFEEEFEEE):
- imm.writeLong(a, 0)
- imm.writeLong(a + 4, 0)
- a += 7
- except:
- break
- #-------------------------------------------------------------------------------
- # IsDebuggerPresent ..
- # Note: This Api checks a value in PEB, so if patching PEB then no need to patch Api ..
- def Patch_IsDebuggerPresent(imm):
- ispresent = imm.getAddress( "kernel32.IsDebuggerPresent" )
- # Just incase .. ;)
- if (ispresent <= 0):
- imm.log( "No IsDebuggerPresent to patch .." )
- return
- imm.log( "Patching IsDebuggerPresent...", address = ispresent )
- Code = imm.assemble("DB 0x64\n Mov EAX, DWORD PTR DS:[18]") + Poly_Return0(imm) + imm.assemble( "ret" )
- # Careful for Win2k ..
- while len(Code) > 0x0E:
- Code = imm.assemble("DB 0x64\n Mov EAX, DWORD PTR DS:[18]") + Poly_Return0(imm) + imm.assemble( "ret" )
- imm.writeMemory( ispresent, Code )
- #-------------------------------------------------------------------------------
- # CheckRemoteDebuggerPresent ..
- # Note: This Api calls ZwQueryInformationProcess Api, so usually no need to patch both ..
- def Patch_CheckRemoteDebuggerPresent(imm):
- deb = imm.getAddress( "kernel32.CheckRemoteDebuggerPresent" )
- # Just incase on Win2k .. ;)
- if (deb <= 0):
- imm.log( "No CheckRemoteDebuggerPresent to patch .." )
- return
- imm.log( "Patching CheckRemoteDebuggerPresent ..", address = deb )
- imm.writeMemory( deb, imm.assemble( " \
- Mov EDI, EDI \n \
- Push EBP \n \
- Mov EBP, ESP \n \
- Mov EAX, [EBP + C] \n \
- Push 0 \n \
- Pop [EAX] \n \
- Xor EAX, EAX \n \
- Pop EBP \n \
- Ret 8 \
- " ) )
- #-------------------------------------------------------------------------------
- # ZwQueryInformationProcess ..
- def Patch_ZwQueryInformationProcess(imm):
- qip = imm.getAddress( "ntdll.ZwQueryInformationProcess" )
- # Just incase .. ;)
- if (qip <= 0):
- imm.log( "No ZwQueryInformationProcess to patch .." )
- return
- imm.log( "Patching ZwQueryInformationProcess ..", address = qip )
- IsPatched = False
- a = 0
- s = 0
- # Scan Api and get size of first 2 instructions ..
- # On Win2k SysCall starts with Mov EAX, xxxxxxxx\n Lea EDX, [ESP + 4] ..
- # On WinXP, Win2k3 + Vista, SysCall always starts with Mov EAX, xxxxxxxx\n MOV EDX, 0x7FFE0300 ..
- while a < 2:
- a += 1
- s += imm.disasmSizeOnly(qip + s).opsize
- # Check if already patched ..
- FakeCode = imm.readMemory(qip, 1) + imm.assemble("DD 0x12345678") + imm.readMemory(qip + 5, 1)
- if FakeCode == imm.assemble( "Push 0x12345678\n Ret"):
- # Definately found a push jump ..
- IsPatched = True
- # Get address of where it points to ..
- a = imm.readLong(qip + 1)
- # Get length of the 2 instructions before patch code ..
- i = 0
- s = 0
- while i < 2:
- i += 1
- s += imm.disasmSizeOnly(a + s).opsize
- # If not patched already, allocate some memory for patch code ..
- if IsPatched == False:
- # Allocate memory for hook code ..
- a = imm.remoteVirtualAlloc(size=0x1000)
- # Write 2 instructions from api to allocated mem ..
- imm.writeMemory( a, imm.readMemory(qip, s) )
- # If ProcessInformationClass = ProcessDebugPort then return 0 in
- # ProcessInformation; else call ZwQueryInformationProcess as normal ..
- PatchCode = " \
- Cmp DWord [ESP + 8], 7 \n \
- DB 0x74, 0x06 \n \
- \n \
- Push 0x%08X \n \
- Ret \n \
- \n \
- Mov EAX, DWord [ESP + 0x0C] \n \
- Push 0 \n \
- Pop [EAX] \n \
- Xor EAX, EAX \n \
- Ret 14 \n \
- " % (qip + s)
- # Write patch code in allocated memory after the original first 2 instructions ..
- imm.writeMemory( a + s, imm.assemble( PatchCode ) )
- # If not patched, write Push Jmp to redirect Api to my code ..
- if IsPatched == False:
- imm.writeMemory( qip, imm.assemble( "Push 0x%08X\n Ret" % a) )
- #-------------------------------------------------------------------------------
- # GetTickCount ..
- # Poly return cos it's an obvious one for a packer to check for Mov EAX, xxxxxxxx or Xor EAX, EAX ..
- def Patch_GetTickCount(imm):
- a = imm.getAddress("kernel32.GetTickCount")
- # Just incase .. ;)
- if (a <= 0):
- imm.log( "No GetTickCount to patch .." )
- return
- imm.log("Patching GetTickCount ..", address = a)
- # Keep first instruction to avoid checks ..
- Code = imm.assemble("Mov EDX, 0x7FFE0000") + Poly_ReturnDW(imm, 0xB0B1560D) + imm.assemble("Ret")
- # Careful of Win2k's lack of alignment ..
- while len(Code) > 0x0F:
- Code = imm.assemble("Mov EDX, 0x7FFE0000") + Poly_ReturnDW(imm, 0xB0B1560D) + imm.assemble("Ret")
- imm.writeMemory( a, Code )
- #-------------------------------------------------------------------------------
- # ImmunityDbg.Exe Process detection Patches ..
- #-------------------------------------------------------------------------------
- #-------------------------------------------------------------------------------
- # ZwQuerySystemInformation ..
- # If called with size < needed size then just returns size ..
- # If called with size >= needed size then fills buffer with list of all processes and lots of info about them ..
- def Patch_ZwQuerySystemInformation(imm):
- qsi = imm.getAddress( "ntdll.ZwQuerySystemInformation" )
- # Just incase .. ;)
- if (qsi <= 0):
- imm.log( "No ZwQuerySystemInformation to patch .." )
- return
- imm.log("Patching ZwQuerySystemInformation ..", address = qsi)
- IsPatched = False
- a = 0
- s = 0
- # Scan Api and get size of first 3 instructions ..
- # On Win2k thats: Mov EAX, xxxxxxxx\n Lea EDX, [ESP + 4]\n Int 0x2E ..
- # On WinXP, Win2k3 + Vista thats: Mov EAX, xxxxxxxx\n MOV EDX, 0x7FFE0300\n Call [EDX] ..
- # So patch code will call SysCall before doing anything else ..
- while a < 3:
- a += 1
- s += imm.disasmSizeOnly(qsi + s).opsize
- # Check if already patched ..
- FakeCode = imm.readMemory(qsi, 1) + imm.assemble("DD 0x12345678") + imm.readMemory(qsi + 5, 1)
- if FakeCode == imm.assemble( "Push 0x12345678\n Ret"):
- # Definately found a push jump ..
- IsPatched = True
- # Get address of where it points to ..
- a = imm.readLong(qsi + 1)
- # Get length of the 3 instructions before patch code ..
- i = 0
- s = 0
- while i < 3:
- i += 1
- s += imm.disasmSizeOnly(a + s).opsize
- # If not patched already, allocate some memory for patch code ..
- if IsPatched == False:
- # Allocate memory for hook code ..
- a = imm.remoteVirtualAlloc(size=0x1000)
- # Write 3 instructions from api to allocated mem ..
- imm.writeMemory( a, imm.readMemory(qsi, s) )
- # If SystemInformationClass == SystemProcessesAndThreadsInformation then
- # replace ImmunityDebugger.Exe with SVCHOST.EXE in returned process list .. :)
- # There are no labels, so all jmps, calls etc are written as bytes ..
- # Also, due to some weird bug LodsW assembles as LodsD so I put
- # "DB 0x66\n LodsD" to force LodsW, and same for MovsW .. (should work after bug fix)
- PatchCode = " \
- \n\
- Cmp EAX, 0 \n\
- DB 0x74, 0x03 \n\
- Ret 0x10 \n\
- \n\
- PushAD \n\
- Mov EAX, [ESP + 0x24] \n\
- Lea EBX, [ESP + 0x28] \n\
- Mov ECX, [ESP + 0x2C] \n\
- \n\
- DB 0xE8 \n\
- DD 0x2C \n\
- DW 'I', 'M', 'M', 'U' \n\
- DW 'N', 'I', 'T', 'Y' \n\
- DW 'D', 'E', 'B', 'U' \n\
- DW 'G', 'G', 'E', 'R' \n\
- DW '.', 'E', 'X', 'E' \n\
- DW 0x00,0x00 \n\
- \n\
- Pop EDI \n\
- Cmp EAX, 5 \n\
- DB 0x74, 0x04 \n\
- PopAD \n\
- Ret 0x10 \n\
- \n\
- Cmp ECX, 0 \n\
- DB 0x74, 0xF4 \n\
- Cmp EBX, 0 \n\
- DB 0x74, 0xEC \n\
- \n\
- Mov EBX, [EBX] \n\
- PushAD \n\
- Xor EAX, EAX \n\
- Mov ESI, [EBX + 0x3C] \n\
- Cmp ESI, 0 \n\
- DB 0x74, 0x0A \n\
- DB 0x66 \n\
- LodsD \n\
- Cmp EAX, 0 \n\
- DB 0x75, 0x0C \n\
- \n\
- Pop EDI \n\
- Push EDI \n\
- DB 0x8B, 0x03 \n\
- Or EAX, EAX \n\
- DB 0x74, 0x6F \n\
- Add EBX, EAX \n\
- DB 0xEB, 0xDA \n\
- \n\
- Cmp AL, 0x61 \n\
- DB 0x7C, 0x03 \n\
- Sub AL, 0x20 \n\
- Cmp [EDI], AL \n\
- DB 0x75, 0xE8 \n\
- Inc EDI \n\
- Inc EDI \n\
- Cmp DWORD [EDI], 0 \n\
- DB 0x75, 0xD4 \n\
- \n\
- Sub ESI, 0x28 \n\
- \n\
- DB 0xE8 \n\
- DD 0x28 \n\
- DW 'S', 'V', 'C', 'H' \n\
- DW 'O', 'S', 'T', '.' \n\
- DW 'E', 'X', 'E', 0x00 \n\
- DD 0x00,0x00,0x00,0x00 \n\
- \n\
- XChg ESI, EDI \n\
- Pop ESI \n\
- Mov ECX, 0x14 \n\
- DB 0x66 \n\
- Rep MovsD \n\
- \n\
- Mov DWord [EBX + 0x40], 2 \n\
- Mov DWord [EBX + 0x44], 0 \n\
- DB 0xEB, 0x89 \n\
- \n\
- PopAD \n\
- PopAD \n\
- Ret 0x10 \n\
- \
- "
- # Write patch code in allocated memory after the original first 3 instructions ..
- imm.writeMemory( a + s, imm.assemble( PatchCode ) )
- # If not patched, write Push Jmp to redirect Api to my code ..
- if IsPatched == False:
- imm.writeMemory( qsi, imm.assemble( "Push 0x%08X\n Ret" % a) )
- #-------------------------------------------------------------------------------
- # Window Detection Patches ..
- #-------------------------------------------------------------------------------
- #-------------------------------------------------------------------------------
- # Patch for FindWindowA, FindWindowW, FindWindowExA, FindWindowExW ..
- def Patch_FindWindow(imm, ex = False, suffix = "A"):
- suffix = suffix.upper()
- RetVal = 0x08
- if ex:
- suffix = "Ex" + suffix
- RetVal = 0x10
- FW = imm.getAddress("user32.FindWindow%s" % suffix)
- # Just incase .. ;)
- if (FW <= 0):
- imm.log("No FindWindow%s to patch .. (Is User32 Loaded?)" % suffix)
- return False
- # Find place for jmp in Api ..
- p = 0
- d = imm.disasm(FW)
- l = d
- dis = ""
- FoundCall = False
- while p < 100:
- if d.getDisasm() == "POP EBP":
- dis = l.getDisasm()
- p -= l.getSize()
- if l.isCall():
- FoundCall = True
- break
- # Try to continue without expected call instrucion ..
- dis = l.getDisasm()
- break
- # Did we already patch this api ?
- if d.getDisasm() == "RETN":
- if l.isPush():
- imm.log("FindWindow%s already patched .." % suffix, address = FW)
- return False
- p += d.getSize()
- l = d
- d = imm.disasm(FW + p)
- imm.log("Patching FindWindow%s .." % suffix, address = FW)
- HookMem = imm.remoteVirtualAlloc(size=0x1000)
- HookCode = imm.assemble("Push 0x%08X\n Ret" % HookMem)
- if FoundCall == True:
- # Get address pointed to by call instruction ..
- a = l.getJmpAddr()
- # Fix Call instruction in patch function to point to original call address ..
- a = ((a - HookMem) - 5)
- dis = "DB 0xE8\n DD 0x%08X" % a
- # Get HWnd of ImmDbg .. If this is exposed by ImmLib, I didn't find it.. :)
- ImmHWnd = ctypes.windll.LoadLibrary("User32.DLL").FindWindowA("ID", 0)
- # Code calls Api, if HWnd matches ImmDbg return 0 ..
- # Else all works as before ..
- # Again, all jumps are as bytes cos no labels ..
- PatchCode = " \
- %s \n\
- Cmp EAX, 0x%08X \n\
- DB 0x74, 0x02 \n\
- DB 0xEB, 0x02 \n\
- Xor EAX, EAX \n\
- Pop EBP \n\
- Ret 0x%02X \n\
- " % (dis, ImmHWnd, RetVal)
- imm.writeMemory(HookMem, imm.assemble(PatchCode))
- imm.writeMemory(FW + p, HookCode)
- return True
- #-------------------------------------------------------------------------------
- def Patch_EnumWindows(imm):
- EW = imm.getAddress("user32.EnumWindows")
- # Just incase .. ;)
- if (EW <= 0):
- imm.log("No EnumWindows to patch .. (Is User32 Loaded?)")
- return False
- # Find place for jmp in Api ..
- p = 0
- d = imm.disasm(EW)
- l = d
- dis = ""
- FoundCall = False
- while p < 100:
- if d.getDisasm() == "POP EBP":
- dis = l.getDisasm()
- p -= l.getSize()
- if l.isCall():
- FoundCall = True
- break
- # Try to continue without expected call instrucion ..
- dis = l.getDisasm()
- break
- # Did we already patch this api ?
- if d.getDisasm() == "RETN":
- if l.isPush():
- imm.log("EnumWindows already patched ..", address = EW)
- return False
- p += d.getSize()
- l = d
- d = imm.disasm(EW + p)
- imm.log("Patching EnumWindows ..", address = EW)
- HookMem = imm.remoteVirtualAlloc(size=0x1000)
- HookCode = imm.assemble("Push 0x%08X\n Ret" % HookMem)
- if FoundCall == True:
- # Get address pointed to by call instruction ..
- a = l.getJmpAddr()
- # Fix Call instruction in patch function to point to original call address ..
- a = ((a - (HookMem + 0x5B)) - 5) # 0x5B = offset of call instruction in patch code ..
- dis = "DB 0xE8\n DD 0x%08X" % a
- # Get HWnd of ImmDbg ..
- ImmHWnd = ctypes.windll.LoadLibrary("User32.DLL").FindWindowA("ID", 0)
- # Code calls Api, using own callback function ..
- # My callback calls user's callback function (if hwnd not ImmDbg) ..
- # Else all works as before ..
- PatchCode = " \
- DB 0xEB,0x31 \n\
- \n\
- Sub EAX, EAX \n\
- Inc EAX \n\
- PushAD \n\
- DB 0x81,0x7C,0x24,0x24 \n\
- DD 0x%08X \n\
- DB 0x74,0x1B \n\
- Push [ESP + 0x28] \n\
- Push [ESP + 0x28] \n\
- Call [0x0000002F] \n\
- Mov [ESP + 0x1C], EAX \n\
- PopAD \n\
- Ret 8 \n\
- \n\
- DD 0xB0b1560d \n\
- \n\
- DB 0xE8 \n\
- DD 0x00000000 \n\
- Pop EAX \n\
- Sub EAX, 0x38 \n\
- Add [EAX + 0x20], EAX \n\
- Push [EBP + 0x08] \n\
- Pop [EAX + 0x2F] \n\
- \n\
- Inc EAX \n\
- Inc EAX \n\
- Push EAX \n\
- Pop [ESP + 0x08] \n\
- %s \n\
- Pop EBP \n\
- Ret 8 \n\
- " % (ImmHWnd, dis)
- imm.writeMemory(HookMem, imm.assemble(PatchCode))
- imm.writeMemory(EW + p, HookCode)
- return True
- #-------------------------------------------------------------------------------
- # Main Function ..
- def main(args):
- ptypes={
- # Debug types
- 'isdebuggerpresent':0, 'peb':1, 'checkremotedebuggerpresent':2,
- 'zwqueryinformationprocess':3, 'gettickcount':4, 'all_debug':10,
- # Process Types
- 'zwquerysysteminformation':20, 'all_process':21,
- # Window Types
- 'findwindowa':30, 'findwindoww':31, 'findwindowexa':32, 'findwindowexw':33,
- 'enumwindows':34, 'all_window':35,
- # Packers (some example ones - of course many more are supported, add them as you find them)
- 'upx-lock':100, 'nspack':101, 'exestealth':102, 'escargot':103, 'rlpack':104
- }
- imm = immlib.Debugger()
- if not args:
- usage(imm)
- return "Error : No patch type .. See log window for usage (Alt-L) .."
- ptype = args[0].lower()
- if ptypes.has_key( ptype ):
- ptype = ptypes[ ptype ]
- else:
- return "Invalid type: %s" % ptype
- # Intro text ..
- imm.log(" ")
- imm.log("%s v%s By BoB -> Team PEiD" % (ProgName, ProgVers), highlight=1)
- # --------------------------------------------------------------------------
- # IsDebuggerPresent ..
- # If patch PEB then no need for this ..
- if ptype == 0:
- Patch_IsDebuggerPresent(imm)
- return "IsDebuggerPresent patched .."
- # PEB ..
- elif ptype == 1:
- Patch_PEB(imm)
- return "PEB Flags patched .."
- # CheckRemoteDebuggerPresent ..
- # If patch ZwQueryInformationProcess then no need for this ..
- elif ptype == 2:
- Patch_CheckRemoteDebuggerPresent(imm)
- return "CheckRemoteDebuggerPresent patched .."
- # ZwQueryInformationProcess ..
- elif ptype == 3:
- Patch_ZwQueryInformationProcess(imm)
- return "ZwQueryInformationProcess patched .."
- # GetTickCount ..
- elif ptype == 4:
- Patch_GetTickCount(imm)
- return "GetTickCount patched .."
- # Patch all anti-debug / debug-detection Apis and flags ..
- elif ptype == 10:
- Patch_PEB(imm)
- Patch_IsDebuggerPresent(imm)
- Patch_CheckRemoteDebuggerPresent(imm)
- Patch_ZwQueryInformationProcess(imm)
- Patch_GetTickCount(imm)
- return "All Anti-debug Apis and flags patched .."
- # --------------------------------------------------------------------------
- # ZwQuerySystemInformation ..
- elif ptype == 20:
- Patch_ZwQuerySystemInformation(imm)
- return "ZwQuerySystemInformation patched .."
- # Patch all Process Apis to not return ImmDbg.EXE ..
- elif ptype == 21:
- Patch_ZwQuerySystemInformation(imm)
- return "All debugger process finding Apis patched .."
- # --------------------------------------------------------------------------
- # User32.DLL isn't always in memory, so these are done slightly differently ..
- # FindWindowA ..
- elif ptype == 30:
- if Patch_FindWindow(imm) == True:
- return "FindWindowA patched .."
- return "FindWindowA not patched .."
- # FindWindowW ..
- elif ptype == 31:
- if Patch_FindWindow(imm, "W") == True:
- return "FindWindowW patched .."
- return "FindWindowW not patched .."
- # FindWindowExA ..
- elif ptype == 32:
- if Patch_FindWindow(imm, True) == True:
- return "FindWindowExA patched .."
- return "FindWindowExA not patched .."
- # FindWindowExW ..
- elif ptype == 33:
- if Patch_FindWindow(imm, True, "W") == True:
- return "FindWindowExW patched .."
- return "FindWindowExW not patched .."
- # EnumWindows ..
- elif ptype == 34:
- if Patch_EnumWindows(imm) == True:
- return "EnumWindows patched .."
- return "EnumWindows not patched .."
- # All Window functions ..
- elif ptype == 35:
- a = True
- b = Patch_FindWindow(imm)
- if b == False:
- a = b
- b = Patch_FindWindow(imm, suffix = "W")
- if b == False:
- a = b
- b = Patch_FindWindow(imm, True, "A")
- if b == False:
- a = b
- b = Patch_FindWindow(imm, True, "W")
- if b == False:
- a = b
- b = Patch_EnumWindows(imm)
- if b == False:
- a = b
- if a:
- return "All debugger Window finding Apis patched .."
- return "Some Window Apis not patched .. See Log .."
- # --------------------------------------------------------------------------
- # Fix Anti-Debug of Upx-Lock ..
- elif ptype == 100:
- Patch_IsDebuggerPresent(imm)
- Patch_GetTickCount(imm)
- return "ImmDbg hidden from Upx-Lock .."
- # Fix Anti-Debug of NsPack ..
- elif ptype == 101:
- Patch_PEB(imm)
- return "ImmDbg hidden from NsPack .."
- # Fix Anti-Debug of ExeStealth ..
- elif ptype == 102:
- Patch_PEB(imm)
- return "ImmDbg hidden from ExeStealth .."
- # Fix Anti-Debug of Escargot ..
- elif ptype == 103:
- Patch_IsDebuggerPresent(imm)
- return "ImmDbg hidden from Escargot .."
- # Fix Anti-Debug of RL!Pack (v1.18+ Still detects debug by guard page) ..
- elif ptype == 104:
- Patch_PEB(imm)
- Patch_ZwQueryInformationProcess(imm)
- Patch_EnumWindows(imm)
- return "ImmDbg hidden from RL!Pack .."
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- DESC="""Heap logging function"""
- import immlib
- import immutils
- import getopt
- # We need to find this specific place
- def getRet(imm, allocaddr, max_opcodes = 300):
- addr = allocaddr
- for a in range(0, max_opcodes):
- op = imm.disasmForward( addr )
- if op.isRet():
- if op.getImmConst() == 0xc:
- op = imm.disasmBackward( addr, 3)
- return op.getAddress()
- addr = op.getAddress()
- return 0x0
- def usage( imm ):
- imm.log("!hippie -[o|s|d|p|c] InjectHook on Allocate/Free Heap", focus=1)
- #imm.log("-n Name Tag Name ")
- imm.log("-o Enable Hook")
- imm.log("-s Show Hook results")
- imm.log("-d Delete Hooks")
- imm.log("-p Pause Hook")
- imm.log("-C Clear Hook")
- imm.log("-c Continue Hook")
- imm.log("-h Filter by Heap")
- imm.log("-a Filter by Chunk Address")
- SWITCH = 1
- SHOW = 2
- DELETE = 3
- PAUSE = 4
- CONTINUE = 5
- CLEAR = 6
- def showresult(imm, a, rtlallocate, extra = ""):
- if a[0] == rtlallocate:
- imm.log("RtlAllocateHeap(0x%08x, 0x%08x, 0x%08x) <- 0x%08x %s" % ( a[1][0], a[1][1], a[1][2], a[1][3], extra), address = a[1][3] )
- else:
- imm.log("RtlFreeHeap(0x%08x, 0x%08x, 0x%08x) %s" % (a[1][0], a[1][1], a[1][2], extra) )
- def main(args):
- imm = immlib.Debugger()
- try:
- opts, argo = getopt.getopt(args, "osdpch:a:C")
- except getopt.GetoptError:
- usage(imm)
- return "Wrong Argument (Check Log Window)"
- FlagCmd = 0
- heap = None
- chunkaddress = None
- for o,a in opts:
- if o == '-o':
- FlagCmd = SWITCH
- elif o == '-s':
- FlagCmd = SHOW
- elif o == '-d':
- FlagCmd = DELETE
- elif o == '-p':
- FlagCmd = PAUSE
- elif o == '-c':
- FlagCmd = CONTINUE
- elif o == '-C':
- FlagCmd = CLEAR
- elif o == '-h':
- heap = int(a, 16)
- elif o == '-a':
- chunkaddress = int(a, 16)
- Name = "hippiehook"
- if FlagCmd == SWITCH:
- if imm.getKnowledge(Name):
- usage(imm)
- return "Cannot set Hooks: Hooks are already set"
- imm.pause()
- rtlfree = imm.getAddress("ntdll.RtlFreeHeap")
- allocate = imm.getAddress("ntdll.RtlAllocateHeap")
- # We need to hook on the the ret point of RtlAllocateHeap so we can
- # get the result of the allocation.
- mod = imm.getModule("ntdll.dll")
- if not mod.isAnalysed():
- imm.analyseCode( mod.getCodebase() )
- #imm.log("oOoo: 0x%08x" % allocate)
- rtlallocate = getRet(imm, allocate, 1000)
- imm.addKnowledge("FuncNames", ( rtlallocate, rtlfree ) )
- #imm.log("0x%08x 0x%08x (0x%08x)" % (rtlallocate, rtlfree, allocate))
- fast = immlib.STDCALLFastLogHook( imm )
- imm.log("Logging on Free 0x%08x" % rtlfree)
- fast.logFunction( rtlfree, 3 )
- imm.log("Logging on Alloc 0x%08x" % rtlallocate)
- fast.logFunction( rtlallocate, 0)
- fast.logBaseDisplacement( "EBP", 8)
- fast.logBaseDisplacement( "EBP", 0xC)
- fast.logBaseDisplacement( "EBP", 0x10)
- fast.logRegister( "EAX" )
- # Manual Way to do it
- #fast = immlib.FastLogHook( imm )
- #imm.log("Logging on 0x%08x" % rtlallocate)
- #fast.logFunction( rtlallocate )
- #fast.logBaseDisplacement("ESP", 4)
- #fast.logBaseDisplacement("ESP", 8)
- #fast.logBaseDisplacement("ESP", 12)
- #fast.logRegister("EAX")
- #fast.logFunction( rtlfree )
- #imm.log("Logging on 0x%08x" % rtlfree)
- #fast.logBaseDisplacement("ESP", 4)
- #fast.logBaseDisplacement("ESP", 8)
- #fast.logBaseDisplacement("ESP", 12)
- fast.Hook()
- imm.addKnowledge(Name, fast, force_add = 1)
- elif FlagCmd == DELETE:
- fast = imm.getKnowledge( Name )
- if not fast:
- return "Couldn't find the name tag"
- fast.unHook()
- imm.forgetKnowledge( Name )
- return "Hook removed: %s" % Name
- elif FlagCmd == CLEAR:
- fast = imm.getKnowledge(Name)
- if not fast:
- return "Couldn't find the name tag"
- fast.Clear()
- return "Hook has been clear"
- elif FlagCmd == SHOW:
- fast = imm.getKnowledge(Name)
- if not fast:
- return "Couldn't find the name tag"
- rtlallocate, rtlfree = imm.getKnowledge("FuncNames")
- ret = fast.getAllLog()
- NDX = {rtlallocate: 3, rtlfree: 2}
- for a in ret:
- extra = ""
- if heap:
- if heap == a[1][0]:
- if chunkaddress:
- if a[1][ NDX[ a[0] ] ] == chunkaddress:
- extra = "<---- * FOUND *"
- showresult(imm, a, rtlallocate, extra)
- #else:
- # showresult(imm, a, rtlallocate)
- else:
- if chunkaddress:
- if a[1][ NDX[ a[0] ] ] == chunkaddress:
- extra = "<---- * FOUND *"
- showresult(imm, a, rtlallocate, extra)
- #else:
- # showresult(imm, a, rtlallocate)
- imm.log("=" * 0x2f)
- return "Traced %d functions" % len(ret)
- elif FlagCmd == PAUSE:
- fast = imm.getKnowledge(Name)
- if not fast:
- return "Couldn't find the name tag"
- if not fast.Pause():
- return "Error: not been able to pause %s hook " % Name
- imm.addKnowledge(Name, fast, force_add = 1)
- return "Hook %s paused" % Name
- elif FlagCmd == CONTINUE:
- fast = imm.getKnowledge(Name)
- if not fast:
- return "Couldn't find the name tag"
- if not fast.Continue():
- return "Error: not been able to continue %s hook " % Name
- imm.addKnowledge(Name, fast, force_add = 1)
- return "Hook %s continued" % Name
- return "Done"
- #!/usr/bin/env python
- """
- Hook on RtlAllocateHeap
- """
- DESC = """Hook on RtlAllocateHeap/RtlFreeHeap and display information """
- import immlib
- from immlib import LogBpHook
- import getopt
- import struct
- # RtlAllocateHeap Hook class
- ALLOCLABEL = "Alloc Hook"
- class RtlAllocateHeapHook(LogBpHook):
- def __init__(self, heap):
- LogBpHook.__init__(self)
- self.Heap = heap
- def run(self,regs):
- """This will be executed when hooktype happens"""
- imm = immlib.Debugger()
- #for a in regs:
- #imm.log("%s:%08x" % (a, regs[a]))
- readaddr=""
- size=""
- res=imm.readMemory( regs['ESP'] + 4, 0xc)
- if len(res) != 0xc:
- imm.log("RtlAllocateHeap: ESP seems to broken, unable to get args")
- return 0x0
- (heap, flags, size) = struct.unpack("LLL", res)
- if heap == self.Heap:
- imm.log("RtlAllocateHeap(0x%08x, 0x%08x, 0x%08x)" % (heap, flags, size))
- # RtlFreeHeap Hook class
- FREELABEL = "Free Hook"
- class RtlFreeHeapHook(LogBpHook):
- def __init__(self, heap):
- LogBpHook.__init__(self)
- self.Heap = heap
- def run(self,regs):
- """This will be executed when hooktype happens"""
- imm = immlib.Debugger()
- #for a in regs:
- #imm.log("%s:%08x" % (a, regs[a]))
- readaddr=""
- size=""
- res=imm.readMemory( regs['ESP'] + 4, 0xc)
- if len(res) != 0xc:
- imm.log("RtlFreeHeap: ESP seems to broken, unable to get args")
- return 0x0
- (heap, flags, size) = struct.unpack("LLL", res)
- if heap == self.Heap:
- imm.log("RtlFreeHeap(0x%08x, 0x%08x, 0x%08x)" % (heap, flags, size))
- def usage(imm):
- imm.log("!hookalloc Hook on RtlAllocateHeap/RtlFreeHeap and display information")
- imm.log("-h Heap to hook")
- imm.log("-a Hook on RtlAllocateHeap")
- imm.log("-f Hook on RtlFreeHeap")
- imm.log("-u Disable Hooks")
- def HookOn(imm, heap, LABEL, HeapHook, bp_address, Disable):
- hookalloc = imm.getKnowledge( LABEL + "_%08x" % heap )
- if Disable:
- if not hookalloc:
- imm.log("Error %s: No hook for heap 0x%08x to disable" % (LABEL, heap))
- return "No %s to disable for heap 0x%08x" % (LABEL, heap)
- else:
- hookalloc.UnHook()
- imm.log("UnHooked %s" % LABEL)
- imm.forgetKnowledge( LABEL + "_%08x" % heap )
- return "%s for 0x%08x heap unhooked" % (LABEL, heap)
- else:
- if not hookalloc:
- hookalloc= HeapHook( heap )
- hookalloc.add( LABEL + "_%08x" % heap, bp_address)
- imm.log("Placed %s" % LABEL)
- imm.addKnowledge( LABEL + "_%08x" % heap, hookalloc )
- else:
- imm.log("HookAlloc for heap 0x%08x is already running" % heap)
- return "Hooking on RtlAllocateHeap"
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- def main(args):
- if not args:
- return "No arguments given"
- heap = None
- Disable = False
- AllocFlag = False
- FreeFlag = False
- imm = immlib.Debugger()
- try:
- opts, argo = getopt.getopt(args, "h:uaf")
- except getopt.GetoptError:
- imm.setStatusBar("Bad argument %s" % str(args))
- usage(imm)
- return 0
- for o,a in opts:
- if o == "-h" :
- try:
- heap = int(a, 16)
- except ValueError, msg:
- return "Invalid heap address: %s" % a
- elif o == "-u" :
- Disable = True
- elif o == "-a":
- AllocFlag = True
- elif o == "-f":
- FreeFlag = True
- ret = ""
- if heap:
- if AllocFlag:
- allocaddr = imm.getAddress("ntdll.RtlAllocateHeap" )
- ret = "Alloc Hook <%s>" % HookOn(imm, heap, ALLOCLABEL, RtlAllocateHeapHook, allocaddr, Disable)
- if FreeFlag:
- freeaddr = imm.getAddress("ntdll.RtlFreeHeap" )
- if ret:
- ret+= " - "
- ret +="Free Hook <%s>" % HookOn(imm, heap, FREELABEL, RtlFreeHeapHook, freeaddr, Disable)
- return ret
- else:
- return "Please, select a correct Heap"
- import socket
- import struct
- import xmlrpclib
- import traceback
- import base64
- from immlib import *
- from immutils import *
- import getopt
- DESC="""Hooks the NDR unmarshalling routines and prints them out so you can see which ones worked"""
- #############################################################################
- class set_hooks(LogBpHook):
- def __init__(self):
- LogBpHook.__init__(self)
- self.description=""
- return
- #########################################################################
- def run(self,regs):
- '''
- '''
- imm = Debugger()
- imm.log("%s"%self.description)
- return
- def usage(imm):
- imm.log("!hookndr.py")
- imm.log("%s" % DESC)
- imm.log("-D (to uninstall hook)")
- imm.log("-h This help")
- # The main routine that gets run when you type !packets
- def main(args):
- imm = Debugger()
- imm.ignoreSingleStep("CONTINUE")
- try:
- opts,argo = getopt.getopt(args, "Dh")
- except:
- return usage(imm)
- xmlhost=""
- xmlport=0
- for o,a in opts:
- if o == "-D":
- ndrhooks=imm.getKnowledge("ndrhooks")
- if not ndrhooks:
- imm.log("Could not find hooks to delete!")
- return "Did not find hook to delete"
- for hooker in ndrhooks:
- imm.removeHook(hooker)
- #now forget about that hook
- imm.forgetKnowledge("ndrhooks")
- return "Unhooked our ndr hooks"
- if o =="-h":
- return usage(imm)
- #otherwise it's time to hook some functions! Horray!
- #these functions are all in RPCRT4.dll
- #you know what would be good, being able to get all these automatically by listing names
- #and then looking for Ndr*Unmarshall!
- names= ["NdrPointerUnmarshall","NdrNonConformantStringUnmarshall","NdrNonEncapsulatedUnionUnmarshall"]
- names+=["NdrRangeUnmarshall","NdrSimpleStructUnmarshall","NdrSimpleTypeUnmarshall","NdrUserMarshalUnmarshall"]
- names+=["NdrVaryingArrayUnmarshall","NdrXmitOrRepAsUnmarshall","NdrByteCountPointerUnmarshall","NdrClientContextUnmarshall"]
- names+=["NdrComplexArrayUnmarshall","NdrConformantArrayUnmarshall","NdrConformantStringUnmarshall","NdrConformantStructUnmarshall"]
- names+=["NdrConformantVaryingArrayUnmarshall","NdrConformantVaryingStructUnmarshall","NdrEncapsulatedUnionUnmarshall"]
- names+=["NdrFixedArrayUnmarshall","NdrInterfacePointerUnmarshall"]
- hooks=[]
- for functionname in names:
- # Find the addresses of the functions we want to hook
- # Then register the hooks
- addy = imm.getAddress("RPCRT4."+functionname)
- imm.log(functionname+ " found at 0x%x"%addy)
- if addy == -1:
- imm.log("Could not locate %s"%functionname)
- continue
- # Set the hooks - this is the start hook
- hooker = set_hooks()
- hooker.description="Entering: %s"%functionname
- ret=hooker.add(hooker.description, addy)
- if ret==-1:
- imm.log("Hooking add failed!")
- else:
- hooks+=[hooker.description]
- func = imm.getFunction( addy )
- endaddies=imm.getFunctionEnd( func) #get the address of all the rets of the function
- for addy in endaddies:
- # Set the hooks
- hooker = set_hooks()
- #hooker.description="Leaving: %s"%functionname
- ret=hooker.add(hooker.description, addy)
- if ret==-1:
- imm.log("Hooking add failed!")
- else:
- hooks+=[hooker.description]
- imm.log("Added %d hooks"%(len(hooks)))
- imm.addKnowledge("ndrhooks",hooks)
- return "Network hooks in place."
- import socket
- import struct
- import xmlrpclib
- import traceback
- import base64
- from immlib import *
- from immutils import *
- import getopt
- DESC="""Creates a table that displays packets received on the network."""
- #############################################################################
- class set_hooks(LogBpHook):
- def __init__(self):
- LogBpHook.__init__(self)
- self.xmlhost = ""
- self.xmlport = 0
- return
- #########################################################################
- def run(self,regs):
- '''
- This routine is the first one hit, when a socket operation occurs.
- '''
- imm = Debugger()
- # Retrieve the function name
- function_name = imm.getKnowledge("%08x" % regs['EIP'])
- imm.log("Hook hit for %s"%function_name)
- self.retrieve_packet(imm,function_name,regs)
- return
- #########################################################################
- def retrieve_packet(self,imm,function_name,regs):
- '''
- This function logs the packet data into cap_win
- '''
- imm.log("Retrieving packet from %s"%function_name)
- # Determine what function we have hooked, based on this, retrieve the packet contents
- if function_name == "SSL3DecryptMessage":
- #nothing yet
- return
- elif function_name == "SSL3EncryptMessage":
- imm.log("Looking at SSL3EncryptMessage data")
- #The payload ptr is at esp+24
- pbuffer_ptr = imm.readMemory( regs['ESP'] + 0x24, 4)
- pbuffer_ptr = int(struct.unpack("L", pbuffer_ptr)[0])
- #the size of the buffer is at esp+0x20
- pbuffer_len = imm.readMemory( regs['ESP'] + 0x20, 4)
- pbuffer_len = int(struct.unpack("L", pbuffer_len)[0])
- imm.log("pbuffer_Size=%d"%pbuffer_len)
- #imm.log("Buffer Location: 0x%08x" % pbuffer_ptr[0])
- imm.log("pbuffer_ptr=%s"%repr(pbuffer_ptr))
- # Get the pointer to the packet payload
- payload = imm.readMemory(pbuffer_ptr, pbuffer_len)
- imm.log("Payload=%s"%repr(payload))
- #payload= "Payload!"
- decoded_payload = ""
- # Build the list thats table-friendly
- log_items = [function_name,repr(payload),decoded_payload]
- # Get a handle to the window and add the items, along with the related
- # address, this is sweet cause you can double-click on a packet and
- # see in the disassembly where it was sent/received :)
- #save this data to a file called payloads.txt
- #file("payloads.txt","ab").write(repr(payload)+"\n")
- using_xml_rpc = False
- if self.xmlport != 0:
- server = xmlrpclib.ServerProxy("http://%s:%d/"%(self.xmlhost,self.xmlport), allow_none=True)
- imm.log("Using server: %s:%d"%(self.xmlhost, self.xmlport))
- using_xml_rpc = True
- else:
- server = None
- if using_xml_rpc:
- #send our xml request to the remove side
- #if self.filter matches...(stub for now)
- try:
- result = server.senddata(("ssldata",[base64.encodestring(payload)]))
- except:
- data=traceback.format_exc()
- imm.log("Failed to connect to remote server, sorry")
- imm.logLines("Error was: %s"%data)
- return
- #Now parse what we got back - a command and list of arguments
- command, arguments = result
- if command=="LEAVEALONE":
- imm.log("Leaving alone")
- return
- elif command=="REPLACE":
- payload=arguments[0]
- payload=base64.decodestring(payload) #decode it
- imm.log("New Payload recved: %s"%repr(payload))
- #they encrypt messages in place, so we need to use their original
- #buffer to put our message into.
- #The payload ptr is at esp+24
- pbuffer_ptr = imm.readLong( regs['ESP'] + 0x24)
- imm.log("Replacing buffer at %8.8x with data of length %d"%(pbuffer_ptr, len(payload)))
- imm.writeMemory(pbuffer_ptr, payload)
- #add more commands from XML-RPC here
- return
- def usage(imm):
- imm.log("!hookssl.py")
- imm.log("-D (to uninstall hook)")
- imm.log("-s host:port (Server to send XML-RPC data to)")
- imm.log("-h This help")
- return
- # The main routine that gets run when you type !packets
- def main(args):
- imm = Debugger()
- imm.ignoreSingleStep("CONTINUE")
- try:
- opts,argo = getopt.getopt(args, "Dhs:")
- except:
- return usage(imm)
- xmlhost=""
- xmlport=0
- for o,a in opts:
- if o == "-D":
- hooker=imm.getKnowledge("ssl3hook")
- if not hooker:
- imm.log("Could not find hook to delete!")
- return "Did not find hook to delete"
- imm.removeHook("SSL 3 Encrypt Message")
- imm.removeHook("SSL 3 Decrypt Message")
- #now forget about that hook
- imm.forgetKnowledge("ssl3hook")
- return "Unhooked our ssl3hook"
- if o == "-s":
- xmlhost,xmlport = a.split(":")
- xmlport=int(xmlport)
- if o =="-h":
- return usage(imm)
- hooker = set_hooks()
- hooker.xmlhost=xmlhost
- hooker.xmlport=xmlport
- # Find the addresses of the functions we want to hook
- # Then register the hooks
- ssl3encryptmessage = imm.getAddress("schannel._Ssl3EncryptMessage@12")
- imm.log("SSL3 Encrypt Message found at 0x%x"%ssl3encryptmessage)
- if ssl3encryptmessage == -1:
- imm.log("Could not locate ssl3encryptmessage")
- return "Failed to find address to hook!"
- ssl3decryptmessage = imm.getAddress("schannel._Ssl3DecryptMessage@12")
- imm.log("SSL3 Decrypt Message found at 0x%x"%ssl3encryptmessage)
- if ssl3decryptmessage == -1:
- imm.log("Could not locate ssl3encryptmessage")
- return "Failed to find address to hook!"
- # Set the hooks
- ret=hooker.add("SSL 3 Encrypt Message", ssl3encryptmessage)
- ret=hooker.add("SSL 3 Decrypt Message", ssl3decryptmessage)
- imm.addKnowledge("ssl3hook",hooker)
- imm.log("Hooker.add returned %s"%ret)
- if ret==-1:
- imm.log("Hooker add failed! :<")
- return "Failed to add hook!"
- # Register the hook-address pair with the knowledgebase
- imm.addKnowledge("%08x" % ssl3encryptmessage, "SSL3EncryptMessage")
- imm.addKnowledge("%08x" % ssl3decryptmessage, "SSL3DecryptMessage")
- return "Network hooks in place."
- #!/usr/bin/env python
- ##Copyright IBM Corp. 2010
- ##
- ##Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
- ##
- ##http://www.apache.org/licenses/LICENSE-2.0
- ##
- ##Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- import immlib
- import getopt
- from libheap import *
- import libdatatype
- DESC= "Low Fragmentation Heap Viewer"
- def usage(imm):
- imm.log("!horse [-h HEAP_ADDR] [-b BLOCKS_ADDR] [-s Heap Bucket / SubSegment Info")
- imm.log(" -h HEAPADDR Set the heap address to inspect")
- imm.log(" -b BLOCKSADDR Set the _HEAP_LIST_LOOKUP block to inspect")
- imm.log(" -n Find bins which are NOT being managed by the LFH")
- def main(args):
- imm = immlib.Debugger()
- window = None
- if not args:
- imm.log("Please supply a valid _HEAP")
- return "NO HEAP PASSED"
- # options:
- # -h HEAP
- # -b Only look at specific _HEAP_LIST_LOOKUP
- # -n Look for empty bins
- try:
- opts, argo = getopt.getopt(args, "h:nsb:")
- except getopt.GetoptError:
- #imm.setStatusBar("Bad heap argument %s" % args[0])
- usage(imm)
- return "Bad heap argument %s" % args[0]
- heap = 0x0
- lfhthreshold = 0x12
- singleblock = False
- blockindex = 0x0
- emptybins = False
- restore = False
- opennewwindow = False
- for o,a in opts:
- if o == "-h":
- try:
- heap = int(a, 16)
- except ValueError, msg:
- return "Invalid heap address: %s" % a
- elif o == "-b":
- singleblock = True
- try:
- blockindex = int(a, 16)
- except ValueError, msg:
- return "Invalid heap address: %s" % a
- elif o == "-n":
- emptybins = True
- elif o == "-r":
- restore = True
- if (heap and ( heap in imm.getHeapsAddress() )) or blockindex:
- tag = "heap_%08x" % heap
- if not opennewwindow:
- window = imm.getKnowledge(tag)
- if window and not window.isValidHandle():
- imm.forgetKnowledge(tag)
- del window
- window = None
- if not window:
- window = imm.createTable("Heap dump 0x%08x" % heap, ["Address", "Chunks"] )
- imm.addKnowledge(tag, window, force_add = 1)
- if not heap and blockindex:
- pheap = imm.getHeap(blockindex & 0xFFFF0000, restore)
- else:
- pheap = imm.getHeap( heap, restore )
- if pheap and pheap.FrontEndHeapType == 0x2 and pheap.FrontEndHeap:
- lfhthreshold = 0x11
- for i in (0, len(pheap.blocks)-1):
- block = pheap.blocks[i]
- #we're looking for a specific blockindex
- if singleblock:
- if block.address != blockindex:
- continue
- num_of_freelists = block.ArraySize - block.BaseIndex
- window.Log("Printing Block information for 0x%08x" % block.address)
- window.Log("ExtendedLookup => 0x%08x" % block.ExtendedLookup)
- window.Log("ArraySize [max permitted in blocks] => 0x%08x" % block.ArraySize)
- window.Log("BaseIdex => 0x%08x" % block.BaseIndex)
- window.Log("End Block information for 0x%08x" % block.address)
- window.Log("Block has [0x%x] FreeLists starting at 0x%08x:" % (num_of_freelists, block.ListHints))
- memory = imm.readMemory( block.ListHints, num_of_freelists * 8 )
- for a in range(0, num_of_freelists):
- free_entry = []
- # Previous and Next Chunk of the head of the double linked list
- (flink, heap_bucket) = struct.unpack("LL", memory[a *8 : a * 8 + 8] )
- bin = a + block.BaseIndex
- freelist_addr = block.ListHints + (bin - block.BaseIndex) * 8
- if heap_bucket != 0 and not emptybins:
- if heap_bucket & 1:
- window.Log("Flink => 0x%08x | Bin[0x%x] enabled | Bucket => 0x%08x" % (flink, bin, heap_bucket - 1), address = freelist_addr)
- elif (heap_bucket & 0x0000FFFF) >= 0x22: #there appears to be a case where the LFH isn't activated when it should be...
- window.Log("Flink => 0x%08x | Bin[0x%x] ??????? | Bucket => 0x%08x" % (flink, bin, heap_bucket), address = freelist_addr)
- else:
- allocations = heap_bucket & 0x0000FFFF
- allocations = allocations / 2
- amount_needed = lfhthreshold - allocations
- window.Log("Flink => 0x%08x | Bin[0x%x] has had 0x%x allocations | Needs 0x%x more" % (flink, bin, allocations, amount_needed), address = freelist_addr)
- else:
- if emptybins and heap_bucket == 0 and bin != 0x1 and bin != 0x0:
- window.Log("Flink => 0x%08x | Bin[0x%x] is Emtpy!" % (flink, bin), address = freelist_addr)
- window.Log("")
- window.Log("=-" * 0x23 + "=")
- return "Heap 0x%x dumped" % heap
- else:
- imm.log("Error: A proper heap or blockindex needs to be defined")
- return "Error: A proper heap or blockindex needs to be defined"
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- List all pycommands with its descriptions in log window
- """
- DESC="""List PyCommands"""
- import immlib
- import os
- CMD_DIR = "./PyCommands"
- def do_dir_list(imm, path):
- dir_list = os.listdir(path)
- for name in dir_list:
- if name[-3:] == ".py":
- imm.log("* %s" % name)
- def main(args):
- imm=immlib.Debugger()
- dir_list = os.listdir(CMD_DIR)
- imm.log("List of available PyCommands")
- for name in dir_list:
- path = os.path.join(CMD_DIR, name)
- if os.path.isdir(path):
- do_dir_list(imm, path)
- elif name[-3:] == ".py":
- imm.log("* %s" % name)
- imm.log("",focus=1)
- return "See log window for results"
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- __VERSION__ = '1.0'
- DESC = """Shows the Lookaside of the Heap structure"""
- import immlib
- from libheap import *
- import getopt
- import libdatatype
- def usage(imm):
- imm.log("!lookaside Shows the Lookaside of the Heap structure")
- imm.log("-h Heap Address", focus=1)
- imm.log("-d Discovery DataType")
- def main(args):
- imm = immlib.Debugger()
- heap = 0x0
- discover = None
- if not args:
- usage(imm)
- return "Wrong args (Check the Log Window)"
- try:
- opts, argo = getopt.getopt(args, "h:d")
- except getopt.GetoptError:
- usage(imm)
- return "Bad heap argument %s" % args[0]
- for o,a in opts:
- if o == "-h":
- try:
- heap = int(a, 16)
- except ValueError, msg:
- self.InfoLine("Invalid heap address: %s" % a)
- return 0
- elif o == '-d':
- discover = libdatatype.DataTypes(imm)
- if heap:
- pheap = PHeap( imm, heap )
- lookaddr = pheap.Lookaddr
- imm.log("Dumping Lookaside: 0x%08x (0x%08x) " % (lookaddr, heap) )
- if lookaddr:
- plook = PHeapLookaside( imm, lookaddr )
- for ndx in range(0, len(plook) ):
- l = plook[ndx]
- if not l.isEmpty():
- imm.log("Lookaside[%02x]: " % ndx, address = l.addr)
- for a in l.getList():
- imm.log(" " * 15 +"> 0x%08x (%d)" % (a, ndx * 8), address = a, focus=1)
- if discover:
- list = discover.Get( a+4, ndx*8 - 4)
- for obj in list:
- imm.log(" " * 15 + "[%s] %s" % (obj.name, obj.Print()), address = obj.address )
- return "Lookaside at 0x%08x dumped" % lookaddr
- else:
- usage(imm)
- return "No Heap Provided"
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- import immlib
- import getopt
- __VERSION__ = '1.1'
- DESC= "Static Analysis: Mark the tiny ones"
- def usage(imm):
- """ All the options"""
- imm.log("!mark search and mark given function")
- imm.log("!mark [-f NAME ] [-c COMMENT] [-m MODULE]")
- imm.log("Example: mark with DANGER_MOUSE string all the strcpy ones")
- imm.log("!mark -f strcpy -c DANGER_MOUSE -m ALL")
- def main(args):
- imm = immlib.Debugger()
- if not args:
- imm.log("### Immunity's Mark the tiny ones script###",focus=1)
- imm.log("Command ok, but no args, using defaults")
- try:
- opts, argo = getopt.getopt(args, "f:c:m:")
- except getopt.GetoptError: #get args, if error, show usage
- usage(imm)
- return "Bad argument %s" % args[0]
- #tiny ones default list
- tinyones=[]
- tinyones.append("strcpy")
- tinyones.append("memcpy")
- tinyones.append("memmov")
- module=None
- function=None
- function_address=0
- comment="default comment"
- #parsing args
- for o,a in opts:
- if o == "-f":
- try:
- function = a
- function_address=imm.getAddress(function)
- imm.log("%s address: 0x%8x" % (function,function_address),focus=1)
- except ValueError, msg:
- imm.log("No function given, using the tiny ones")
- if o == "-c":
- comment = a
- imm.log("Comment: %s" %comment)
- if o == "-m":
- if a and a != "ALL":
- try:
- module = imm.getModule(a)
- if not module:
- return "Invalid module: %s" % a
- else:
- imm.log("module: %s" %module.getName())
- base = module.getBase()
- except ValueError, msg:
- return "Invalid module: %s" % a
- else:
- regs=imm.getRegs()
- module = imm.findModule(regs['EIP']) # if no module given, use the one we are standing on
- if not module:
- return "Module?"
- else:
- imm.log("module: %s" %module[0])
- base=module[1]
- #all data, find and mark
- if module == "ALL":
- mods = imm.getAllModules()
- for mod in mods:
- refaddr=imm.getInterCalls(mod.getBase())
- for a in refaddr.keys():
- op = imm.disasm(a)
- #imm.log("op: %s"% op.comment)
- decoded=imm.decodeAddress(refaddr[a][0][2]) # decode destination
- if function_address != 0:
- if function in decoded: #and ask if function name is in destination
- imm.log("From: 0x%08x - to 0x%08x" %(a,refaddr[a][0][0]))
- imm.log("Decoded destination: %s" % decoded)
- imm.setComment(a,comment) #so, set your comment
- else:
- for function in tinyones:
- if function in decoded: #and ask if function name is in destination
- imm.log("From: 0x%08x - to 0x%08x" %(a,refaddr[a][0][0]))
- imm.log("Decoded destination: %s" % decoded)
- imm.setComment(a,comment) #so, set your comment
- else:
- regs=imm.getRegs()
- refaddr=imm.getInterCalls(regs['EIP'])
- for a in refaddr.keys():
- op = imm.disasm(a)
- #imm.log("op: %s"% op.comment)
- decoded=imm.decodeAddress(refaddr[a][0][2]) # decode destination
- if function_address != 0:
- if function in decoded: #and ask if function name is in destination
- imm.log("From: 0x%08x - to 0x%08x" %(a,refaddr[a][0][0]))
- imm.log("Decoded destination: %s" % decoded)
- imm.setComment(a,comment) #so, set your comment
- else:
- for function in tinyones:
- if function in decoded: #and ask if function name is in destination
- imm.log("From: 0x%08x - to 0x%08x" %(a,refaddr[a][0][0]))
- imm.log("Decoded destination: %s" % decoded)
- imm.setComment(a,comment) #so, set your comment
- return "mark finished executing"
- import getopt
- import struct
- import time
- import sys
- import threading
- from immutils import *
- from immlib import *
- from libstackanalyze import *
- from graphclass import *
- from immvcglib import *
- from socket import *
- DESC="""Attempts to automate tracing the lifecycle of a packet's contents."""
- #############################################################################
- '''
- Some defines for re-use.
- '''
- PACKET_TYPE_SEND = "Send "
- PACKET_TYPE_RECV = "Recv "
- PACKET_PROTOCOL_UDP = "(UDP)"
- PACKET_PROTOCOL_TCP = "(TCP)"
- #############################################################################
- class packet_analyzer(BpHook):
- #########################################################################
- def __init__(self, address, hook_type):
- BpHook.__init__(self)
- self.begin_address = address
- self.imm = Debugger()
- self.graph = Graph()
- self.draw = Draw()
- self.buf = []
- self.nodes_buf = []
- self.nodes = []
- self.edges_buf = []
- self.func_start = None
- self.func_end = None
- self.graph_handler = None
- self.last_bb = None
- self.hook_type = hook_type
- self.first_func_finished = False
- self.bb_end = True
- self.node_count = 0
- self.node_covered = {}
- self.active_node = ""
- #########################################################################
- def run(self, regs):
- '''
- This is the main hook routine that occurs at [ESP] of a socket
- function call. It kicks off the whole process of sniffing the
- packet, graphing, and analyzing it.
- '''
- session = self.imm.getKnowledge("session")
- if session == True:
- self.imm.forgetKnowledge("session")
- self.imm.addKnowledge("session", False, force_add=0x1)
- else:
- self.imm.run()
- return
- # Now we determine what type of packet sniff we need to do
- if self.hook_type == "simple":
- if self.simple_packet_sniff(regs) == False:
- return
- else:
- if self.extended_packet_sniff(regs) == False:
- return
- # Make sure that the module has been analyzed.
- if self.imm.isAnalysed(self.begin_address) != 1:
- self.imm.analyseCode(self.begin_address)
- # Workaround for EIP == functionBegin address
- if self.begin_address == regs['EIP']:
- self.func_start = self.regs['EIP']
- else:
- self.func_start = self.imm.getFunctionBegin(self.begin_address)
- # Once we have the function information set some variables
- func = self.imm.getFunction(self.func_start)
- self.func_end = func.getEnd()
- func_name = func.getName()
- # Setup the VCG header, add the first basic block and return
- self.start_graph(func_name)
- # Now we enter into a step-over routine where we will begin
- # tracing the execution/data flow of our packet, initialize the
- # code coverage counter beforehand
- self.imm.addKnowledge("code_coverage",0,force_add = 0x1)
- self.deep_analysis_loop(regs)
- # This stitches all the buffers together and splashes the graph
- self.render_graph()
- # We need to clear out the knowledgebase so let's grab the information
- # we want to keep first
- boo_address = self.imm.getKnowledge("boo_address")
- boo_port = self.imm.getKnowledge("boo_port")
- test_port = self.imm.getKnowledge("test_port")
- test_protocol = self.imm.getKnowledge("test_protocol")
- # Disable the breakpoint or this hooer will get hit again
- #self.imm.disableBreakpoint(self.begin_address)
- boo = boo_comm(boo_address,boo_port,test_port,test_protocol)
- boo.prepare_next_case()
- self.imm.run()
- # Give it some time to finish up any of its previous loops
- #packet.send_test_packet()
- #########################################################################
- def deep_analysis_loop(self, regs):
- '''
- This is the loop that steps the instruction pointer, determines
- branching decisions, and does the data analysis.
- '''
- loop_status = True
- # We do the first instruction first, then enter a loop of stepping
- # to analyze the rest of the code paths
- self.imm.gotodisasmWindow(regs['EIP'])
- loop_status, processed_reg, step_type = self.opcode_processor(regs)
- # Begin the analysis loop, go grab a coffee this can take awhile
- while loop_status == True:
- # Determine whether we want to step over or in
- if step_type == "in":
- self.imm.stepIn()
- else:
- self.imm.stepOver()
- stepped_regs = self.imm.getRegs()
- if self.imm.isAnalysed(stepped_regs['EIP']) != 1:
- self.imm.analyseCode(stepped_regs['EIP'])
- # Test if we landed inside a system DLL
- if self.test_system_dll(stepped_regs['EIP']) == True and self.first_func_finished == True or self.imm.isRunning() == True:
- break
- # The opcode processor does all of the dirty work
- loop_status, processed_reg, step_type = self.opcode_processor(stepped_regs)
- return
- #########################################################################
- def opcode_processor(self, regs):
- step_type = "over"
- loop_status = True
- # Grab the opcode from the address (EIP)
- opcode = self.imm.disasm(regs['EIP'])
- # Register the code coverage hit
- code_coverage = self.imm.getKnowledge("code_coverage")
- self.imm.forgetKnowledge("code_coverage")
- code_coverage += 1
- self.imm.addKnowledge("code_coverage",code_coverage,force_add=0x1)
- # For call instructions, if its calling into a non-system module
- # then we want to follow it. Otherwise the graph would explode.
- if opcode.isCall() == 1:
- if self.test_system_dll(opcode.jmpaddr) == False:
- step_type = "in"
- # The threshold is a way to prematurely terminate the analysis, otherwise
- # you can go wandering off in threading routines, garbage collection stuff, etc.
- # Break the loop if the threshold has been hit.
- threshold = self.imm.getKnowledge("threshold")
- if code_coverage >= threshold:
- loop_status = False
- if self.first_func_finished == True:
- # Now let's send the information off to our graphing function
- if self.bb_end == True:
- self.add_node_header(regs['EIP'])
- self.bb_end = False
- if opcode.isJmp() == 1 or opcode.isRet() == 1 or opcode.isConditionalJmp() == 1 or loop_status == False or step_type == "in":
- self.bb_end = True
- info_panel = self.imm.getInfoPanel()
- comment = self.imm.getComment(regs['EIP'])
- # Add the instructions, information and comments to the graph.
- self.add_node_instructions(regs['EIP'],opcode,comment,info_panel)
- # We want to step into RET instructions so that we correctly get
- # back to the callee
- if opcode.isRet() == 1:
- #self.imm.log("Ret Destination: 0x%08x" % opcode.jmpaddr)
- if self.first_func_finished == False:
- self.first_func_finished = True
- if self.test_system_dll(opcode.jmpaddr) == True:
- loop_status = False
- return loop_status, regs['EIP'], step_type
- #########################################################################
- def test_system_dll(self, address):
- '''
- This function is designed to take an address and return whether
- it lies within a system DLL.
- '''
- jmp_module = self.imm.getModuleByAddress(address)
- if jmp_module is not None:
- system_dll = jmp_module.getIssystemdll()
- # We test here, as well the msvcr71.dll is really a system dll
- # but a lot of developers redistribute, treat it as such
- if system_dll == 1 or jmp_module.name.lower() == "msvcr71.dll":
- return True
- else:
- return False
- return None
- #########################################################################
- def start_graph(self, func_name):
- '''
- This just sets up the graphing header, and initializes the graphing routine.
- '''
- # Now we do a bunch of VCG lovin to get the graph setup the way we want it
- # this part of the code was taken directly from immvcglib.py and should not
- # be included as part of the judging criteria
- iteration = self.imm.getKnowledge("current_iteration")
- if iteration != 0 and iteration is not None:
- self.node_covered = self.imm.getKnowledge("node_covered")
- else:
- iteration = 0
- self.buf.append('graph: {\x0d\x0a')
- self.buf.append('title: "Packet Life (%s - Iteration: %d)"\r\n' % (self.imm.getDebuggedName(),iteration))
- self.buf.append("manhattan_edges: yes\r\n")
- self.buf.append("layoutalgorithm: mindepth\r\n")
- self.buf.append("finetuning: no\r\n")
- self.buf.append("layout_downfactor: 100\r\n")
- self.buf.append("layout_upfactor: 0\r\n")
- self.buf.append("layout_nearfactor: 0\r\n")
- self.buf.append("xlspace: 12\r\n")
- self.buf.append("yspace: 30\r\n")
- self.buf.append("display_edge_labels: yes\r\n")
- self.buf.append("colorentry 99: 193 255 193\r\n")
- self.buf.append("colorentry 100: 238 233 233\r\n")
- self.buf.append("colorentry 98: 255 69 0\r\n")
- self.buf.append("colorentry 97: 0 139 0\r\n")
- #########################################################################
- def add_node_header(self,address):
- '''
- Adds the first node to the graph, this will be the function that called
- the receive socket operation.
- '''
- decode_address = self.imm.decodeAddress(address)
- # Start a new node by creating the header.
- if self.node_covered.has_key(address):
- self.active_node += 'node: { title: "%s" color: \f100 vertical_order: %d label:"\r\n\x0c31%s\x0c31\r\n\r\n' % (decode_address,self.node_count,decode_address)
- else:
- self.active_node += 'node: { title: "%s" color: \f99 vertical_order: %d label:"\r\n\x0c31%s\x0c31\r\n\r\n' % (decode_address,self.node_count,decode_address)
- self.node_covered[address] = True
- self.nodes.append(decode_address)
- self.node_count += 1
- #########################################################################
- def add_node_instructions(self, address,opcode,comment=None,infopanel=None):
- '''
- Adds the current instruction, associated comments and information.
- '''
- self.active_node += "\f310x%08x: \f12%s\r\n" % (address, opcode.result)
- if comment is not None and comment != "":
- if opcode.isCall() == 1:
- self.active_node += " \t\t\t\f98%s\r\n" % (comment.replace("\"", ""))
- else:
- self.active_node += " \t\t\t\f01%s\r\n" % (comment.replace("\"", ""))
- if infopanel is not None and infopanel != "":
- # Here we do matching against the packet contents and
- # what is registered in the infopanel
- self.data_match(opcode,infopanel)
- self.active_node += "\r\n"
- if self.bb_end == True:
- self.active_node += "\r\n\"}\r\n"
- self.last_bb = address
- self.nodes_buf.append(self.active_node)
- self.active_node = ""
- #########################################################################
- def data_match(self,opcode,infopanel):
- self.imm.log("In Data Match ++++++++++++++")
- matched = False
- sub_info = []
- # Clean up the output a little
- for info in infopanel:
- if info != "":
- sub_info.append(info)
- for data in sub_info:
- if data.find("=") != -1:
- clean_data = data.split("=")[1]
- op_left = opcode.result.split(" ")[0]
- self.imm.log("Front Opcode: %s" % cmp)
- # Check for the packet length
- packet_length = "%08x" % self.imm.getKnowledge("packet_length")
- self.imm.log("Comparing %s <-> %s" % (packet_length,clean_data))
- if clean_data.lower() == packet_length.lower():
- self.active_node += " \t\t\t\f08%s \f02(Packet Length)\r\n" % data.replace("\"","\\\"")
- self.imm.log("Possible Packet Length Match++++++++++++++++++++++++++++")
- matched = True
- if matched == False:
- ascii_packet = self.imm.getKnowledge("ascii_packet")
- binary_packet = self.imm.getKnowledge("binary_packet")
- # Now let's begin matching the payload junk (I suck at this, many improvements can be made)
- # Check for ASCII references
- clean_data = data.split("ASCII")
- self.imm.log("Cleaned Split: %s" % clean_data)
- if clean_data != "" and clean_data[0] != data:
- match = clean_data[1].replace("\"","").replace(")","").strip()
- self.imm.log("MATCH: %s -------------------------------------------------" % match)
- self.imm.log("PACKE: %s -------------------------------------------------" % ascii_packet)
- if ascii_packet.rfind(match) != -1:
- self.active_node += " \t\t\t\f08%s \f09(Packet Payload)\r\n" % data.replace("\"","\\\"")
- self.imm.log("Wooot========================================")
- matched = True
- # Now let's see if there is any binary matches such as ESI=41424344
- # again, not perfect but it should work well
- if matched == False:
- clean_data = data.split("=")
- if clean_data != "" and clean_data[0] != data:
- for bin in clean_data:
- match = bin.replace("\"","").replace("(","").replace("[","").replace("]","").strip()
- self.imm.log("MATCH: %s -------------------------------------------------" % match)
- self.imm.log("PACKE: %s -------------------------------------------------" % binary_packet)
- if binary_packet.rfind(match) != -1 or binary_packet[::-1].rfind(match) != -1:
- self.active_node += " \t\t\t\f08%s \f97(Packet Payload)\r\n" % data.replace("\"","\\\"")
- self.imm.log("Wooot========================================")
- matched = True
- # We didn't find any matches at all, output default info
- if matched == False:
- self.active_node += " \t\t\t\f08%s\r\n" % data.replace("\"","\\\"")
- else:
- self.active_node += " \t\t\t\f08%s\r\n" % data.replace("\"","\\\"")
- #########################################################################
- def render_graph(self):
- '''
- This function assembles the nodes_buf and the edges_buf for the overall
- graph, and pushes it to the screen.
- '''
- for a in range(0,len(self.nodes_buf)):
- self.buf.append(self.nodes_buf[a])
- self.buf.append("\r\n")
- for a in range(0,len(self.nodes)):
- if a < len(self.nodes)-1:
- self.buf.append('edge: { sourcename: "%s" targetname: "%s" color: darkgreen }\r\n' % (self.nodes[a],self.nodes[a+1]))
- self.buf.append("\n}\r\n")
- # Send the graph back to Boo for storage
- boo_port = self.imm.getKnowledge("boo_port")
- boo_address = self.imm.getKnowledge("boo_address")
- test_port = self.imm.getKnowledge("test_port")
- test_protocol = self.imm.getKnowledge("test_protocol")
- iteration = self.imm.getKnowledge("current_iteration")
- version = self.imm.getModule(self.imm.getDebuggedName()).getVersion()
- s = socket(AF_INET,SOCK_STREAM)
- s.connect((boo_address,int(boo_port)))
- message = "graph|%s|%s|%d|%s|%d|%s||\r\n" % (self.imm.getDebuggedName(),version,int(test_port),test_protocol,int(iteration),"".join(self.buf))
- self.imm.log("%s" % message)
- s.send(message)
- self.imm.addKnowledge("node_covered", self.node_covered,force_add=0x1)
- #########################################################################
- def simple_packet_sniff(self, regs):
- '''
- The simple packet sniff is one where we merely have a pointer
- to the buffer and a length. It's very easy to read the packets
- out of memory.
- '''
- (payload_ptr, type, function_name) = self.imm.getKnowledge("%08x" % regs['EIP'])
- # The length is stored as a function return argument, so let's read EAX
- length = regs['EAX']
- try:
- # Because return codes can be -1 (error) we have to test for that.
- if length > 1 and length != 0xffffffff:
- counter = 0
- payload = ""
- bin_payload = ""
- # Get the raw packet payload and the length of the bytes
- raw_payload = self.imm.readMemory(payload_ptr, length)
- pack_len = str(length)+"c"
- if raw_payload is not None:
- final_payload = struct.unpack(pack_len, raw_payload)
- # Iterate through the unpacked string, only outputting printable
- # ascii characters, output the standard dots if non-printable
- while counter < int(length):
- if ord(final_payload[counter]) >= 32 and ord(final_payload[counter]) <= 126:
- payload += final_payload[counter]
- else:
- payload += "."
- bin_payload += "%02x" % ord(final_payload[counter])
- counter += 1
- # Build the list thats table-friendly
- log_items = [function_name, type, "%d" % int(length), bin_payload[:512], payload[:512]]
- # Add the packet to the knowledgebase
- self.imm.addKnowledge("binary_packet", bin_payload, force_add=0x1)
- self.imm.addKnowledge("ascii_packet", payload, force_add=0x1)
- self.imm.addKnowledge("packet_length", int(length[0]),force_add=0x1)
- # Get a handle to the window and add the items, along with the related
- # address, this is sweet cause you can double-click on a packet and
- # see in the disassembly where it was sent/received :)
- cap_win = self.imm.getKnowledge("cap_win")
- cap_win.add(regs['EIP'], log_items)
- #self.imm.disableBreakpoint(regs['EIP'])
- except:
- return False
- #########################################################################
- def extended_packet_sniff(self, regs):
- '''
- This is for the WSA* family of socket functions where we have to
- do more pointer manipulation and there's a bit more work involved
- in getting the packets.
- '''
- (payload_ptr, recv_ptr, type, function_name) = self.imm.getKnowledge("%08x" % regs['EIP'])
- # This is an [out] pointer that let's us know how much data was
- # received on a socket (non-overlapped)
- length = self.imm.readMemory(recv_ptr, 4)
- length = struct.unpack("l", length)
- try:
- # Network apps are chatty, we don't want to grab garbage packets
- if length[0] > 1:
- counter = 0
- payload = ""
- bin_payload = ""
- # Get the raw packet payload and the length of the bytes
- raw_payload = self.imm.readMemory(payload_ptr, int(length[0]))
- pack_len = str(int(length[0]))+"c"
- if raw_payload is not None:
- final_payload = struct.unpack(pack_len, raw_payload)
- # Iterate through the unpacked string, only outputting printable
- # ascii characters, output the standard dots if non-printable
- while counter < int(length[0]):
- if ord(final_payload[counter]) >= 32 and ord(final_payload[counter]) <= 126:
- payload += final_payload[counter]
- else:
- payload += "."
- bin_payload += "%02x" % ord(final_payload[counter])
- counter += 1
- # Build the list thats table-friendly
- log_items = [function_name, type, "%d" % int(length[0]), bin_payload[:512], payload[:512]]
- # Add the packet to the knowledgebase
- self.imm.addKnowledge("binary_packet", bin_payload, force_add=0x1)
- self.imm.addKnowledge("ascii_packet", payload, force_add=0x1)
- self.imm.addKnowledge("packet_length", int(length[0]),force_add=0x1)
- # Get a handle to the window and add the items, along with the related
- # address, this is sweet cause you can double-click on a packet and
- # see in the disassembly where it was sent/received :)
- cap_win = self.imm.getKnowledge("cap_win")
- cap_win.add(regs['EIP'], log_items)
- #self.imm.disableBreakpoint(regs['EIP'])
- except:
- return False
- #############################################################################
- class set_hooks(LogBpHook):
- #########################################################################
- def __init__(self):
- LogBpHook.__init__(self)
- self.imm = Debugger()
- #########################################################################
- def create_hooks(self):
- '''
- This creates the original hooks on the common socket receive functions,
- this is not comprehensive but it should catch most socket operations.
- Future enhancements will include all possible socket operations.
- '''
- ws_wsarecv = self.imm.getAddress("ws2_32.WSARecv")
- ws_wsasend = self.imm.getAddress("ws2_32.WSASend")
- ws_recv = self.imm.getAddress("ws2_32.recv")
- ws_recvfrom = self.imm.getAddress("ws2_32.recvfrom")
- # Set the hooks
- current_iteration = self.imm.getKnowledge("current_iteration")
- if current_iteration == 0:
- self.add("WSARecv", ws_wsarecv)
- self.add("WSASend", ws_wsasend)
- self.add("recv", ws_recv)
- self.add("recvfrom", ws_recvfrom)
- # Register the hook-address pair with the knowledgebase
- self.imm.addKnowledge("%08x" % ws_wsarecv, "WSARecv",force_add=0x1)
- self.imm.addKnowledge("%08x" % ws_wsasend, "WSASend",force_add=0x1)
- self.imm.addKnowledge("%08x" % ws_recv, "recv",force_add=0x1)
- self.imm.addKnowledge("%08x" % ws_recvfrom, "recvfrom",force_add=0x1)
- #########################################################################
- def retrieve_packet(self, function_name, regs):
- '''
- This function determines how to handle the packet data. Some socket
- operations require more work (such as WSARecv), and others less (recv).
- If necessary this function will register a hook on [ESP], where any
- [out] pointers from a function will be set.
- '''
- extended_hook = None
- # Determine what function we have hooked, based on this, retrieve the packet contents
- if function_name == "WSARecv":
- type = PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- extended_hook = True
- if function_name == "WSASend":
- type=PACKET_TYPE_SEND+PACKET_PROTOCOL_TCP
- extended_hook = True
- if function_name == "recvfrom":
- type=PACKET_TYPE_RECV+PACKET_PROTOCOL_UDP
- extended_hook = False
- if function_name =="recv":
- type=PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- extended_hook = False
- if extended_hook is None:
- self.imm.addKnowledge("session", False, force_add=0x1)
- return
- # An extended hook requires a bit more work to pull out the packet info
- if extended_hook == True:
- # Get the pointer to the payload pointer :(
- pbuffer_ptr = self.imm.readMemory(regs['ESP'] + 8, 4)
- pbuffer_ptr = struct.unpack("L", pbuffer_ptr)
- # Get the pointer to the packet payload
- payload_ptr = self.imm.readMemory(pbuffer_ptr[0]+4, 4)
- payload_ptr = struct.unpack("<L", payload_ptr)
- # Get the [out] pointer of the received bytes
- recv_ptr = self.imm.readMemory(regs['ESP'] + 0x10, 4)
- recv_ptr = struct.unpack("L", recv_ptr)
- # Figure out [esp]
- esp_ptr = self.imm.readMemory(regs['ESP'], 4)
- esp_ptr = struct.unpack("<L", esp_ptr)
- # Now we hook [esp] if this isn't the first iteration, don't reset the hook
- ret_hook = packet_analyzer(esp_ptr[0], "ext_hook")
- ret_hook.add("%08x" % esp_ptr[0], esp_ptr[0])
- # Add this ret hook to the knowledgebase
- self.imm.addKnowledge("%08x" % esp_ptr[0], (payload_ptr[0], recv_ptr[0], type, function_name),force_add=0x1)
- else:
- # Get the pointer to the buffer
- payload_ptr = self.imm.readMemory(regs['ESP'] + 8, 4)
- payload_ptr = struct.unpack("L", payload_ptr)
- # Figure out where [ESP] points to
- esp_ptr = self.imm.readMemory(regs['ESP'], 4)
- esp_ptr = struct.unpack("<L", esp_ptr)
- # Add the [ESP] hook for when the function returns
- simple_hook = packet_analyzer(esp_ptr[0], "simple")
- simple_hook.add("%08x" % esp_ptr[0], esp_ptr[0])
- # Add our pertinent information to the knowledgebase
- self.imm.addKnowledge("%08x" % esp_ptr[0], (payload_ptr[0], type, function_name),force_add=0x1)
- #########################################################################
- def run(self, regs):
- '''
- This routine is the first one hit, when a socket operation occurs.
- '''
- # Determine if we are in the middle of an analysis session
- session = self.imm.getKnowledge("session")
- # Retrieve the function name
- function_name = self.imm.getKnowledge("%08x" % regs['EIP'])
- # Clear the breakpoint
- self.retrieve_packet(function_name, regs)
- class boo_comm():
- def __init__(self,boo_address,boo_port,test_port,test_protocol):
- self.imm = Debugger()
- self.boo_address = boo_address
- self.boo_port = int(boo_port)
- self.boo_sock = socket(AF_INET,SOCK_STREAM)
- self.test_port = int(test_port)
- self.test_protocol = test_protocol
- def notify(self,message):
- self.imm.log("Boo Port: %d Boo Address: %s" % (self.boo_port,self.boo_address))
- if message == "begin_test":
- self.imm.addKnowledge("session", True, force_add=0x1)
- message = message + "|" + str(self.test_port) + "|" + self.test_protocol
- try:
- self.boo_sock.connect((self.boo_address,self.boo_port))
- except:
- self.imm.log("Couldn't connect to Boo! Poor thing...")
- return
- # We notify boo we are ready to begin
- # Double pipe is our delimiter
- message = message + "||\r\n"
- self.boo_sock.send(message)
- self.boo_sock.close()
- def prepare_next_case(self):
- # We need to clear the knowledgebase so grab the packet first, as well the capture window
- binary_packet = self.imm.getKnowledge("binary_packet")
- ascii_packet = self.imm.getKnowledge("ascii_packet")
- code_coverage = self.imm.getKnowledge("code_coverage")
- current_iteration = self.imm.getKnowledge("current_iteration")
- threshold = self.imm.getKnowledge("threshold")
- new_threshold = threshold + 25
- # Now re-add the information in a list called iteration
- self.imm.addKnowledge("iteration_%d" % current_iteration, (code_coverage,binary_packet,ascii_packet),force_add=0x1)
- # Output some test results
- self.imm.log("=====================================================")
- self.imm.log("Test Results for Iteration: %d" % current_iteration)
- self.imm.log("")
- self.imm.log("Code Coverage: %d (Threshold %d)" % (code_coverage,threshold))
- self.imm.log("Binary Packet: %s" % binary_packet)
- self.imm.log("ASCII Packet: %s" % ascii_packet)
- self.imm.log("")
- self.imm.log("Increasing Threshold to: %d" % new_threshold)
- self.imm.log("=====================================================")
- # Track the iteration number
- self.imm.addKnowledge("threshold", new_threshold, force_add=0x1)
- current_iteration += 1
- self.imm.addKnowledge("current_iteration", current_iteration, force_add=0x1)
- self.imm.run()
- #############################################################################
- def usage(imm):
- '''
- Prints the usage information for this pycommand.
- '''
- imm.log("!mike BOOADDRESS BOOPORT TESTPORT PROTOCOL - Sulley's best friend, it analyzes a protocol and outputs graphs and Sulley scripts. Get the process running first!")
- imm.log("eg. !mike 192.168.7.1 1337")
- #############################################################################
- def main(args):
- '''
- This is the main routine when a PyCommand is run. This creates the window object,
- sets the hooks and then fires out a test packet.
- '''
- imm = Debugger()
- # Check commandline args, I hate this part :)
- if not args:
- usage(imm)
- return "Usage information outputted please check the log window"
- imm.ignoreSingleStep("CONTINUE")
- # Create the packet capture window
- column_titles = ["Function", "Type", "Length", "Binary", "ASCII"]
- cap_win = imm.createWindow("Captured Packets", column_titles)
- # Add the window to the knowledge base, and monitor whether the
- # analysis session is active
- imm.addKnowledge("cap_win", cap_win, force_add=0x1)
- # Set the hooks on the socket operations.
- try:
- hooker = set_hooks()
- hooker.create_hooks()
- except:
- return "Can't find exported socket functions."
- # Track the iteration number
- imm.addKnowledge("current_iteration", 0, force_add = 0x1)
- # We kick the testing off by using a known test packet to begin
- # the attempt at reversing the protocol
- boo_address = args[0]
- boo_port = args[1]
- test_port = args[2]
- test_protocol = args[3]
- threshold = 50
- imm.addKnowledge("boo_address", boo_address,force_add=0x1)
- imm.addKnowledge("boo_port", boo_port,force_add=0x1)
- imm.addKnowledge("threshold", threshold,force_add=0x1)
- imm.addKnowledge("test_port", test_port,force_add=0x1)
- imm.addKnowledge("test_protocol", test_protocol,force_add=0x1)
- boo = boo_comm(boo_address,boo_port,test_port,test_protocol)
- boo.notify("begin_test")
- return "Network hooks in place."
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- modptr
- """
- __VERSION__ = '1.0'
- DESC="""!modptr Patch all Function Pointers and detect when they triggered """
- import immlib
- import immutils
- import libdatatype
- import getopt
- from immlib import AccessViolationHook
- INDEXER = 0xb4000000
- INDEX_MASK = 0xFF000000
- FNDX_MASK = 0x00FFFFFF
- def usage(imm):
- imm.log("!modptr Patch all Function Pointers and detect when they triggered")
- imm.log("! -a address")
- imm.log("! -x 0xADDR[,0xADDR...] (Addresses to exclude)")
- imm.log(" [Note: it will patch all the function pointer on the memory pages of the given address]")
- return "Usage: !modptr -a ADDRESS"
- # Access Violation Hook class
- class FunctionTriggeredHook(AccessViolationHook):
- def __init__( self, fn_ptr):
- AccessViolationHook.__init__( self )
- #self.threadid = threadid
- self.fn_ptr = fn_ptr
- # found the access violation we force by patching every function pointer.
- # Recognise what pointer is and show it on Log Window
- def run(self, regs):
- imm = immlib.Debugger()
- eip = regs['EIP']
- # Checking if we are on the correct Access Violation
- if ( eip & INDEX_MASK ) != INDEXER:
- return ""
- fndx = eip & FNDX_MASK
- if fndx >= len( self.fn_ptr ) :
- return ""
- obj = self.fn_ptr[ fndx ] # it shouldn't be out of index
- # Print info and Unhook
- imm.log("Found a pointer at 0x%08x that triggers: " % obj.address, address = obj.address, focus =1 )
- imm.log(" %s: %s" % ( obj.name, obj.Print() ), address = obj.address)
- imm.setReg("EIP", int(obj.data) )
- imm.run()
- #self.UnHook()
- def main(args):
- imm = immlib.Debugger()
- if not args:
- return usage(imm)
- exclude = []
- address = None
- try:
- opts, argo = getopt.getopt(args, "a:x:")
- except getopt.GetoptError:
- usage(imm)
- return "Wrong Argument (Check Log Window)"
- for o,a in opts:
- if o == '-a':
- address = int( a, 16 )
- elif o == '-x':
- x_list = a.split(',')
- for x_addr in x_list:
- try:
- exclude.append(int(x_addr, 16))
- except ValueError:
- return "Invalid exclude value %s" % str(x_addr)
- else:
- usage(imm)
- return "Invalid option %s" % o
- if address is None:
- usage(imm)
- return "You must specify an address (-a)"
- page = imm.getMemoryPageByAddress( address )
- if not page:
- return "Failed to grab Memory Page, wrong addres: 0x%08x" % address
- addr = page.getBaseAddress()
- mem = imm.readMemory( page.getBaseAddress(), page.getSize() )
- ndx = INDEXER
- fn_ptr = []
- # Discovering Function Pointers
- dt = libdatatype.DataTypes( imm )
- ret = dt.Discover( mem, addr, what = 'pointers' )
- if ret:
- for obj in ret:
- if obj.isFunctionPointer() and obj.address not in exclude:
- # Writing a dword that would make the Function Pointer crash on AV
- # and later we will identify on our AV Hook
- imm.log( "Modifying: 0x%08x" % obj.address )
- imm.writeLong( obj.address, ndx )
- ndx += 1
- fn_ptr.append( obj )
- hook = FunctionTriggeredHook( fn_ptr )
- hook.add( "modptr_%08x" % addr )
- return "Hooking on %d Functions" % len( fn_ptr )
- else:
- return "No Function pointers found on the page of 0x%08x" % address
- #!/usr/bin/env python
- """
- nohooks
- """
- __VERSION__ = '0.1'
- DESC="""Clean all hooks from memory"""
- import immlib
- def main(args):
- imm = immlib.Debugger()
- for hook in imm.listHooks():
- imm.removeHook(hook)
- imm.log("Removed \"%s\" hook from memory" % str(hook))
- return "Hooks removed"
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- openfile example
- """
- __VERSION__ = '1.0'
- DESC="""Open a File"""
- import immlib
- def usage(imm):
- imm.log("!openfile file")
- imm.log("ex: !openfile c:\\boot.ini", focus=1)
- def main(args):
- imm=immlib.Debugger()
- if not args:
- usage(imm)
- return "Wrong Arguments (Check Log Windows for the usage information)"
- ret = imm.openTextFile( args[0] )
- if ret == 0:
- return "File %s open" % args[0]
- else:
- return "Cannot open %s" % args[0]
- import socket
- import struct
- from immlib import *
- DESC="""Creates a table that displays packets received on the network."""
- #############################################################################
- '''
- Some defines for re-use.
- '''
- PACKET_TYPE_SEND = "Send "
- PACKET_TYPE_RECV = "Recv "
- PACKET_PROTOCOL_UDP = "(UDP)"
- PACKET_PROTOCOL_TCP = "(TCP)"
- #############################################################################
- class simple_hooks(LogBpHook):
- #########################################################################
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- imm = Debugger()
- (payload_ptr,type,function_name) = imm.getKnowledge("%08x" % regs['EIP'])
- # The length is stored as a function return argument, so let's read EAX
- length = regs['EAX']
- # Because return codes can be -1 (error) we have to test for that.
- if length > 1 and length != 0xffffffff:
- counter = 0
- payload = ""
- bin_payload = ""
- # Get the raw packet payload and the length of the bytes
- raw_payload = imm.readMemory(payload_ptr,length)
- pack_len = str(length)+"c"
- imm.log("Pack Len: %s " % pack_len)
- if raw_payload is not None:
- final_payload = struct.unpack(pack_len,raw_payload)
- # Iterate through the unpacked string, only outputting printable
- # ascii characters, output the standard dots if non-printable
- while counter < int(length):
- if ord(final_payload[counter]) >= 32 and ord(final_payload[counter]) <= 126:
- payload += final_payload[counter]
- else:
- payload += "."
- bin_payload += "%02x" % ord(final_payload[counter])
- counter += 1
- # Build the list thats table-friendly
- log_items = [function_name,type,"%d" % int(length),bin_payload[:512],payload[:512]]
- # Get a handle to the window and add the items, along with the related
- # address, this is sweet cause you can double-click on a packet and
- # see in the disassembly where it was sent/received :)
- cap_win = imm.getKnowledge("cap_win")
- cap_win.add(regs['EIP'],log_items)
- # Drop the entry in the KB, disable the BP, and unHook.
- imm.forgetKnowledge("%08x" % regs['EIP'])
- imm.disableBreakpoint(regs['EIP'])
- self.UnHook()
- #############################################################################
- class ext_hooks(LogBpHook):
- #########################################################################
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- imm = Debugger()
- (payload_ptr,recv_ptr,type,function_name) = imm.getKnowledge("%08x" % regs['EIP'])
- # This is an [out] pointer that let's us know how much data was
- # received on a socket (non-overlapped)
- length = imm.readMemory(recv_ptr,4)
- length = struct.unpack("l",length)
- # Network apps are chatty, we don't want to grab garbage packets
- if length[0] > 1:
- counter = 0
- payload = ""
- bin_payload = ""
- # Get the raw packet payload and the length of the bytes
- raw_payload = imm.readMemory(payload_ptr,int(length[0]))
- pack_len = str(int(length[0]))+"c"
- if raw_payload is not None:
- final_payload = struct.unpack(pack_len,raw_payload)
- # Iterate through the unpacked string, only outputting printable
- # ascii characters, output the standard dots if non-printable
- while counter < int(length[0]):
- if ord(final_payload[counter]) >= 32 and ord(final_payload[counter]) <= 126:
- payload += final_payload[counter]
- else:
- payload += "."
- bin_payload += "%02x" % ord(final_payload[counter])
- counter += 1
- # Build the list thats table-friendly
- log_items = [function_name,type,"%d" % int(length[0]),bin_payload[:512],payload[:512]]
- # Get a handle to the window and add the items, along with the related
- # address, this is sweet cause you can double-click on a packet and
- # see in the disassembly where it was sent/received :)
- cap_win = imm.getKnowledge("cap_win")
- cap_win.add(regs['EIP'],log_items)
- # Drop the entry in the KB, disable the BP, and unHook.
- imm.forgetKnowledge("%08x" % regs['EIP'])
- imm.disableBreakpoint(regs['EIP'])
- self.UnHook()
- #############################################################################
- class set_hooks(LogBpHook):
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- '''
- This routine is the first one hit, when a socket operation occurs.
- '''
- imm = Debugger()
- # Retrieve the function name
- function_name = imm.getKnowledge("%08x" % regs['EIP'])
- self.retrieve_packet(imm,function_name,regs)
- #########################################################################
- def retrieve_packet(self,imm,function_name,regs):
- '''
- This function determines how to handle the packet data. Some socket
- operations require more work (such as WSARecv), and others less (recv).
- If necessary this function will register a hook on [ESP], where any
- [out] pointers from a function will be set.
- '''
- # Determine what function we have hooked, based on this, retrieve the packet contents
- if function_name == "WSARecv":
- type = PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- extended_hook = True
- if function_name == "WSASend":
- type=PACKET_TYPE_SEND+PACKET_PROTOCOL_TCP
- extended_hook = True
- if function_name == "recvfrom":
- type=PACKET_TYPE_RECV+PACKET_PROTOCOL_UDP
- extended_hook = False
- if function_name =="recv":
- type=PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- extended_hook = False
- # An extended hook requires a bit more work to pull out the packet info
- if extended_hook == True:
- # Get the pointer to the payload pointer :(
- pbuffer_ptr = imm.readMemory( regs['ESP'] + 8, 4)
- pbuffer_ptr = struct.unpack("L", pbuffer_ptr)
- #imm.log("Buffer Location: 0x%08x" % pbuffer_ptr[0])
- # Get the pointer to the packet payload
- payload_ptr = imm.readMemory(pbuffer_ptr[0]+4,4)
- payload_ptr = struct.unpack("<L", payload_ptr)
- #imm.log("Payload Pointer: %08x" % payload_ptr[0])
- # Get the [out] pointer of the received bytes
- recv_ptr = imm.readMemory(regs['ESP'] + 0x10, 4)
- recv_ptr = struct.unpack("L",recv_ptr)
- #imm.log("Receive Pointer: %08x" % recv_ptr[0])
- # Figure out [esp]
- esp_ptr = imm.readMemory(regs['ESP'],4)
- esp_ptr = struct.unpack("<L", esp_ptr)
- #imm.log("[ESP] at 0x%08x" % esp_ptr[0])
- # Now we hook [esp]
- ret_hook = ext_hooks()
- ret_hook.add("%08x" % esp_ptr[0],esp_ptr[0])
- # Add this ret hook to the knowledgebase
- imm.addKnowledge("%08x" % esp_ptr[0],(payload_ptr[0],recv_ptr[0],type,function_name))
- else:
- # Get the pointer to the buffer
- payload_ptr = imm.readMemory(regs['ESP'] + 8, 4)
- payload_ptr = struct.unpack("L", payload_ptr)
- # Figure out where [ESP] points to
- esp_ptr = imm.readMemory(regs['ESP'],4)
- esp_ptr = struct.unpack("<L", esp_ptr)
- # Add the [ESP] hook for when the function returns
- simple_hook = simple_hooks()
- simple_hook.add("%08x" % esp_ptr[0],esp_ptr[0])
- # Add our pertinent information to the knowledgebase
- imm.addKnowledge("%08x" % esp_ptr[0],(payload_ptr[0],type,function_name))
- # The main routine that gets run when you type !packets
- def main(args):
- imm = Debugger()
- imm.ignoreSingleStep("CONTINUE")
- hooker = set_hooks()
- # Create the packet capture window
- column_titles = ["Function","Type","Length","Binary","ASCII"]
- cap_win = imm.createWindow("Captured Packets", column_titles )
- # Add the window to the knowledge base
- imm.addKnowledge("cap_win", cap_win,force_add=0x1)
- # Find the addresses of the functions we want to hook
- # Then register the hooks
- ws_wsarecv = imm.getAddress("ws2_32.WSARecv")
- ws_wsasend = imm.getAddress("ws2_32.WSASend")
- ws_recv = imm.getAddress("ws2_32.recv")
- ws_recvfrom = imm.getAddress("ws2_32.recvfrom")
- # Set the hooks
- hooker.add("WSARecv", ws_wsarecv)
- hooker.add("WSASend", ws_wsasend)
- hooker.add("recv", ws_recv)
- hooker.add("recvfrom", ws_recvfrom)
- # Register the hook-address pair with the knowledgebase
- imm.addKnowledge("%08x" % ws_wsarecv, "WSARecv")
- imm.addKnowledge("%08x" % ws_wsasend, "WSASend")
- imm.addKnowledge("%08x" % ws_recv, "recv")
- imm.addKnowledge("%08x" % ws_recvfrom, "recvfrom")
- return "Network hooks in place."
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- __VERSION__ = '1.0'
- import immlib, string
- import traceback
- import sys
- DESC = "Non interactive python shell [immlib already imported]"
- def usage(imm):
- imm.log("!pyexec code")
- imm.log("%s" % DESC)
- def main(args):
- imm = immlib.Debugger()
- if args:
- commands = string.joinfields(args, "")
- try:
- exec commands
- except:
- error = traceback.format_exception_only(sys.exc_type, sys.exc_value)
- imm.log("Error on: %s" % commands, focus = 1)
- for line in error: # Its just one line anyways, for format_exception_only
- line = line.strip()
- imm.log(line)
- return line
- else:
- return "No python command given"
- """
- recognize.py - Function Recongnizing using heuristic patterns.
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- __VERSION__ = '1.0'
- import immlib
- import immutils
- import getopt
- import string
- import os
- import csv
- from librecognition import *
- DESC="Function Recognizing using heuristic patterns."
- def usage(imm):
- imm.log("!recognize -{a|m} -n name [ -x address ] [ -i filename ] [-v version/extra]")
- imm.log("!recognize -d [ -i filename ] -n name")
- imm.log("!recognize -l [-i filename] [-n name]")
- imm.log("!recognize -f -n name [-i filename] [-v version/extra] [-o module] [-h heuristic_threasold]")
- imm.log("!recognize -r -x address [-i filename] [-h heuristic_threasold]")
- imm.log(" ex (find a pattern, accept 80%% of match): !recognize -f -n iTunes.AntiDebuggers -h 80 -o iTunes.exe")
- imm.log(" ex (resolv an address, accept 93%% of match): !recognize -r -x 004EDE00 -h 93")
- imm.log(" ex (add a pattern): !recognize -a -x 004EDE00 -n iTunes.AntiDebuggers -i itunes.dat -v 7.4.1")
- imm.log(" ex (add a pattern guessing the address from labels or symbols): !recognize -a -n _SPExternalAlloc@4")
- imm.log(" ex (modify a pattern): !recognize -m -x 004EDE00 -n iTunes.AntiDebuggers -i itunes.dat -v protections_disabled")
- imm.log(" ex (delete a pattern): !recognize -d -i itunes.dat -n iTunes.AntiDebuggers")
- imm.log(" ex (list patterns): !recognize -l -i itunes.dat -n antidebug", focus=1)
- return ""
- def main(args):
- imm = immlib.Debugger()
- imm.log("################# Immunity's Function Recognizing ################")
- imm.markBegin()
- if not args:
- usage(imm)
- return "not enough args"
- try:
- opts, notused = getopt.getopt(args, "amdlfrx:n:i:h:v:o:")
- except getopt.GetoptError:
- usage(imm)
- return "Wrong Arguments (Check usage on the Log Window)"
- defaultfilename = os.path.join("Data", "default.dat")
- name = address = id = action = module = filename = None
- version = ""
- heuristic = 90
- for o,a in opts:
- if o == '-x':
- address = imm.getAddress(a)
- if address < 0:
- imm.log("invalid address or expresion")
- usage(imm)
- return "address error!"
- if o == '-o':
- module = a
- if o == '-n':
- name = string.strip(a, " '\"\\{}%;,")
- if o == "-i":
- filename = os.path.basename(string.strip(a, " '\"{}%;,"))+".dat"
- if not filename:
- usage(imm)
- return "invalid filename"
- filename = os.path.join("Data",filename)
- if o == '-v':
- version = string.strip(a, " '\"\\{}%;,")
- if o == "-h":
- try:
- heuristic = int(a)
- except:
- imm.log("invalid heuristic threasold")
- usage(imm)
- return "heuristic theashold error!"
- if o in ["-a","-m","-d","-l","-f","-r"]:
- action = o[1]
- if not action:
- usage(imm)
- return "no action set"
- #add/modify an element
- if action == "a" or action == "m":
- if not filename: filename = defaultfilename
- if not name:
- usage(imm)
- return "insufficient arguments to add/modify an entry"
- if not address:
- tmp = imm.getAddressOfExpression(name)
- if tmp > 0:
- address = tmp
- else:
- return "name hasn't a known address"
- modif = False
- recon = FunctionRecognition(imm, filename)
- for d in recon.dictionaries:
- if name == d[0]:
- if action == "a":
- usage(imm)
- return "the name '%s' is already in the selected dictionary" % name
- if action == "m":
- modif = True
- break
- if action == "m" and not modif:
- usage(imm)
- return "the name '%s' wasn't found in the selected dictionary" % name
- tmp = recon.makeFunctionHash(address, compressed=True)
- file = extractFile(imm, address)
- definition = [ name, tmp[0], tmp[1][0], tmp[1][1], tmp[2], version, file, string.join(tmp[3],"|") ]
- remakeDictionary(imm, recon, filename, definition, action)
- imm.log("Element '%s' added/modified" % name, focus=1)
- #delete an element
- if action == "d":
- if not name:
- usage(imm)
- return "incomplete information to delete an element"
- if not filename: filename = defaultfilename
- delete = False
- recon = FunctionRecognition(imm, filename)
- for d in recon.dictionaries:
- if name == d[0]:
- delete = True
- break
- if not delete:
- usage(imm)
- return "the function '%s' wasn't found in the selected dictionary" % name
- remakeDictionary(imm, recon, filename, name, action)
- imm.log("Element '%s' deleted" % name, focus=1)
- #list elements
- if action == "l":
- recon = FunctionRecognition(imm, filename)
- list = []
- for values in recon.dictionaries:
- if not name or name.lower() in values[0].lower():
- list.append([values[0],values[5],values[6],values[4], os.path.basename(values[-1])[:-4]])
- if not list:
- return "the name '%s' wasn't found in the dictionaries" % name
- else:
- imm.log("-" * 156)
- imm.log("|%-30s|%-40s|%-20s|%-40s|%-20s|" % ("real name","version/extra","binary file","SHA1","repository"))
- imm.log("-" * 156)
- for v in list:
- imm.log("|%-30s|%-40s|%-20s|%-40s|%-20s|" % (v[0][0:30],v[1][0:40],v[2][0:20],v[3][0:40], v[4][0:20]), focus=1)
- imm.log("-" * 156)
- #search for an element
- if action == "f":
- if not name:
- usage(imm)
- return "incomplete information to search"
- #we need to maintain separated csv indexes
- dict = FunctionRecognition(imm, filename)
- recon = FunctionRecognition(imm, filename)
- addy = None
- for values in dict.dictionaries:
- if name.lower() in values[0].lower():
- tmp = recon.searchFunctionByName(values[0], heuristic, module, version)
- if tmp:
- for addy,heu in tmp:
- imm.log("Function '%s' address: %08X (%d%%)" % (values[0], addy,heu), addy, focus=1)
- if addy:
- imm.gotoDisasmWindow(addy)
- else:
- imm.log("We can't find a function that fullfit all the requirements", focus=1)
- #resolv an address to a function name
- if action == "r":
- if not address:
- usage(imm)
- return "we need an address to resolv"
- recon = FunctionRecognition(imm, filename)
- name = recon.resolvFunctionByAddress(address)
- if name:
- imm.log("function at %08X FOUND: %s" % (address, name), address, focus=1)
- imm.gotoDisasmWindow(address)
- else:
- imm.log("function not found", focus=1)
- return "Done in %d secs! see the log for details" % imm.markEnd()
- def remakeDictionary(imm, recon, filename, data, action):
- tmpfd = os.tmpfile()
- writer = csv.writer(tmpfd)
- if action == "a" or action == "m":
- writer.writerow(data)
- for row in recon.dictionaries:
- row.pop() #drop the filename added by the CSV iterator (always the last element)
- if action == "a":
- writer.writerow(row)
- if action == "m" and data[0] != row[0]:
- writer.writerow(row)
- if action == "d" and data != row[0]:
- writer.writerow(row)
- tmpfd.flush()
- del recon
- del writer
- fd = open(filename, "wb")
- tmpfd.seek(0)
- for line in tmpfd:
- fd.write(line)
- tmpfd.close()
- fd.close()
- def extractFile(imm, address):
- for mod in imm.getAllModules().values():
- if mod.getBaseAddress() <= address and address <= mod.getBaseAddress()+mod.getSize():
- return os.path.basename(mod.getPath())
- return ""
- #!/usr/bin/env python
- """
- Immunity Debugger safeseh search
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- __VERSION__ = '1.1'
- import immlib
- import getopt
- from immutils import *
- import struct
- LOG_HANDLERS=True
- DESC= "Looks for exception handlers registered with SafeSEH"
- def usage(imm):
- imm.log("!safeseh (-m module)",focus=1)
- def main(args):
- imm = immlib.Debugger()
- module = None
- try:
- opts, argo = getopt.getopt(args, "m:s")
- except getopt.GetoptError:
- usage(imm)
- return "Bad argument %s" % args[0]
- for o,a in opts:
- if o == "-m":
- module = a
- allmodules=imm.getAllModules()
- table=imm.createTable('SafeSEH Table',['Module','Handler'])
- for key in allmodules.keys():
- if module is not None and module != key:
- continue
- mod=imm.getModule(key)
- mzbase=mod.getBaseAddress()
- peoffset=struct.unpack('<L',imm.readMemory(mzbase+0x3c,4))[0]
- pebase=mzbase+peoffset
- flags=struct.unpack('<H',imm.readMemory(pebase+0x5e,2))[0]
- if (flags&0x400)!=0:
- imm.log('%s: SafeSEH protected'%(key))
- imm.log('%s: No handler'%(key))
- continue
- numberofentries=struct.unpack('<L',imm.readMemory(pebase+0x74,4))[0]
- if numberofentries>10:
- sectionaddress,sectionsize=struct.unpack('<LL',imm.readMemory(pebase+0x78+8*10,8))
- sectionaddress+=mzbase
- data=struct.unpack('<L',imm.readMemory(sectionaddress,4))[0]
- condition=(sectionsize!=0) and ((sectionsize==0x40) or (sectionsize==data))
- #imm.log('%s: %08x %04x %08x %08x %d'%(key,mzbase,flags,sectionaddress,sectionsize,condition))
- if condition==False:
- imm.log('%s: *** SafeSEH unprotected ***'%(key))
- continue
- if data<0x48:
- imm.log('%s: TODO check section 0xe!'%(key)) #checked in RtlCaptureImageExceptionValues() though I have never seen such a DLL/EXE
- continue
- sehlistaddress,sehlistsize=struct.unpack('<LL',imm.readMemory(sectionaddress+0x40,8))
- #imm.log('%s: %08x %d'%(key,sehlistaddress,sehlistsize))
- if sehlistaddress!=0 and sehlistsize!=0:
- imm.log('%s: SafeSEH protected'%(key))
- imm.log('%s: %d handler(s)'%(key,sehlistsize))
- if LOG_HANDLERS==True:
- for i in range(sehlistsize):
- sehaddress=struct.unpack('<L',imm.readMemory(sehlistaddress+4*i,4))[0]
- sehaddress+=mzbase
- table.add(sehaddress,[key,'0x%08x'%(sehaddress)])
- imm.log('0x%08x'%(sehaddress))
- continue
- else:
- imm.log('%s: TODO check section 0xe!'%(key)) #checked in RtlCaptureImageExceptionValues() though I have never seen such a DLL/EXE
- continue
- imm.log('%s: *** SafeSEH unprotected ***'%(key))
- return "Check your table and log window for results"
- #!/usr/bin/env python
- #-------------------------------------------------------------------------------
- #
- # By BoB -> Team PEiD
- # http://www.SecretAsHell.com/BobSoft/
- # BobSoft@GMail.Com
- #
- #-------------------------------------------------------------------------------
- #
- # Based on findpacker.py, this script will scan the entrypoint or whole file of
- # the main module, using Ero's PEFile and my UserDB.txt as before ..
- # Also added is logging of the entropy of the file and a guess based on the
- # entropy as to whether the file is packed or not.
- #
- # By BoB, whilst freezing in England.. ;)
- # I only started with Python a week ago, and this is my first ever script ..
- # So, please excuse any bad Python coding :P
- #
- # Thanks to JMS for checking my dodgy code .. :)
- #
- #-------------------------------------------------------------------------------
- __VERSION__ = '1.00'
- ProgName = 'ScanPE'
- ProgVers = __VERSION__
- DESC = "Detect a Packer/Cryptor of Main Module, also scan just EntryPoint .."
- import immlib
- import math
- import pefile
- import peutils
- #-------------------------------------------------------------------------------
- def usage(imm):
- imm.log(" ")
- imm.log("%s v%s By BoB -> Team PEiD" % (ProgName, ProgVers), focus=1, highlight=1)
- imm.log("This script will scan the loaded module for any matching signatures in .\Data\UserDB.TXT ..")
- imm.log("Usage:")
- imm.log(" !%s [-h]" % ProgName.lower())
- imm.log(" ")
- imm.log("Options:")
- imm.log(" -h : Hardcore mode - Scan whole file .. (default is to scan just the Entrypoint)")
- imm.log(" ")
- return "See log window (Alt-L) for usage .. "
- #-------------------------------------------------------------------------------
- # RawToRva - Convert offset to Rva ..
- def rawToRva(pe, Raw):
- sections = [s for s in pe.sections if s.contains_offset(Raw)]
- if sections:
- section = sections[0]
- return (Raw - section.PointerToRawData) + section.VirtualAddress
- else:
- return 0
- #-------------------------------------------------------------------------------
- # GetSectionInfo - Returns info about section as string ..
- def getSectionInfo(pe, Va):
- sec = pe.get_section_by_rva(Va - pe.OPTIONAL_HEADER.ImageBase)
- if sec:
- # Get section number ..
- sn = 0
- for i in range(pe.FILE_HEADER.NumberOfSections):
- if pe.sections[i] == sec:
- sn = i + 1
- break
- # Get section name ..
- name = ""
- for j in range(7):
- # Only until first null ..
- if sec.Name[j] == chr(0):
- break
- name = "%s%s" % (name, sec.Name[j])
- # If name is not blank then set name string to ', "<name>"'' ..
- if name != "":
- name = ", \"%s\"" % name
- # Return section number and name (if exist) ..
- return " (section #%02d%s)" % (sn, name)
- return " (not in a section)"
- #-------------------------------------------------------------------------------
- # GetEntropy - Returns entropy of some data - Taken from Ero's PEFile.py ..
- def getEntropy(data):
- """Calculate the entropy of a chunk of data."""
- if not data:
- return 0
- entropy = 0
- for x in range(256):
- p_x = float(data.count(chr(x)))/len(data)
- if p_x > 0:
- entropy += - p_x*math.log(p_x, 2)
- return entropy
- #-------------------------------------------------------------------------------
- def main(args):
- imm = immlib.Debugger()
- name = imm.getDebuggedName()
- EP_Only = 1
- if args:
- if args[0].lower() == '-h':
- EP_Only = 0
- try:
- Mod = imm.getModule(name)
- if not Mod:
- raise Exception, "Couldn't find %s .." % name
- except Exception, msg:
- return "Error: %s" % msg
- imm.log(" ")
- imm.log("%s v%s By BoB -> Team PEiD" % (ProgName, ProgVers), focus=1, highlight=1)
- imm.log("Processing \"%s\" .." % name)
- # Load PE File ..
- pe = pefile.PE(name = Mod.getPath())
- # Displays same guessed results as PEiD -> Extra information -> Entropy ..
- e = getEntropy( pe.__data__ )
- if e < 6.0:
- a = "Not packed"
- elif e < 7.0:
- a = "Maybe packed"
- else: # 7.0 .. 8.0
- a = "Packed"
- # Start processing ..
- imm.log(" o File Entropy : %.2f (%s)" % (e, a))
- imm.log(" o Loading signatures ..")
- imm.setStatusBar("Loading signatures ..")
- # Show now as sigs take a few seconds to load ..
- imm.updateLog()
- # Load signatures ..
- sig_db = peutils.SignatureDatabase('Data/UserDB.TXT')
- imm.log(" o %d total sigs in database .." % (sig_db.signature_count_eponly_true + sig_db.signature_count_eponly_false + sig_db.signature_count_section_start))
- # Display number of signatures to scan ..
- if EP_Only == 1:
- imm.log(" o %d EntryPoint sigs to scan .." % sig_db.signature_count_eponly_true)
- imm.log(" o Scanning Entrypoint ..")
- imm.setStatusBar("Scanning Entrypoint ..")
- else:
- imm.log(" o %d sigs to scan in hardcore mode .." % sig_db.signature_count_eponly_false)
- imm.log(" o Scanning whole file ..")
- imm.setStatusBar("Scanning whole file .. This may take a few minutes, so go make a coffee ..")
- imm.log(" ")
- # Force update now or user will not know any info until scan finished ..
- # Which can take minutes for a large file scanned with -a option ..
- imm.updateLog()
- # Do the scan, EP only or hardcore mode ..
- ret = sig_db.match( pe, EP_Only == 1 )
- # Display results of scan ..
- imm.log("Result:")
- if not ret:
- imm.log(" Nothing found ..")
- imm.log(" ")
- return "Nothing found .."
- if EP_Only == 1:
- # If EP detection then result is a string and we know EP address ..
- va = pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.AddressOfEntryPoint
- addr = pe.get_offset_from_rva(pe.OPTIONAL_HEADER.AddressOfEntryPoint)
- imm.log(" Found \"%s\" at offset 0x%08X %s" % (ret[0], addr, getSectionInfo(pe, va)), address = va)
- imm.log(" ")
- return "Found \"%s\" at 0x%08X .." % (ret[0], va)
- else:
- # If more than 1 returned detection, then display all possibilities ..
- if len(ret) > 1:
- a = 1
- for (addr, name) in ret:
- va = pe.OPTIONAL_HEADER.ImageBase + rawToRva(pe, addr)
- imm.log(' %02d : \"%s\" at offset 0x%08X %s' % (a, name[0], addr, getSectionInfo(pe, va)), address = va)
- a += 1
- imm.log(" ")
- return "Found %d possible matches .." % len(ret)
- else:
- # If only 1 detection then display result ..
- for (addr, name) in ret:
- va = pe.OPTIONAL_HEADER.ImageBase + rawToRva(pe, addr)
- imm.log(' Found \"%s\" at offset 0x%08X %s' % (name[0], addr, getSectionInfo(pe, va)), address = va)
- imm.log(" ")
- return "Found \"%s\" at 0x%08X .." % (name[0], va)
- """
- Immunity Debugger Regexp Search
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- search.py - simple script that lets you quickie search for regexp
- """
- __VERSION__ = '1.1'
- import immlib
- # TODO: -a <ASM> -m <modname>, search all on no -m
- # TODO: migrate/replace searchcode.py
- DESC = "Search for given assembly code"
- def usage(imm):
- imm.log("!search <ASM>")
- imm.log("For example: !search pop r32\\npop r32\\nret")
- def main(args):
- if not args:
- return "Usage: !search <ASM>"
- imm = immlib.Debugger()
- code = " ".join(args).replace("\\n","\n")
- ret = imm.searchCommands(code.upper())
- for a in ret:
- result=imm.disasm(a[0])
- imm.log("Found %s at 0x%X (%s)"% (result.result, a[0], a[2]), address=a[0], focus=1)
- return "Search completed!"
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- __VERSION__ = '1.0'
- import immlib
- DESC = "Search code in memory"
- def usage(imm):
- imm.log("!searchcode Search code in memory")
- imm.log("!searchcode <asm code>")
- def main(args):
- imm = immlib.Debugger()
- look = " ".join(args)
- ret = imm.search( imm.assemble( look ) )
- for a in ret:
- module = imm.findModule(a)
- if not module:
- module = "none"
- else:
- module = module[0]
- # Grab the memory access type for this address
- page = imm.getMemoryPageByAddress( a )
- access = page.getAccess( human = True )
- imm.log("Found %s at 0x%08x [%s] Access: (%s)" % (look, a, module, access), address = a)
- if ret:
- return "Found %d address (Check the Log Windows for details)" % len(ret)
- else:
- return "Sorry, no code found"
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- Search a defined memory range looking for cryptographic routines
- """
- __VERSION__ = '1.0'
- import immlib
- import getopt
- from immutils import *
- DESC = "Search a defined memory range looking for cryptographic routines"
- def usage(imm):
- imm.log("!searchcrypt [-a FROMADDRESS] [-t TOADDRESS] [-o OWNER]", focus=1)
- imm.log(" FROMADDRESS start address")
- imm.log(" TOADDRESS end address")
- imm.log(" OWNER memory page owner")
- imm.log("ex: !searchcrypt -a 0x70000000")
- def main(args):
- imm = immlib.Debugger()
- try:
- opts, notused = getopt.getopt(args, "a:t:o:")
- except getopt.GetoptError:
- usage(imm)
- return "Wrong Arguments (Check usage on the Log Window)"
- fromaddy = toaddy = owner = None
- for o,a in opts:
- if o == '-a':
- try:
- fromaddy = int( a, 16 )
- except ValueError:
- usage(imm)
- return "Wrong Address (%s) % " % a
- if o == '-t':
- try:
- toaddy = int( a, 16 )
- except ValueError:
- usage(imm)
- return "Wrong Address (%s) % " % a
- if o == '-o':
- owner = a
- if isinstance(toaddy, int) and isinstance(fromaddy, int) and toaddy <= fromaddy:
- usage(imm)
- return "end address can't be less than start address"
- result = []
- #the first dword has to be unique in the complete dictionary to get an accurate address
- consts = {
- "AES": [ 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5 ], \
- "BLOWFISH": [ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b ], \
- "CAMELLIA": [ 0xA09E667F, 0x3BCC908B, 0xB67AE858, 0x4CAA73B2, 0xC6EF372F, 0xE94F82BE, 0x54FF53A5, 0xF1D36F1C, 0x10E527FA, 0xDE682D1D, 0xB05688C2, 0xB3E6C1FD ], \
- "CAST": [ 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779 ], \
- "MD5": [ 0xd76aa478, 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ], \
- "RC2": [ 0xc4f978d9, 0xedb5dd19, 0x79fde928, 0x9dd8a04a, 0x83377ec6, 0x8e53762b, 0x88644c62, 0xa2fb8b44, 0xf5599a17, 0x134fb387, 0x8d6d4561, 0x327d8109, 0xeb408fbd, 0x0b7bb786, 0x222195f0, 0x824e6b5c, 0x9365d654, 0x1cb260ce, 0x14c05673, 0xdcf18ca7, 0x1fca7512, 0xd1e4be3b, 0x30d43d42, 0x26b63ca3, 0xda0ebf6f, 0x57076946, 0x9b1df227, 0x034394bc, 0xf6c711f8, 0xe73eef90, 0x2fd5c306, 0xd71e66c8, 0xdeeae808, 0xf7ee5280, 0xac72aa84, 0x2a6a4d35, 0x71d21a96, 0x7449155a, 0x5ed09f4b, 0xeca41804, 0x6e41e0c2, 0xcccb510f, 0x50af9124, 0x3970f4a1, 0x853a7c99, 0x7ab4b823, 0x5b3602fc, 0x31975525, 0x98fa5d2d, 0xae928ae3, 0x1029df05, 0xc9ba6c67, 0xcfe600d3, 0x2ca89ee1, 0x3f011663, 0xa989e258, 0x1b34380d, 0xb0ff33ab, 0x5f0c48bb, 0x2ecdb1b9, 0x47dbf3c5, 0x779ca5e5, 0x6820a60a, 0xadc17ffe ], \
- "RC5": [ 0xb7e15163, 0x9e3779b9 ], \
- "RIPEMD160": [ 0x50A28BE6, 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0, 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9 ], \
- "SHA1": [ 0xCA62C1D6, 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC ], \
- "SHA256": [ 0xc67178f2, 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7 ], \
- "SHA512": [ 0xf3bcc908, 0x6a09e667, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1, 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179, 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483 ] \
- }
- result = MultiSearch(imm, consts, fromaddy, toaddy, owner)
- for name,addy in result:
- mem = imm.getMemoryPageByAddress(addy)
- imm.log("Const Found: %10s Owner: %s - Section: %s" % ( name, mem.getOwner(), \
- mem.getSection() ), addy )
- return "search finished"
- def MultiSearch(imm, consts, fromaddy, toaddy, arg_owner):
- if not consts:
- return []
- found = []
- hits = {}
- addys = {}
- for a in imm.getMemoryPages().keys():
- if isinstance(fromaddy, int) and a < fromaddy:
- continue
- if isinstance(toaddy, int) and a > toaddy:
- continue
- owner = imm.MemoryPages[a].getOwner()
- if isinstance(arg_owner, str) and owner.upper() != arg_owner.upper():
- continue
- mem = imm.MemoryPages[a].getMemory()
- if not mem:
- continue
- for name,consts_list in consts.iteritems():
- if not isinstance(consts_list,list):
- consts_list = [ consts_list ]
- count = 0
- for const in consts_list:
- const = int2str32_swapped(const)
- f = mem.find ( const )
- if f == -1:
- continue
- #check if it's outside the scope of my search
- if isinstance(toaddy, int) and (f + a) > toaddy:
- break
- #we save the hits by owner
- try:
- hits[name][owner] += 1
- except KeyError:
- if not hits.has_key(name):
- hits[name] = {}
- hits[name][owner] = 1
- #get the address of the first hit
- if not addys.has_key(name):
- addys[name] = {}
- if not addys[name].has_key(owner):
- addys[name][owner] = f + a
- # it has to match every const to get a real match
- for name,consts_list in consts.iteritems():
- if hits.has_key(name):
- for owner,count in hits[name].iteritems():
- if count >= len(consts_list):
- found.append( [name, addys[name][owner] ] )
- return found
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- __VERSION__ = '1.0'
- import immlib
- import getopt
- from libheap import *
- DESC = "Search the heap for specific chunks"
- def usage(imm):
- imm.log("!searchheap Search the heap for specific chunks")
- imm.log("!searchheap [-h HEAP_ADDR] [-s] [-r] [-f] [-c]")
- imm.log(" -h HEAPADDR Set the heap address to inspect")
- imm.log(" -w what What to search for: size, prevsize, flags, address, next, prev")
- imm.log(" -a action Search action: =, !=, >, <, >=, <=, &, not")
- imm.log(" -v value Value to be searched")
- imm.log(" -k Show the content of the chunk")
- imm.log(" -r Use the restored heap (see !heap for more details)")
- def main(args):
- imm = immlib.Debugger()
- imm.log("### Immunity's Search Heap ###")
- try:
- opts, argo = getopt.getopt(args, "h:w:a:v:rk", ["heap=", "what=", "action=", "value="])
- except getopt.GetoptError:
- imm.setStatusBar("Bad heap argument %s" % args[0])
- usage(imm)
- return 0
- heap = 0x0
- what = None
- action = None
- value = None
- restore = False
- chunkdisplay = 0
- for o,a in opts:
- if o == "-h":
- try:
- heap = int(a, 16)
- except ValueError, msg:
- imm.InfoLine("Invalid heap address: %s" % a)
- return 0
- elif o == "-r":
- restore = True
- elif o == "-k":
- chunkdisplay = SHOWCHUNK_FULL
- elif o in ("-w", "--what"):
- what = a
- elif o in ("-a", "--action"):
- action = a
- elif o in ("-v", "--value"):
- try:
- value = int(a, 16)
- except ValueError, msg:
- return "Invalid value: %s" % a
- return 0
- if not heap or ( heap in imm.getHeapsAddress() ):
- s = SearchHeap(imm, what, action, value, heap = heap, restore = restore, option = chunkdisplay)
- if heap:
- return "Heap 0x%x dumped" % heap
- else:
- return "Heap dumped"
- return "Wrong Heap"# -*- coding: utf-8 -*-
- from immlib import *
- import getopt
- def main(args):
- """
- Script to search all occurences of a string in memory and
- display them on a table. Useful (for me) to visualize heap
- layout created by heap spray.
- !searchspray -h fe ca fe ca 11 11 11 11
- !searchspray -s I am evil homer
- """
- imm = Debugger()
- try:
- opts, argo = getopt.getopt(args, "s:h:", ["string", "hex"])
- except getopt.GetoptError, err:
- usage(dbg)
- return str(err)
- opt = " ".join(args[1:]).strip('"')
- if args[0] == "-s":
- string = opt
- elif args[0] == "-h":
- string = "".join(["%c" % int(i, 16) for i in opt.split()])
- log = imm.createTable("Heap Spray", ["#", "Adddress", "What?"])
- i = 0
- for a in imm.search(string):
- i += 1
- log.add(a, [str(i), str(hex(a)), " ".join(["%x" %ord(j) for j in string])])
- return "Logging to Heap Spray Window"
- import socket
- import struct
- from immlib import *
- DESC="""Creates a table that displays packets received on the network."""
- #############################################################################
- '''
- Some defines for re-use.
- '''
- PACKET_TYPE_SEND = "Send "
- PACKET_TYPE_RECV = "Recv "
- PACKET_PROTOCOL_UDP = "(UDP)"
- PACKET_PROTOCOL_TCP = "(TCP)"
- #############################################################################
- class simple_hooks(LogBpHook):
- #########################################################################
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- imm = Debugger()
- (payload_ptr,type,function_name) = imm.getKnowledge("%08x" % regs['EIP'])
- # The length is stored as a function return argument, so let's read EAX
- length = regs['EAX']
- # Because return codes can be -1 (error) we have to test for that.
- if length > 1 and length != 0xffffffff:
- counter = 0
- payload = ""
- bin_payload = ""
- # Get the raw packet payload and the length of the bytes
- raw_payload = imm.readMemory(payload_ptr,length)
- pack_len = str(length)+"c"
- imm.log("Pack Len: %s " % pack_len)
- if raw_payload is not None:
- final_payload = struct.unpack(pack_len,raw_payload)
- # Iterate through the unpacked string, only outputting printable
- # ascii characters, output the standard dots if non-printable
- while counter < int(length):
- if ord(final_payload[counter]) >= 32 and ord(final_payload[counter]) <= 126:
- payload += final_payload[counter]
- else:
- payload += "."
- bin_payload += "%02x" % ord(final_payload[counter])
- counter += 1
- # Build the list thats table-friendly
- log_items = [function_name,type,"%d" % int(length),bin_payload[:512],payload[:512]]
- # Get a handle to the window and add the items, along with the related
- # address, this is sweet cause you can double-click on a packet and
- # see in the disassembly where it was sent/received :)
- cap_win = imm.getKnowledge("cap_win")
- cap_win.add(regs['EIP'],log_items)
- # Drop the entry in the KB, disable the BP, and unHook.
- imm.forgetKnowledge("%08x" % regs['EIP'])
- imm.disableBreakpoint(regs['EIP'])
- self.UnHook()
- #############################################################################
- class ext_hooks(LogBpHook):
- #########################################################################
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- imm = Debugger()
- (payload_ptr,recv_ptr,type,function_name) = imm.getKnowledge("%08x" % regs['EIP'])
- # This is an [out] pointer that let's us know how much data was
- # received on a socket (non-overlapped)
- length = imm.readMemory(recv_ptr,4)
- length = struct.unpack("l",length)
- # Network apps are chatty, we don't want to grab garbage packets
- if length[0] > 1:
- counter = 0
- payload = ""
- bin_payload = ""
- # Get the raw packet payload and the length of the bytes
- raw_payload = imm.readMemory(payload_ptr,int(length[0]))
- pack_len = str(int(length[0]))+"c"
- if raw_payload is not None:
- final_payload = struct.unpack(pack_len,raw_payload)
- # Iterate through the unpacked string, only outputting printable
- # ascii characters, output the standard dots if non-printable
- while counter < int(length[0]):
- if ord(final_payload[counter]) >= 32 and ord(final_payload[counter]) <= 126:
- payload += final_payload[counter]
- else:
- payload += "."
- bin_payload += "%02x" % ord(final_payload[counter])
- counter += 1
- # Build the list thats table-friendly
- log_items = [function_name,type,"%d" % int(length[0]),bin_payload[:512],payload[:512]]
- # Get a handle to the window and add the items, along with the related
- # address, this is sweet cause you can double-click on a packet and
- # see in the disassembly where it was sent/received :)
- cap_win = imm.getKnowledge("cap_win")
- cap_win.add(regs['EIP'],log_items)
- # Drop the entry in the KB, disable the BP, and unHook.
- imm.forgetKnowledge("%08x" % regs['EIP'])
- imm.disableBreakpoint(regs['EIP'])
- self.UnHook()
- #############################################################################
- class set_hooks(LogBpHook):
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- '''
- This routine is the first one hit, when a socket operation occurs.
- '''
- imm = Debugger()
- # Retrieve the function name
- function_name = imm.getKnowledge("%08x" % regs['EIP'])
- #self.retrieve_packet(imm,function_name,regs)
- self.display_mem_reg(imm,function_name,regs)
- #########################################################################
- def display_mem_reg(self,imm,function_name,regs):
- '''
- display info in log
- '''
- #Figure out [esp]
- #esp_ptr = imm.readMemory(regs['ESP'],4)
- #esp_ptr = struct.unpack("<L", esp_ptr)
- imm.log("%s" % function_name)
- imm.log("[ESP] @ 0x%08x" % regs['ESP'])
- imm.log("[EIP] @ 0x%08x" % regs['EIP'])
- imm.log("[EAX] @ 0x%08x" % regs['EAX'])
- ## #########################################################################
- ## def retrieve_packet(self,imm,function_name,regs):
- ## '''
- ## This function determines how to handle the packet data. Some socket
- ## operations require more work (such as WSARecv), and others less (recv).
- ##
- ## If necessary this function will register a hook on [ESP], where any
- ## [out] pointers from a function will be set.
- ## '''
- ##
- ## # Determine what function we have hooked, based on this, retrieve the packet contents
- ## if function_name == "WSARecv":
- ## type = PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- ## extended_hook = True
- ##
- ## if function_name == "WSASend":
- ## type=PACKET_TYPE_SEND+PACKET_PROTOCOL_TCP
- ## extended_hook = True
- ##
- ## if function_name == "recvfrom":
- ## type=PACKET_TYPE_RECV+PACKET_PROTOCOL_UDP
- ## extended_hook = False
- ##
- ## if function_name =="recv":
- ## type=PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- ## extended_hook = False
- ##
- ## # An extended hook requires a bit more work to pull out the packet info
- ## if extended_hook == True:
- ##
- ## # Get the pointer to the payload pointer :(
- ## pbuffer_ptr = imm.readMemory( regs['ESP'] + 8, 4)
- ## pbuffer_ptr = struct.unpack("L", pbuffer_ptr)
- ## #imm.log("Buffer Location: 0x%08x" % pbuffer_ptr[0])
- ##
- ## # Get the pointer to the packet payload
- ## payload_ptr = imm.readMemory(pbuffer_ptr[0]+4,4)
- ## payload_ptr = struct.unpack("<L", payload_ptr)
- ## #imm.log("Payload Pointer: %08x" % payload_ptr[0])
- ##
- ## # Get the [out] pointer of the received bytes
- ## recv_ptr = imm.readMemory(regs['ESP'] + 0x10, 4)
- ## recv_ptr = struct.unpack("L",recv_ptr)
- ## #imm.log("Receive Pointer: %08x" % recv_ptr[0])
- ##
- ## # Figure out [esp]
- ## esp_ptr = imm.readMemory(regs['ESP'],4)
- ## esp_ptr = struct.unpack("<L", esp_ptr)
- ## #imm.log("[ESP] at 0x%08x" % esp_ptr[0])
- ##
- ## # Now we hook [esp]
- ## ret_hook = ext_hooks()
- ## ret_hook.add("%08x" % esp_ptr[0],esp_ptr[0])
- ##
- ## # Add this ret hook to the knowledgebase
- ## imm.addKnowledge("%08x" % esp_ptr[0],(payload_ptr[0],recv_ptr[0],type,function_name))
- ##
- ## else:
- ##
- ## # Get the pointer to the buffer
- ## payload_ptr = imm.readMemory(regs['ESP'] + 8, 4)
- ## payload_ptr = struct.unpack("L", payload_ptr)
- ##
- ## # Figure out where [ESP] points to
- ## esp_ptr = imm.readMemory(regs['ESP'],4)
- ## esp_ptr = struct.unpack("<L", esp_ptr)
- ##
- ## # Add the [ESP] hook for when the function returns
- ## simple_hook = simple_hooks()
- ## simple_hook.add("%08x" % esp_ptr[0],esp_ptr[0])
- ##
- ## # Add our pertinent information to the knowledgebase
- ## imm.addKnowledge("%08x" % esp_ptr[0],(payload_ptr[0],type,function_name))
- # The main routine that gets run when you type !packets
- def main(args):
- imm = Debugger()
- imm.ignoreSingleStep("CONTINUE")
- hooker = set_hooks()
- # Find the addresses of the functions we want to hook
- # Then register the hooks
- ws_send = imm.getAddress("ws2_32.send")
- ws_sendto = imm.getAddress("ws2_32.sendto")
- ws_wsarecv = imm.getAddress("ws2_32.WSARecv")
- ws_wsasend = imm.getAddress("ws2_32.WSASend")
- ws_recv = imm.getAddress("ws2_32.recv")
- ws_recvfrom = imm.getAddress("ws2_32.recvfrom")
- # Set the hooks
- hooker.add("send", ws_send)
- hooker.add("sendto", ws_sendto)
- hooker.add("WSARecv", ws_wsarecv)
- hooker.add("WSASend", ws_wsasend)
- hooker.add("recv", ws_recv)
- hooker.add("recvfrom", ws_recvfrom)
- # Register the hook-address pair with the knowledgebase
- imm.addKnowledge("%08x" % ws_wsarecv, "WSARecv")
- imm.addKnowledge("%08x" % ws_wsasend, "WSASend")
- imm.addKnowledge("%08x" % ws_recv, "recv")
- imm.addKnowledge("%08x" % ws_recvfrom, "recvfrom")
- return "Network hooks in place."
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2008
- U{Immunity Inc.<http://www.immunityinc.com>}
- Shellcode diff
- """
- DESC="""Check for badchars"""
- from immlib import *
- import sys
- NAME = "shellcodediff"
- USAGE = "address"
- def main(args):
- imm = Debugger()
- if len(args) != 1:
- imm.log("Usage: !" + NAME + " " + USAGE)
- return "See log window for usage info"
- address = 0
- length = 0
- bad_byte_offset = 0
- mangled = False
- address = int(args[0],16)
- fd = open("shellcode.txt","r")
- canvas_byte_list = fd.readlines()
- fd.close()
- canvas_shellcode = ""
- # Just pretty this up
- for i in canvas_byte_list:
- canvas_shellcode += i.rstrip("\x0a")
- length = len(canvas_shellcode) / 2
- id_shellcode = imm.readMemory( address, length )
- id_shellcode = id_shellcode.encode("HEX")
- imm.log("Address: 0x%08x" % address)
- imm.log("SC Len : %d" % length)
- imm.log("CANVAS Shellcode: %s" % canvas_shellcode[:512])
- imm.log("ID Shellcode: %s" % id_shellcode[:512])
- count = 0
- # We use the CANVAS shellcode length here again cause
- # presumably its not mangled
- while count <= (length*2):
- if id_shellcode[count] != canvas_shellcode[count]:
- imm.log("Missed at byte: %d" % count)
- bad_byte_offset = count
- mangled = True
- break
- count += 1
- if mangled:
- imm.log(" ")
- imm.log("Bad byte is centered in output with three leading and three trailing bytes.")
- imm.log(" ")
- imm.log("Bad byte at offset: %d" % bad_byte_offset)
- imm.log("Bad byte value from attacker: %s" % canvas_shellcode[bad_byte_offset:bad_byte_offset+2])
- imm.log("====================\n\n")
- imm.log("CANVAS: %s %s %s" % (canvas_shellcode[bad_byte_offset-6:bad_byte_offset],canvas_shellcode[bad_byte_offset:bad_byte_offset+2],canvas_shellcode[bad_byte_offset+2:bad_byte_offset+6]))
- imm.log("ID : %s %s %s" % (id_shellcode[bad_byte_offset-6:bad_byte_offset], id_shellcode[bad_byte_offset:bad_byte_offset+2],id_shellcode[bad_byte_offset+2:bad_byte_offset+6]))
- imm.log("\n\n====================")
- return "Shellcode diff output to log window."
- #/usr/bin/env python
- import getopt
- import xmlrpclib
- import traceback
- import struct
- import debugger #needed on old ID for removeHook
- from immlib import *
- LICENSE="BSD 3-clause non-attribution" #yay!
- copyright="(C) Immunity, Inc., jms@bughunter.ca"
- """
- This script supports the SQLOLEDB method of executing queries and, when
- combined with sql_listener.py will send you all the queries executed by a web
- application. Server-side filtering (necessary to avoid sending thousands of
- queries a second to you on a busy server) is stubbed in for later. We hooked
- IIS rather than SQL Server because common practice is to have your SQL tier
- un-routable, but the web tier is likely to have Internet access.
- Somewhat later we'll have this integrate into SPIKE Proxy and other tools to
- automate detection of blind-sql attacks/detection and sql injection in
- general.
- In order to use this script:
- 1. Run a few queries against your target server, this will start up two
- dllhost.exe's
- 2. Load Immunity Debugger and attach to the second dllhost.exe (this can be
- slightly tricky if the PID for the second one is lower than the first, but
- eventually we'll automate it)
- 3. run !sqlhooker -s myhostip:myport. For example, I use !sqlhooker
- 192.168.1.1:8081, and then on my .1 machine I run "python sql_listener.py
- 8081".
- Here's an example snippet of ASP script this would work against:
- _start cut_
- set conn = server.createObject("ADODB.Connection")
- set rs = server.createObject("ADODB.Recordset")
- query = "select count(*) from users where userName='" & userName & "' and userPass='" & password & "'"
- conn.Open "Provider=SQLOLEDB; Data Source=(local); Initial Catalog=myDB; User Id=sa; Password="
- rs.activeConnection = conn
- rs.open query
- _end cut_
- We currently support:
- WinXPPro Sp2, IIS 5.0 SQLServer 2000
- Win2K3, IIS 6.0, SQLServer 2000
- Win2K, IIS 5.0, SQLServer 2000
- Win2K Old,IIS 5.0, SQLServer 2000
- If anyone has requests for other database systems, they should email us, along
- with the necessary information to get an application running, and we will
- spend the time to find you hook spots. Or just submit a patch to
- forum.immunityinc.com.
- """
- class ole_hooker(LogBpHook):
- def __init__(self,hook_version,xmlhost=None,xmlport=0):
- LogBpHook.__init__(self)
- self.imm = Debugger()
- self.hook_version = hook_version
- self.xmlhost = xmlhost
- self.xmlport = int(xmlport)
- def run(self,regs):
- '''
- Called everytime the SQL hook is hit.
- '''
- self.imm.log("Hook version: %s" % self.hook_version)
- if self.hook_version == "winxp_pro_sp2" or self.hook_version == "win2k3":
- sql_addr = regs['EDI']
- if self.hook_version == "win2k":
- sql_addr = regs['ESI']
- if self.hook_version == "win2k_old":
- buffer_ptr = self.imm.readMemory(regs['ESP'] + 4, 4)
- buffer_ptr = struct.unpack("L", buffer_ptr)
- sql_addr = buffer_ptr[0]
- sql_query = self.imm.readWString(sql_addr)
- sql_query = sql_query.replace("\x00","")
- self.imm.log("SQL Query: %s" % sql_query)
- using_xml_rpc = False
- if self.xmlport != 0:
- server = xmlrpclib.ServerProxy("http://%s:%d/"%(self.xmlhost,self.xmlport), allow_none=True)
- self.imm.log("Using server: %s:%d"%(self.xmlhost, self.xmlport))
- using_xml_rpc = True
- else:
- server = None
- if using_xml_rpc:
- #send our xml request to the remove side
- #if self.filter matches...(stub for now)
- try:
- result = server.sendsql(("sqlquery",[sql_query]))
- except:
- data=traceback.format_exc()
- self.imm.log("Failed to connect to remote server, sorry")
- self.imm.logLines("Error was: %s"%data)
- return
- #Now parse what we got back - a command and list of arguments
- command, arguments = result
- if command=="NEWFILTER":
- #stub
- self.filter=arguments[0]
- elif command=="UNHOOK":
- #stub
- self.imm.log("Unhook called")
- #etc
- return
- def usage(imm):
- imm.log("!sqlhooker.py")
- imm.log("-u (to uninstall hook)")
- imm.log("-s host:port (Server to send XML-RPC data to)")
- def main(args):
- imm = Debugger()
- xmlhost = None
- xmlport = 0
- sql_oledb = imm.getModule("sqloledb.dll")
- if not sql_oledb.isAnalysed():
- imm.analyseCode(sql_oledb.getCodebase())
- try:
- opts,argo = getopt.getopt(args, "ius:")
- except:
- return usage(imm)
- for o,a in opts:
- if o == "-u":
- if hasattr(imm, "removeHook"):
- imm.removeHook("query")
- elif hasattr(debugger, "remove_hook"):
- debugger.remove_hook("query")
- else:
- imm.log("Could not remove hook - no remove hook function found!")
- return "Removed hook on SQL function."
- if o == "-s":
- xmlhost,xmlport = a.split(":")
- # Various versions, we need to match on
- winxp_pro_sp2 = "2000.085.1117.00 (xpsp_sp2_rtm."
- win2k3 = "2000.086.3959.00 (srv03_sp2_rtm"
- win2k = "2000.081.9031.018"
- win2k_old = "2000.080.0194"
- version = sql_oledb.getVersion()
- sql_base = sql_oledb.getBaseAddress()
- if version == winxp_pro_sp2:
- offset = 0xF6F5
- hook_version = "winxp_pro_sp2"
- if version == win2k3:
- offset = 0x6522
- hook_version = "win2k3"
- if version == win2k:
- offset = 0xFA2D
- hook_version = "win2k"
- if version == win2k_old:
- offset = 0x4034
- hook_version = "win2k_old"
- bp_address = sql_base + offset
- # Set a hook
- hooker = ole_hooker(hook_version,xmlhost,xmlport)
- hooker.add("query",bp_address)
- return "SQL Hooks in Place. Ready for Test Cases."
- import socket
- import struct
- from immlib import *
- DESC="""packets received on the network."""
- #############################################################################
- '''
- Some defines for re-use.
- '''
- PACKET_TYPE_SEND = "Send "
- PACKET_TYPE_RECV = "Recv "
- PACKET_PROTOCOL_UDP = "(UDP)"
- PACKET_PROTOCOL_TCP = "(TCP)"
- #############################################################################
- class simple_hooks(LogBpHook):
- #########################################################################
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- imm = Debugger()
- # The length is stored as a function return argument, so let's read EAX
- length = regs['EAX']
- imm.log("fff %d" % length)
- # imm.disableBreakpoint(regs['EIP'])
- # self.UnHook()
- #############################################################################
- class ext_hooks(LogBpHook):
- #########################################################################
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- imm = Debugger()
- imm.log("ext_hookdebugger")
- #############################################################################
- class set_hooks(LogBpHook):
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- '''
- This routine is the first one hit, when a socket operation occurs.
- '''
- imm = Debugger()
- imm.log("set")
- self.display_mem_reg(imm,regs)
- #########################################################################
- def display_mem_reg(self,imm,regs):
- '''
- display info in log
- '''
- #Figure out [esp]
- #esp_ptr = imm.readMemory(regs['ESP'],4)
- #esp_ptr = struct.unpack("<L", esp_ptr)
- #imm.log("%s" % function_name)
- imm.log("[ESP] @ 0x%08x" % regs['ESP'])
- imm.log("[EIP] @ 0x%08x" % regs['EIP'])
- imm.log("[EAX] @ 0x%08x" % regs['EAX'])
- # The main routine that gets run when you type !packets
- def main(args):
- imm = Debugger()
- imm.ignoreSingleStep("CONTINUE")
- hooker = set_hooks()
- # Find the addresses of the functions we want to hook
- # Then register the hooks
- ws_send = imm.getAddress("ws2_32.send")
- ws_sendto = imm.getAddress("ws2_32.sendto")
- ws_wsarecv = imm.getAddress("ws2_32.WSARecv")
- ws_wsasend = imm.getAddress("ws2_32.WSASend")
- ws_recv = imm.getAddress("ws2_32.recv")
- ws_recvfrom = imm.getAddress("ws2_32.recvfrom")
- # Set the hooks
- hooker.add("send", ws_send)
- hooker.add("sendto", ws_sendto)
- hooker.add("WSARecv", ws_wsarecv)
- hooker.add("WSASend", ws_wsasend)
- hooker.add("recv", ws_recv)
- hooker.add("recvfrom", ws_recvfrom)
- # Register the hook-address pair with the knowledgebase
- # imm.addKnowledge("%08x" % ws_wsarecv, "WSARecv")
- # imm.addKnowledge("%08x" % ws_wsasend, "WSASend")
- # imm.addKnowledge("%08x" % ws_recv, "recv")
- # imm.addKnowledge("%08x" % ws_recvfrom, "recvfrom")
- return "i hooks in place."
- #!/usr/bin/env python
- """
- Immunity Debugger stackvars
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>} Debugger API for python
- stackvars.py - set comments around the code to follow stack variables size and content.
- """
- __VERSION__ = "1.2"
- import immlib
- import immutils
- import getopt
- from libstackanalyze import *
- DESC="Set comments around the code to follow stack variables size and content"
- def usage(imm):
- imm.log("!stackvars address_or_expresion [steps_to_decode]")
- imm.log("%s" % DESC)
- imm.log("Note: each step represent one call further from the base function")
- def main(args):
- imm = immlib.Debugger()
- if not args:
- imm.log("you must define the address of the function to analyze")
- usage(imm)
- return "not enough args"
- address = imm.getAddress(args[0])
- if address < 0:
- imm.log("invalid address or expresion")
- usage(imm)
- return "address error!"
- if len(args) > 1:
- steps_after = int(args[1])
- else:
- steps_after = 1
- imm.log("################# Immunity's StackVars ################")
- imm.log("Analyzing function %08X - %s..." % (address, imm.decodeAddress(address)))
- flow = FlowAnalyzer(imm, address, steps_after)
- Calls,varsHits,argsHits,varsSize = flow.getFlowInformation()
- imm.log("----------- code flow -------------")
- for start,data in Calls.iteritems():
- imm.log("function: %s" % imm.decodeAddress(start))
- for k,v in data.iteritems():
- imm.log("from: %s - to: %s - argc: %d - args:" % \
- (imm.decodeAddress(k), imm.decodeAddress(v[0]), len(v[1])))
- for kk,vv in v[1].iteritems():
- imm.log("arg %d - data: %s" % (kk,str(vv)))
- imm.setComment(vv['addy'], flow.argInfo(start,k,kk))
- #paint args
- for start,data in argsHits.iteritems():
- for const in data:
- for hit in data[const]:
- imm.setComment(hit, "using arg[%d] of function: %s" % ((const-4)/4, imm.decodeAddress(start)))
- #paint vars
- for start,data in varsHits.iteritems():
- for const in data:
- try:
- size = varsSize[start][const]
- except KeyError:
- imm.log("local var size not found: addr: %08X, value: %d" % (start,const))
- size = "unknown"
- for hit in data[const]:
- imm.setComment(hit, "Local Var: %X - size: %s" % (const, size))
- imm.log("functionBegin: %08X" % flow.getFunctionBegin())
- imm.log("-------- size of variables --------")
- for start,data in varsSize.iteritems():
- imm.log("function: %s" % imm.decodeAddress(start))
- for const,size in data.iteritems():
- imm.log("lvar %X: %d" % (const,size))
- return "Done! see the log for details"
- # (c) Immunity Inc.
- # This is a port of Ero Carrera's script that he wrote for
- # IDAPython. This is the same deal, however it can be easily
- # expanded to track hits to these calls. The beauty of a debugger.
- #
- # http://www.openrce.org/blog/view/1077/Digging_up_system_call_ordinals
- #
- import getopt
- from immlib import *
- syscall_table = {'2003':
- {'0x0103': 'NtSignalAndWaitForSingleObject',
- '0x009e': 'NtQueryInformationFile',
- '0x0079': 'NtOpenEventPair',
- '0x0078': 'NtOpenEvent',
- '0x00c9': 'NtReplaceKey',
- '0x0073': 'NtModifyDriverEntry',
- '0x0072': 'NtModifyBootEntry',
- '0x0071': 'NtMapViewOfSection',
- '0x0070': 'NtMapUserPhysicalPagesScatter',
- '0x0077': 'NtOpenDirectoryObject',
- '0x0076': 'NtNotifyChangeMultipleKeys',
- '0x0075': 'NtNotifyChangeKey',
- '0x0074': 'NtNotifyChangeDirectoryFile',
- '0x008f': 'NtProtectVirtualMemory',
- '0x00db': 'NtSetBootEntryOrder',
- '0x008d': 'NtPrivilegeObjectAuditAlarm',
- '0x008e': 'NtPrivilegedServiceAuditAlarm',
- '0x008b': 'NtPowerInformation',
- '0x008c': 'NtPrivilegeCheck',
- '0x008a': 'NtPlugPlayControl',
- '0x00ba': 'NtQueryVirtualMemory',
- '0x00bb': 'NtQueryVolumeInformationFile',
- '0x00bc': 'NtQueueApcThread',
- '0x00bd': 'NtRaiseException',
- '0x00be': 'NtRaiseHardError',
- '0x00bf': 'NtReadFile',
- '0x00da': 'NtSecureConnectPort',
- '0x00a9': 'NtQueryMutant',
- '0x00a8': 'NtQueryMultipleValueKey',
- '0x000f': 'NtAllocateLocallyUniqueId',
- '0x00a4': 'NtQueryInstallUILanguage',
- '0x000d': 'NtAlertResumeThread',
- '0x000e': 'NtAlertThread',
- '0x000b': 'NtAdjustGroupsToken',
- '0x000c': 'NtAdjustPrivilegesToken',
- '0x00a3': 'NtQueryInformationToken',
- '0x000a': 'NtAddDriverEntry',
- '0x00df': 'NtSetDefaultHardErrorPort',
- '0x00dd': 'NtSetContextThread',
- '0x007c': 'NtOpenJobObject',
- '0x007b': 'NtOpenIoCompletion',
- '0x007a': 'NtOpenFile',
- '0x00de': 'NtSetDebugFilterState',
- '0x007f': 'NtOpenObjectAuditAlarm',
- '0x007e': 'NtOpenMutant',
- '0x007d': 'NtOpenKey',
- '0x010f': 'NtUnloadDriver',
- '0x00c3': 'NtRegisterThreadTerminatePort',
- '0x0120': 'NtYieldExecution',
- '0x00f9': 'NtSetSystemInformation',
- '0x0008': 'NtAddAtom',
- '0x0009': 'NtAddBootEntry',
- '0x0006': 'NtAccessCheckByTypeResultListAndAuditAlarm',
- '0x0007': 'NtAccessCheckByTypeResultListAndAuditAlarmByHandle',
- '0x0004': 'NtAccessCheckByTypeAndAuditAlarm',
- '0x0005': 'NtAccessCheckByTypeResultList',
- '0x0002': 'NtAccessCheckAndAuditAlarm',
- '0x0003': 'NtAccessCheckByType',
- '0x0000': 'NtAcceptConnectPort',
- '0x0001': 'NtAccessCheck',
- '0x0086': 'NtOpenThread',
- '0x0087': 'NtOpenThreadToken',
- '0x0084': 'NtOpenSemaphore',
- '0x0085': 'NtOpenSymbolicLinkObject',
- '0x0082': 'NtOpenProcessTokenEx',
- '0x0083': 'NtOpenSection',
- '0x0080': 'NtOpenProcess',
- '0x0081': 'NtOpenProcessToken',
- '0x00b0': 'NtQuerySecurityObject',
- '0x00b1': 'NtQuerySemaphore',
- '0x00b2': 'NtQuerySymbolicLinkObject',
- '0x00b3': 'NtQuerySystemEnvironmentValue',
- '0x00b4': 'NtQuerySystemEnvironmentValueEx',
- '0x00b5': 'NtQuerySystemInformation',
- '0x0088': 'NtOpenThreadTokenEx',
- '0x0089': 'NtOpenTimer',
- '0x0109': 'NtTerminateJobObject',
- '0x00af': 'NtQuerySection',
- '0x00aa': 'NtQueryObject',
- '0x010d': 'NtTraceEvent',
- '0x00f1': 'NtSetIoCompletion',
- '0x00ac': 'NtQueryOpenSubKeysEx',
- '0x00ab': 'NtQueryOpenSubKeys',
- '0x00c7': 'NtRemoveProcessDebug',
- '0x00b8': 'NtQueryTimerResolution',
- '0x00c5': 'NtReleaseSemaphore',
- '0x00c4': 'NtReleaseMutant',
- '0x0019': 'NtCancelTimer',
- '0x0018': 'NtCancelIoFile',
- '0x00c1': 'NtReadRequestData',
- '0x00b9': 'NtQueryValueKey',
- '0x0015': 'NtAssignProcessToJobObject',
- '0x0014': 'NtAreMappedFilesTheSame',
- '0x0017': 'NtCancelDeviceWakeupRequest',
- '0x0016': 'NtCallbackReturn',
- '0x0011': 'NtAllocateUuids',
- '0x0010': 'NtAllocateUserPhysicalPages',
- '0x0013': 'NtApphelpCacheControl',
- '0x0012': 'NtAllocateVirtualMemory',
- '0x0095': 'NtQueryDefaultLocale',
- '0x0094': 'NtQueryDebugFilterState',
- '0x0097': 'NtQueryDirectoryFile',
- '0x0096': 'NtQueryDefaultUILanguage',
- '0x0091': 'NtQueryAttributesFile',
- '0x0090': 'NtPulseEvent',
- '0x0093': 'NtQueryBootOptions',
- '0x0092': 'NtQueryBootEntryOrder',
- '0x002a': 'NtCreateJobSet',
- '0x002b': 'NtCreateKey',
- '0x002c': 'NtCreateMailslotFile',
- '0x002d': 'NtCreateMutant',
- '0x002e': 'NtCreateNamedPipeFile',
- '0x002f': 'NtCreatePagingFile',
- '0x00ae': 'NtQueryQuotaInformationFile',
- '0x00c2': 'NtReadVirtualMemory',
- '0x0028': 'NtCreateIoCompletion',
- '0x0029': 'NtCreateJobObject',
- '0x00d0': 'NtRequestWaitReplyPort',
- '0x009f': 'NtQueryInformationJobObject',
- '0x009a': 'NtQueryEaFile',
- '0x00a0': 'NtQueryInformationPort',
- '0x009c': 'NtQueryFullAttributesFile',
- '0x009b': 'NtQueryEvent',
- '0x0020': 'NtCompressKey',
- '0x0021': 'NtConnectPort',
- '0x0022': 'NtContinue',
- '0x0023': 'NtCreateDebugObject',
- '0x0024': 'NtCreateDirectoryObject',
- '0x0025': 'NtCreateEvent',
- '0x0026': 'NtCreateEventPair',
- '0x0027': 'NtCreateFile',
- '0x00cf': 'NtRequestPort',
- '0x00ce': 'NtRequestDeviceWakeup',
- '0x00cd': 'NtReplyWaitReplyPort',
- '0x00cc': 'NtReplyWaitReceivePortEx',
- '0x00b6': 'NtQuerySystemTime',
- '0x00ca': 'NtReplyPort',
- '0x00e8': 'NtSetInformationDebugObject',
- '0x001e': 'NtCompareTokens',
- '0x001d': 'NtCompactKeys',
- '0x001f': 'NtCompleteConnectPort',
- '0x001a': 'NtClearEvent',
- '0x001c': 'NtCloseObjectAuditAlarm',
- '0x001b': 'NtClose',
- '0x004b': 'NtEnumerateKey',
- '0x004c': 'NtEnumerateSystemEnvironmentValuesEx',
- '0x004a': 'NtEnumerateDriverEntries',
- '0x004f': 'NtFilterToken',
- '0x011b': 'NtWaitLowEventPair',
- '0x004d': 'NtEnumerateValueKey',
- '0x004e': 'NtExtendSection',
- '0x0037': 'NtCreateThread',
- '0x0036': 'NtCreateSymbolicLinkObject',
- '0x0035': 'NtCreateSemaphore',
- '0x0034': 'NtCreateSection',
- '0x0033': 'NtCreateProfile',
- '0x0032': 'NtCreateProcessEx',
- '0x0031': 'NtCreateProcess',
- '0x0030': 'NtCreatePort',
- '0x0039': 'NtCreateToken',
- '0x0038': 'NtCreateTimer',
- '0x00e1': 'NtSetDefaultUILanguage',
- '0x00e0': 'NtSetDefaultLocale',
- '0x00e3': 'NtSetEaFile',
- '0x00e2': 'NtSetDriverEntryOrder',
- '0x00e5': 'NtSetEventBoostPriority',
- '0x00e4': 'NtSetEvent',
- '0x00e7': 'NtSetHighWaitLowEventPair',
- '0x00e6': 'NtSetHighEventPair',
- '0x00e9': 'NtSetInformationFile',
- 'NA': 'NtWriteErrorLogEntry',
- '0x00f2': 'NtSetLdtEntries',
- '0x00fd': 'NtSetTimer',
- '0x00fe': 'NtSetTimerResolution',
- '0x00ff': 'NtSetUuidSeed',
- '0x0108': 'NtSystemDebugControl',
- '0x0102': 'NtShutdownSystem',
- '0x00fa': 'NtSetSystemPowerState',
- '0x00fb': 'NtSetSystemTime',
- '0x00fc': 'NtSetThreadExecutionState',
- '0x003f': 'NtDeleteBootEntry',
- '0x003e': 'NtDeleteAtom',
- '0x003d': 'NtDelayExecution',
- '0x003c': 'NtDebugContinue',
- '0x003b': 'NtDebugActiveProcess',
- '0x003a': 'NtCreateWaitablePort',
- '0x009d': 'NtQueryInformationAtom',
- '0x00d1': 'NtRequestWakeupLatency',
- '0x0042': 'NtDeleteKey',
- '0x0043': 'NtDeleteObjectAuditAlarm',
- '0x0040': 'NtDeleteDriverEntry',
- '0x0041': 'NtDeleteFile',
- '0x0046': 'NtDisplayString',
- '0x0047': 'NtDuplicateObject',
- '0x0044': 'NtDeleteValueKey',
- '0x0045': 'NtDeviceIoControlFile',
- '0x00d6': 'NtResumeThread',
- '0x0048': 'NtDuplicateToken',
- '0x0049': 'NtEnumerateBootEntries',
- '0x00a7': 'NtQueryKey',
- '0x00d7': 'NtSaveKey',
- '0x00a6': 'NtQueryIoCompletion',
- '0x00f8': 'NtSetSystemEnvironmentValueEx',
- '0x00d4': 'NtRestoreKey',
- '0x0125': 'NtQueryPortInformationProcess',
- '0x00a1': 'NtQueryInformationProcess',
- '0x00f6': 'NtSetSecurityObject',
- '0x0126': 'NtGetCurrentProcessorNumber',
- '0x0121': 'NtCreateKeyedEvent',
- '0x00d2': 'NtResetEvent',
- '0x0123': 'NtReleaseKeyedEvent',
- '0x0122': 'NtOpenKeyedEvent',
- '0x00ea': 'NtSetInformationJobObject',
- '0x00ec': 'NtSetInformationObject',
- '0x00eb': 'NtSetInformationKey',
- '0x00ee': 'NtSetInformationThread',
- '0x00ed': 'NtSetInformationProcess',
- '0x00f7': 'NtSetSystemEnvironmentValue',
- '0x00ef': 'NtSetInformationToken',
- '0x00a2': 'NtQueryInformationThread',
- '0x00d8': 'NtSaveKeyEx',
- '0x00f4': 'NtSetLowWaitHighEventPair',
- '0x010e': 'NtTranslateFilePath',
- '0x00d9': 'NtSaveMergedKeys',
- '0x010c': 'NtTestAlert',
- '0x010b': 'NtTerminateThread',
- '0x010a': 'NtTerminateProcess',
- '0x00a5': 'NtQueryIntervalProfile',
- '0x006d': 'NtMakePermanentObject',
- '0x006e': 'NtMakeTemporaryObject',
- '0x006f': 'NtMapUserPhysicalPages',
- '0x00d3': 'NtResetWriteWatch',
- '0x006a': 'NtLockProductActivationKeys',
- '0x006b': 'NtLockRegistryKey',
- '0x006c': 'NtLockVirtualMemory',
- '0x0051': 'NtFlushBuffersFile',
- '0x0050': 'NtFindAtom',
- '0x0053': 'NtFlushKey',
- '0x0052': 'NtFlushInstructionCache',
- '0x0055': 'NtFlushWriteBuffer',
- '0x0054': 'NtFlushVirtualMemory',
- '0x0057': 'NtFreeVirtualMemory',
- '0x0056': 'NtFreeUserPhysicalPages',
- '0x0059': 'NtGetContextThread',
- '0x0058': 'NtFsControlFile',
- '0x00c8': 'NtRenameKey',
- '0x00f5': 'NtSetQuotaInformationFile',
- '0x0118': 'NtWaitForMultipleObjects',
- '0x0119': 'NtWaitForSingleObject',
- '0x0124': 'NtWaitForKeyedEvent',
- '0x00d5': 'NtResumeProcess',
- '0x0110': 'NtUnloadKey',
- '0x0111': 'NtUnloadKey2',
- '0x00f3': 'NtSetLowEventPair',
- '0x0113': 'NtUnlockFile',
- '0x0114': 'NtUnlockVirtualMemory',
- '0x0115': 'NtUnmapViewOfSection',
- '0x0116': 'NtVdmControl',
- '0x0117': 'NtWaitForDebugEvent',
- '0x00cb': 'NtReplyWaitReceivePort',
- '0x005a': 'NtGetDevicePowerState',
- '0x005c': 'NtGetWriteWatch',
- '0x005b': 'NtGetPlugPlayEvent',
- '0x005e': 'NtImpersonateClientOfPort',
- '0x005d': 'NtImpersonateAnonymousToken',
- '0x005f': 'NtImpersonateThread',
- '0x011a': 'NtWaitHighEventPair',
- '0x0107': 'NtSuspendThread',
- '0x0106': 'NtSuspendProcess',
- '0x0105': 'NtStopProfile',
- '0x0099': 'NtQueryDriverEntryOrder',
- '0x0068': 'NtLoadKeyEx',
- '0x0069': 'NtLockFile',
- '0x0101': 'NtSetVolumeInformationFile',
- '0x0100': 'NtSetValueKey',
- '0x0064': 'NtListenPort',
- '0x0065': 'NtLoadDriver',
- '0x0066': 'NtLoadKey',
- '0x0067': 'NtLoadKey2',
- '0x0060': 'NtInitializeRegistry',
- '0x0061': 'NtInitiatePowerAction',
- '0x0062': 'NtIsProcessInJob',
- '0x0063': 'NtIsSystemResumeAutomatic',
- '0x00f0': 'NtSetIntervalProfile',
- '0x00dc': 'NtSetBootOptions',
- '0x00b7': 'NtQueryTimer',
- '0x0104': 'NtStartProfile',
- '0x011e': 'NtWriteRequestData',
- '0x0098': 'NtQueryDirectoryObject',
- '0x00c6': 'NtRemoveIoCompletion',
- '0x00c0': 'NtReadFileScatter',
- '0x011c': 'NtWriteFile',
- '0x011d': 'NtWriteFileGather',
- '0x0112': 'NtUnloadKeyEx',
- '0x011f': 'NtWriteVirtualMemory',
- '0x00ad': 'NtQueryPerformanceCounter'},
- '2000': {
- '0x009e': 'NtQueueApcThread',
- '0x0079': 'NtQueryInformationAtom',
- '0x0078': 'NtPulseEvent',
- '0x00c9': 'NtSetIntervalProfile',
- '0x0073': 'NtPowerInformation',
- '0x0072': 'NtPlugPlayControl',
- '0x0071': 'NtOpenTimer',
- '0x0070': 'NtOpenThreadToken',
- '0x0077': 'NtProtectVirtualMemory',
- '0x0076': 'NtPrivilegeObjectAuditAlarm',
- '0x0075': 'NtPrivilegedServiceAuditAlarm',
- '0x0074': 'NtPrivilegeCheck',
- '0x008f': 'NtQueryOpenSubKeys',
- '0x00d3': 'NtSetThreadExecutionState',
- '0x008d': 'NtQueryMutant',
- '0x008e': 'NtQueryObject',
- '0x008b': 'NtQueryKey',
- '0x008c': 'NtQueryMultipleValueKey',
- '0x008a': 'NtQueryIntervalProfile',
- '0x00ba': 'NtSetContextThread',
- '0x00bb': 'NtSetDefaultHardErrorPort',
- '0x00bc': 'NtSetDefaultLocale',
- '0x00bd': 'NtSetDefaultUILanguage',
- '0x00be': 'NtSetEaFile',
- '0x00bf': 'NtSetEvent',
- '0x00da': 'NtSignalAndWaitForSingleObject',
- '0x00a9': 'NtReplaceKey',
- '0x00a8': 'NtRemoveIoCompletion',
- '0x000f': 'NtAllocateUuids',
- '0x00a4': 'NtReadVirtualMemory',
- '0x000d': 'NtAllocateLocallyUniqueId',
- '0x000e': 'NtAllocateUserPhysicalPages',
- '0x000b': 'NtAlertResumeThread',
- '0x000c': 'NtAlertThread',
- '0x00a3': 'NtReadRequestData',
- '0x000a': 'NtAdjustPrivilegesToken',
- '0x00df': 'NtTerminateJobObject',
- '0x00dd': 'NtSuspendThread',
- '0x00b9': 'NtSetIoCompletion',
- '0x007c': 'NtQueryDefaultUILanguage',
- '0x007b': 'NtQueryDefaultLocale',
- '0x007a': 'NtQueryAttributesFile',
- '0x00de': 'NtSystemDebugControl',
- '0x007f': 'NtQueryEaFile',
- '0x007e': 'NtQueryDirectoryObject',
- '0x007d': 'NtQueryDirectoryFile',
- '0x00c3': 'NtSetInformationJobObject',
- '0x0008': 'NtAddAtom',
- '0x0009': 'NtAdjustGroupsToken',
- '0x0006': 'NtAccessCheckByTypeResultListAndAuditAlarm',
- '0x0007': 'NtAccessCheckByTypeResultListAndAuditAlarmByHandle',
- '0x0004': 'NtAccessCheckByTypeAndAuditAlarm',
- '0x0005': 'NtAccessCheckByTypeResultList',
- '0x0002': 'NtAccessCheckAndAuditAlarm',
- '0x0003': 'NtAccessCheckByType',
- '0x0000': 'NtAcceptConnectPort',
- '0x0001': 'NtAccessCheck',
- '0x0086': 'NtQueryInformationProcess',
- '0x0087': 'NtQueryInformationThread',
- '0x0084': 'NtQueryIoCompletion',
- '0x0085': 'NtQueryInformationPort',
- '0x0082': 'NtQueryInformationFile',
- '0x0083': 'NtQueryInformationJobObject',
- '0x0080': 'NtQueryEvent',
- '0x0081': 'NtQueryFullAttributesFile',
- '0x00b0': 'NtRequestWaitReplyPort',
- '0x00b1': 'NtRequestWakeupLatency',
- '0x00b2': 'NtResetEvent',
- '0x00b3': 'NtResetWriteWatch',
- '0x00b4': 'NtRestoreKey',
- '0x00b5': 'NtResumeThread',
- '0x0088': 'NtQueryInformationToken',
- '0x0089': 'NtQueryInstallUILanguage',
- '0x00af': 'NtRequestPort',
- '0x00aa': 'NtReplyPort',
- '0x00ac': 'NtReplyWaitReceivePortEx',
- '0x00ab': 'NtReplyWaitReceivePort',
- '0x00c7': 'NtSetInformationThread',
- '0x00b8': 'NtSecureConnectPort',
- '0x00c5': 'NtSetInformationObject',
- '0x00c4': 'NtSetInformationKey',
- '0x0019': 'NtCloseObjectAuditAlarm',
- '0x0018': 'NtClose',
- '0x00c1': 'NtSetHighWaitLowEventPair',
- '0x00c0': 'NtSetHighEventPair',
- '0x0015': 'NtCancelTimer',
- '0x0014': 'NtCancelIoFile',
- '0x0017': 'NtClearEvent',
- '0x0016': 'NtCancelDeviceWakeupRequest',
- '0x0011': 'NtAreMappedFilesTheSame',
- '0x0010': 'NtAllocateVirtualMemory',
- '0x0013': 'NtCallbackReturn',
- '0x0012': 'NtAssignProcessToJobObject',
- '0x0095': 'NtQuerySymbolicLinkObject',
- '0x0094': 'NtQuerySemaphore',
- '0x0097': 'NtQuerySystemInformation',
- '0x0096': 'NtQuerySystemEnvironmentValue',
- '0x0091': 'NtQueryQuotaInformationFile',
- '0x0090': 'NtQueryPerformanceCounter',
- '0x0093': 'NtQuerySecurityObject',
- '0x0092': 'NtQuerySection',
- '0x002a': 'NtCreateProfile',
- '0x002b': 'NtCreateSection',
- '0x002c': 'NtCreateSemaphore',
- '0x002d': 'NtCreateSymbolicLinkObject',
- '0x002e': 'NtCreateThread',
- '0x002f': 'NtCreateTimer',
- '0x00ae': 'NtRequestDeviceWakeup',
- '0x00c2': 'NtSetInformationFile',
- '0x0028': 'NtCreatePort',
- '0x0029': 'NtCreateProcess',
- '0x00d0': 'NtSetSystemInformation',
- '0x009f': 'NtRaiseException',
- '0x009a': 'NtQueryTimerResolution',
- '0x00a0': 'NtRaiseHardError',
- '0x009c': 'NtQueryVirtualMemory',
- '0x009b': 'NtQueryValueKey',
- '0x0020': 'NtCreateFile',
- '0x0021': 'NtCreateIoCompletion',
- '0x0022': 'NtCreateJobObject',
- '0x0023': 'NtCreateKey',
- '0x0024': 'NtCreateMailslotFile',
- '0x0025': 'NtCreateMutant',
- '0x0026': 'NtCreateNamedPipeFile',
- '0x0027': 'NtCreatePagingFile',
- '0x00cf': 'NtSetSystemEnvironmentValue',
- '0x00ce': 'NtSetSecurityObject',
- '0x00cd': 'NtSetQuotaInformationFile',
- '0x00cc': 'NtSetLowWaitHighEventPair',
- '0x00b6': 'NtSaveKey',
- '0x00ca': 'NtSetLdtEntries',
- '0x00e8': 'NtVdmControl',
- '0x001e': 'NtCreateEvent',
- '0x001d': 'NtCreateDirectoryObject',
- '0x001f': 'NtCreateEventPair',
- '0x001a': 'NtCompleteConnectPort',
- '0x001c': 'NtContinue',
- '0x001b': 'NtConnectPort',
- '0x004b': 'NtGetPlugPlayEvent',
- '0x004c': 'NtGetTickCount',
- '0x004a': 'NtGetDevicePowerState',
- '0x004f': 'NtImpersonateClientOfPort',
- '0x004d': 'NtGetWriteWatch',
- '0x004e': 'NtImpersonateAnonymousToken',
- '0x0037': 'NtDeleteValueKey',
- '0x0036': 'NtDeleteObjectAuditAlarm',
- '0x0035': 'NtDeleteKey',
- '0x0034': 'NtDeleteFile',
- '0x0033': 'NtDeleteAtom',
- '0x0032': 'NtDelayExecution',
- '0x0031': 'NtCreateWaitablePort',
- '0x0030': 'NtCreateToken',
- '0x0039': 'NtDisplayString',
- '0x0038': 'NtDeviceIoControlFile',
- '0x00e1': 'NtTerminateThread',
- '0x00e0': 'NtTerminateProcess',
- '0x00e3': 'NtUnloadDriver',
- '0x00e2': 'NtTestAlert',
- '0x00e5': 'NtUnlockFile',
- '0x00e4': 'NtUnloadKey',
- '0x00e7': 'NtUnmapViewOfSection',
- '0x00e6': 'NtUnlockVirtualMemory',
- '0x00e9': 'NtWaitForMultipleObjects',
- 'NA': 'NtWriteErrorLogEntry',
- '0x003f': 'NtFilterToken',
- '0x003e': 'NtExtendSection',
- '0x003d': 'NtEnumerateValueKey',
- '0x003c': 'NtEnumerateKey',
- '0x003b': 'NtDuplicateToken',
- '0x003a': 'NtDuplicateObject',
- '0x009d': 'NtQueryVolumeInformationFile',
- '0x00d1': 'NtSetSystemPowerState',
- '0x0042': 'NtFlushInstructionCache',
- '0x0043': 'NtFlushKey',
- '0x0040': 'NtFindAtom',
- '0x0041': 'NtFlushBuffersFile',
- '0x0046': 'NtFreeUserPhysicalPages',
- '0x0047': 'NtFreeVirtualMemory',
- '0x0044': 'NtFlushVirtualMemory',
- '0x0045': 'NtFlushWriteBuffer',
- '0x00d6': 'NtSetUuidSeed',
- '0x0048': 'NtFsControlFile',
- '0x0049': 'NtGetContextThread',
- '0x00a7': 'NtReleaseSemaphore',
- '0x00d7': 'NtSetValueKey',
- '0x00a6': 'NtReleaseMutant',
- '0x00d4': 'NtSetTimer',
- '0x00f4': 'NtReplyWaitSendChannel',
- '0x00a1': 'NtReadFile',
- '0x00f6': 'NtSetContextChannel',
- '0x00d5': 'NtSetTimerResolution',
- '0x00f0': 'NtWriteVirtualMemory',
- '0x00f1': 'NtCreateChannel',
- '0x00f2': 'NtListenChannel',
- '0x00f3': 'NtOpenChannel',
- '0x00ea': 'NtWaitForSingleObject',
- '0x00ec': 'NtWaitLowEventPair',
- '0x00eb': 'NtWaitHighEventPair',
- '0x00ee': 'NtWriteFileGather',
- '0x00ed': 'NtWriteFile',
- '0x00f7': 'NtYieldExecution',
- '0x00ef': 'NtWriteRequestData',
- '0x00a2': 'NtReadFileScatter',
- '0x00d8': 'NtSetVolumeInformationFile',
- '0x00d9': 'NtShutdownSystem',
- '0x00a5': 'NtRegisterThreadTerminatePort',
- '0x006d': 'NtOpenSemaphore',
- '0x006e': 'NtOpenSymbolicLinkObject',
- '0x006f': 'NtOpenThread',
- '0x00d2': 'NtSetSystemTime',
- '0x006a': 'NtOpenProcess',
- '0x006b': 'NtOpenProcessToken',
- '0x006c': 'NtOpenSection',
- '0x0051': 'NtInitializeRegistry',
- '0x0050': 'NtImpersonateThread',
- '0x0053': 'NtIsSystemResumeAutomatic',
- '0x0052': 'NtInitiatePowerAction',
- '0x0055': 'NtLoadDriver',
- '0x0054': 'NtListenPort',
- '0x0057': 'NtLoadKey2',
- '0x0056': 'NtLoadKey',
- '0x0059': 'NtLockVirtualMemory',
- '0x0058': 'NtLockFile',
- '0x00c8': 'NtSetInformationToken',
- '0x00f5': 'NtSendWaitReplyChannel',
- '0x00cb': 'NtSetLowEventPair',
- '0x005a': 'NtMakeTemporaryObject',
- '0x005c': 'NtMapUserPhysicalPagesScatter',
- '0x005b': 'NtMapUserPhysicalPages',
- '0x005e': 'NtNotifyChangeDirectoryFile',
- '0x005d': 'NtMapViewOfSection',
- '0x005f': 'NtNotifyChangeKey',
- '0x00db': 'NtStartProfile',
- '0x0099': 'NtQueryTimer',
- '0x0068': 'NtOpenMutant',
- '0x0069': 'NtOpenObjectAuditAlarm',
- '0x0064': 'NtOpenFile',
- '0x0065': 'NtOpenIoCompletion',
- '0x0066': 'NtOpenJobObject',
- '0x0067': 'NtOpenKey',
- '0x0060': 'NtNotifyChangeMultipleKeys',
- '0x0061': 'NtOpenDirectoryObject',
- '0x0062': 'NtOpenEvent',
- '0x0063': 'NtOpenEventPair',
- '0x00dc': 'NtStopProfile',
- '0x00b7': 'NtSaveMergedKeys',
- '0x0098': 'NtQuerySystemTime',
- '0x00c6': 'NtSetInformationProcess',
- '0x00ad': 'NtReplyWaitReplyPort'},
- 'NT':{
- '0x009e': 'NtSetHighEventPair',
- '0x0079': 'NtQuerySemaphore',
- '0x0078': 'NtQuerySecurityObject',
- '0x00c9': 'NtWriteFileGather',
- '0x0073': 'NtQueryMutant',
- '0x0072': 'NtQueryMultipleValueKey',
- '0x0071': 'NtQueryKey',
- '0x0070': 'NtQueryIntervalProfile',
- '0x0077': 'NtQuerySection',
- '0x0076': 'NtQueryPerformanceCounter',
- '0x0075': 'NtQueryOleDirectoryFile',
- '0x0074': 'NtQueryObject',
- '0x008f': 'NtReplyPort',
- '0x008d': 'NtRemoveIoCompletion',
- '0x008e': 'NtReplaceKey',
- '0x008b': 'NtReleaseMutant',
- '0x008c': 'NtReleaseSemaphore',
- '0x008a': 'NtRegisterThreadTerminatePort',
- '0x00ba': 'NtSystemDebugControl',
- '0x00bb': 'NtTerminateProcess',
- '0x00bc': 'NtTerminateThread',
- '0x00bd': 'NtTestAlert',
- '0x00be': 'NtUnloadDriver',
- '0x00bf': 'NtUnloadKey',
- '0x00a9': 'NtSetLowEventPair',
- '0x00a8': 'NtSetLdtEntries',
- '0x000f': 'NtClose',
- '0x00a4': 'NtSetInformationProcess',
- '0x000d': 'NtCancelTimer',
- '0x000e': 'NtClearEvent',
- '0x000b': 'NtCallbackReturn',
- '0x000c': 'NtCancelIoFile',
- '0x00a3': 'NtSetInformationObject',
- '0x000a': 'NtAllocateVirtualMemory',
- '0x007c': 'NtQuerySystemInformation',
- '0x007b': 'NtQuerySystemEnvironmentValue',
- '0x007a': 'NtQuerySymbolicLinkObject',
- '0x007f': 'NtQueryTimerResolution',
- '0x007e': 'NtQueryTimer',
- '0x007d': 'NtQuerySystemTime',
- '0x00c3': 'NtVdmControl',
- '0x0008': 'NtAllocateLocallyUniqueId',
- '0x0009': 'NtAllocateUuids',
- '0x0006': 'NtAlertResumeThread',
- '0x0007': 'NtAlertThread',
- '0x0004': 'NtAdjustGroupsToken',
- '0x0005': 'NtAdjustPrivilegesToken',
- '0x0002': 'NtAccessCheckAndAuditAlarm',
- '0x0003': 'NtAddAtom',
- '0x0000': 'NtAcceptConnectPort',
- '0x0001': 'NtAccessCheck',
- '0x0086': 'NtReadFile',
- '0x0087': 'NtReadFileScatter',
- '0x0084': 'NtRaiseException',
- '0x0085': 'NtRaiseHardError',
- '0x0082': 'NtQueryVolumeInformationFile',
- '0x0083': 'NtQueueApcThread',
- '0x0080': 'NtQueryValueKey',
- '0x0081': 'NtQueryVirtualMemory',
- '0x00b0': 'NtSetSystemTime',
- '0x00b1': 'NtSetTimer',
- '0x00b2': 'NtSetTimerResolution',
- '0x00b3': 'NtSetValueKey',
- '0x00b4': 'NtSetVolumeInformationFile',
- '0x00b5': 'NtShutdownSystem',
- '0x0088': 'NtReadRequestData',
- '0x0089': 'NtReadVirtualMemory',
- '0x00af': 'NtSetSystemPowerState',
- '0x00aa': 'NtSetLowWaitHighEventPair',
- '0x00ac': 'NtSetSecurityObject',
- '0x00ab': 'NtSetLowWaitHighThread',
- '0x00c7': 'NtWaitLowEventPair',
- '0x00b8': 'NtStopProfile',
- '0x00c5': 'NtWaitForSingleObject',
- '0x00c4': 'NtWaitForMultipleObjects',
- '0x0019': 'NtCreateKey',
- '0x0018': 'NtCreateIoCompletion',
- '0x00c1': 'NtUnlockVirtualMemory',
- '0x00b9': 'NtSuspendThread',
- '0x0015': 'NtCreateEvent',
- '0x0014': 'NtCreateDirectoryObject',
- '0x0017': 'NtCreateFile',
- '0x0016': 'NtCreateEventPair',
- '0x0011': 'NtCompleteConnectPort',
- '0x0010': 'NtCloseObjectAuditAlarm',
- '0x0013': 'NtContinue',
- '0x0012': 'NtConnectPort',
- '0x0095': 'NtRestoreKey',
- '0x0094': 'NtResetEvent',
- '0x0097': 'NtSaveKey',
- '0x0096': 'NtResumeThread',
- '0x0091': 'NtReplyWaitReplyPort',
- '0x0090': 'NtReplyWaitReceivePort',
- '0x0093': 'NtRequestWaitReplyPort',
- '0x0092': 'NtRequestPort',
- '0x002a': 'NtDeleteKey',
- '0x002b': 'NtDeleteObjectAuditAlarm',
- '0x002c': 'NtDeleteValueKey',
- '0x002d': 'NtDeviceIoControlFile',
- '0x002e': 'NtDisplayString',
- '0x002f': 'NtDuplicateObject',
- '0x00ae': 'NtSetSystemInformation',
- '0x00c2': 'NtUnmapViewOfSection',
- '0x0028': 'NtDeleteAtom',
- '0x0029': 'NtDeleteFile',
- '0x00d0': 'NtReplyWaitSendChannel',
- '0x00d1': 'NtSendWaitReplyChannel',
- '0x009a': 'NtSetDefaultHardErrorPort',
- '0x009c': 'NtSetEaFile',
- '0x009b': 'NtSetDefaultLocale',
- '0x0020': 'NtCreateProfile',
- '0x0021': 'NtCreateSection',
- '0x0022': 'NtCreateSemaphore',
- '0x0023': 'NtCreateSymbolicLinkObject',
- '0x0024': 'NtCreateThread',
- '0x0025': 'NtCreateTimer',
- '0x0026': 'NtCreateToken',
- '0x0027': 'NtDelayExecution',
- '0x00cf': 'NtOpenChannel',
- '0x00ce': 'NtListenChannel',
- '0x00cd': 'NtCreateChannel',
- '0x00cc': 'NtW32Call',
- '0x00b6': 'NtSignalAndWaitForSingleObject',
- '0x00ca': 'NtWriteRequestData',
- '0x001e': 'NtCreatePort',
- '0x001d': 'NtCreatePagingFile',
- '0x001f': 'NtCreateProcess',
- '0x001a': 'NtCreateMailslotFile',
- '0x001c': 'NtCreateNamedPipeFile',
- '0x001b': 'NtCreateMutant',
- '0x004b': 'NtNotifyChangeKey',
- '0x004c': 'NtOpenDirectoryObject',
- '0x004a': 'NtNotifyChangeDirectoryFile',
- '0x004f': 'NtOpenFile',
- '0x004d': 'NtOpenEvent',
- '0x004e': 'NtOpenEventPair',
- '0x0037': 'NtFlushKey',
- '0x0036': 'NtFlushInstructionCache',
- '0x0035': 'NtFlushBuffersFile',
- '0x0034': 'NtFindAtom',
- '0x0033': 'NtExtendSection',
- '0x0032': 'NtEnumerateValueKey',
- '0x0031': 'NtEnumerateKey',
- '0x0030': 'NtDuplicateToken',
- '0x0039': 'NtFlushWriteBuffer',
- '0x0038': 'NtFlushVirtualMemory',
- 'NA': 'NtWriteErrorLogEntry',
- '0x003f': 'NtImpersonateClientOfPort',
- '0x003e': 'NtGetTickCount',
- '0x003d': 'NtGetPlugPlayEvent',
- '0x003c': 'NtGetContextThread',
- '0x003b': 'NtFsControlFile',
- '0x003a': 'NtFreeVirtualMemory',
- '0x009d': 'NtSetEvent',
- '0x0042': 'NtListenPort',
- '0x0043': 'NtLoadDriver',
- '0x0040': 'NtImpersonateThread',
- '0x0041': 'NtInitializeRegistry',
- '0x0046': 'NtLockFile',
- '0x0047': 'NtLockVirtualMemory',
- '0x0044': 'NtLoadKey',
- '0x0045': 'NtLoadKey2',
- '0x0048': 'NtMakeTemporaryObject',
- '0x0049': 'NtMapViewOfSection',
- '0x00a7': 'NtSetIntervalProfile',
- '0x00a6': 'NtSetInformationToken',
- '0x00a1': 'NtSetInformationFile',
- '0x00d2': 'NtSetContextChannel',
- '0x00a0': 'NtSetHighWaitLowThread',
- '0x00a2': 'NtSetInformationKey',
- '0x00a5': 'NtSetInformationThread',
- '0x006d': 'NtQueryInformationProcess',
- '0x006e': 'NtQueryInformationThread',
- '0x006f': 'NtQueryInformationToken',
- '0x00d3': 'NtYieldExecution',
- '0x006a': 'NtQueryInformationFile',
- '0x006b': 'NtQueryIoCompletion',
- '0x006c': 'NtQueryInformationPort',
- '0x0051': 'NtOpenKey',
- '0x0050': 'NtOpenIoCompletion',
- '0x0053': 'NtOpenObjectAuditAlarm',
- '0x0052': 'NtOpenMutant',
- '0x0055': 'NtOpenProcessToken',
- '0x0054': 'NtOpenProcess',
- '0x0057': 'NtOpenSemaphore',
- '0x0056': 'NtOpenSection',
- '0x0059': 'NtOpenThread',
- '0x0058': 'NtOpenSymbolicLinkObject',
- '0x00c8': 'NtWriteFile',
- '0x00cb': 'NtWriteVirtualMemory',
- '0x005a': 'NtOpenThreadToken',
- '0x005c': 'NtPlugPlayControl',
- '0x005b': 'NtOpenTimer',
- '0x005e': 'NtPrivilegedServiceAuditAlarm',
- '0x005d': 'NtPrivilegeCheck',
- '0x005f': 'NtPrivilegeObjectAuditAlarm',
- '0x0099': 'NtSetContextThread',
- '0x0068': 'NtQueryEvent',
- '0x0069': 'NtQueryFullAttributesFile',
- '0x009f': 'NtSetHighWaitLowEventPair',
- '0x0064': 'NtQueryDefaultLocale',
- '0x0065': 'NtQueryDirectoryFile',
- '0x0066': 'NtQueryDirectoryObject',
- '0x0067': 'NtQueryEaFile',
- '0x0060': 'NtProtectVirtualMemory',
- '0x0061': 'NtPulseEvent',
- '0x0062': 'NtQueryInformationAtom',
- '0x0063': 'NtQueryAttributesFile',
- '0x00b7': 'NtStartProfile',
- '0x0098': 'NtSetIoCompletion',
- '0x00c6': 'NtWaitHighEventPair',
- '0x00c0': 'NtUnlockFile',
- '0x00ad': 'NtSetSystemEnvironmentValue'},
- 'XP': {
- '0x0103': 'NtTestAlert',
- '0x009e': 'NtQueryIntervalProfile',
- '0x0079': 'NtOpenObjectAuditAlarm',
- '0x0078': 'NtOpenMutant',
- '0x00c9': 'NtRequestWakeupLatency',
- '0x0073': 'NtOpenEventPair',
- '0x0072': 'NtOpenEvent',
- '0x0071': 'NtOpenDirectoryObject',
- '0x0070': 'NtNotifyChangeMultipleKeys',
- '0x0077': 'NtOpenKey',
- '0x0076': 'NtOpenJobObject',
- '0x0075': 'NtOpenIoCompletion',
- '0x0074': 'NtOpenFile',
- '0x008f': 'NtQueryDefaultLocale',
- '0x00db': 'NtSetEvent',
- '0x008d': 'NtQueryBootOptions',
- '0x008e': 'NtQueryDebugFilterState',
- '0x008b': 'NtQueryAttributesFile',
- '0x008c': 'NtQueryBootEntryOrder',
- '0x008a': 'NtPulseEvent',
- '0x00ba': 'NtReadVirtualMemory',
- '0x00bb': 'NtRegisterThreadTerminatePort',
- '0x00bc': 'NtReleaseMutant',
- '0x00bd': 'NtReleaseSemaphore',
- '0x00be': 'NtRemoveIoCompletion',
- '0x00bf': 'NtRemoveProcessDebug',
- '0x00da': 'NtSetEaFile',
- '0x00a9': 'NtQuerySemaphore',
- '0x00a8': 'NtQuerySecurityObject',
- '0x000f': 'NtAllocateUserPhysicalPages',
- '0x00a4': 'NtQueryOpenSubKeys',
- '0x000d': 'NtAlertThread',
- '0x000e': 'NtAllocateLocallyUniqueId',
- '0x000b': 'NtAdjustPrivilegesToken',
- '0x000c': 'NtAlertResumeThread',
- '0x00a3': 'NtQueryObject',
- '0x000a': 'NtAdjustGroupsToken',
- '0x00c0': 'NtRenameKey',
- '0x00df': 'NtSetInformationDebugObject',
- '0x00dd': 'NtSetHighEventPair',
- '0x007c': 'NtOpenProcessTokenEx',
- '0x007b': 'NtOpenProcessToken',
- '0x007a': 'NtOpenProcess',
- '0x00de': 'NtSetHighWaitLowEventPair',
- '0x007f': 'NtOpenSymbolicLinkObject',
- '0x007e': 'NtOpenSemaphore',
- '0x007d': 'NtOpenSection',
- '0x00c3': 'NtReplyWaitReceivePort',
- '0x00f9': 'NtShutdownSystem',
- '0x0008': 'NtAddAtom',
- '0x0009': 'NtAddBootEntry',
- '0x0006': 'NtAccessCheckByTypeResultListAndAuditAlarm',
- '0x0007': 'NtAccessCheckByTypeResultListAndAuditAlarmByHandle',
- '0x0004': 'NtAccessCheckByTypeAndAuditAlarm',
- '0x0005': 'NtAccessCheckByTypeResultList',
- '0x0002': 'NtAccessCheckAndAuditAlarm',
- '0x0003': 'NtAccessCheckByType',
- '0x0000': 'NtAcceptConnectPort',
- '0x0001': 'NtAccessCheck',
- '0x0086': 'NtPrivilegeCheck',
- '0x0087': 'NtPrivilegeObjectAuditAlarm',
- '0x0084': 'NtPlugPlayControl',
- '0x0085': 'NtPowerInformation',
- '0x0082': 'NtOpenThreadTokenEx',
- '0x0083': 'NtOpenTimer',
- '0x0080': 'NtOpenThread',
- '0x0081': 'NtOpenThreadToken',
- '0x00b0': 'NtQueryTimerResolution',
- '0x00b1': 'NtQueryValueKey',
- '0x00b2': 'NtQueryVirtualMemory',
- '0x00b3': 'NtQueryVolumeInformationFile',
- '0x00b4': 'NtQueueApcThread',
- '0x00b5': 'NtRaiseException',
- '0x0088': 'NtPrivilegedServiceAuditAlarm',
- '0x0089': 'NtProtectVirtualMemory',
- '0x00af': 'NtQueryTimer',
- '0x00aa': 'NtQuerySymbolicLinkObject',
- '0x010d': 'NtWaitForDebugEvent',
- '0x00f1': 'NtSetSystemPowerState',
- '0x00ac': 'NtQuerySystemEnvironmentValueEx',
- '0x00ab': 'NtQuerySystemEnvironmentValue',
- '0x00c7': 'NtRequestPort',
- '0x00b8': 'NtReadFileScatter',
- '0x00c5': 'NtReplyWaitReplyPort',
- '0x00c4': 'NtReplyWaitReceivePortEx',
- '0x0019': 'NtClose',
- '0x0018': 'NtClearEvent',
- '0x00c1': 'NtReplaceKey',
- '0x00b9': 'NtReadRequestData',
- '0x0015': 'NtCancelDeviceWakeupRequest',
- '0x0014': 'NtCallbackReturn',
- '0x0017': 'NtCancelTimer',
- '0x0016': 'NtCancelIoFile',
- '0x0011': 'NtAllocateVirtualMemory',
- '0x0010': 'NtAllocateUuids',
- '0x0013': 'NtAssignProcessToJobObject',
- '0x0012': 'NtAreMappedFilesTheSame',
- '0x0095': 'NtQueryFullAttributesFile',
- '0x0094': 'NtQueryEvent',
- '0x0097': 'NtQueryInformationFile',
- '0x0096': 'NtQueryInformationAtom',
- '0x0091': 'NtQueryDirectoryFile',
- '0x0090': 'NtQueryDefaultUILanguage',
- '0x0093': 'NtQueryEaFile',
- '0x0092': 'NtQueryDirectoryObject',
- '0x002a': 'NtCreateMailslotFile',
- '0x002b': 'NtCreateMutant',
- '0x002c': 'NtCreateNamedPipeFile',
- '0x002d': 'NtCreatePagingFile',
- '0x002e': 'NtCreatePort',
- '0x002f': 'NtCreateProcess',
- '0x00ae': 'NtQuerySystemTime',
- '0x00c2': 'NtReplyPort',
- '0x0028': 'NtCreateJobSet',
- '0x0029': 'NtCreateKey',
- '0x00d0': 'NtSaveKeyEx',
- '0x009f': 'NtQueryIoCompletion',
- '0x009a': 'NtQueryInformationProcess',
- '0x00d7': 'NtSetDefaultHardErrorPort',
- '0x009c': 'NtQueryInformationToken',
- '0x009b': 'NtQueryInformationThread',
- '0x0020': 'NtContinue',
- '0x0021': 'NtCreateDebugObject',
- '0x0022': 'NtCreateDirectoryObject',
- '0x0023': 'NtCreateEvent',
- '0x0024': 'NtCreateEventPair',
- '0x0025': 'NtCreateFile',
- '0x0026': 'NtCreateIoCompletion',
- '0x0027': 'NtCreateJobObject',
- '0x00cf': 'NtSaveKey',
- '0x00ce': 'NtResumeThread',
- '0x00cd': 'NtResumeProcess',
- '0x00cc': 'NtRestoreKey',
- '0x00b6': 'NtRaiseHardError',
- '0x00ca': 'NtResetEvent',
- '0x00e8': 'NtSetIoCompletion',
- '0x001e': 'NtCompressKey',
- '0x001d': 'NtCompleteConnectPort',
- '0x001f': 'NtConnectPort',
- '0x001a': 'NtCloseObjectAuditAlarm',
- '0x001c': 'NtCompareTokens',
- '0x001b': 'NtCompactKeys',
- '0x004b': 'NtFilterToken',
- '0x004c': 'NtFindAtom',
- '0x004a': 'NtExtendSection',
- '0x004f': 'NtFlushKey',
- '0x004d': 'NtFlushBuffersFile',
- '0x004e': 'NtFlushInstructionCache',
- '0x0037': 'NtCreateToken',
- '0x0036': 'NtCreateTimer',
- '0x0035': 'NtCreateThread',
- '0x0034': 'NtCreateSymbolicLinkObject',
- '0x0033': 'NtCreateSemaphore',
- '0x0032': 'NtCreateSection',
- '0x0031': 'NtCreateProfile',
- '0x0030': 'NtCreateProcessEx',
- '0x0039': 'NtDebugActiveProcess',
- '0x0038': 'NtCreateWaitablePort',
- '0x00e1': 'NtSetInformationJobObject',
- '0x00e0': 'NtSetInformationFile',
- '0x00e3': 'NtSetInformationObject',
- '0x00e2': 'NtSetInformationKey',
- '0x00e5': 'NtSetInformationThread',
- '0x00e4': 'NtSetInformationProcess',
- '0x00e7': 'NtSetIntervalProfile',
- '0x00e6': 'NtSetInformationToken',
- '0x00e9': 'NtSetLdtEntries',
- 'NA': 'NtWriteErrorLogEntry',
- '0x0109': 'NtUnlockFile',
- '0x00fd': 'NtSuspendProcess',
- '0x00fe': 'NtSuspendThread',
- '0x00ff': 'NtSystemDebugControl',
- '0x0108': 'NtUnloadKeyEx',
- '0x0102': 'NtTerminateThread',
- '0x00fa': 'NtSignalAndWaitForSingleObject',
- '0x00fb': 'NtStartProfile',
- '0x00fc': 'NtStopProfile',
- '0x003f': 'NtDeleteKey',
- '0x003e': 'NtDeleteFile',
- '0x003d': 'NtDeleteBootEntry',
- '0x003c': 'NtDeleteAtom',
- '0x003b': 'NtDelayExecution',
- '0x003a': 'NtDebugContinue',
- '0x009d': 'NtQueryInstallUILanguage',
- '0x00d1': 'NtSaveMergedKeys',
- '0x0042': 'NtDeviceIoControlFile',
- '0x0043': 'NtDisplayString',
- '0x0040': 'NtDeleteObjectAuditAlarm',
- '0x0041': 'NtDeleteValueKey',
- '0x0046': 'NtEnumerateBootEntries',
- '0x0047': 'NtEnumerateKey',
- '0x0044': 'NtDuplicateObject',
- '0x0045': 'NtDuplicateToken',
- '0x00d6': 'NtSetDebugFilterState',
- '0x0048': 'NtEnumerateSystemEnvironmentValuesEx',
- '0x0049': 'NtEnumerateValueKey',
- '0x00a7': 'NtQuerySection',
- '0x00a6': 'NtQueryQuotaInformationFile',
- '0x00f8': 'NtSetVolumeInformationFile',
- '0x00d4': 'NtSetBootOptions',
- '0x00f4': 'NtSetTimer',
- '0x00a1': 'NtQueryMultipleValueKey',
- '0x00f6': 'NtSetUuidSeed',
- '0x00d5': 'NtSetContextThread',
- '0x00f0': 'NtSetSystemInformation',
- '0x00d2': 'NtSecureConnectPort',
- '0x00f2': 'NtSetSystemTime',
- '0x00a0': 'NtQueryKey',
- '0x00ea': 'NtSetLowEventPair',
- '0x00ec': 'NtSetQuotaInformationFile',
- '0x00eb': 'NtSetLowWaitHighEventPair',
- '0x00ee': 'NtSetSystemEnvironmentValue',
- '0x00ed': 'NtSetSecurityObject',
- '0x00f7': 'NtSetValueKey',
- '0x00ef': 'NtSetSystemEnvironmentValueEx',
- '0x00a2': 'NtQueryMutant',
- '0x00d8': 'NtSetDefaultLocale',
- '0x010f': 'NtWaitForSingleObject',
- '0x010e': 'NtWaitForMultipleObjects',
- '0x00d9': 'NtSetDefaultUILanguage',
- '0x010c': 'NtVdmControl',
- '0x010b': 'NtUnmapViewOfSection',
- '0x010a': 'NtUnlockVirtualMemory',
- '0x00a5': 'NtQueryPerformanceCounter',
- '0x006d': 'NtModifyBootEntry',
- '0x006e': 'NtNotifyChangeDirectoryFile',
- '0x006f': 'NtNotifyChangeKey',
- '0x00d3': 'NtSetBootEntryOrder',
- '0x006a': 'NtMapUserPhysicalPages',
- '0x006b': 'NtMapUserPhysicalPagesScatter',
- '0x006c': 'NtMapViewOfSection',
- '0x0051': 'NtFlushWriteBuffer',
- '0x0050': 'NtFlushVirtualMemory',
- '0x0053': 'NtFreeVirtualMemory',
- '0x0052': 'NtFreeUserPhysicalPages',
- '0x0055': 'NtGetContextThread',
- '0x0054': 'NtFsControlFile',
- '0x0057': 'NtGetPlugPlayEvent',
- '0x0056': 'NtGetDevicePowerState',
- '0x0059': 'NtImpersonateAnonymousToken',
- '0x0058': 'NtGetWriteWatch',
- '0x00c8': 'NtRequestWaitReplyPort',
- '0x00f5': 'NtSetTimerResolution',
- '0x0118': 'NtOpenKeyedEvent',
- '0x0119': 'NtReleaseKeyedEvent',
- '0x0110': 'NtWaitHighEventPair',
- '0x0111': 'NtWaitLowEventPair',
- '0x00f3': 'NtSetThreadExecutionState',
- '0x0113': 'NtWriteFileGather',
- '0x0114': 'NtWriteRequestData',
- '0x0115': 'NtWriteVirtualMemory',
- '0x0116': 'NtYieldExecution',
- '0x0117': 'NtCreateKeyedEvent',
- '0x00cb': 'NtResetWriteWatch',
- '0x005a': 'NtImpersonateClientOfPort',
- '0x005c': 'NtInitializeRegistry',
- '0x005b': 'NtImpersonateThread',
- '0x005e': 'NtIsProcessInJob',
- '0x005d': 'NtInitiatePowerAction',
- '0x005f': 'NtIsSystemResumeAutomatic',
- '0x011a': 'NtWaitForKeyedEvent',
- '0x0107': 'NtUnloadKey',
- '0x0106': 'NtUnloadDriver',
- '0x0105': 'NtTranslateFilePath',
- '0x0099': 'NtQueryInformationPort',
- '0x0068': 'NtMakePermanentObject',
- '0x0069': 'NtMakeTemporaryObject',
- '0x0101': 'NtTerminateProcess',
- '0x0100': 'NtTerminateJobObject',
- '0x0064': 'NtLockFile',
- '0x0065': 'NtLockProductActivationKeys',
- '0x0066': 'NtLockRegistryKey',
- '0x0067': 'NtLockVirtualMemory',
- '0x0060': 'NtListenPort',
- '0x0061': 'NtLoadDriver',
- '0x0062': 'NtLoadKey',
- '0x0063': 'NtLoadKey2',
- '0x00dc': 'NtSetEventBoostPriority',
- '0x00b7': 'NtReadFile',
- '0x0104': 'NtTraceEvent',
- '0x0098': 'NtQueryInformationJobObject',
- '0x00c6': 'NtRequestDeviceWakeup',
- '0x011b': 'NtQueryPortInformationProcess',
- '0x0112': 'NtWriteFile',
- '0x00ad': 'NtQuerySystemInformation'},
- 'Vista': {'0x0172': 'NtCancelIoFileEx',
- '0x0173': 'NtCancelSynchronousIoFile',
- '0x0079': 'NtDeleteFile',
- '0x0078': 'NtDeleteDriverEntry',
- '0x0176': 'NtPullTransaction',
- '0x0177': 'NtMarshallTransaction',
- '0x0174': 'NtRemoveIoCompletionEx',
- '0x0175': 'NtRegisterProtocolAddressInformation',
- '0x0073': 'NtDebugActiveProcess',
- '0x0072': 'NtCreateWaitablePort',
- '0x0178': 'NtPropagationComplete',
- '0x0012': 'NtAllocateVirtualMemory',
- '0x0077': 'NtDeleteBootEntry',
- '0x0076': 'NtDeleteAtom',
- '0x0075': 'NtDelayExecution',
- '0x0074': 'NtDebugContinue',
- '0x00ba': 'NtOpenJobObject',
- '0x00bb': 'NtOpenKey',
- '0x00bc': 'NtOpenMutant',
- '0x00bd': 'NtOpenPrivateNamespace',
- '0x00be': 'NtOpenObjectAuditAlarm',
- '0x00bf': 'NtOpenProcess',
- '0x000f': 'NtAllocateLocallyUniqueId',
- '0x000d': 'NtAlertResumeThread',
- '0x000e': 'NtAlertThread',
- '0x000b': 'NtAdjustGroupsToken',
- '0x000c': 'NtAdjustPrivilegesToken',
- '0x000a': 'NtAddDriverEntry',
- '0x017b': 'NtReleaseWorkerFactoryWorker',
- '0x017c': 'NtWaitForWorkViaWorkerFactory',
- '0x017a': 'NtCreateWorkerFactory',
- '0x017f': 'NtWorkerFactoryWorkerReady',
- '0x017d': 'NtSetInformationWorkerFactory',
- '0x017e': 'NtQueryInformationWorkerFactory',
- '0x007c': 'NtDeleteObjectAuditAlarm',
- '0x007b': 'NtDeletePrivateNamespace',
- '0x007a': 'NtDeleteKey',
- '0x007f': 'NtDisplayString',
- '0x007e': 'NtDeviceIoControlFile',
- '0x007d': 'NtDeleteValueKey',
- '0x00f8': 'NtQueryTimerResolution',
- '0x0128': 'NtSetEaFile',
- '0x0008': 'NtAddAtom',
- '0x0009': 'NtAddBootEntry',
- '0x0006': 'NtAccessCheckByTypeResultListAndAuditAlarm',
- '0x0007': 'NtAccessCheckByTypeResultListAndAuditAlarmByHandle',
- '0x0004': 'NtAccessCheckByTypeAndAuditAlarm',
- '0x0005': 'NtAccessCheckByTypeResultList',
- '0x0002': 'NtAccessCheckAndAuditAlarm',
- '0x0003': 'NtAccessCheckByType',
- '0x0000': 'NtAcceptConnectPort',
- '0x0001': 'NtAccessCheck',
- '0x00b8': 'NtOpenFile',
- '0x00b9': 'NtOpenIoCompletion',
- '0x0171': 'NtGetNextThread',
- '0x00f5': 'NtQuerySystemInformation',
- '0x00b0': 'NtModifyBootEntry',
- '0x00b1': 'NtModifyDriverEntry',
- '0x00b2': 'NtNotifyChangeDirectoryFile',
- '0x00b3': 'NtNotifyChangeKey',
- '0x00b4': 'NtNotifyChangeMultipleKeys',
- '0x00b5': 'NtOpenDirectoryObject',
- '0x00b6': 'NtOpenEvent',
- '0x00b7': 'NtOpenEventPair',
- '0x00f7': 'NtQueryTimer',
- '0x00f0': 'NtQuerySecurityObject',
- '0x00f1': 'NtQuerySemaphore',
- '0x00f2': 'NtQuerySymbolicLinkObject',
- '0x00f3': 'NtQuerySystemEnvironmentValue',
- '0x0071': 'NtStartTm',
- '0x0179': 'NtPropagationFailed',
- '0x0095': 'NtGetContextThread',
- '0x0094': 'NtFsControlFile',
- '0x0097': 'NtGetNlsSectionPtr',
- '0x0096': 'NtGetDevicePowerState',
- '0x0091': 'NtFreeVirtualMemory',
- '0x0090': 'NtFreeUserPhysicalPages',
- '0x0093': 'NtFreezeTransactions',
- '0x0092': 'NtFreezeRegistry',
- '0x0099': 'NtGetWriteWatch',
- '0x0098': 'NtGetPlugPlayEvent',
- '0x009e': 'NtInitializeRegistry',
- '0x009d': 'NtInitializeNlsFiles',
- '0x009f': 'NtInitiatePowerAction',
- '0x009a': 'NtImpersonateAnonymousToken',
- '0x009c': 'NtImpersonateThread',
- '0x009b': 'NtImpersonateClientOfPort',
- '0x004b': 'NtCreateSymbolicLinkObject',
- '0x004c': 'NtCreateThread',
- '0x004a': 'NtCreateSemaphore',
- '0x004f': 'NtCreateTransaction',
- '0x004d': 'NtCreateTimer',
- '0x004e': 'NtCreateToken',
- '0x012e': 'NtSetInformationFile',
- '0x00fe': 'NtRaiseHardError',
- '0x00ff': 'NtReadFile',
- '0x012f': 'NtSetInformationJobObject',
- '0x012a': 'NtSetEventBoostPriority',
- '0x00fa': 'NtQueryVirtualMemory',
- '0x012c': 'NtSetHighWaitLowEventPair',
- '0x012b': 'NtSetHighEventPair',
- '0x0042': 'NtCreateNamedPipeFile',
- '0x0043': 'NtCreatePrivateNamespace',
- '0x0040': 'NtCreateMailslotFile',
- '0x0041': 'NtCreateMutant',
- '0x0046': 'NtCreateProcess',
- '0x0047': 'NtCreateProcessEx',
- '0x0044': 'NtCreatePagingFile',
- '0x0045': 'NtCreatePort',
- '0x0048': 'NtCreateProfile',
- '0x0049': 'NtCreateSection',
- '0x0170': 'NtGetNextProcess',
- '0x0129': 'NtSetEvent',
- '0x00f9': 'NtQueryValueKey',
- '0x0125': 'NtSetDefaultLocale',
- '0x0124': 'NtSetDefaultHardErrorPort',
- '0x00f6': 'NtQuerySystemTime',
- '0x0126': 'NtSetDefaultUILanguage',
- '0x0121': 'NtSetBootOptions',
- '0x0120': 'NtSetBootEntryOrder',
- '0x0123': 'NtSetDebugFilterState',
- '0x0122': 'NtSetContextThread',
- '0x0070': 'NtQueryInformationEnlistment',
- '0x016a': 'NtOpenKeyedEvent',
- '0x016c': 'NtWaitForKeyedEvent',
- '0x016b': 'NtReleaseKeyedEvent',
- '0x016e': 'NtGetCurrentProcessorNumber',
- '0x016d': 'NtQueryPortInformationProcess',
- '0x016f': 'NtWaitForMultipleObjects32',
- '0x0161': 'NtWaitForSingleObject',
- '0x0160': 'NtWaitForMultipleObjects',
- '0x0163': 'NtWaitLowEventPair',
- '0x0162': 'NtWaitHighEventPair',
- '0x0165': 'NtWriteFileGather',
- '0x0164': 'NtWriteFile',
- '0x0167': 'NtWriteVirtualMemory',
- '0x0166': 'NtWriteRequestData',
- '0x0169': 'NtCreateKeyedEvent',
- '0x0168': 'NtYieldExecution',
- '0x00c7': 'NtOpenThreadToken',
- '0x00c6': 'NtOpenThread',
- '0x00c5': 'NtOpenSymbolicLinkObject',
- '0x00c4': 'NtOpenSession',
- '0x0019': 'NtAlpcCreateSectionView',
- '0x0018': 'NtAlpcCreateResourceReserve',
- '0x00c1': 'NtOpenProcessTokenEx',
- '0x00c0': 'NtOpenProcessToken',
- '0x0015': 'NtAlpcConnectPort',
- '0x0014': 'NtAlpcCancelMessage',
- '0x0017': 'NtAlpcCreatePortSection',
- '0x0016': 'NtAlpcCreatePort',
- '0x0011': 'NtAllocateUuids',
- '0x0010': 'NtAllocateUserPhysicalPages',
- '0x0013': 'NtAlpcAcceptConnectPort',
- '0x00c8': 'NtOpenThreadTokenEx',
- '0x00e7': 'NtQueryKey',
- '0x00e6': 'NtQueryIoCompletion',
- '0x00cf': 'NtProtectVirtualMemory',
- '0x00ce': 'NtPrivilegedServiceAuditAlarm',
- '0x00cd': 'NtPrivilegeObjectAuditAlarm',
- '0x00cc': 'NtPrivilegeCheck',
- '0x00cb': 'NtPowerInformation',
- '0x00ca': 'NtPlugPlayControl',
- 'NA': 'NtWriteErrorLogEntry',
- '0x001e': 'NtAlpcDeleteSecurityContext',
- '0x001d': 'NtAlpcDeleteSectionView',
- '0x001f': 'NtAlpcDisconnectPort',
- '0x001a': 'NtAlpcCreateSecurityContext',
- '0x001c': 'NtAlpcDeleteResourceReserve',
- '0x001b': 'NtAlpcDeletePortSection',
- '0x0062': 'NtCreateTransactionManager',
- '0x0063': 'NtOpenTransactionManager',
- '0x0069': 'NtCreateResourceManager',
- '0x0127': 'NtSetDriverEntryOrder',
- '0x00c9': 'NtOpenTimer',
- '0x00f4': 'NtQuerySystemEnvironmentValueEx',
- '0x0068': 'NtRecoverTransactionManager',
- '0x0051': 'NtQueryInformationTransaction',
- '0x0050': 'NtOpenTransaction',
- '0x0053': 'NtPrePrepareEnlistment',
- '0x0052': 'NtQueryInformationTransactionManager',
- '0x0055': 'NtCommitEnlistment',
- '0x0054': 'NtPrepareEnlistment',
- '0x0057': 'NtRollbackComplete',
- '0x0056': 'NtReadOnlyEnlistment',
- '0x0059': 'NtCommitTransaction',
- '0x0058': 'NtRollbackEnlistment',
- '0x0118': 'NtSaveKeyEx',
- '0x0119': 'NtSaveMergedKeys',
- '0x0110': 'NtRequestWaitReplyPort',
- '0x0111': 'NtRequestWakeupLatency',
- '0x0112': 'NtResetEvent',
- '0x0113': 'NtResetWriteWatch',
- '0x0114': 'NtRestoreKey',
- '0x0115': 'NtResumeProcess',
- '0x018a': 'NtGetMUIRegistryInfo',
- '0x0117': 'NtSaveKey',
- '0x005a': 'NtRollbackTransaction',
- '0x005c': 'NtPrepareComplete',
- '0x005b': 'NtPrePrepareComplete',
- '0x005e': 'NtSinglePhaseReject',
- '0x005d': 'NtCommitComplete',
- '0x005f': 'NtSetInformationTransaction',
- '0x0189': 'NtFlushInstallUILanguage',
- '0x0188': 'NtIsUILanguageComitted',
- '0x0187': 'NtClearMUILicenseInfo',
- '0x0186': 'NtGetMUILicenseInfo',
- '0x0185': 'NtListTransactions',
- '0x011c': 'NtRollbackSavepointTransaction',
- '0x011d': 'NtSavepointTransaction',
- '0x011e': 'NtSavepointComplete',
- '0x011f': 'NtSecureConnectPort',
- '0x0180': 'NtShutdownWorkerFactory',
- '0x0158': 'NtUnloadKey',
- '0x0159': 'NtUnloadKey2',
- '0x0154': 'NtTraceEvent',
- '0x0155': 'NtTraceControl',
- '0x0156': 'NtTranslateFilePath',
- '0x0157': 'NtUnloadDriver',
- '0x0150': 'NtTerminateThread',
- '0x0151': 'NtTestAlert',
- '0x0152': 'NtThawRegistry',
- '0x0153': 'NtThawTransactions',
- '0x00db': 'NtQueryEvent',
- '0x00dc': 'NtQueryFullAttributesFile',
- '0x00da': 'NtQueryEaFile',
- '0x00df': 'NtQueryInformationJobObject',
- '0x00dd': 'NtQueryInformationAtom',
- '0x00de': 'NtQueryInformationFile',
- '0x002a': 'NtCallbackReturn',
- '0x002b': 'NtCancelDeviceWakeupRequest',
- '0x002c': 'NtCancelIoFile',
- '0x002d': 'NtCancelTimer',
- '0x002e': 'NtClearEvent',
- '0x002f': 'NtClose',
- '0x00ed': 'NtQueryPerformanceCounter',
- '0x015d': 'NtUnmapViewOfSection',
- '0x015e': 'NtVdmControl',
- '0x015f': 'NtWaitForDebugEvent',
- '0x015a': 'NtUnloadKeyEx',
- '0x015b': 'NtUnlockFile',
- '0x015c': 'NtUnlockVirtualMemory',
- '0x0028': 'NtAreMappedFilesTheSame',
- '0x0029': 'NtAssignProcessToJobObject',
- '0x00d0': 'NtPulseEvent',
- '0x00d1': 'NtQueryAttributesFile',
- '0x00d6': 'NtQueryDefaultUILanguage',
- '0x00d7': 'NtQueryDirectoryFile',
- '0x00d4': 'NtQueryDebugFilterState',
- '0x00d5': 'NtQueryDefaultLocale',
- '0x0020': 'NtAlpcImpersonateClientOfPort',
- '0x0021': 'NtAlpcOpenSenderProcess',
- '0x0022': 'NtAlpcOpenSenderThread',
- '0x0023': 'NtAlpcQueryInformation',
- '0x0024': 'NtAlpcQueryInformationMessage',
- '0x0025': 'NtAlpcSendWaitReceivePort',
- '0x0026': 'NtAlpcSetInformation',
- '0x0027': 'NtApphelpCacheControl',
- '0x00d2': 'NtQueryBootEntryOrder',
- '0x00d3': 'NtQueryBootOptions',
- '0x00d8': 'NtQueryDirectoryObject',
- '0x010f': 'NtRequestPort',
- '0x010e': 'NtRequestDeviceWakeup',
- '0x010d': 'NtReplyWaitReplyPort',
- '0x010c': 'NtReplyWaitReceivePortEx',
- '0x010b': 'NtReplyWaitReceivePort',
- '0x010a': 'NtReplyPort',
- '0x006d': 'NtCreateEnlistment',
- '0x006e': 'NtOpenEnlistment',
- '0x006f': 'NtSetInformationEnlistment',
- '0x006a': 'NtOpenResourceManager',
- '0x006b': 'NtGetNotificationResourceManager',
- '0x006c': 'NtQueryInformationResourceManager',
- '0x0136': 'NtSetIoCompletion',
- '0x0137': 'NtSetLdtEntries',
- '0x0107': 'NtRemoveProcessDebug',
- '0x0106': 'NtRemoveIoCompletion',
- '0x0105': 'NtReleaseSemaphore',
- '0x0104': 'NtReleaseMutant',
- '0x0103': 'NtRegisterThreadTerminatePort',
- '0x0102': 'NtReadVirtualMemory',
- '0x0101': 'NtReadRequestData',
- '0x0100': 'NtReadFileScatter',
- '0x0064': 'NtRenameTransactionManager',
- '0x0065': 'NtRollforwardTransactionManager',
- '0x0066': 'NtRecoverEnlistment',
- '0x0067': 'NtRecoverResourceManager',
- '0x0060': 'NtSetInformationTransactionManager',
- '0x0061': 'NtSetInformationResourceManager',
- '0x0109': 'NtReplaceKey',
- '0x0108': 'NtRenameKey',
- '0x00d9': 'NtQueryDriverEntryOrder',
- '0x0116': 'NtResumeThread',
- '0x008f': 'NtFlushWriteBuffer',
- '0x008d': 'NtFlushProcessWriteBuffers',
- '0x008e': 'NtFlushVirtualMemory',
- '0x008b': 'NtFlushInstructionCache',
- '0x008c': 'NtFlushKey',
- '0x008a': 'NtFlushBuffersFile',
- '0x00a9': 'NtLockRegistryKey',
- '0x00a8': 'NtLockProductActivationKeys',
- '0x00a5': 'NtLoadKey2',
- '0x00a4': 'NtLoadKey',
- '0x00a7': 'NtLockFile',
- '0x00a6': 'NtLoadKeyEx',
- '0x00a1': 'NtIsSystemResumeAutomatic',
- '0x00a0': 'NtIsProcessInJob',
- '0x00a3': 'NtLoadDriver',
- '0x00a2': 'NtListenPort',
- '0x00ae': 'NtMapUserPhysicalPagesScatter',
- '0x00ad': 'NtMapUserPhysicalPages',
- '0x00af': 'NtMapViewOfSection',
- '0x00aa': 'NtLockVirtualMemory',
- '0x00ac': 'NtMakeTemporaryObject',
- '0x00ab': 'NtMakePermanentObject',
- '0x0086': 'NtEnumerateValueKey',
- '0x0087': 'NtExtendSection',
- '0x0084': 'NtEnumerateKey',
- '0x0085': 'NtEnumerateSystemEnvironmentValuesEx',
- '0x0082': 'NtEnumerateBootEntries',
- '0x0083': 'NtEnumerateDriverEntries',
- '0x0080': 'NtDuplicateObject',
- '0x0081': 'NtDuplicateToken',
- '0x0088': 'NtFilterToken',
- '0x0089': 'NtFindAtom',
- '0x014c': 'NtSuspendThread',
- '0x014b': 'NtSuspendProcess',
- '0x014a': 'NtStopProfile',
- '0x014f': 'NtTerminateProcess',
- '0x014e': 'NtTerminateJobObject',
- '0x014d': 'NtSystemDebugControl',
- '0x0149': 'NtStartProfile',
- '0x0148': 'NtSignalAndWaitForSingleObject',
- '0x0143': 'NtSetTimerResolution',
- '0x0142': 'NtSetTimer',
- '0x0141': 'NtSetThreadExecutionState',
- '0x0140': 'NtSetSystemTime',
- '0x0147': 'NtShutdownSystem',
- '0x0146': 'NtSetVolumeInformationFile',
- '0x0145': 'NtSetValueKey',
- '0x0144': 'NtSetUuidSeed',
- '0x0037': 'NtCreateDebugObject',
- '0x0036': 'NtContinue',
- '0x0035': 'NtConnectPort',
- '0x0034': 'NtCompressKey',
- '0x0033': 'NtCompleteConnectPort',
- '0x0032': 'NtCompareTokens',
- '0x0031': 'NtCompactKeys',
- '0x0030': 'NtCloseObjectAuditAlarm',
- '0x0039': 'NtCreateEvent',
- '0x0038': 'NtCreateDirectoryObject',
- '0x00e1': 'NtQueryInformationProcess',
- '0x00e0': 'NtQueryInformationPort',
- '0x00e3': 'NtQueryInformationToken',
- '0x00e2': 'NtQueryInformationThread',
- '0x00e5': 'NtQueryIntervalProfile',
- '0x00e4': 'NtQueryInstallUILanguage',
- '0x0138': 'NtSetLowEventPair',
- '0x0139': 'NtSetLowWaitHighEventPair',
- '0x00e9': 'NtQueryMutant',
- '0x00e8': 'NtQueryMultipleValueKey',
- '0x0134': 'NtSetInformationToken',
- '0x0135': 'NtSetIntervalProfile',
- '0x0132': 'NtSetInformationProcess',
- '0x0133': 'NtSetInformationThread',
- '0x0130': 'NtSetInformationKey',
- '0x0131': 'NtSetInformationObject',
- '0x003f': 'NtCreateKey',
- '0x003e': 'NtCreateJobSet',
- '0x003d': 'NtCreateJobObject',
- '0x003c': 'NtCreateIoCompletion',
- '0x003b': 'NtCreateFile',
- '0x003a': 'NtCreateEventPair',
- '0x00fd': 'NtRaiseException',
- '0x012d': 'NtSetInformationDebugObject',
- '0x013e': 'NtSetSystemInformation',
- '0x00ea': 'NtQueryObject',
- '0x00ec': 'NtQueryOpenSubKeysEx',
- '0x00eb': 'NtQueryOpenSubKeys',
- '0x00ee': 'NtQueryQuotaInformationFile',
- '0x00fb': 'NtQueryVolumeInformationFile',
- '0x00ef': 'NtQuerySection',
- '0x013f': 'NtSetSystemPowerState',
- '0x013d': 'NtSetSystemEnvironmentValueEx',
- '0x00fc': 'NtQueueApcThread',
- '0x013b': 'NtSetSecurityObject',
- '0x013c': 'NtSetSystemEnvironmentValue',
- '0x013a': 'NtSetQuotaInformationFile',
- '0x011a': 'NtClearSavepointTransaction',
- '0x00c3': 'NtOpenSemaphore',
- '0x011b': 'NtClearAllSavepointsTransaction',
- '0x00c2': 'NtOpenSection',
- '0x0184': 'NtMapCMFModule',
- '0x0183': 'NtQueryLicenseValue',
- '0x0181': 'NtCreateThreadEx'}}
- def usage(imm):
- imm.log("!syscall PyCommand (c) Immunity Inc.")
- imm.log("Usage: !syscall -m <modulename> [-f <filename>]")
- imm.log("-m Module to be analyzed. (Required)")
- imm.log("-f Specify a filename to log all information to. (Optional)")
- def main(args):
- imm = Debugger()
- log_file = None
- module = ""
- error = False
- try:
- opts,argo = getopt.getopt(args, "m:f")
- except:
- usage(imm)
- return "See log for usage info"
- for o,a in opts:
- if o == "-m":
- module = a
- if o == "-f":
- log_file = a
- # We key into the syscall_table using the OS
- # getOsInformation returns ["Windows", "XP", "5.1.2600"]
- global syscall_table
- syscall_key = imm.getOsInformation()[1]
- # Analyse the binary, and then grab all of the
- # functions
- executable = imm.getModule( module )
- if executable is None:
- imm.log("[*] Error finding module, please check the filename.")
- return usage(imm)
- exec_base = executable.getCodebase()
- if not executable.isAnalysed():
- imm.analyseCode( exec_base )
- # In ImmLib you can use assembly instructions and wildcard
- # search patterns the CONST below means match against any
- # constants used as as operand
- syscall_sig = "MOV EAX, CONST \n \
- MOV EDX, 0x7FFE0300 \n \
- CALL [EDX]"
- address_list= imm.searchCommandsOnModule( exec_base, syscall_sig )
- syscall_count = 0
- for address in address_list:
- # Simply decode the function that this call
- # resides in
- address = int(address[0])
- resident_function = imm.decodeAddress( address )
- # Attempt to map the opcode from our syscall table
- #syscall_number = str(imm.disasm( function_head ).getOpData()[0])
- opcode = imm.disasm( address )
- instructions = opcode.getResult()
- # This is testing whether its a false-positive, just
- # means our search picked up the same binary pattern
- if "MOV EAX" not in instructions:
- imm.log("Werd")
- continue
- syscall_number = "0x%04x" % opcode.getOpData()[0]
- if syscall_table[syscall_key].has_key( syscall_number ):
- syscall_count += 1
- syscall_name = syscall_table[syscall_key][syscall_number]
- imm.setComment(address, "Syscall: %s" % syscall_name)
- log_message = "[*] Syscall: %s (%s) from %s" % ( syscall_name, syscall_number, resident_function )
- imm.log( "%s" % log_message, address = address)
- # I do this for every iteration in case there is a failure
- # we at least get the information logged as far as we could
- if log_file is not None:
- try:
- fd = open(log_file,"w")
- fd.write( log_message )
- fd.close()
- except IOError:
- error = True
- log_file
- imm.log("[*] %d syscalls discovered - check log window for output." % syscall_count)
- if error == True:
- imm.log("[*] Unable to save to log file, please check pathname and permissions.")
- return "[*] %d syscalls discovered - check log window for output." % syscall_count
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- Immunity PyCommand Template
- """
- __VERSION__ = '0.0'
- import immlib
- import getopt
- DESC= "Immunity PyCommand Template" #description used by PyCommands GUI
- def usage(imm):
- """ All the options"""
- imm.log("!template example command")
- imm.log("!template [-a] [-b] [-c] ",focus=1) # focus the usage
- def main(args):
- imm = immlib.Debugger()
- if not args:
- imm.log("### Immunity's PyCommand template ###")
- return "Command ok - no args"
- try:
- opts, argo = getopt.getopt(args, "a:bc:")
- except getopt.GetoptError: #get args, if error, show usage
- usage(imm)
- return "Bad argument %s" % args[0]
- #parsing args
- for o,a in opts:
- if o == "-a":
- #processing args
- ret=processA(imm,a)
- elif o == "-b":
- ret=processB(imm,a)
- elif o == "-c":
- ret=processC(imm,a)
- #ret is the string shown at status bar
- return ret
- def processA(imm,arg):
- """do whatever"""
- imm.log("Argument received: %s" % str(arg))
- return "Command ok with: %s" %str(arg) #string, string, string!
- def processB(imm,arg):
- imm.log("Argument received: %s" % str(arg))
- return "Command ok with: %s" %str(arg)
- def processC(imm,arg):
- imm.log("Argument received: %s" % str(arg))
- return "Command ok with: %s" %str(arg)
- import socket
- import struct
- from immlib import *
- DESC="""Creates a table that displays packets received on the network."""
- #############################################################################
- '''
- Some defines for re-use.
- '''
- PACKET_TYPE_SEND = "Send "
- PACKET_TYPE_RECV = "Recv "
- PACKET_PROTOCOL_UDP = "(UDP)"
- PACKET_PROTOCOL_TCP = "(TCP)"
- #############################################################################
- class set_hooks(LogBpHook):
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- '''
- This routine is the first one hit, when a socket operation occurs.
- '''
- imm = Debugger()
- # Retrieve the function name
- function_name = imm.getKnowledge("%08x" % regs['EIP'])
- self.retrieve_packet(imm,function_name,regs)
- #########################################################################
- def retrieve_packet(self,imm,function_name,regs):
- '''
- This function determines how to handle the packet data. Some socket
- operations require more work (such as WSARecv), and others less (recv).
- If necessary this function will register a hook on [ESP], where any
- [out] pointers from a function will be set.
- '''
- # Determine what function we have hooked, based on this, retrieve the packet contents
- if function_name == "WSARecv":
- type = PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- extended_hook = True
- if function_name == "WSASend":
- type=PACKET_TYPE_SEND+PACKET_PROTOCOL_TCP
- extended_hook = True
- if function_name == "recvfrom":
- type=PACKET_TYPE_RECV+PACKET_PROTOCOL_UDP
- extended_hook = False
- if function_name =="recv":
- type=PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- extended_hook = False
- # An extended hook requires a bit more work to pull out the packet info
- if extended_hook == True:
- # Get the pointer to the payload pointer :(
- pbuffer_ptr = imm.readMemory( regs['ESP'] + 8, 4)
- pbuffer_ptr = struct.unpack("L", pbuffer_ptr)
- imm.log("Buffer Location: 0x%08x" % pbuffer_ptr[0])
- # Get the pointer to the packet payload
- payload_ptr = imm.readMemory(pbuffer_ptr[0]+4,4)
- payload_ptr = struct.unpack("<L", payload_ptr)
- imm.log("Payload Pointer: %08x" % payload_ptr[0])
- # Get the [out] pointer of the received bytes
- recv_ptr = imm.readMemory(regs['ESP'] + 0x10, 4)
- recv_ptr = struct.unpack("L",recv_ptr)
- imm.log("Receive Pointer: %08x" % recv_ptr[0])
- # Figure out [esp]
- esp_ptr = imm.readMemory(regs['ESP'],4)
- esp_ptr = struct.unpack("<L", esp_ptr)
- imm.log("[ESP] at 0x%08x" % esp_ptr[0])
- # Now we hook [esp]
- ret_hook = ext_hooks()
- ret_hook.add("%08x" % esp_ptr[0],esp_ptr[0])
- # Add this ret hook to the knowledgebase
- imm.addKnowledge("%08x" % esp_ptr[0],(payload_ptr[0],recv_ptr[0],type,function_name))
- else:
- # Get the pointer to the buffer
- payload_ptr = imm.readMemory(regs['ESP'] + 8, 4)
- payload_ptr = struct.unpack("L", payload_ptr)
- # Figure out where [ESP] points to
- esp_ptr = imm.readMemory(regs['ESP'],4)
- esp_ptr = struct.unpack("<L", esp_ptr)
- # Add the [ESP] hook for when the function returns
- simple_hook = simple_hooks()
- simple_hook.add("%08x" % esp_ptr[0],esp_ptr[0])
- # Add our pertinent information to the knowledgebase
- imm.addKnowledge("%08x" % esp_ptr[0],(payload_ptr[0],type,function_name))
- # The main routine that gets run when you type !packets
- def main(args):
- imm = Debugger()
- imm.ignoreSingleStep("CONTINUE")
- hooker = set_hooks()
- # Find the addresses of the functions we want to hook
- # Then register the hooks
- ws_wsarecv = imm.getAddress("ws2_32.WSARecv")
- ws_wsasend = imm.getAddress("ws2_32.WSASend")
- ws_recv = imm.getAddress("ws2_32.recv")
- ws_recvfrom = imm.getAddress("ws2_32.recvfrom")
- # Set the hooks
- hooker.add("WSARecv", ws_wsarecv)
- hooker.add("WSASend", ws_wsasend)
- hooker.add("recv", ws_recv)
- hooker.add("recvfrom", ws_recvfrom)
- # Register the hook-address pair with the knowledgebase
- imm.addKnowledge("%08x" % ws_wsarecv, "WSARecv")
- imm.addKnowledge("%08x" % ws_wsasend, "WSASend")
- imm.addKnowledge("%08x" % ws_recv, "recv")
- imm.addKnowledge("%08x" % ws_recvfrom, "recvfrom")
- return "Network hooks in place."
- import socket
- import struct
- from immlib import *
- DESC="""Creates a table that displays packets received on the network."""
- #############################################################################
- '''
- Some defines for re-use.
- '''
- PACKET_TYPE_SEND = "Send "
- PACKET_TYPE_RECV = "Recv "
- PACKET_PROTOCOL_UDP = "(UDP)"
- PACKET_PROTOCOL_TCP = "(TCP)"
- #############################################################################
- class set_hooks(LogBpHook):
- def __init__(self):
- LogBpHook.__init__(self)
- #########################################################################
- def run(self,regs):
- '''
- This routine is the first one hit, when a socket operation occurs.
- '''
- imm = Debugger()
- # Retrieve the function name
- function_name = imm.getKnowledge("%08x" % regs['EIP'])
- self.retrieve_packet(imm,function_name,regs)
- #########################################################################
- def retrieve_packet(self,imm,function_name,regs):
- '''
- This function determines how to handle the packet data. Some socket
- operations require more work (such as WSARecv), and others less (recv).
- If necessary this function will register a hook on [ESP], where any
- [out] pointers from a function will be set.
- '''
- # Determine what function we have hooked, based on this, retrieve the packet contents
- if function_name == "WSARecv":
- type = PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- extended_hook = True
- if function_name == "WSASend":
- type=PACKET_TYPE_SEND+PACKET_PROTOCOL_TCP
- extended_hook = True
- if function_name == "recvfrom":
- type=PACKET_TYPE_RECV+PACKET_PROTOCOL_UDP
- extended_hook = False
- if function_name =="recv":
- type=PACKET_TYPE_RECV+PACKET_PROTOCOL_TCP
- extended_hook = False
- # An extended hook requires a bit more work to pull out the packet info
- if extended_hook == True:
- # Get the pointer to the payload pointer :(
- pbuffer_ptr = imm.readMemory( regs['ESP'] + 8, 4)
- pbuffer_ptr = struct.unpack("L", pbuffer_ptr)
- imm.log("Buffer Location: 0x%08x" % pbuffer_ptr[0])
- # Get the pointer to the packet payload
- payload_ptr = imm.readMemory(pbuffer_ptr[0]+4,4)
- payload_ptr = struct.unpack("<L", payload_ptr)
- imm.log("Payload Pointer: %08x" % payload_ptr[0])
- # Get the [out] pointer of the received bytes
- recv_ptr = imm.readMemory(regs['ESP'] + 0x10, 4)
- recv_ptr = struct.unpack("L",recv_ptr)
- imm.log("Receive Pointer: %08x" % recv_ptr[0])
- # Figure out [esp]
- esp_ptr = imm.readMemory(regs['ESP'],4)
- esp_ptr = struct.unpack("<L", esp_ptr)
- imm.log("[ESP] at 0x%08x" % esp_ptr[0])
- # Now we hook [esp]
- #ret_hook = ext_hooks()
- #ret_hook.add("%08x" % esp_ptr[0],esp_ptr[0])
- # Add this ret hook to the knowledgebase
- #imm.addKnowledge("%08x" % esp_ptr[0],(payload_ptr[0],recv_ptr[0],type,function_name))
- else:
- # Get the pointer to the buffer
- payload_ptr = imm.readMemory(regs['ESP'] + 8, 4)
- payload_ptr = struct.unpack("L", payload_ptr)
- # Figure out where [ESP] points to
- esp_ptr = imm.readMemory(regs['ESP'],4)
- esp_ptr = struct.unpack("<L", esp_ptr)
- imm.log("Payload Pointer: %08x" % payload_ptr[0])
- imm.log("Payload Pointer: %08x" % esp_ptr[0])
- # Add the [ESP] hook for when the function returns
- #simple_hook = simple_hooks()
- #simple_hook.add("%08x" % esp_ptr[0],esp_ptr[0])
- # Add our pertinent information to the knowledgebase
- #imm.addKnowledge("%08x" % esp_ptr[0],(payload_ptr[0],type,function_name))
- # The main routine that gets run when you type !packets
- def main(args):
- imm = Debugger()
- imm.ignoreSingleStep("CONTINUE")
- hooker = set_hooks()
- # Find the addresses of the functions we want to hook
- # Then register the hooks
- ws_wsarecv = imm.getAddress("ws2_32.WSARecv")
- ws_wsasend = imm.getAddress("ws2_32.WSASend")
- ws_recv = imm.getAddress("ws2_32.recv")
- ws_recvfrom = imm.getAddress("ws2_32.recvfrom")
- # Set the hooks
- hooker.add("WSARecv", ws_wsarecv)
- hooker.add("WSASend", ws_wsasend)
- hooker.add("recv", ws_recv)
- hooker.add("recvfrom", ws_recvfrom)
- # Register the hook-address pair with the knowledgebase
- imm.addKnowledge("%08x" % ws_wsarecv, "WSARecv")
- imm.addKnowledge("%08x" % ws_wsasend, "WSASend")
- imm.addKnowledge("%08x" % ws_recv, "recv")
- imm.addKnowledge("%08x" % ws_recvfrom, "recvfrom")
- return "Network 2 in place."
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- Traceargs example
- """
- __VERSION__ = '1.0'
- DESC="""TraceArgs -> Find User supplied arguments into a given function"""
- import immlib
- import immutils
- import getopt
- modarg = []
- visited = []
- COUNT = 100 # LOOP LIMIT
- def usage(imm):
- imm.log( "!traceargs Find user-supplied arguments into a given function" )
- imm.log( "!traceargs -a ADDRESS -n ARG <-s> <-b>" )
- imm.log(" -a ADDRESS Address of the function")
- imm.log(" -n ARG Argument number you want to look for")
- imm.log(" -s Wheter or not, show all the result (including non user-supplied)")
- imm.log(" -b Wheter or not, breakpoint on the calling instructions")
- def main(args):
- imm=immlib.Debugger()
- if not args:
- usage(imm)
- return "Wrong Arguments (Check usage on the Log Window)"
- try:
- opts, argo = getopt.getopt(args, "a:n:sb")
- except getopt.GetoptError:
- usage(imm)
- return "Wrong Arguments (Check usage on the Log Window)"
- funcaddress = 0
- tracedarg = 0
- shownonusersupplied = False
- breakpointoncall = False
- for o,a in opts:
- if o == '-a':
- try:
- funcaddress = int( a, 16 )
- except ValueError:
- usage(imm)
- return "Wrong Address (%s) % " % a
- elif o == '-n':
- try:
- tracedarg = int( a, 16 )
- except ValueError:
- usage(imm)
- return "Wrong Trace Arg (%s) % " % a
- elif o == '-s':
- shownonusersupplied = True
- elif o == '-b':
- breakpointoncall = True
- if not funcaddress:
- usage(imm)
- return "Wrong Arguments. Address is missing"
- if not tracedarg:
- usage(imm)
- return "Wrong Arguments. Trace Argument is missing"
- references = imm.getXrefFrom( funcaddress )
- for ref in references:
- ret = imm.getTraceArgs( ref[0], tracedarg, shownonusersupplied)
- if ret:
- ( op, show ) = ret
- imm.log("Found user-supplied for arg_%d in %s" % ( tracedarg, imm.disasm(ref[0]).result) , address = ref[0])
- if hasattr(op, 'type'): type = op.type
- else: type=""
- imm.log( "%s %s" % (op.getDisasm(), type), address = op.getAddress() )
- for msg in show:
- imm.log( msg.getDisasm(), address = msg.getAddress() )
- imm.log("------")
- if breakpointoncall:
- imm.setBreakpoint( ref[0] )
- return 0
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004-2008
- U{Immunity Inc.<http://www.immunityinc.com>}
- Tree Dll
- """
- __VERSION__ = '1.0'
- NAME = "treedll"
- DESC="""Creates imported dll tree"""
- import immlib
- import immutils
- import getopt
- def usage(imm):
- imm.log("!%s" % NAME)
- imm.log("%s" % DESC)
- imm.log("-p process name")
- imm.log("-l max tree level")
- class Node:
- def __init__(self, name):
- self.name = name
- self.imports = []
- def getName(self, name):
- return name
- def getImports(self):
- return self.imports
- def addImport(self, tl):
- self.imports.append( tl )
- class DLLTree:
- def __init__(self, imm, entry = "", maxlevel = 3):
- self.imm = imm
- if not entry:
- self.entry = imm.getDebuggedName()
- else:
- self.entry = entry
- self.node = None
- self.maxlevel = maxlevel
- self.sym = None
- def Initalize(self):
- self.sym = self.imm.getAllSymbols()
- def Get(self):
- if not self.sym:
- self.Initalize()
- self.tree = {}
- self.checked = {}
- self.node = self.buru(self.entry)
- return self.node
- def Show(self):
- if not self.node:
- self.Get()
- self.showNodeTree(self.node, 0, 0)
- def showNodeTree(self, node, num, level):
- if level >= self.maxlevel:
- return
- self.imm.log(" " * num + node.name)
- self.checked[ node.name ] = 1
- for n in node.getImports():
- self.showNodeTree(n, num + 2, level+1)
- def buru(self, name):
- if name in self.checked.keys():
- return None
- tl = []
- self.checked[name] = Node( name )
- try:
- tl = self.getAssociatedDLL(name)
- except Exception, msg:
- self.imm.log("Exception: %s" % str(msg))
- for nn in tl:
- if nn != name:
- node = self.buru( nn )
- if not node:
- node = self.checked[nn]
- self.checked[name].addImport( node )
- return self.checked[name]
- def getAssociatedDLL(self, name):
- if not self.sym:
- self.Initalize()
- tl = {}
- if name not in self.sym:
- raise Exception, "Entry not a dll found: %s" % name
- symbols = self.sym[name]
- for a in symbols.keys():
- s = symbols[a]
- #self.imm.log("%s | %s " % (s.type, s.name))
- if s.type[:6] == "Import":
- sname = s.name.split(".",1)[0].lower() + ".dll"
- if sname not in tl.keys():
- tl[sname] = 1
- return tl.keys()
- def main(args):
- imm=immlib.Debugger()
- try:
- opts, argo = getopt.getopt(args, "p:l:")
- except getopt.GetoptError:
- usage(imm)
- return "Wrong Arguments (Check usage on the Log Window)"
- processname = None
- level = 3
- for o,a in opts:
- if o == '-p':
- processname = a
- elif o == '-l':
- level = int(a, 16)
- if processname is None:
- usage(imm)
- return "See log for usage info"
- d = DLLTree(imm, processname, level)
- d.Show()
- return "Check log window for results."
- #!/usr/bin/env python
- """
- (c) Immunity, Inc. 2004 - 2007
- U{Immunity Inc.<http://www.immunityinc.com>}
- """
- __VERSION__ = '1.0'
- import immlib
- DESC = "Return the usage information for a python command"
- def usage(imm):
- imm.log("!usage Returns the usage information for a pytho command")
- def main(args):
- imm = immlib.Debugger()
- ret_str = None
- if args:
- try:
- mod = __import__(args[0])
- except ImportError:
- return "Error: %s is not a python command" % args[0]
- try:
- ret_str = mod.usage(imm)
- except AttributeError:
- return "Sorry, no usage available for this command"
- else:
- return "No arguments given"
- if ret_str is None:
- return "See log window for usage information"
- import immutils
- from immlib import *
- import getopt
- # Hook names, no need for an explanation
- HOOK_NAME = "vct_hook"
- # Symbol names of the functions we want to hook
- HOOK_SYMS = ["VariantChangeTypeEx"]
- # Module name, just to know where we are
- HOOK_MODULE = "OLEAUT32"
- class VCTHook(LogBpHook):
- """
- VariantChangeType Hook
- This hook is used to check if the arguments of VariantChangeType are pointers
- to the same object. There might be vulnerabilities in code that call this function
- in such a manner.
- """
- def __init__(self):
- LogBpHook.__init__(self)
- self.dbg = Debugger()
- self.count = 0
- def run(self, regs):
- pvargDest = self.dbg.readLong(regs['ESP'] + 0x4)
- pvarSrc = self.dbg.readLong(regs['ESP'] + 0x8)
- third = self.dbg.readLong(regs['ESP'] + 0xc)
- if pvargDest == pvarSrc:
- self.dbg.log("-"*80)
- call_stack = self.dbg.callStack()
- for frame in call_stack:
- self.dbg.log("Address = %08x | Stack = %08x | Procedure %s | Frame %08x | Called from %08x" \
- %(frame.address, frame.stack, frame.procedure, frame.frame, frame.calledfrom), address=frame.calledfrom)
- def usage(dbg):
- dbg.log("!VCTHook.py")
- dbg.log("-u (to uninstall hook)")
- def main(args):
- """
- """
- dbg = Debugger()
- mod = dbg.getModule(HOOK_MODULE)
- try:
- opts, argo = getopt.getopt(args, "ulc:", ["remove", "list", "count"])
- except getopt.GetoptError, err:
- usage(dbg)
- return str(err)
- for o,a in opts:
- if o == "-u":
- # TODO check if the hook exists
- dbg.removeHook(HOOK_NAME)
- return "Removed hook on %s." %(HOOK_NAME)
- elif o == "-l":
- hooks = dbg.listHooks()
- for hook in hooks:
- dbg.log(hook)
- return "OK"
- elif o == "-c":
- count = int(a)
- hooker = VCTHook()
- # Set hooks
- for sym_name in HOOK_SYMS:
- full_sym_name = HOOK_MODULE + "." + sym_name
- bp_address = dbg.getAddress(full_sym_name)
- dbg.log("Adding hook to %s on address %08x" %(full_sym_name, bp_address))
- hooker.add(HOOK_NAME, bp_address)
- return "Hooks are in Place!"
- if __name__ == "__main__":
- main()
Add Comment
Please, Sign In to add comment