def __PltResolver(jmprel, strtab, symtab, pltgot):
     seg_sec = idc.selector_by_name('.plt.sec')
     sec_start = idc.get_segm_by_sel(seg_sec)
     sec_end = idc.get_segm_end(sec_start)
     if sec_start == idaapi.BADADDR:
         print("[-] can't find .plt.sec segment")
         return
     idx = 0
     while True:
         r_off = idc.get_wide_dword(jmprel + 0x8 * idx)
         r_info1 = idc.get_wide_byte(jmprel + 0x8 * idx + 0x4)
         r_info2 = idc.get_wide_byte(jmprel + 0x8 * idx + 0x5)
         if r_off > 0x7fffffff:
             return
         if r_info1 == 7:
             st_name = idc.get_wide_dword(symtab + r_info2 * 0x10)
             name = idc.get_strlit_contents(strtab + st_name)
             # rename got
             idc.set_name(r_off, name.decode("ascii") + '_ptr')
             plt_func = idc.get_wide_dword(r_off)
             # rename plt
             idc.set_name(plt_func, 'j_' + name.decode("ascii"))
             SetFuncFlags(plt_func)
             # rename plt.sec
             for addr in idautils.DataRefsTo(r_off):
                 plt_sec_func = idaapi.get_func(addr)
                 if plt_sec_func:
                     plt_sec_func_addr = plt_sec_func.start_ea
                     idc.set_name(plt_sec_func_addr,
                                  '_' + name.decode("ascii"))
                     SetFuncFlags(plt_sec_func_addr)
                 else:
                     print("[!] idaapi.get_func({}) failed".format(
                         hex(addr)))
             got_off = r_off - pltgot
             target = '+{}h'.format(
                 hex(got_off).lower().replace('0x',
                                              '').replace('l',
                                                          '').rjust(2, '0'))
             for func_ea in idautils.Functions(sec_start, sec_end):
                 func = idaapi.get_func(func_ea)
                 cur = func.start_ea
                 end = func.endEA
                 find = False
                 while cur <= end:
                     code = idc.GetDisasm(cur).lower().replace(' ', '')
                     if target in code:
                         find = True
                         break
                     cur = idc.NextHead(cur, end)
                 if find:
                     idc.set_name(func_ea, '_' + name)
                     SetFuncFlags(func_ea)
         idx += 1
Esempio n. 2
0
def get_j_val(ea):
    size = 0
    j_val = 0
    op1 = idc.get_wide_byte(ea)
    if op1 == 0x0f:  # jz or jnz
        j_val = idc.get_wide_dword(ea + 2)
        size = 6
    else:  # jz short or jnz short
        j_val = idc.get_wide_byte(ea + 1)
        size = 2

    return j_val, size
Esempio n. 3
0
def decrypt_string(idx):
    if idx >= 0x36F4:
        return  # out of bounds
    res = ""
    while True:
        c = idc.get_wide_byte(enc_strings +
                              idx) ^ idc.get_wide_byte(bytes_arr +
                                                       (idx & 0x3F))
        if c == 0: break
        res += chr(c)
        idx += 1
    return res
