Ejemplo n.º 1
0
def decrypt_aes_string(index):
    index ^= 0xAA

    addr = idaapi.get_dword(0x81A5140 + (index << 2))

    if index % 2 == 1:

        string = ''
        i = 0
        while True:
            ch = idaapi.get_byte(addr + i)
            if ch < 0x20 or ch > 0x7e:
                break
            string += chr(ch)
            i += 1

        decr_string = ''

        for i in range(len(string) >> 1):
            arg2, arg3 = ord(string[2 * i]), ord(string[2 * i + 1])
            eax = (16 * (arg2 - 1)) | (arg3 - 1) & 0xF
            eax &= 0xFF
            decr_string += chr(eax)

        return decr_string

    else:
        key = bytes(idaapi.get_byte(addr + i) for i in range(16))
        size = idaapi.get_dword(addr + 16)
        cipher = bytes(idaapi.get_byte(addr + 20 + i) for i in range(size))

        decryptor = AES.new(key, AES.MODE_ECB)
        decrypted_data = decryptor.decrypt(cipher)

        return str(decrypted_data)
Ejemplo n.º 2
0
def decrypt_xor_string(index):
    addr = idaapi.get_dword(0x81A51C0 + ((index ^ 0xAA) << 2))
    key = bytes(idaapi.get_byte(addr + i) for i in range(4))
    size = idaapi.get_dword(addr + 4)
    cipher = bytes(idaapi.get_byte(addr + 8 + i) for i in range(size))
    plain = ''.join(chr(cipher[i] ^ key[i % 4]) for i in range(size))

    return plain
Ejemplo n.º 3
0
def is_sead_safestringbase_null_char(c, cfunc): # type: (...) -> bool
    c = unwrap_cast(c)
    if c.op == hr.cot_var and cfunc:
        return "zero_" in cfunc.get_lvars()[c.v.idx].name
    if c.op != hr.cot_obj:
        return c.is_zero_const()
    return idaapi.get_byte(c.obj_ea) == 0
Ejemplo n.º 4
0
def make_cstrings():
    """Highlight a range and turn it into c-style strings
    
    NOTE: read_selection appears to be a fickle bitch. You absolutely have to 
    select more than one line at a time in order for it to work as expected.
    """
    # TODO check to verify that each byte is valid ascii
    selected = get_selected_bytes()
    if selected:
        curr_start = selected[1]
        curr_length = 0
        for ea in range(selected[1], selected[2]):
            if not cool_to_clobber(ea):
                print "[-] Error: Something that we shouldn't clobber at 0x%x" % ea
                break
            curr_byte = idaapi.get_byte(ea)
            curr_length += 1
            if curr_byte == 0:
                if curr_length > 1:
                    idaapi.doASCI(curr_start, curr_length)
                    curr_length = 0
                    curr_start = ea + 1
                else:
                    curr_length = 0
                    curr_start = ea + 1
    else:
        print "[-] Error: EA is not currently a selection endpoint %x" % idc.ScreenEA(
        )
Ejemplo n.º 5
0
    def process_instruction(self, packet, addr):
        """Architecture specific instruction processing"""
        
        # Call the generic part with the architecture specific operand
        # handling
        #
        
        (instruction,
        i_mnemonic,
        operands,
        operand_strings,
        data) = self.process_instruction_generic(addr)
        
        if i_mnemonic is None:
            return None

        if idaapi.get_byte(addr) == 0xf0:
            prefix = 'lock '
        else:
            prefix = ''
                    
        packet.add_instruction(instruction, addr, prefix+i_mnemonic,
            operand_strings, operands, data)
        
        return instruction
Ejemplo n.º 6
0
def get_str(x):
    res = bytearray()
    while True:
        c = idaapi.get_byte(x)
        if c == 0: break
        res.append(c)
        x += 1
    return res
Ejemplo n.º 7
0
 def get_strlen(self, addr):
     strlen = 0
     while get_byte(addr + strlen) != 0x0 and strlen < 50:
         strlen += 1
     #assume no names will ever be longer than 50 bytes
     if strlen == 50:
         return None
     return strlen
