def display_seh_chain(): """ Walk on the stack to find the SEH handlers """ addr_teb = threads.GetCurrentTEB() seh_addr = memory.ReadDwordMemory(addr_teb) if seh_addr == 0: return None seh_entries = [] # This is the last entry if SEH.Next = -1 while seh_addr != 0xffffffff: if memory.IsMemoryExists(seh_addr) == False: break seh_next, seh_handler = memory.ReadDwordMemory( seh_addr), memory.ReadDwordMemory(seh_addr + 4) seh_entries.append({ 'handler': seh_handler, 'symbol': sym.GetSymbolFromAddress(seh_handler), 'next': seh_next }) seh_addr = seh_next i = 0 for entry in seh_entries: print '#%.2d - Handler: %s (%#.8x) - Next @ %#.8x' % ( i, entry['symbol'], entry['handler'], entry['next']) i += 1
def display_call_stack(nb_max_frame=100): """ Walk on the stack & generate a call stack """ frames_info = [] args = [] ebp = threads.GetEbp() for i in range(nb_max_frame): # IsMemoryExists recognizes kernel memory, so we have to manually check it if memory.IsMemoryExists(ebp) == False or ebp >= 0x80000000: break # at EBP we have the SEBP sebp = memory.ReadDwordMemory(ebp) # and right after the SEIP seip = memory.ReadDwordMemory(ebp + 4) if sebp == 0 or seip == 0 or memory.IsMemoryExists( sebp) == False or memory.IsMemoryExists(seip) == False: break symbol = sym.GetSymbolFromAddress(seip) frames_info.append({ 'return-address': seip, 'address': sebp + 4, 'symbol': symbol if symbol != None else 'no symbol found', }) ebp = sebp eip = threads.GetEip() print "#%.2d %#.8x : %s" % (len(frames_info), eip, sym.GetSymbolFromAddress(eip)) for i in range(len(frames_info)): c = frames_info[i] ri = len(frames_info) - i - 1 print '#%.2d %#.8x : %s (found @%#.8x)' % (ri, c['return-address'], c['symbol'], c['address'])
def FindInstr(instr, address_start=None): """ Find the address of a specific instruction """ if address_start == None: address_start = threads.GetEip() if memory.IsMemoryExists(address_start) == False: return 0 # now assembleallforms to get the t_asmmod required to call comparecommand asmmod, nmodel = '', 0 try: #XXX: fix the ip parameter to be able of finding eip-dependent instruction asmmod, nmodel = AssembleAllForms(instr, 0) except Exception, e: raise (e)
def FindHexInPage(s, address_start=None): """ Find hexadecimal values like E9??FF?A?? The '?' is a wildcard for one nibbles ; that idea comes from the excellent ODBG scripting language Note: This function try to find an hexadecimal pattern only in one page of the memory (either in address_start's page or in EIP's page) """ def hex_matched(data, s): """ Validate if s match with data """ does_it_matched = True idx_data = 0 for idx in range(0, len(s), 2): b_str = s[idx:idx + 2] byte_to_compare = ord(data[idx_data]) # have we a wildcard ? if '?' in b_str: # wildcard on the high nibble if b_str[0] == '?' and b_str[1] != '?': low_nibble = (byte_to_compare & 0x0f) if low_nibble != int(b_str[1], 16): does_it_matched = False # wildcard on the low nibble elif b_str[1] == '?' and b_str[0] != '?': high_nibble = ((byte_to_compare & 0xf0) >> 4) if high_nibble != int(b_str[0], 16): does_it_matched = False # wildcard on the entire byte else: pass else: b = int(b_str, 16) if b != byte_to_compare: does_it_matched = False idx_data += 1 if does_it_matched == False: break return does_it_matched # ensure we have a multiple of 2 digits assert (len(s) % 2 == 0) s = s.lower() # we only accept hexa digits and the wildcard '?' assert (filter(lambda c: c in '0123456789abcdef?', s) == s) if address_start == None: address_start = threads.GetEip() # some memory must be mapped at this address if memory.IsMemoryExists(address_start) == False: return 0 # get information about the memory block mem_info = memory.FindMemory(address_start).contents size_mem_block = mem_info.size - (address_start - mem_info.base) offset, found = 0, False nb_bytes = len(s) / 2 while offset < (size_mem_block - nb_bytes) and found == False: data = memory.ReadMemory(nb_bytes, address_start + offset) if hex_matched(data, s): found = True else: offset += 1 if found: return address_start + offset return 0