Esempio n. 4
0
    def isLocalAsciiString(self, ea, check_refs=True):
        r"""Check if the given address is the beginning of a valid local string.

        Args:
            ea (int): effective address to be checked

        Notes
        -----
            0. If selected, the string must have a data reference to it.
            1. The string should be aligned (local alignment).
            2. The string should only contain chars from our alpha-bet.
            3. The string should be '\0' terminated.
            4. If applicable, the string should be padded with the correct padding byte.
            5. The string's length must follow one of the following rules:
                a) Larger than the local alignment.
                b) At least 2 bytes, and the first is '%' (for short format strings).
                c) Exactly one byte, and it should be a punctuation char.
                d) At least 3 bytes.

        Return Value:
            True iff the given address could be the start of a local string
        """
        # line should be referenced (as data)
        if check_refs and not self._analyzer.locals_identifier.isDataConstant(
                ea):
            return False
        str_content = self.getAsciiString(ea)
        # check each of the chars
        if str_content is None or len(
                list(
                    filter(lambda x: chr(x) in self._valid_alphabet,
                           str_content))) != len(str_content):
            return False
        # check for a '\0' terminator
        if idc.get_wide_byte(ea + len(str_content)) != ord('\0'):
            return False
        # check for the correct padding
        if self._local_pad is not None:
            end_address = ea + len(str_content) + 1
            for offset in range(padSize(end_address, self._local_alignment)):
                if idc.get_wide_byte(end_address + offset) != self._local_pad:
                    return False
        # filtering heuristic
        if len(str_content) > self._local_alignment:
            return True
        elif len(str_content) > 1 and chr(str_content[0]) == '%':
            return True
        elif len(str_content) == 1 and chr(
                str_content[0]) in string.punctuation:
            return True
        else:
            return len(str_content) > 2
def patch():
    ea = idc.find_binary(0,
                         idc.SEARCH_NEXT | idc.SEARCH_DOWN | idc.SEARCH_CASE,
                         PATTERN)

    start_addr = None
    pattern_len = _pattern_len(PATTERN)

    while not (ea == ida_idaapi.BADADDR or idc.get_segm_name(ea) != '.text'):
        # If we don't have start address saved, save it and search for the next pattern match
        if not start_addr:
            start_addr = ea

        # If start address was saved before, we got end address. It's time to patch
        else:
            # Remove marker patterns to prevent re-encryption on the next script run
            fill_with_nops(start_addr, start_addr + pattern_len)
            fill_with_nops(ea, ea + pattern_len)

            # Decrypt the code between markers
            for addr in range(start_addr + pattern_len, ea):
                ida_bytes.patch_byte(addr, ~idc.get_wide_byte(addr))

            print('[0x%08X..0x%08X] Region patched' %
                  (start_addr, ea + pattern_len))

            start_addr = None

        ea = idc.find_binary(
            ea, idc.SEARCH_NEXT | idc.SEARCH_DOWN | idc.SEARCH_CASE, PATTERN)

    print('[PATCHING FINISHED]')
def decryptor(index, call_addr):
    decrypted_string = ""
    current_struct_start = struct_start + 8 * index
    current_struct_bytes = idc.get_bytes(current_struct_start, 8)
    print(current_struct_bytes.hex())
    #structure parsing and xoring
    key = int.from_bytes(current_struct_bytes[0:1],
                         byteorder='little',
                         signed=False)
    length = int.from_bytes(current_struct_bytes[2:4],
                            byteorder='little',
                            signed=False)
    buffer_string_addr = int.from_bytes(current_struct_bytes[4:8],
                                        byteorder='little',
                                        signed=False)
    print(hex(key), hex(length), hex(buffer_string_addr))
    #decrypting
    for i in range(0, length):
        decrypted_string += chr(key
                                ^ idc.get_wide_byte(buffer_string_addr + i))
    print(decrypted_string)
    #commenting assembly view
    idc.set_cmt(call_addr, decrypted_string, 0)
    #commenting decompile view on the same address as assembly view
    cfunc = idaapi.decompile(call_addr)
    tl = idaapi.treeloc_t()
    tl.ea = call_addr
    tl.itp = idaapi.ITP_SEMI
    cfunc.set_user_cmt(tl, decrypted_string)
    cfunc.save_user_cmts()
Esempio n. 7
0
def get_header_idb():
    """get file header from idb"""
    if idc.get_segm_name(0) == "HEADER":
        header = bytearray(
            [idc.get_wide_byte(ea) for ea in range(0, idc.get_segm_end(0))])
        return header
    return bytearray(b"")