def decrypt(ea, key):

    # Virtual address to IMAGE_IMPORT_DESCRIPTOR->FirstThunk
    va_iat = 0
    # Virtual address to IMAGE_IMPORT_DESCRIPTOR->OriginalFirstThunk
    va_int = 0
    tmp_ea = ea

    # Back-tracing to locate the IMAGE_IMPORT_DESCRIPTOR from import address table passed from the callback
    for xref in idautils.XrefsTo(ea, 0):
        if XrefTypeName(xref.type) == 'Data_Offset':
            va_iat = xref.frm - 0x10

    if va_iat != 0:
        print "Import Name Table->%08x" % (idaapi.get_long(va_iat) + IMG_BASE)
        va_int = idaapi.get_long(va_iat) + IMG_BASE
    else:
        return

    if va_int != 0:
        va_itd = idaapi.get_long(va_int)
        # Enumerate array of IMAGE_THUNK_DATA
        while va_itd != 0:
            va_itd = va_itd + IMG_BASE
            if va_itd > IMG_BASE and va_itd <= IMG_END:
                print "Image thunk data->%08x" % va_itd
                va_ibn = va_itd + 2
                ch = idaapi.get_byte(va_ibn)
                str = ''
                while ch != 0 and ch != 255:
                    str += chr(ch ^ key)
                    va_ibn += 1
                    ch = idaapi.get_byte(va_ibn)

                # Save the decoded import name
                print "IMAGE_IMPORT_BY_NAME->Name (%08x): %s" % (va_itd + 2,
                                                                 str)
                idc.MakeName(tmp_ea, str)
                tmp_ea += 4

            # Next IMAGE_THUNK_DATA
            va_int += 4
            va_itd = idaapi.get_long(va_int)
    else:
        return
def decrypt(ea, key):
    
    # Virtual address to IMAGE_IMPORT_DESCRIPTOR->FirstThunk
    va_iat = 0
    # Virtual address to IMAGE_IMPORT_DESCRIPTOR->OriginalFirstThunk
    va_int = 0
    tmp_ea = ea
    
    # Back-tracing to locate the IMAGE_IMPORT_DESCRIPTOR from import address table passed from the callback
    for xref in idautils.XrefsTo(ea, 0):
        if XrefTypeName(xref.type) == 'Data_Offset':
            va_iat = xref.frm - 0x10

    if va_iat != 0:
        print "Import Name Table->%08x" % (idaapi.get_long(va_iat) + IMG_BASE)
        va_int = idaapi.get_long(va_iat) + IMG_BASE
    else:
        return
        
    if va_int != 0:
        va_itd = idaapi.get_long(va_int)
        # Enumerate array of IMAGE_THUNK_DATA
        while va_itd != 0:
            va_itd = va_itd + IMG_BASE
            if va_itd > IMG_BASE and va_itd <= IMG_END:
                print "Image thunk data->%08x" % va_itd
                va_ibn = va_itd + 2
                ch = idaapi.get_byte(va_ibn)
                str = ''
                while ch != 0 and ch != 255:
                    str += chr(ch ^ key)
                    va_ibn += 1
                    ch = idaapi.get_byte(va_ibn)
                
                # Save the decoded import name
                print "IMAGE_IMPORT_BY_NAME->Name (%08x): %s" % (va_itd+2, str)
                idc.MakeName(tmp_ea, str)
                tmp_ea += 4
                
            # Next IMAGE_THUNK_DATA
            va_int += 4
            va_itd = idaapi.get_long(va_int)
    else:
        return
Ejemplo n.º 10
0
def get_loaded_bytes(start_addr, size, fill_with="\x00"):
  data = ""
  cur_ea = start_addr
  while cur_ea < (start_addr+size):
    if idaapi.is_loaded(cur_ea):
      data += chr(idaapi.get_byte(cur_ea))
    else:
      data += fill_with
    cur_ea += 1
  return bytes(data, 'latin1')
Ejemplo n.º 11
0
    def get_string_table_start_address(self, address):
        string_table_start_address = address
        # find current string start address
        while idaapi.get_byte(string_table_start_address - 1) != 0:
            string_table_start_address -= 1

        while self.get_prev_ascii_string_address(string_table_start_address):
            string_table_start_address = self.get_prev_ascii_string_address(string_table_start_address)

        return string_table_start_address
Ejemplo n.º 12
0
def Dump_Memory(start_addr, end_addr):

    print '[*]begin to dump memory'
    handle_f = open('d:/dump.so', 'wb')
    for byte_addr in range(start_addr, end_addr):
        byte_value = idaapi.get_byte(byte_addr)
        handle_f.write(struct.pack('B', byte_value))
    handle_f.close()
    print '[-]dump memory save to d:/dump.so'
    print '[*]script finish'
