예제 #1
0
 def parse_iat(self, file):
     labeledIatList = open(file, "r").read().splitlines()
     labeledIatDict = dict()
     for i in labeledIatList:
         cur_rva, cur_iat_label = i.split('\t')
         labeledIatDict[hex(ida_nalt.get_imagebase() +
                            int(cur_rva, 16))] = cur_iat_label
     return labeledIatDict
예제 #2
0
    def dump_info(self, filepath):
        self._base = ida_nalt.get_imagebase()

        output = {
            'general'   : self.__process_general(), 
            'segments'  : self.__process_segments(),
            'functions' : self.__process_functions(),
            'names'     : self.__process_names()
        }

        with open(filepath, "w") as f:
            json.dump(output, f, indent=4)
예제 #3
0
    def _init_ctrl_flow_redirections(self):
        """Initializes the control flow redirections using function thunks"""

        # We only support the ELF format for now
        inf = ida_idaapi.get_inf_structure()
        if inf.filetype != ida_ida.f_ELF:
            return

        # List the function thunks first
        input_file_path = ida_nalt.get_input_file_path()
        image_parser = create_elf_image_parser(input_file_path)
        function_thunk_list = image_parser.get_function_thunk_list()

        # Go through each function thunk, and look at its cross references; there
        # should always be only one user, which is the wrapper around the imported
        # function
        #
        # Note that the __libc_start_main # thunk does not need redirection since
        # it's called directly without any wrapper function from the module entry
        # point
        is_32_bit = image_parser.get_image_bitness() == 32

        for function_thunk in function_thunk_list:
            if function_thunk.name == "__libc_start_main":
                continue

            thunk_va = ida_nalt.get_imagebase() + function_thunk.start

            redirection_dest = (
                ida_bytes.get_wide_dword(thunk_va)
                if is_32_bit
                else ida_bytes.get_qword(thunk_va)
            )

            caller_address = ida_xref.get_first_cref_to(redirection_dest)
            if caller_address == ida_idaapi.BADADDR:
                continue

            redirection_source = idc.get_func_attr(caller_address, idc.FUNCATTR_START)

            print(
                "anvill: Redirecting the user {:x} of thunk {} at rva {:x} to {:x}".format(
                    redirection_source,
                    function_thunk.name,
                    function_thunk.start,
                    redirection_dest,
                )
            )

            self.add_control_flow_redirection(redirection_source, redirection_dest)
예제 #4
0
    def __init__(self,
                 arch: Arch,
                 os: OS,
                 maybe_base_address: Optional[int] = None):
        if maybe_base_address is not None:
            delta = abs(ida_nalt.get_imagebase() - maybe_base_address)
            if maybe_base_address < ida_nalt.get_imagebase():
                delta = delta * -1

            if ida_segment.rebase_program(delta, ida_segment.MSF_FIXONCE) != 0:
                raise RuntimeError("Failed to rebase the program")

        # Wait until IDA has finished analysis before we proceed, otherwise
        # we will end up missing code, data and cross references
        ida_auto.auto_wait()

        super(IDASpecification, self).__init__(arch, os)

        try:
            self._init_func_thunk_ctrl_flow()
        except:
            DEBUG(
                "Failed to initialize the control flow information for functin thunks"
            )
예제 #5
0
    def slot_import_pickle(self):
        path = idaapi.ask_file(True, "*.capa", "Choose file")
        if not path:
            return
        if not os.path.exists(path):
            msg('capa: File does not exists !')
            return

        data = None
        with open(path, "rb") as import_file:
            self.range_model_proxy.invalidate()
            self.search_model_proxy.invalidate()
            self.model_data.reset()
            self.model_data.clear()
            self.disable_controls()
            self.set_view_status_label("Loading...")

            success = False
            act = True
            try:
                self.doc = pickle.load(import_file)
                if self.doc["meta"]["analysis"][
                        "base_address"] != ida_nalt.get_imagebase():
                    if 0 == idaapi.ask_yn(
                            1, "Imagebase is not match! Continue to load ?"):
                        act = False
            except Exception as e:
                act = False
                logger.error("Failed to load capa results (error: %s)", e)

            if act:
                try:

                    self.model_data.render_capa_doc(self.doc)
                    self.render_capa_doc_mitre_summary()
                    self.enable_controls()
                    success = True
                except Exception as e:
                    logger.error("Failed to render results (error: %s)", e)

            self.reset_view_tree()

            if not success:
                self.set_view_status_label("Click Analyze to get started...")
                logger.info("Loading Analysis failed.")
            else:
                logger.info("Loading Analysis completed.")
예제 #6
0
 def apply_iat(self, iat):
     min_ea = ida_ida.inf_get_min_ea()
     max_ea = ida_ida.inf_get_max_ea()
     image_base = ida_nalt.get_imagebase()
     idaapi.msg(f"{hex(min_ea)} - {hex(max_ea)} - {hex(image_base)} \n")
     for i in range(min_ea, max_ea):
         mnemonic = idc.print_insn_mnem(i)
         if mnemonic == "call" and str(idc.print_operand(
                 i, 0)).startswith("dword"):
             try:
                 idc.set_name(
                     idc.get_operand_value(i, 0),
                     iat[hex(idc.get_operand_value(i, 0))] +
                     str(random.randint(0, 1000))
                 )  # I added random.randint() because some functions already in the IAT are dynamically resolved again, so renaming them causes a conflict, if you want remove it. (Sample causing the problem: https://bazaar.abuse.ch/sample/49fd52a3f3d1d46dc065217e588d1d29fba4d978cd8fdb2887fd603320540f71/)
                 open("resolved_iat.txt",
                      "a").write(f"{hex(idc.get_operand_value(i, 0))}\n")
             except:
                 open("unresolved_iat.txt",
                      "a").write(f"{hex(idc.get_operand_value(i, 0))}\n")