Esempio n. 8
0
def isinthunk(winname, thunk):
    ea, name = thunk
    funcstart = idc.get_func_attr(ea, idc.FUNCATTR_START)
    funcend = idc.get_func_attr(ea, idc.FUNCATTR_END)

    if funcend - funcstart > 20:  # Highest I've seen is 13 opcodes but this works ig
        return False

    addr = idc.next_head(funcstart, funcend)

    if addr == idc.BADADDR:
        return False

    b = idc.get_wide_byte(addr)
    if b in (0xEB, 0xE9):
        dis = idc.generate_disasm_line(addr, 0)
        try:
            funcname = dis[dis.find("jmp") + 3:].strip()
            if funcname.find("short") != -1:
                funcname = funcname[funcname.find("short") + 5:].strip()

            # When this function gets typed, a comment is added
            # Remove it
            if funcname.find(";") != -1:
                funcname = funcname[:funcname.find(";")]

            if funcname == winname:
                return True
        except:
            pass

    return False
Esempio n. 9
0
 def getKindEnumName(self, addr):
     try:
         struc_id = ida_struct.get_struc_id("type")
         offset_kind = idc.get_member_offset(struc_id, "kind")
         kind = idc.get_wide_byte(addr + offset_kind) & 0x1F
         return self.settings.typer.standardEnums[0][1][kind]
     except IndexError as e:
         pass
Esempio n. 10
0
 def _getbytes(self, start, l=1):
     out = []
     for ad in range(l):
         offset = ad + start + self.base_address
         if not is_mapped(offset):
             raise IOError("not enough bytes")
         out.append(int_to_byte(get_wide_byte(offset)))
     return b''.join(out)
Esempio n. 11
0
    def decide(self):
        """Sum up the information from all of the seen records, and decide what is the alignment pattern.

        Return Value:
            (alignment, pad byte) if found a full pattern, (alignment, None) if no padding, and None for errors.
        """
        # Sanity check
        if len(self._records) < 2:
            return None
        # Now check for a basic alignment rule
        seen_eas = list(map(lambda x: x[0], self._records))
        # Deterministic results per binary, but still random
        random.seed(struct.unpack("!I", ida_nalt.retrieve_input_file_md5()[:4])[0])
        while True:
            # Check against two random candidates, and always make sure the representative isn't rare
            measure_candidate = seen_eas[random.randint(0, len(seen_eas) - 1)]
            measure_candidate_alt = seen_eas[random.randint(0, len(seen_eas) - 1)]
            gcds = list(map(lambda x: gcd(measure_candidate, x), seen_eas))
            gcds_alt = list(map(lambda x: gcd(measure_candidate_alt, x), seen_eas))
            alignment = min(gcds)
            alignment_alt = min(gcds_alt)
            if alignment > alignment_alt:
                alignment = alignment_alt
                measure_candidate = measure_candidate_alt
                try_again = True
            elif alignment != alignment_alt:
                try_again = True
            else:
                try_again = False
            # Try to check if removing outliers will improve the alignment
            if try_again or gcds.count(alignment) <= len(gcds) * 0.01:
                # pick the next element, and try to improve the result
                seen_eas = list(filter(lambda x: gcd(measure_candidate, x) != alignment, seen_eas))
            # we can't improve the results
            else:
                break
        # We shouldn't look for padding bytes (we have no size)
        if self._records[0][1] is None:
            return alignment
        # Alignment is 1, there is no padding to be found
        if alignment == 1:
            return (alignment, None)
        # Check if there is a common padding byte (skip the outliers)
        pad_byte = None
        for ea, size in filter(lambda x: x[0] % alignment == 0, self._records):
            for offset in range((alignment - ((ea + size) % alignment)) % alignment):
                test_byte = idc.get_wide_byte(ea + size + offset)
                if pad_byte is None:
                    pad_byte = test_byte
                # Failed to find a single padding byte...
                elif pad_byte != test_byte:
                    return (alignment, None)
        # Found a padding byte :)
        if pad_byte is not None:
            return (alignment, pad_byte)
        # There were no gaps to be padded, no padding is needed
        else:
            return (alignment, None)