Ejemplo n.º 13
0
    def get_next_ascii_string_address(address):
        """

        :param address: must be current ascii string start address.
        :return:
        """
        next_string_start_address = address
        # find current string end address
        while idaapi.get_byte(next_string_start_address) != 0:
            next_string_start_address += 1

        # string table interval should less than 5 bytes.
        # TODO: need handle short string.
        if idc.Dword(next_string_start_address + 1) == 0:
            return None

        while idaapi.get_byte(next_string_start_address) == 0:
            next_string_start_address += 1

        return next_string_start_address
Ejemplo n.º 14
0
def main(ea_start, ea_end, save_file):
    print '[*]begin to dump segment'

    handle_f = open(save_file, 'wb')
    for byte_addr in range(ea_start, ea_end):
        byte_value = idaapi.get_byte(byte_addr)
        handle_f.write(struct.pack('B', byte_value))

    handle_f.close()

    print '[*]script by freakish, enjoy~~'
    print '[*]script finish'
Ejemplo n.º 15
0
def hook_skip_calls(emu, addr, size, user_data):
    # Need to skip return instructions too: when we emulate an area not
    # recognized as a function, the emulation will not stop at the retn and the
    # execution will continue at someplace we don't want to exec.
    #
    # Skip 0xCC (INT3 breakpoints) to not stop the execution.
    mnem = GetMnem(addr)
    if mnem == "call" or idaapi.get_byte(addr) == 0xCC or "ret" in mnem:
        emu.reg_write(UC_X86_REG_RIP, addr + size)
    elif "j" in mnem:
        if hex(int(GetOpnd(addr, 0)[4:], 16)) > next_call:
            emu.reg_write(UC_X86_REG_RIP, addr + size)
    return
Ejemplo n.º 16
0
 def followAddress(self, address):
     b = idaapi.get_byte(address)
     if (b == 0xE8):
         callOffset = ida_bytes.get_dword(address + 1)
         if (callOffset > 2147483647):
             callOffset -= 4294967296
         address = address + 5 + callOffset
         return address, False
     elif (b == 0xE9):
         # Lazy and none of my signatures use this yet...
         return address, "JMP Instruction signatures not supported yet"
     else:
         return address, False
Ejemplo n.º 17
0
    def activate(self, ctx):
        info = idaapi.get_inf_structure()
        selection = idaapi.read_selection()
        start = selection[1]
        end = selection[2]

        if selection[0] == False:
            start = idaapi.get_screen_ea()

            if start == idaapi.BADADDR:
                print 'Easy Nop :: Screen EA == idaapi.BADADDR'
                return 0

            end = start + idaapi.get_item_size(start)
        else:
            end += idaapi.get_item_size(end)

        if start == idaapi.BADADDR:
            print 'Easy Nop :: Selection EA == idaapi.BADADDR'
            return 0

        if start == end:
            print 'Easy Nop :: Nothing to nop'
            return 0

        for x in range(start, end):
            # Maybe theres a smarter way to get the nop value for different archs e.g. Assemble('nop') -> 0x90
            idaapi.patch_byte(x, 0x90)

        for x in range(start + 1, end):
            idaapi.hide_item(x)

        # Must do this else it bugs out on 2x 1 byte instructions being nopped
        idaapi.hide_item(start)
        idaapi.unhide_item(start)

        # Search for hidden nops and add to count
        while idaapi.get_byte(end) == 0x90 and idaapi.is_hidden_item(
                end) == True:
            end += 1

        count = end - start

        if count > 1:
            idaapi.set_cmt(start, "truncated nops (%d)" % (count), False)

        print end
        print start

        return 1
Ejemplo n.º 18
0
def xor_s(addr, key):
  ret = []
  while True:
    c = idaapi.get_byte(addr)
    addr += 1
    if c == 0:
      print str(ret)
      ret_s = []
      for x in ret:
        ret_s.append(chr(x))
      print ''.join(ret_s)
      return
    ret.append(c ^ key)
  return
Ejemplo n.º 19
0
def xor_mem(addr, key, n):
  ret = []
  for i in range(n):
    c = idaapi.get_byte(addr)
    addr += 1
    ret.append(c ^ key)
  print str(ret)
  ret_s = []
  for x in ret:
    if x == 0:
      ret_s.append('\\0')
    else:
      ret_s.append(chr(x))
  print ''.join(ret_s)
  return
