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
# get information about the memory block mem_info = memory.FindMemory(address_start).contents # now we can call comparecommand size_to_dump = mem_info.size - (address_start - mem_info.base) offset, found = 0, False while offset < size_to_dump and found == False: # XXX: maybe its more efficient to read the whole memory block to avoid ReadMemory calls ? size_to_read = 16 # we'll go outside of the boundaries if (offset + size_to_read) >= size_to_dump: size_to_read = size_to_dump - offset code_process = memory.ReadMemory(size_to_read, address_start + offset) r = CompareCommand(code_process, size_to_read, address_start + offset, asmmod, nmodel) # if this is the same command, we found a match \o/ if r > 0: found = True else: offset += 1 if found: return address_start + offset return 0