Esempio n. 12
0
    def execute(self, ip=None):
        """
        "Execute" the instruction at IP and store results in the context.
        The RIP/EIP register will be set to the value supplied in IP so that it is
        correct.

        :param ip: instruction address to execute (defaults to currently set ip)
        """
        if not ip:
            ip = self.ip

        # Set instruction pointer to where we are currently executing.
        self.ip = ip

        # Determine if a rep* instruction and add termination condition.
        term_condition = None
        if idc.get_wide_byte(ip) in (0xF2, 0xF3):
            insn = idc.GetDisasm(ip)  # IDA pro never has operands for rep opcodes.
            if insn.startswith("rep "):
                term_condition = lambda: self.registers.ecx == 0
            elif insn.startswith(("repe ", "repz ")):
                term_condition = lambda: self.registers.ecx == 0 or self.registers.zf == 0
            elif insn.startswith(("repne ", "repnz ")):
                term_condition = lambda: self.registers.ecx == 0 or self.registers.zf == 1

        # Emulate instruction.
        mnem = idc.print_insn_mnem(ip)
        operands = self.operands
        instruction = self.OPCODES.get(mnem)
        if instruction:
            try:
                if term_condition:
                    # As a safety measure, don't allow rep instructions to surpass
                    # our max memory read limit.
                    if self.registers.ecx > self.memory.MAX_MEM_READ:
                        logger.warning(
                            "0x{:08X} :: Emulation attempted to read {} instruction {} times. "
                            "Ignoring instruction.".format(ip, mnem, self.registers.ecx)
                        )
                    else:
                        logger.debug("Emulating {} instruction {} times.".format(mnem, self.registers.ecx))
                        while not term_condition():
                            instruction(self, ip, mnem, operands)
                            self.registers.ecx -= 1
                else:
                    instruction(self, ip, mnem, operands)
            except Exception:
                logger.exception("Failed to execute address 0x{:X}: {}".format(ip, idc.GetDisasm(ip)))
        else:
            logger.debug("{} instruction not implemented.".format(mnem))

        # Record executed instruction.
        self.executed_instructions.append(ip)

        # After execution, set instruction pointer to next instruction assuming
        # standard code flow and if no jump was made.
        if self.ip == ip:
            self.ip = idc.next_head(ip)
def simplify_jumps(ea):
    # If we got long first conditional jump
    if idc.get_wide_byte(ea) == 0x0F:
        alternative_jmp_cmd = idc.get_wide_byte(ea + 1) ^ 1
        interm_jmp_offt = 6
    else:
        alternative_jmp_cmd = idc.get_wide_byte(ea) ^ 0xF1
        interm_jmp_offt = 2

    # Get intermediate jump's value
    if idc.get_wide_byte(ea + interm_jmp_offt) == 0x0F:
        interm_jmp_param = idc.get_wide_dword(ea + interm_jmp_offt + 2)
        final_jmp_addr = ea + interm_jmp_param + interm_jmp_offt + 6
    else:
        interm_jmp_param = idc.get_wide_byte(ea + interm_jmp_offt + 1)
        final_jmp_addr = ea + interm_jmp_param + interm_jmp_offt + 2

    # Check the last conditional jump

    # 75 ?? ... 0F 85 ?? ?? ?? ??
    if idc.get_wide_byte(final_jmp_addr) == 0x0F and \
       idc.get_wide_byte(final_jmp_addr + 1) == alternative_jmp_cmd:
        final_jmp_param = idc.get_wide_dword(final_jmp_addr + 2)
        final_jmp_target = (final_jmp_addr + final_jmp_param + 6) & 0xFFFFFFFF

    # 75 ?? ... 75 ??
    elif idc.get_wide_byte(final_jmp_addr) ^ 0xF0 == alternative_jmp_cmd:
        final_jmp_param = idc.get_wide_byte(final_jmp_addr + 1)
        final_jmp_target = (final_jmp_addr + final_jmp_param + 2) & 0xFFFFFFFF

    # Make a little cleanup: remove garbage code
    elif interm_jmp_param < 0x10:
        fill_with_nops(ea + interm_jmp_offt, final_jmp_addr)
        return True

    else:
        return

    if final_jmp_target - ea < 0xFF:
        fill_with_nops(ea + interm_jmp_offt, final_jmp_target)
    else:
        fill_with_nops(ea + interm_jmp_offt, final_jmp_addr + 6)

    # Restore seconds jump
    idc.patch_byte(ea + interm_jmp_offt, 0x0F)
    idc.patch_byte(ea + interm_jmp_offt + 1, alternative_jmp_cmd)
    idc.patch_dword(ea + interm_jmp_offt + 2, final_jmp_target - (ea + interm_jmp_offt) - 6)
    idc.create_insn(ea + interm_jmp_offt)

    return True