def dynamic_breakpoint(targe_type):
    has_linker = False
    module_base = idc.GetFirstModule()
    while module_base != None:
        module_name = idc.GetModuleName(module_base)
        if module_name.find('linker') >= 0:
            has_linker = True
            break

        module_base = idc.GetNextModule(module_base)

    if has_linker == False:
        print '[*]unable to find linker module base'
        return

    module_size = idc.GetModuleSize(module_base)
    print '[*]found linker base=>0x%08X, Size=0x%08X' % (module_base,
                                                         module_size)

    print("\t[-]begin to search DT_INIT")
    init_func_ea = 0
    init_array_ea = 0
    # bytecode=b'\x53\x1e\x73\xb5\x03\x33\x06\x46\x0d\x46\x14\x46\x24\xd8\x13\x48\x78\x44\x01\x68\x01\x29'
    bytecode = [
        0x14, 0x49, 0x04, 0x20, 0x23, 0x46, 0x14, 0x4A, 0x79, 0x44, 0x7A, 0x44
    ]
    findcode = True
    for ea_offset in range(module_base, module_base + module_size):
        findcode = True
        for i in xrange(len(bytecode)):
            if idaapi.get_byte(ea_offset + i) != bytecode[i]:
                findcode = False
                break
        if (findcode == True):
            init_func_ea = ea_offset + 0x1A
            init_array_ea = ea_offset + 0x30
            break
    if (findcode == False):
        print("can't find bytecode")
        return
    print "\t[-]found INIT=>0x%08X INIT_ARRAY=>0x%08X" % (init_func_ea,
                                                          init_array_ea)
    print("\t[-]try set breakpoint there")
    if targe_type == 12:
        idc.AddBpt(init_func_ea)
    if targe_type == 25:
        idc.AddBpt(init_array_ea)
    print("[*]script finish")
Ejemplo n.º 21
0
    def activate(self, ctx):
        t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t(
        ), idaapi.get_current_viewer()
        if idaapi.read_selection(view, t0, t1):
            start, end = t0.place(view).toea(), t1.place(view).toea()
            end += idaapi.get_item_size(end)
        else:
            start = idaapi.get_screen_ea()

            if start == idaapi.BADADDR:
                print('Easy Nop :: Screen EA == idaapi.BADADDR')
                return 0

            end = start + idaapi.get_item_size(start)

        if start == idaapi.BADADDR:
            print('Easy Nop :: Selection EA == idaapi.BADADDR')
            return 0

        if start == end:
            print('Easy Nop :: Nothing to nop')
            return 0

        for x in range(start, end):
            # Maybe theres a smarter way to get the nop value for different archs e.g. Assemble('nop') -> 0x90
            idaapi.patch_byte(x, 0x90)

        for x in range(start + 1, end):
            idaapi.hide_item(x)

        # Must do this else it bugs out on 2x 1 byte instructions being nopped
        idaapi.hide_item(start)
        idaapi.unhide_item(start)

        # Search for hidden nops and add to count
        while idaapi.get_byte(end) == 0x90 and idaapi.is_hidden_item(
                end) == True:
            end += 1

        count = end - start

        if count > 1:
            idaapi.set_cmt(start, "truncated nops (%d)" % (count), False)

        print(end)
        print(start)

        return 1
Ejemplo n.º 22
0
    def get_prev_ascii_string_address(address):
        """

        :param address: must be current ascii string start address.
        :return:
        """
        prev_string_start_address = address
        # string table interval should less than 5 bytes.
        if idc.Dword(address - 5) == 0:
            return None
        else:
            prev_string_start_address -= 5
            # TODO: Need handle short string.
            while idaapi.get_byte(prev_string_start_address) != 0:
                prev_string_start_address -= 1
            return prev_string_start_address + 1
Ejemplo n.º 23
0
    def process_instruction(self, packet, addr):
        """Architecture specific instruction processing"""

        # Call the generic part with the architecture specific operand
        # handling
        #

        (instruction, i_mnemonic, operands, operand_strings,
         data) = self.process_instruction_generic(addr)

        if i_mnemonic is None:
            return None

        if idaapi.get_byte(addr) == 0xf0:
            prefix = 'lock '
        else:
            prefix = ''

        packet.add_instruction(instruction, addr, prefix + i_mnemonic,
                               operand_strings, operands, data)

        return instruction
