def ReadDwordMemory(address=None): """ Read a dword in memory """ if address is None: address = threads.GetEip() data = ReadMemory(4, address) return u('<I', data)[0]
def ReadMemory(size, addr=None, mode=0): """ Read the memory of the process at a specific address """ # XXX: test if the address exists if addr is None: addr = threads.GetEip() b = bytearray(size) n = api.Readmemory(b, addr, size, mode) # XXX: Hmm, don't care about n right ? return str(b)
def PatchCode(s, address=None): """ Assemble s and patch address """ # XXX: test if the memory exists if address is None: address = threads.GetEip() bin = '' try: bin, s = utils.Assemble__(s) except Exception, e: raise e
def WriteMemory(buff, addr=None, mode=0): """ Write directly in the memory of the process """ # XXX: check if memory exists if addr is None: addr = threads.GetEip() n = api.Writememory(buff, addr, len(buff), mode) # flush the cache after writing ; not sure it's good/required to do that though. FlushMemoryCache() return n
def PatchCodeWithHex(s, address=None): """ Patch the code at address with unhexlify(s) """ # XXX: test if the memory exists if address is None: address = threads.GetEip() bin = '' try: bin = unhexlify(s) except: raise Exception('You must supply a string composed exclusively of hex symbols') # patch the code WriteMemory(address, bin)
def ReadMemory(size, addr = None, mode = 0): """ Read the memory of the process at a specific address """ # XXX: test if the address exists if addr == None: addr = threads.GetEip() buff = create_string_buffer(size) Readmemory( c_void_p(addressof(buff)), c_ulong(addr), c_ulong(size), c_int(mode) ) return buff.raw
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 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 WriteMemory(buff, addr = None, mode = 0): """ Write directly in the memory of the process """ # XXX: check if memory exists if addr == None: addr = threads.GetEip() b = create_string_buffer(buff) n = Writememory( c_void_p(addressof(b)), c_ulong(addr), c_ulong(sizeof(b) - 1), # create_string_buffer adds a null byte a the end c_int(mode) ) # flush the cache after writing ; not sure it's good/required to do that though. FlushMemoryCache() return n
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