Esempio n. 14
0
def read_bytes_slowly(start, end):
  bytestr = []
  for i in xrange(start, end):
    if idc.has_value(idc.get_full_flags(i)):
      bt = idc.get_wide_byte(i)
      bytestr.append(chr(bt))
    else:
      bytestr.append("\x00")
  return "".join(bytestr)
Esempio n. 15
0
def get_header_idb():
    '''
    get file header from idb
    '''
    if idc.get_segm_name(0) == 'HEADER':
        header = bytearray(
            [idc.get_wide_byte(ea) for ea in range(0, idc.get_segm_end(0))])
        return header
    return bytearray(b'')
Esempio n. 16
0
 def processStructField(self, addr, index):
     offset = addr + index
     sid = ida_struct.get_struc_id("structField")
     ptr = self.getPtr(sid, offset, "Name")
     ln = idc.get_wide_byte(ptr + 2)
     fieldName = self.get_str(ptr + 3, ln)
     Utils.rename(ptr, fieldName)
     ptr = self.getPtr(sid, offset, "typ")
     self.handle_offset(ptr)
Esempio n. 17
0
def read_bytes_slowly(start, end):
    bytestr = bytearray()
    for i in xrange(start, end):
        if idc.has_value(idc.get_full_flags(i)):
            bt = idc.get_wide_byte(i)
            bytestr.append(bt)
        else:
            bytestr.append(0)
    return bytes(bytestr)
Esempio n. 18
0
def read_bytes_slowly(start, end):
    bytestr = []
    for i in xrange(start, end):
        if idc.has_value(idc.get_full_flags(i)):
            bt = idc.get_wide_byte(i)
            bytestr.append(chr(bt))
        else:
            bytestr.append("\x00")
    return "".join(bytestr)
Esempio n. 19
0
def get_guid(address):
    """get GUID located by address"""
    guid = list()
    guid.append(idc.get_wide_dword(address))
    guid.append(idc.get_wide_word(address + 4))
    guid.append(idc.get_wide_word(address + 6))
    for addr in range(address + 8, address + 16, 1):
        guid.append(idc.get_wide_byte(addr))
    return guid
Esempio n. 20
0
    def extractFunctionTypeSample(self, ea):
        """Extract features for a "code type" sample.

        Args:
            ea (int): effective address to be sampled

        Return Value:
            feature set (list of byte values)
        """
        return list(map(lambda o: idc.get_wide_byte(ea + o), self._classifier_type_offsets))
Esempio n. 21
0
    def extractSample(self, ea):
        """Extract features for a sample.

        Args:
            ea (int): effective address to be sampled

        Return Value:
            feature set (list of byte values)
        """
        return [idc.get_wide_byte(ea + o) for o in self._classifier_offsets]