Ejemplo n.º 24
0
    def ev_ana_insn(self, insn):
        b1 = idaapi.get_byte(insn.ea)
        if b1 >= 0x70 and b1 <= 0x7F:
            d1 = idaapi.get_byte(insn.ea + 1)
            b2 = idaapi.get_byte(insn.ea + 2)
            d2 = idaapi.get_byte(insn.ea + 3)
            if b2 == b1 ^ 0x01 and d1 - 2 == d2:
                idaapi.put_byte(insn.ea, 0xEB)
                idaapi.put_word(insn.ea + 2, 0x9090)

        elif b1 == 0x0F:
            b1_1 = idaapi.get_byte(insn.ea + 1)
            d1 = idaapi.get_long(insn.ea + 2)
            b2 = idaapi.get_byte(insn.ea + 6)
            b2_1 = idaapi.get_byte(insn.ea + 7)
            d2 = idaapi.get_long(insn.ea + 8)
            if b2 == 0x0F and b1_1 ^ 0x01 == b2_1 and d1 - 6 == d2:
                idaapi.put_byte(insn.ea, 0xE9)
                idaapi.put_long(insn.ea + 1, d1 + 1)
                idaapi.put_byte(insn.ea + 5, 0x90)
                idaapi.put_word(insn.ea + 6, 0x9090)
                idaapi.put_long(insn.ea + 8, 0x90909090)

        return False
Ejemplo n.º 25
0
def selfmod_decoder(rip_address):
	if ((rip_address > 0x400935) and (rip_address <= 0x40103D)):
		idaapi.patch_byte(rip_address, idaapi.get_byte(rip_address) ^ (rip_address & 0xFF))
	return
Ejemplo n.º 26
0
def repeating_key_xor(start_address, buffer_len, key):
	for i in xrange(buffer_len):
		c = idaapi.get_byte(start_address + i) ^ ord(key[(i % len(key))])
		idaapi.patch_byte(start_address + i, c)	
	return
Ejemplo n.º 27
0
import idaapi

def derive_key(xs, ys):
	return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys))

def repeating_key_xor(start_address, buffer_len, key):
	for i in xrange(buffer_len):
		c = idaapi.get_byte(start_address + i) ^ ord(key[(i % len(key))])
		idaapi.patch_byte(start_address + i, c)	
	return

def selfmod_decoder(rip_address):
	if ((rip_address > 0x400935) and (rip_address <= 0x40103D)):
		idaapi.patch_byte(rip_address, idaapi.get_byte(rip_address) ^ (rip_address & 0xFF))
	return

routine_1_address = 0x400E0E
candidate_plaintext = [0x55, 0x48, 0x89, 0xE5]
key1 = ''.join([chr(idaapi.get_byte(routine_1_address + i) ^ candidate_plaintext[i]) for i in xrange(len(candidate_plaintext))])

print "[+] Key1: [%s]" % key1

# Step 1
repeating_key_xor(routine_1_address, 0x9E, key1)

# Step 2
routine_2_address = 0x400936
repeating_key_xor(routine_2_address, 0xEC, key1)

# Step 3 to be applied manually (or as a per-instruction SIGTRAP hook)
Ejemplo n.º 28
0
def create_func_signature(start, length):
    """Return function signature in mega format."""
    if length < MIN_SIG_LENGTH:
        return

    ea = start
    end = start + length
    sig = ""
    publics = []
    refs = {}
    v = [False for _ in range(length)]

    while (ea - start < length):
        flags = idaapi.getFlags(ea)
        if idaapi.has_name(flags):
            publics.append(ea)

        ref = idaapi.get_first_dref_from(ea)
        if ref != idaapi.BADADDR:
            ref_loc = ea
            set_v_bytes(v, ref_loc - start)
            refs[ref_loc] = ref

            # Check if there is a second data location ref'd
            ref = idaapi.get_next_dref_from(ea, ref)
            if ref != idaapi.BADADDR:
                ref_loc = ea
                set_v_bytes(v, ref_loc - start)
                refs[ref_loc] = ref
        else:
            # Code ref?
            ref = idaapi.get_first_fcref_from(ea)
            if ref != idaapi.BADADDR:
                if not start <= ref < end:
                    ref_loc = ea
                    set_v_bytes(v, ref_loc - start)
                    refs[ref_loc] = ref

            # Check for r13 and rtoc
            disasm = idaapi.generate_disasm_line(ea)
            if "%r13" in disasm or "%rtoc" in disasm:
                ref_loc = ea
                set_v_bytes(v, ref_loc - start)

        ea = idaapi.next_not_tail(ea)

    line = ""
    for i in range(length):
        if v[i]:
            line += ".."
        else:
            line += "{:02X}".format(idaapi.get_byte(start + i))

    # Write publics
    found = False
    for public in sorted(publics):
        name = idaapi.get_true_name(idaapi.BADADDR, public)
        if name:
            found = True
            if is_skipped(name):
                idaapi.warning("Rename the function {} ({})!".format(
                    name, "it is on the skip list"))
                return
            else:
                line += " :{:04X} {}".format(public - start, name)

    if not found:
        idaapi.warning("The function has autogenerated name, rename it first!")

    # Write refs
    for ref_loc, ref in sorted(refs.items()):
        name = idaapi.get_true_name(idaapi.BADADDR, ref)
        if name:
            if not is_skipped(name) and ref_loc != idaapi.BADADDR:
                line += " ^{:04X} {}".format(ref_loc - start, name)

    return line