예제 #7
0
def goto_rva():
    rva = 0
    txt = clip_text()
    if txt.isdigit():
        try:
            rva = int(txt, 10)
        except:
            pass
    elif txt.isalnum():
        try:
            rva = int(txt, 16)
        except:
            pass
    rva = ida_kernwin.ask_addr(rva, "Enter the RVA to jump to")
    if rva is None:
        return 0

    base = ida_nalt.get_imagebase()
    ea = base + rva
    plg_print("RVA = 0x%X -> EA = 0x%X" % (rva, ea))
    idc.jumpto(ea)
    return 1
예제 #8
0
def bin_search(bin_str: str) -> List[int]:
    if not isinstance(bin_str, str):
        raise ValueError('bin_str must be a string')

    if bin_str in cached_patterns:
        return cached_patterns[bin_str]

    bin_list = bin_str.split()
    image = bytearray()
    mask = bytearray()

    # Create the mask and convert '?' to 'CC'.
    for i in range(len(bin_list)):
        byte = bin_list[i]
        if byte == '?':
            image.append(int('CC', 16))
            mask.append(0)
        else:
            image.append(int(byte, 16))
            mask.append(1)

    image = bytes(image)
    mask = bytes(mask)

    start = ida_nalt.get_imagebase()
    end = ida_idaapi.BADADDR

    addrs: List[int] = []

    ea = ida_bytes.bin_search(start, end, image, mask, 0,
                              ida_bytes.BIN_SEARCH_FORWARD)
    while ea != ida_idaapi.BADADDR:
        addrs.append(ea)
        ea = ida_bytes.bin_search(ea + len(image), end, image, mask, 0,
                                  ida_bytes.BIN_SEARCH_FORWARD)

    cached_patterns[bin_str] = addrs
    return cached_patterns[bin_str]
예제 #9
0
        self.when = when
        self.testcase = testcase

filename = idaapi.ask_file(False, '*.csv', 'Please select csv')

blocks = []

with open(filename) as csvfile:
    readCSV = csv.reader(csvfile, delimiter=";", quotechar='"')
    next(readCSV)
    for row in readCSV:
        print row
        blocks.append(int(row[4]))



for bb in blocks:
    absPos = bb + ida_nalt.get_imagebase()
    f = idaapi.get_func(absPos)
    if f is None:
        continue
    fc = idaapi.FlowChart(f)
    # Highlight the complete function
    idc.SetColor(absPos, idc.CIC_FUNC, 0xFFF000)
    for block in fc:
        if block.startEA <= absPos and block.endEA > absPos:
            #print "Setting colour for %x" % absPos
            for i in Heads(block.startEA, block.endEA):
                idc.set_color(i, CIC_ITEM, 0xFFAA00)

예제 #10
0
def copy_rva():
    ea = idc.get_screen_ea()
    base = ida_nalt.get_imagebase()
    rva = ea - base
    plg_print("EA = %X - RVA = %X copied to clipboard" % (ea, rva))
    copy_to_clip("0x%X" % rva)
예제 #11
0
 def image_rebase():
     if get_imagebase() == 0:
         rebase_program(DEFAULT_IMAGE_BASE, MSF_FIXONCE)
예제 #12
0
def main():
    rva = ida_kernwin.ask_addr(0x0, "RVA")
    if not rva:
        return

    ida_kernwin.jumpto(ida_nalt.get_imagebase() + rva)
예제 #13
0
# Step Nr. 5: Let user change offset (optional)
offset = ida_kernwin.ask_long(0, "Add offset (if it's hex prepend a 0x)")

# Step Nr. 6: Retrieve covered blocks
engine = create_engine(database_string)
with engine.connect() as con:
    #blocksDB = con.execute('SELECT Offset FROM covered_blocks WHERE ModuleID = %d' % selected_module)
    blocksDistinctDB = con.execute(
        'SELECT DISTINCT Offset FROM covered_blocks WHERE ModuleID = %d ORDER BY Offset ASC'
        % selected_module[0])
print "Found ? block(s) (%d distinct)" % (blocksDistinctDB.rowcount)

# Step Nr. 7: Color the currently loaded binary
for (bb, ) in blocksDistinctDB:
    absPos = bb + offset
    if not rawModule:
        absPos += ida_nalt.get_imagebase()
    print absPos

    f = ida_funcs.get_func(absPos)
    if f is None:
        continue
    fc = ida_gdl.FlowChart(f)
    # Highlight the complete function
    idc.set_color(absPos, idc.CIC_FUNC, 0xFFF000)
    for block in fc:
        if block.start_ea <= absPos and block.end_ea > absPos:
            #print "Setting colour for %x" % absPos
            for i in Heads(block.start_ea, block.end_ea):
                idc.set_color(i, CIC_ITEM, 0xFFAA00)
예제 #14
0
파일: ida_api.py 프로젝트: wangjenmin/tenet
 def get_imagebase(self):
     return ida_nalt.get_imagebase()