def deobfuscate_rets(ea):
    if idc.get_wide_byte(ea) == 0x83:
        fill_with_nops(ea, ea + 7)
    else:
        fill_with_nops(ea, ea + 8)

    idc.patch_byte(ea, 0xC3)
    idc.create_insn(ea)

    return True
Esempio n. 23
0
def parse_vtable(ea, typename):
    os = get_os()
    if os == OS_Linux:
        ea += 8
    funcs = []

    while ea != idc.BADADDR:
        eatemp = ea
        offs = idc.get_wide_dword(ea)
        #		if ida_bytes.is_unknown(ida_bytes.get_full_flags(ea)):
        #			break

        size = idc.get_item_size(
            ea
        )  # This is bad abd abadbadbadbabdbabdad but there's no other choice here
        if size != 4:
            # This looks like it might be a bug with IDA
            # Random points of a vtable are getting turned into unknown data
            if size != 1:
                break

            s = "".join([
                "%02x" % idc.get_wide_byte(ea + i) for i in range(3, -1, -1)
            ])  #.replace("0x", "")
            if not s.lower().startswith("ffff"):
                ea = ida_bytes.next_not_tail(ea)
                continue

            offs = int(s, 16)
            ea += 3

        name = idc.get_name(offs, ida_name.GN_VISIBLE)
        if name:
            if os == OS_Linux:
                if not (name.startswith("_Z") or
                        name.startswith("__cxa")) or name.startswith("_ZTV"):
                    break  # If we've exceeded past this vtable
            elif name.startswith("??"):
                break
        else:
            if os == OS_Win:
                break

            # dd -offsettothis
            # This is even worseworsoewewrosorooese
            s = "%02x" % offs
            if not s.lower().startswith("ffff"):
                ea = ida_bytes.next_not_tail(ea)
                continue

            name = (1 << 32) - int(offs)
        funcs.append(name)

        ea = ida_bytes.next_not_tail(ea)
    return funcs, eatemp
Esempio n. 24
0
 def get_data_guids(self):
     '''
     rename GUIDs in idb
     '''
     EFI_GUID = 'EFI_GUID *'
     EFI_GUID_ID = idc.get_struc_id('EFI_GUID')
     segments = ['.text', '.data']
     for segment in segments:
         seg_start, seg_end = 0, 0
         for seg in idautils.Segments():
             if idc.get_segm_name(seg) == segment:
                 seg_start = idc.get_segm_start(seg)
                 seg_end = idc.get_segm_end(seg)
                 break
         ea = seg_start
         while (ea <= seg_end - 15):
             prot_name = ''
             if idc.get_name(ea, ida_name.GN_VISIBLE).find('unk_') != -1:
                 find = False
                 cur_guid = []
                 cur_guid.append(idc.get_wide_dword(ea))
                 cur_guid.append(idc.get_wide_word(ea + 4))
                 cur_guid.append(idc.get_wide_word(ea + 6))
                 for addr in range(ea + 8, ea + 16, 1):
                     cur_guid.append(idc.get_wide_byte(addr))
                 if cur_guid == [0] * 11:
                     ea += 1
                     continue
                 for guid_place in [
                         'ami_guids', 'asrock_guids', 'dell_guids',
                         'edk_guids', 'edk2_guids', 'lenovo_guids'
                 ]:
                     for name in self.Protocols[guid_place]:
                         if self.Protocols[guid_place][name] == cur_guid:
                             prot_name = name + '_' + \
                                 '{addr:#x}'.format(addr=ea)
                             record = {
                                 'address': ea,
                                 'service': 'unknown',
                                 'guid': cur_guid,
                                 'protocol_name': name,
                                 'protocol_place': guid_place
                             }
                             find = True
                             break
                         if find:
                             break
                 if find and (idc.get_name(ea, ida_name.GN_VISIBLE) !=
                              prot_name):
                     idc.SetType(ea, EFI_GUID)
                     self.apply_struct(ea, 16, EFI_GUID_ID)
                     idc.set_name(ea, prot_name)
                     self.Protocols['data'].append(record)
             ea += 1