Ejemplo n.º 29
0
def selfmod_decoder(rip_address):
    if ((rip_address > 0x400935) and (rip_address <= 0x40103D)):
        idaapi.patch_byte(rip_address,
                          idaapi.get_byte(rip_address) ^ (rip_address & 0xFF))
    return
Ejemplo n.º 30
0
	else :
		print "Certs processing fail!"

	# TODO: Parse rights of the keys
	# TODO: Parse ASN1 from digests

	# Processing Images
	i = 0
	while i < 4 :
		print "images type %s " % type (certppa.images)
		if certppa.images[i].image_offset != 0 :
			print "Found PPA image at %x offset " % certppa.images[i].image_offset
		if certisw.images[i].image_offset != 0 :
			print "Found ISW image at %x offset " % certisw.images[i].image_offset
		i += 1

	# image start at certppa mark address + certppa.images[i].image_offset


# Script body

start = idc.MinEA()
stop = idc.MaxEA()
version_addr = idaapi.find_binary(start, stop, "43 65 72 74 49 53 57 00", 0, 0) + 0x79e # "CertISW" string
version_minor = idaapi.get_byte(version_addr)
version_major = idaapi.get_byte(version_addr + 1)
print "MBM loader Major Version: %x " % version_major
print "MBM loader Minor Version: %x " % version_minor
parse_structures()

Ejemplo n.º 31
0
    def process_instruction_generic(self, addr):
        """Architecture agnostic instruction parsing."""
        
        # Retrieve the instruction mnemonic
        #
        i_mnemonic = self.get_mnemonic(addr)
        if not i_mnemonic:
            return None, None, None, None, None
            
        # Set the current location to the instruction to disassemble
        #
        #idaapi.jumpto(addr)
        #idaapi.ua_ana0(addr)

        # Up to IDA 5.7 it was called ua_code...
        if hasattr(idaapi, 'ua_code'):
            # Gergely told me of using ua_code() and idaapi.cvar.cmd
            # instead of jumpto() and get_current_instruction(). The latter
            # where always making IDA to reposition the cursor and refresh
            # the GUI, which was quite painful
            #
            idaapi.ua_code(addr)
            # Retrieve the current instruction's structure and
            # set its type
            ida_instruction = idaapi.cvar.cmd
        else:
            # now it's called decode_insn()
            idaapi.decode_insn(addr)
            # Retrieve the current instruction's structure and
            # set its type
            ida_instruction = idaapi.cmd


        instruction = Instruction(
            ida_instruction.itype, ida_instruction.size, ida_instruction.ip)
        self.current_instruction_type = instruction.itype
        
        
        # Try to process as many operands as IDA supports
        #
        # Up to IDA 5.7 it was called ua_code... so we use it to check for 5.7
        if hasattr(idaapi, 'ua_code'):
            operands = self.operands_parser( addr, [(
                idaapi.get_instruction_operand(ida_instruction, idx),
                idx ) for idx in range(6)] )
        else:
            operands = self.operands_parser( addr, [(
                ida_instruction.Operands[idx],
                idx ) for idx in range(6)] )
                
        # Retrieve the operand strings
        #
        operand_strings = [
            idc.GetOpnd(addr, idx) for idx in range(len(operands))]
        
        # Get the instruction data
        #
        data = ''.join(
            [chr(idaapi.get_byte(addr+i)) for i in range(idc.ItemSize(addr))])
        
        # Return the mnemonic and the operand AST
        #
        return instruction, i_mnemonic, operands, operand_strings, data
Ejemplo n.º 32
0
for func_addr in idautils.Functions(0, 0xffffffff):
    # Signature is based on the beginning of the decryption function:
    # 53                  push    ebx
    # 8B DA               mov     ebx, edx
    # 56                  push    esi
    # 33 F6               xor     esi, esi
    # 57                  push    edi
    # 8B F9               mov     edi, ecx
    # 39 34 DD C4 DE 06+  cmp     dword_1006DEC4[ebx*8], esi
    if idaapi.get_many_bytes(func_addr, 12) == "538BDA5633F6578BF93934DD".decode('hex'):
        decoding_func = idaapi.get_func(func_addr)
        break

for addr in idautils.Heads(decoding_func.startEA, decoding_func.endEA):
    if chr(idaapi.get_byte(addr)) == "\x8A":
        # 8A 89 B0 D5 04 10  mov     cl, key[ecx]
        #       ^ key offset
        key_offset = struct.unpack("<I", idaapi.get_many_bytes(addr + 2, 4))[0]
    elif idaapi.get_many_bytes(addr, 1) == "\x6B":
        # 6B C2 33                   imul    eax, edx, 51
        #       ^ key length
        key_len = idaapi.get_byte(addr + 2)
    elif idaapi.get_many_bytes(addr, 3) == "\x8B\x04\xDD":
        # 8B 04 DD C0 DE 06 10       mov     eax, packed_strings_list[ebx*8]
        #          ^ address of string list
        struct_base = struct.unpack("<I", idaapi.get_many_bytes(addr + 3, 4))[0]

print "[*] Decoding function : 0x{:08x}".format(int(decoding_func.startEA))
print "[*] Encoded string list base : 0x{:08x}".format(struct_base)
Ejemplo n.º 33
0
    def decoder(self,from_loc,to_loc,key):
        self.GlobalCounter += 1
        for loc in range(from_loc, to_loc+1):
            temp = idc.Byte(loc) ^ key
            idc.PatchByte(loc,temp)
            SetColor(loc, CIC_ITEM, 0x208020)

        next_inst = from_loc
        ready = False
        xor_check = False
        jmp_dword = False
        
        idc.MakeUnkn(from_loc,1)
        idc.MakeCode(from_loc)

        while next_inst <= to_loc:
 
            #idc.MakeCode(next_inst)
            idaapi.decode_insn(next_inst)
            inst = idc.GetDisasm(next_inst)
            print "inst %s next_inst %x" % (inst, next_inst)
            opndValue = idc.GetOperandValue(next_inst,1)

            if ready and xor_check and jmp_dword:
                self.flag.append(format(key,'x'))
                print '[{0:d}] decoder(0x{1:x},0x{2:x},0x{3:x})'.format(self.GlobalCounter,from_loc,to_loc,key)
                
                
                if self.GlobalCounter >= 10:
                    print ''.join([chr(int(i,16)) for i in self.flag]).strip()
                
                
                return self.decoder(from_loc,to_loc,key)
                
              
            elif "xor" in inst:
                #key = hex(opndValue)
                #print idaapi.cmd.Operands[1].value
                xor_check = True
                key = idc.GetOperandValue(next_inst,1)
                print key
                
            elif "mov" in inst or format(idaapi.get_byte(next_inst),'x') == "BA":
                print idaapi.cmd.Operands[1].value
                to_loc = idaapi.cmd.Operands[1].value
               
            elif format(idaapi.get_byte(next_inst),'x') == "81" or "cmp" in inst:
                print idaapi.cmd.Operands[1].value
                from_loc = idaapi.cmd.Operands[1].value
                ready = True
                
            elif format(idaapi.get_byte(next_inst),'x') == "e9" or "jmp" in inst:
                print 'jmp_dword hitted'
                jmp_dword = True
                
                if idaapi.cmd.Operands[0].type == o_near and "dword" in GetOpnd(next_inst,0):
                
                    offset = int(idaapi.tag_remove(idaapi.ua_outop2(next_inst, 0))[24:-1],16)
                    address = GetOperandValue(next_inst,0)
                    dword_adr = address - offset
                    idc.MakeUnkn(dword_adr,DOUNK_SIMPLE)
                    idc.MakeCode(address)
                
            next_inst = idc.NextHead(next_inst)
            #next_inst += idaapi.decode_insn(next_inst)
            
        print "out of loop"
Ejemplo n.º 34
0
    def _addBytesToSig(self, sigIndex, ea, size):

        for i in range(0, size):
            b = idaapi.get_byte(ea + i)
            self.Sigs[sigIndex].sig.append('%02X' % b)
Ejemplo n.º 35
0
import idaapi
from idaapi import Choose2

start_ea = 0x7C19

for ix in xrange(0xCF):
    print ix
    byte_to_decr = idaapi.get_byte(start_ea + ix)
    to_rotate = (0xCF - ix) % 8
    byte_decr = (byte_to_decr >> to_rotate) | (byte_to_decr << (8 - to_rotate))

    idaapi.patch_byte(start_ea + ix, byte_decr)
Ejemplo n.º 36
0
 def get_byte(self, addr):
     return idaapi.get_byte(addr)