Esempio n. 25
0
    def extractFunctionStartSample(self, ea, code_type):
        """Extract features for a "function start" sample.

        Args:
            ea (int): effective address to be sampled
            code_type (int): code type of the wanted sample

        Return Value:
            feature set (list of byte values)
        """
        return list(map(lambda o: idc.get_wide_byte(ea + o), self._classifiers_start_offsets[code_type]))
Esempio n. 26
0
 def get_data_guids(self):
     """rename GUIDs in idb"""
     EFI_GUID = "EFI_GUID"
     EFI_GUID_ID = idc.get_struc_id("EFI_GUID")
     segments = [".text", ".data"]
     for segment in segments:
         seg_start, seg_end = 0, 0
         for seg in idautils.Segments():
             if idc.get_segm_name(seg) == segment:
                 seg_start = idc.get_segm_start(seg)
                 seg_end = idc.get_segm_end(seg)
                 break
         ea = seg_start
         while ea <= seg_end - 15:
             prot_name = str()
             if "unk" in idc.get_name(ea, ida_name.GN_VISIBLE):
                 find = False
                 cur_guid = list()
                 cur_guid.append(idc.get_wide_dword(ea))
                 cur_guid.append(idc.get_wide_word(ea + 4))
                 cur_guid.append(idc.get_wide_word(ea + 6))
                 for addr in range(ea + 8, ea + 16, 1):
                     cur_guid.append(idc.get_wide_byte(addr))
                 if cur_guid == [0] * 11:
                     ea += 1
                     continue
                 for guid_place in [
                     "ami_guids",
                     "asrock_guids",
                     "dell_guids",
                     "edk_guids",
                     "edk2_guids",
                     "lenovo_guids",
                 ]:
                     for name in self.Protocols[guid_place]:
                         if self.Protocols[guid_place][name] == cur_guid:
                             prot_name = f"{name}_{ea:016X}"
                             record = {
                                 "address": ea,
                                 "service": "unknown",
                                 "guid": cur_guid,
                                 "protocol_name": name,
                                 "protocol_place": guid_place,
                             }
                             find = True
                             break
                         if find:
                             break
                 if find and (idc.get_name(ea, ida_name.GN_VISIBLE) != prot_name):
                     idc.SetType(ea, EFI_GUID)
                     self.apply_struct(ea, 16, EFI_GUID_ID)
                     idc.set_name(ea, prot_name)
                     self.Protocols["data"].append(record)
             ea += 1
def resolve_calls_through_register(ea):
    next_instr_addr = idc.get_wide_dword(ea + 1)

    # Check if that's just a parameter passing through stack
    if ea & 0xFFFF0000 != next_instr_addr & 0xFFFF0000:
        return

    if next_instr_addr - ea > 0x100:
        return

    if idc.get_wide_byte(ea + 6) & 0xF0 in [0x20, 0xE0]:
        call_param = 0x9000 + idc.get_wide_byte(ea + 6) ^ 0x30
    else:
        call_param = idc.get_wide_word(ea + 6) ^ 0x30

    fill_with_nops(ea, next_instr_addr)
    idc.patch_byte(ea, 0xFF)
    idc.patch_word(ea + 1, call_param)
    idc.create_insn(ea)

    return True
Esempio n. 28
0
 def processMethods(self, offst):
     sid = ida_struct.get_struc_id("method__")
     name = self.getDword(sid, offst, "name")
     name += self.robase
     name = self.get_str(name + 3, idc.get_wide_byte(name + 2))
     type_meth = self.getDword(sid, offst, "mtyp")
     type_meth_addr1 = self.robase + type_meth
     func_body1 = self.getDword(sid, offst, "ifn")
     func_addr1 = self.text_addr + func_body1
     func_body2 = self.getDword(sid, offst, "tfn")
     func_addr2 = self.text_addr + func_body1
     return "%s %x %x %x" % (name, type_meth_addr1, func_addr1, func_addr2)