Ejemplo n.º 37
0
anim = sark.structure.get_struct('AnimationFrame')
end_of_frame = sark.structure.get_struct("EndOfAnimFrame")
play_sound = sark.structure.get_struct("PartialFuncPlaySound")
func_with_count = sark.structure.get_struct("PartialFuncWithCount")
partial_func_param1 = sark.structure.get_struct("PartialFuncParam1Func")
set_image_width = sark.structure.get_struct("PartialFuncSetImageWidth")
dataseg = sark.Segment(name='dataseg').ea
# anim_offset = idaapi.get_word(sark.Line(ea=dataseg + idautils.cpu.di + 2).ea)
current_position = sark.Line().ea
# current_byte = idaapi.get_byte(current_position)

done = False

print("running")
while not done:
    current_byte = idaapi.get_byte(current_position)
    if current_byte == 0xff:
        print("applying EndOfAnimFrame")
        idaapi.doStruct(current_position, 2, end_of_frame)
        next_byte = idaapi.get_byte(current_position + 1)
        if next_byte == 0xff:
            done = True
        current_position += 2
    elif current_byte < 0x80:
        # print(current_byte)
        print("applying AnimationFrame")
        test = idaapi.doStruct(current_position, 6, anim)
        # print(test)
        current_position += 6
        # print(hex(current_position-dataseg))
    elif current_byte == 0x92:
Ejemplo n.º 38
0
def repeating_key_xor(start_address, buffer_len, key):
    for i in xrange(buffer_len):
        c = idaapi.get_byte(start_address + i) ^ ord(key[(i % len(key))])
        idaapi.patch_byte(start_address + i, c)
    return


def selfmod_decoder(rip_address):
    if ((rip_address > 0x400935) and (rip_address <= 0x40103D)):
        idaapi.patch_byte(rip_address,
                          idaapi.get_byte(rip_address) ^ (rip_address & 0xFF))
    return


routine_1_address = 0x400E0E
candidate_plaintext = [0x55, 0x48, 0x89, 0xE5]
key1 = ''.join([
    chr(idaapi.get_byte(routine_1_address + i) ^ candidate_plaintext[i])
    for i in xrange(len(candidate_plaintext))
])

print "[+] Key1: [%s]" % key1

# Step 1
repeating_key_xor(routine_1_address, 0x9E, key1)

# Step 2
routine_2_address = 0x400936
repeating_key_xor(routine_2_address, 0xEC, key1)

# Step 3 to be applied manually (or as a per-instruction SIGTRAP hook)
Ejemplo n.º 39
0
for func_addr in idautils.Functions(0, 0xffffffff):
    # Signature is based on the beginning of the decryption function:
    # 53                  push    ebx
    # 8B DA               mov     ebx, edx
    # 56                  push    esi
    # 33 F6               xor     esi, esi
    # 57                  push    edi
    # 8B F9               mov     edi, ecx
    # 39 34 DD C4 DE 06+  cmp     dword_1006DEC4[ebx*8], esi
    if idaapi.get_many_bytes(func_addr,
                             12) == "538BDA5633F6578BF93934DD".decode('hex'):
        decoding_func = idaapi.get_func(func_addr)
        break

for addr in idautils.Heads(decoding_func.startEA, decoding_func.endEA):
    if chr(idaapi.get_byte(addr)) == "\x8A":
        # 8A 89 B0 D5 04 10  mov     cl, key[ecx]
        #       ^ key offset
        key_offset = struct.unpack("<I", idaapi.get_many_bytes(addr + 2, 4))[0]
    elif idaapi.get_many_bytes(addr, 1) == "\x6B":
        # 6B C2 33                   imul    eax, edx, 51
        #       ^ key length
        key_len = idaapi.get_byte(addr + 2)
    elif idaapi.get_many_bytes(addr, 3) == "\x8B\x04\xDD":
        # 8B 04 DD C0 DE 06 10       mov     eax, packed_strings_list[ebx*8]
        #          ^ address of string list
        struct_base = struct.unpack("<I", idaapi.get_many_bytes(addr + 3,
                                                                4))[0]

print "[*] Decoding function : 0x{:08x}".format(int(decoding_func.startEA))
print "[*] Encoded string list base : 0x{:08x}".format(struct_base)
Ejemplo n.º 40
0
def repeating_key_xor(start_address, buffer_len, key):
    for i in xrange(buffer_len):
        c = idaapi.get_byte(start_address + i) ^ ord(key[(i % len(key))])
        idaapi.patch_byte(start_address + i, c)
    return