Esempio n. 29
0
 def _get_memory(self):
     result = ""
     segment_starts = [ea for ea in idautils.Segments()]
     offsets = []
     start_len = 0
     for start in segment_starts:
         end = idc.get_segm_end(start)
         for ea in lrange(start, end):
             result += chr(idc.get_wide_byte(ea))
         offsets.append((start, start_len, len(result)))
         start_len = len(result)
     return result, offsets
Esempio n. 30
0
    def isGlobalAsciiString(self, ea):
        r"""Check if the given address is the beginning of a valid global string.

        Args:
            ea (int): effective address to be checked

        Notes
        -----
            1. The string should be aligned (global alignment).
            2. The string should only contain chars from our alpha-bet.
            3. The string should be '\0' terminated.
            4. If applicable, the string should be padded with the correct padding byte.
            5. The string's length must be at least the required lower bound.

        Return Value:
            True iff the given address could be the start of a global string
        """
        # start by checking the alignment
        if ea % self._global_alignment != 0:
            return False
        str_content = self.getAsciiString(ea)
        # check each of the chars
        if str_content is None or len(
                list(
                    filter(lambda x: chr(x) in self._valid_alphabet,
                           str_content))) != len(str_content):
            return False
        # check for a '\0' terminator
        if idc.get_wide_byte(ea + len(str_content)) != ord('\0'):
            return False
        # check for the correct padding
        if self._global_pad is not None:
            end_address = ea + len(str_content) + 1
            for offset in range(padSize(end_address, self._global_alignment)):
                if idc.get_wide_byte(end_address + offset) != self._global_pad:
                    return False
        # basic length
        return len(str_content) >= self._min_global_length
Esempio n. 31
0
	def get_func_end(self, start):

		if (idc.add_func(start)):
			return idc.find_func_end(start)

		ea = start
		while (idc.get_wide_byte(ea) != 0xCC):
			idc.create_insn(ea)
			ea += idc.get_item_size(ea)

			if (ea - start > self.jit_max_size):
				return 0

		return ea
Esempio n. 32
0
    def extractFunctionMixedSample(self, ea, code_type):
        """Extract features for a "function start/end" sample.

        Args:
            ea (int): effective address to be sampled
            code_type (int): code type of the wanted sample

        Return Value:
            feature set (list of byte values)
        """
        return [
            idc.get_wide_byte(ea + o)
            for o in self._classifiers_mixed_offsets[code_type]
        ]
Esempio n. 33
0
	def get_native_function(self):

		ecx = idc.get_reg_value("ECX")
		esp = idc.get_reg_value("ESP")

		method_name = self.get_method_name(esp)
		
		if (idc.get_wide_byte(idc.get_wide_dword(ecx + 8) + 0x38) != 0):
			function = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x28)
		else:
			function = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x24)
		
		print("Resolved native function: 0x%x - %s" % (function, method_name))

		if ((method_name not in self.ignore and not self.ignore_all) or
			(method_name in self.debug_if_equals) or 
			(any(x for x in self.debug_if_contains if method_name is not None and x in method_name))):
			self.traced.append({"name": method_name, "ea": function, "type": "native", "hit": 0})
			idc.add_bpt(function)
Esempio n. 34
0
def read_leb128(ea, signed):
  """ Read LEB128 encoded data
  """
  val = 0
  shift = 0
  while True:
    byte = idc.get_wide_byte(ea)
    val |= (byte & 0x7F) << shift
    shift += 7
    ea += 1
    if (byte & 0x80) == 0:
      break

    if shift > 64:
      DEBUG("Bad leb128 encoding at {0:x}".format(ea - shift/7))
      return idc.BADADDR

  if signed and (byte & 0x40):
    val -= (1<<shift)
  return val, ea