Ejemplo n.º 1
0
    def activate(self, ctx):
        import json

        filepath = idc.AskFile(False, "*.zmu;*.overlay;*",
                               "Load Zelos Overlay...")
        if filepath is None:
            return
        f = open(filepath, "r")
        zelos_data = f.read()
        f.close()

        zelos_data = zelos_data[len("DISAS\n"):]
        zelos_dump = json.loads(zelos_data)

        # Apply the overlay data
        for comment in zelos_dump["comments"]:
            ea = comment["address"]
            try:
                comment_text = str(comment["text"])
            except UnicodeEncodeError:
                comment_text = ""
            color = comment.get("color", 0x73F0DF)

            # Set color of instruction line
            idaapi.set_item_color(ea, color)
            idaapi.set_cmt(ea, comment_text, False)

            # Set function name if not already changed
            idc.GetFunctionAttr(ea, idc.FUNCATTR_START)
            name = idc.GetFunctionName(ea)
            if len(name) > 0 and name.startswith("zmu_") is False:
                idc.MakeName(ea, "zmu_" + name)

        return 1
Ejemplo n.º 2
0
    def activate(self, ctx):
        import json

        filepath = idc.AskFile(False, '*.zmu;*.overlay;*',
                               'Load Zemu Overlay...')
        if filepath is None:
            return
        f = open(filepath, 'r')
        zemu_data = f.read()
        f.close()

        zemu_data = zemu_data[len('DISAS\n'):]
        zemu_dump = json.loads(zemu_data)

        # Apply the overlay data
        for comment in zemu_dump['comments']:
            ea = comment['address']
            comment_text = str(comment['text'])
            color = comment.get('color', 0x73f0df)

            # Set color of instruction line
            idaapi.set_item_color(ea, color)
            idaapi.set_cmt(ea, comment_text, False)

            # Set function name if not already changed
            idc.GetFunctionAttr(ea, idc.FUNCATTR_START)
            name = idc.GetFunctionName(ea)
            if len(name) > 0 and name.startswith('zmu_') == False:
                idc.MakeName(ea, 'zmu_' + name)

        return 1
Ejemplo n.º 3
0
    def get_decode_xrefs():
        """
        Find all cross-refernces to 0x132549a in our REvil malware sample.
        Decode the string and annotate the IDA database, this will make analysis a lot
        easier
        """
        for xref in idautils.XrefsTo(0x132549a):
            # first of all, we need to find the arguments to this function, the signature is:
            # BYTE* __cdecl decode_string(char* base, int keyOffset, int keyLen, int dataLen, BYTE* pOut);
            args = get_decode_args(xref.frm)
            if args:
                base, key_offset, key_len, data_len = args
                # get the data from the image, data = [keyBytes][encryptedData]
                data = ida_bytes.get_bytes(base + key_offset,
                                           key_len + data_len)
                str = data_to_str(decode_string(data, key_len, data_len))
                print("0x%08x: %s" % (xref.frm, str))

                # put a comment in the code
                cfunc = idaapi.decompile(xref.frm)
                if cfunc is not None:
                    tl = idaapi.treeloc_t()
                    tl.ea = xref.frm
                    tl.itp = idaapi.ITP_SEMI
                    cfunc.set_user_cmt(tl, str)
                    cfunc.save_user_cmts()
                    idaapi.set_cmt(int(xref.frm), str, True)
            else:
                # We could not get the arguments, likely because it may be a register and not an immediate
                # value, so we'd need to go back further and find what value that register was assigned with.
                # Would be easier to just tell user, and let him decode it manually (HexRays has the actual args)
                print("0x%08x: Could not decode arguments" % xref.frm)
Ejemplo n.º 4
0
def add_to_comment(ea, key, value):
    """Add key:value to comm string at EA."""
    from bap_comment import add_to_comment_string
    old_comm = idaapi.get_cmt(ea, 0)
    if old_comm is None:
        old_comm = ''
    new_comm = add_to_comment_string(old_comm, key, value)
    idaapi.set_cmt(ea, new_comm, 0)
Ejemplo n.º 5
0
 def update(self, ea, key, value):
     """Add key=values to comm string at EA."""
     cmt = idaapi.get_cmt(ea, 0)
     comm = cmt and bap_comment.parse(cmt) or {}
     values = comm.setdefault(key, [])
     if value and value != '()' and value not in values:
         values.append(value)
     idaapi.set_cmt(ea, bap_comment.dumps(comm), 0)
Ejemplo n.º 6
0
def add_to_comment(ea, key, value):
    """Add key:value to comm string at EA."""
    from bap_comment import add_to_comment_string
    old_comm = idaapi.get_cmt(ea, 0)
    if old_comm is None:
        old_comm = ''
    new_comm = add_to_comment_string(old_comm, key, value)
    idaapi.set_cmt(ea, new_comm, 0)
Ejemplo n.º 7
0
def add_refs():
    global refs
    
    for (ea, target_addr, target_name) in refs:
        if target_name and len(target_name) != 0:
            idaapi.set_cmt(ea, "%s - 0x%X" % (target_name, ea + 4), False)
        else:
            idaapi.set_cmt(ea, "0x%X - 0x%X" % (target_addr, ea + 4), False)
        idaapi.add_dref(ea, target_addr, idc.dr_O)
Ejemplo n.º 8
0
def add_refs():
    global refs

    for (ea, target_addr, target_name) in refs:
        if target_name and len(target_name) != 0:
            idaapi.set_cmt(ea, "%s - 0x%X" % (target_name, ea + 4), False)
        else:
            idaapi.set_cmt(ea, "0x%X - 0x%X" % (target_addr, ea + 4), False)
        idaapi.add_dref(ea, target_addr, idc.dr_O)
Ejemplo n.º 9
0
def handle_comments(delta, segs):
    for cmt_offset in get_all_comments():
        for is_repeatable in (True, False):
            cmt = idaapi.get_cmt(cmt_offset, is_repeatable)
            if not cmt:
                continue
            new_cmt = rebase_comment(segs, delta, cmt)
            if not new_cmt:
                continue
            idaapi.set_cmt(cmt_offset, new_cmt, is_repeatable)
Ejemplo n.º 10
0
    def _loadFunctionsNames(self, file_name: Optional[str],
                            ext: str) -> Optional[Tuple[int, int]]:
        """Loads functions names from the given file into the internal mappings.
        Fromats: CSV (default), or TAG (PE-bear, PE-sieve compatibile).
        """

        if file_name is None or len(file_name) == 0:
            return None
        curr_functions = self._listFunctionsAddr()
        delim = ","  # new delimiter (for CSV format)
        delim2 = ":"  # old delimiter
        rva_indx = 0
        cmt_indx = 1
        is_imp_list = False
        if ".imports.txt" in ext:
            is_imp_list = True
            cmt_indx = 2
        if ".tag" in ext:  # a TAG format was chosen
            delim2 = ";"
        functions = 0
        comments = 0
        with open(file_name, 'r') as f:
            for line in f.readlines():
                line = line.strip()
                fn = line.split(delim)
                if len(fn) < 2:
                    fn = line.split(delim2)  # try old delimiter
                if len(fn) < 2:
                    continue
                start = 0
                addr_chunk = fn[rva_indx].strip()
                if not _is_hex_str(addr_chunk):
                    continue
                try:
                    start = int(addr_chunk, 16)
                except ValueError:
                    # this line doesn't start from an offset, so skip it
                    continue
                func_name = fn[cmt_indx].strip()
                if start < idaapi.get_imagebase():  # it is RVA
                    start = rva_to_va(start)  # convert to VA

                if is_imp_list or (start in curr_functions):
                    if is_imp_list:
                        func_name = self._stripImportName(func_name)
                        thunk_val = int(fn[1].strip(), 16)
                        self._defineImportThunk(start, thunk_val)

                    if self.subDataManager.setFunctionName(start, func_name):
                        functions += 1
                        continue

                set_cmt(start, func_name, 1)  # set the name as a comment
                comments += 1
        return (functions, comments)
Ejemplo n.º 11
0
 def implement(self):
     if self._comment_type == "regular":
         idaapi.set_cmt(self._linear_address, self._value, 0)
     elif self._comment_type == "repetable":
         idaapi.set_cmt(self._linear_address, self._value, 1)
     elif self._comment_type == "function":
         idc.set_func_cmt(self._linear_address, self._value, 0)
     elif self._comment_type == "anterior":
         ida_lines.add_extra_cmt(self._linear_address, 1, self._value)
     elif self._comment_type == "posterior":
         ida_lines.add_extra_cmt(self._linear_address, 0, self._value)
    def clear_bap_comments(self):
        """Ask user for confirmation and then clear (BAP ..) comments."""

        if idaapi.askyn_c(ASKBTN_YES,
                          "Delete all `BAP: ..` comments?") != ASKBTN_YES:
            return

        for ea in ida.addresses():  # TODO: store actually commented addresses
            comm = idaapi.get_cmt(ea, 0)
            if comm and comm.startswith('BAP:'):
                idaapi.set_cmt(ea, '', 0)
Ejemplo n.º 13
0
def setComments(info, decStr):
    #Set Comment for Decompile (hexray)
    cfunc = idaapi.decompile(info['addr'])
    tl = idaapi.treeloc_t()
    tl.ea = info['addr'] + 7
    tl.itp = idaapi.ITP_SEMI
    cfunc.set_user_cmt(tl, decStr)
    cfunc.save_user_cmts()

    #Set Comment for Disasemble (IDA)
    idaapi.set_cmt(info['addr'], decStr, None)
Ejemplo n.º 14
0
    def clear_bap_comments(self):
        """Ask user for confirmation and then clear (BAP ..) comments."""

        if idaapi.askyn_c(ASKBTN_YES,
                          "Delete all `BAP: ..` comments?") != ASKBTN_YES:
            return

        for ea in ida.addresses():  # TODO: store actually commented addresses
            comm = idaapi.get_cmt(ea, 0)
            if comm and comm.startswith('BAP:'):
                idaapi.set_cmt(ea, '', 0)
Ejemplo n.º 15
0
    def req_rcmt(self, hash):
        msg, offset, base = hash['msg'], hash['offset'], hash['base']
        offset, msg = self.addr_switch(offset, msg)
        if not offset:
            return

        ea = self.rebase(base, offset)
        if not ea:
            return

        idaapi.set_cmt(ea, str(''), False)
        rs_log("reset comment at 0x%x" % ea)
Ejemplo n.º 16
0
    def req_rcmt(self, hash):
        msg, offset, base = hash["msg"], hash["offset"], hash["base"]
        offset, msg = self.addr_switch(offset, msg)
        if not offset:
            return

        ea = self.rebase(base, offset)
        if not ea:
            return

        idaapi.set_cmt(ea, str(""), False)
        print ("[*] reset comment at 0x%x" % ea)
def fix_relocs(base_address, relocs_address, relocs_size):
	cursor = relocs_address
	end = relocs_address+relocs_size

	multiplier = 4 * (idaapi.get_dword(cursor) & 1) + 4
	cursor += 4
	
	print 'starting to fix relocs...'
	nb_relocs = 0

	delta = idaapi.get_dword(cursor)
	while delta != 0xFFFFFFFF and cursor < end:
		current_reloc = base_address + delta
		while True:
			decorated_addr = idaapi.get_qword(current_reloc)
			if decorated_addr & 0x4000000000000000 == 0:
				if decorated_addr & 0x8000000000000000:
					#tagged ptr
					sign_type = (decorated_addr >> 49) & 3
					real_addr = base_address + (decorated_addr & 0xFFFFFFFF)
					modifier = ((decorated_addr >> 32) & 0xFFFF)
					if decorated_addr & 0x1000000000000:
						if modifier == 0:
							modifier = current_reloc
							modifier_type = 'ptr_addr'
						else:
							modifier_type = '0x%X << 48 | ptr_addr & 0xFFFFFFFFFFFF'%(modifier)
							modifier = (current_reloc & 0xFFFFFFFFFFFF) | (modifier << 48)
					else:
						modifier_type = '0x%X'%modifier
					if sign_type == 0:
						decorator = 'PACIA %s'%modifier_type if modifier else 'PACIZA'
					elif sign_type == 1:
						decorator = 'PACIB %s'%modifier_type if modifier else 'PACIZB'
					elif sign_type == 2:
						decorator = 'PACDA %s'%modifier_type if modifier else 'PACDZA'
					elif sign_type == 3:
						decorator = 'PACDB %s'%modifier_type if modifier else 'PACDZB'
					idaapi.set_cmt(current_reloc , decorator, 1)
				else:
					real_addr = ((decorated_addr << 13) & 0xFF00000000000000) | (decorated_addr & 0x7ffffffffff)
					if decorated_addr & 0x40000000000:
						real_addr |= 0xfffc0000000000
				idaapi.patch_qword(current_reloc, real_addr)
				idaapi.op_offset(current_reloc, 0, idaapi.REF_OFF64)
				nb_relocs += 1
			delta_next_reloc = ((decorated_addr >> 51) & 0x7ff) * multiplier
			if delta_next_reloc == 0:
				break
			current_reloc += delta_next_reloc
		cursor += 4
		delta = idaapi.get_dword(cursor)
	print '%d relocs fixed!'%nb_relocs
    def activate(self, ctx):
        start, end = idc.read_selection_start(), idc.read_selection_end()
        if start == idaapi.BADADDR:
            print 'Please select something'
            return

        import capstone
        md = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64)
        md.details = True
        data = idaapi.get_bytes(start, end - start)
        for insn in md.disasm(data, start):
            # print "0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)
            idaapi.set_cmt(insn.address, str('%s %s' % (insn.mnemonic, insn.op_str)), False)
Ejemplo n.º 19
0
 def implement(self):
     if self._comment_type == "regular":
         idaapi.set_cmt(self._linear_address, self._value, 0)
     elif self._comment_type == "repetable":
         idaapi.set_cmt(self._linear_address, self._value, 1)
     elif self._comment_type == "function":
         idc.set_func_cmt(self._linear_address, self._value, 0)
     elif self._comment_type == "anterior" or self._comment_type == "posterior":
         ida_lines.del_extra_cmt(self._linear_address, self._idx)
         is_anterior = 1 if self._idx - 1000 < 1000 else 0
         if not self._value:
             return 0
         ida_lines.add_extra_cmt(self._linear_address, is_anterior,
                                 self._value)
Ejemplo n.º 20
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.º 21
0
    def activate(self, ctx):
        sel = idaapi.read_selection()
        if not sel[0]:
            print 'Please select something'
            return

        import capstone
        md = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64)
        md.details = True
        data = idaapi.get_many_bytes(sel[1], sel[2] - sel[1])
        for insn in md.disasm(data, sel[1]):
            # print "0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)
            idaapi.set_cmt(insn.address,
                           str('%s %s' % (insn.mnemonic, insn.op_str)), False)
Ejemplo n.º 22
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.º 23
0
    def decode_at_ea(addr, offset, keyLen, dataLen):
        """ use for manually decoding with IDA and will put a comment at screen_ea """
        data = ida_bytes.get_bytes(addr + offset, keyLen + dataLen)
        cmt = data_to_str(decode_string(data, keyLen, dataLen))
        print("%s" % cmt)

        ea = idc.get_screen_ea()
        idaapi.set_cmt(ea, cmt, True)  # disassembly comment
        cfunc = idaapi.decompile(ea)
        if cfunc is not None:
            # decompiled comment
            tl = idaapi.treeloc_t()
            tl.ea = ea
            tl.itp = idaapi.ITP_SEMI
            cfunc.set_user_cmt(tl, cmt)
            cfunc.save_user_cmts()
Ejemplo n.º 24
0
    def decode():
        ea = ScreenEA()
        if ea == idaapi.BADADDR:
            idaapi.msg(PLUGIN_NAME + " ERROR: Could not get get_screen_ea()")
            return

        str_id = idaapi.get_highlighted_identifier()
        if not str_id:
            idaapi.msg(PLUGIN_NAME + " ERROR: No Ioctl Code highlighted!")
            return
        try:
            if str_id[-1] == 'h':
                code = int(str_id[:-1], 16)
            elif str_id[-1] == 'o':
                code = int(str_id[:-1], 8)
            elif str_id[-1] == 'b':
                code = int(str_id[:-1], 2)
            else:
                code = int(str_id)
        except ValueError:
            idaapi.msg(PLUGIN_NAME + " ERROR: Not a valid Ioctl Code: " +
                       str(str_id))
            return

        try:
            decoder = IOCTL_Decoder(code)
            ioctl_data = decoder.decode()

            #print decoded IOCTL to cli
            msg_string = "That IOCTL decodes to: \n\tDevice: %s \n\tFunction: %s \n\tAccess: %s \n\tMethod: %s"
            idaapi.msg(msg_string %
                       (ioctl_data["device"], ioctl_data["function"],
                        ioctl_data["access"], ioctl_data["method"]))

            #add decoded IOCTL as comment
            comment_string = "dwIoControlCode: \n\t\tDevice: %s \n\t\tFunction: %s \n\t\tAccess: %s \n\t\tMethod: %s"
            idaapi.set_cmt(
                ea,
                comment_string % (ioctl_data["device"], ioctl_data["function"],
                                  ioctl_data["access"], ioctl_data["method"]),
                0)
        except Exception as e:
            idaapi.msg(PLUGIN_NAME + " ERROR: " + str(e))
        return
Ejemplo n.º 25
0
 def loadcmt(self):
     total = 0
     count = 0
     for line in self.sym_file:
         total+=1
         sm = re.search("C[\s]+([\dA-F]+)[\s]+(.+)", line)
         if sm:
             if is_printable(sm.group(2)) is False:
                 continue
             if idaapi.set_cmt(int(sm.group(1), 16), sm.group(2), 0):
                 count += 1
             else:
                 print "set comment %s:%s failed" % (sm.group(1), sm.group(2))
     print "total %d applied %d comments" % (total,count)
Ejemplo n.º 26
0
    def old_changed(cls, ea, repeatable_cmt):
        cmt = utils.string.of(idaapi.get_cmt(ea, repeatable_cmt))
        fn = idaapi.get_func(ea)

        # if we're in a function, then clear our contents.
        if fn:
            internal.comment.contents.set_address(ea, 0)

        # otherwise, just clear the tags globally
        else:
            internal.comment.globals.set_address(ea, 0)

        # simply grab the comment and update its refs
        res = internal.comment.decode(cmt)
        if res:
            cls._create_refs(ea, res)

        # otherwise, there's nothing to do if its empty
        else:
            return

        # and then re-write it back to its address
        idaapi.set_cmt(ea, utils.string.to(internal.comment.encode(res)),
                       repeatable_cmt)
Ejemplo n.º 27
0
    def _event(cls):
        while True:
            # cmt_changing event
            ea,rpt,new = (yield)
            old = idaapi.get_cmt(ea, rpt)
            f,o,n = idaapi.get_func(ea),internal.comment.decode(old),internal.comment.decode(new)

            # update references before we update the comment
            cls._update_refs(ea, o, n)

            # wait for cmt_changed event
            newea,nrpt,none = (yield)

            # now fix the comment the user typed
            if (newea,nrpt,none) == (ea,rpt,None):
                ncmt,repeatable = idaapi.get_cmt(ea, rpt), cls._is_repeatable(ea)

                if (ncmt or '') != new:
                    logging.warn("internal.{:s}.event : Comment from event is different from database : {:x} : {!r} != {!r}".format('.'.join((__name__,cls.__name__)), ea, new, ncmt))

                # delete it if it's the wrong type
#                if nrpt != repeatable:
#                    idaapi.set_cmt(ea, '', nrpt)

#                # write the tag back to the address
#                if internal.comment.check(new): idaapi.set_cmt(ea, internal.comment.encode(n), repeatable)
#                # write the comment back if it's non-empty
#                elif new: idaapi.set_cmt(ea, new, repeatable)
#                # otherwise, remove it's reference since it's being deleted
#                else: cls._delete_refs(ea, n)

                if internal.comment.check(new): idaapi.set_cmt(ea, internal.comment.encode(n), rpt)
                elif new: idaapi.set_cmt(ea, new, rpt)
                else: cls._delete_refs(ea, n)

                continue

            # if the changed event doesn't happen in the right order
            logging.fatal("{:s}.event : Comment events are out of sync, updating tags from previous comment. : {!r} : {!r}".format('.'.join((__name__,cls.__name__)), o, n))

            # delete the old comment
            cls._delete_refs(ea, o)
            idaapi.set_cmt(ea, '', rpt)
            logging.warn("{:s}.event : Previous comment at {:x} : {!r}".format('.'.join((__name__,cls.__name__)), o))

            # new comment
            new = idaapi.get_cmt(newea, nrpt)
            n = internal.comment.decode(new)
            cls._create_refs(newea, n)

            continue
        return
Ejemplo n.º 28
0
    def _event(cls):
        while True:
            # cmt_changing event
            ea, rpt, new = (yield)
            old = utils.string.of(idaapi.get_cmt(ea, rpt))
            f, o, n = idaapi.get_func(ea), internal.comment.decode(old), internal.comment.decode(new)

            # update references before we update the comment
            cls._update_refs(ea, o, n)

            # wait for cmt_changed event
            newea, nrpt, none = (yield)

            # now fix the comment the user typed
            if (newea, nrpt, none) == (ea, rpt, None):
                ncmt, repeatable = utils.string.of(idaapi.get_cmt(ea, rpt)), cls._is_repeatable(ea)

                if (ncmt or '') != new:
                    logging.warn(u"{:s}.event() : Comment from event at address {:#x} is different from database. Expected comment ({!s}) is different from current comment ({!s}).".format('.'.join((__name__, cls.__name__)), ea, utils.string.repr(new), utils.string.repr(ncmt)))

                # delete it if it's the wrong type
#                if nrpt != repeatable:
#                    idaapi.set_cmt(ea, '', nrpt)

#                # write the tag back to the address
#                if internal.comment.check(new): idaapi.set_cmt(ea, utils.string.to(internal.comment.encode(n)), repeatable)
#                # write the comment back if it's non-empty
#                elif new: idaapi.set_cmt(ea, utils.string.to(new), repeatable)
#                # otherwise, remove its reference since it's being deleted
#                else: cls._delete_refs(ea, n)

                if internal.comment.check(new): idaapi.set_cmt(ea, utils.string.to(internal.comment.encode(n)), rpt)
                elif new: idaapi.set_cmt(ea, utils.string.to(new), rpt)
                else: cls._delete_refs(ea, n)

                continue

            # if the changed event doesn't happen in the right order
            logging.fatal(u"{:s}.event() : Comment events are out of sync at address {:#x}, updating tags from previous comment. Expected comment ({!s}) is different from current comment ({!s}).".format('.'.join((__name__, cls.__name__)), ea, utils.string.repr(o), utils.string.repr(n)))

            # delete the old comment
            cls._delete_refs(ea, o)
            idaapi.set_cmt(ea, '', rpt)
            logging.warn(u"{:s}.event() : Deleted comment at address {:#x} was {!s}.".format('.'.join((__name__, cls.__name__)), ea, utils.string.repr(o)))

            # new comment
            new = utils.string.of(idaapi.get_cmt(newea, nrpt))
            n = internal.comment.decode(new)
            cls._create_refs(newea, n)

            continue
        return
Ejemplo n.º 29
0
 def tag_write(ea, key, value, repeatable=0):
     dict = tag_read(ea, repeatable=repeatable)
     dict[key] = value
     res = internal.comment.toString(dict)
     return idaapi.set_cmt(ea, res, int(bool(repeatable)))
Ejemplo n.º 30
0
def hwreg(ea, name, comment):
    idaapi.doDwrd(ea, 4)
    idaapi.set_name(ea, name)
    idaapi.set_cmt(ea, cmt, True)  # repeatable comment
Ejemplo n.º 31
0
    def AsmAndWrite(self, mnem, instr=None, write_ea=None, function=None):
        if mnem == '':
            return

        if write_ea != None:
            ea_write = write_ea
        else:
            ea_write = self.free_ea

        idc.MakeUnkn(ea_write, 0)
        #tmp = idaapi.assemble(self.free_ea, self.segment_start, self.free_ea, 1, mnem)

        if debug:
            print ">Assemble:AsmAndWrite - !Writing @ ea[%08x] ip[%08x] instr[%s]" % (ea_write, ea_write, mnem)
        tmp = idaapi.assemble(ea_write, 0, ea_write, 1, mnem)

        if instr != None:
            idaapi.set_cmt(ea_write, "%08x" % instr.GetOriginEA(), 0)

        if tmp == 0:
            if instr == None and function != None:
                raise MiscError

            if debug:
                print '>Assemble:AsmAndWrite - !Messy instruction', mnem
                print '>Assemble:AsmAndWrite - Trying original opcodes!'

            refs_from = [x for x in function.GetRefsFrom(instr.GetOriginEA()) if x != None]
            if len(refs_from) == 0:
                if instr.GetIsModified() == True:
                    raise MiscError

                instr_op = instr.GetOpcode()
                for pos in xrange(0, len(instr_op)):
                    idc.PatchByte(ea_write+pos, ord(instr_op[pos]))

                if idc.MakeCode(ea_write) == 0:
                    raise MiscError

                ea_write += idc.ItemSize(ea_write)

            elif len(refs_from) == 1:
                instr_op = instr.GetOpcode()
                for pos in xrange(0, len(instr_op)):
                    idc.PatchByte(ea_write+pos, ord(instr_op[pos]))

                if idc.MakeCode(ea_write) == 0:
                    raise MiscError

                ea_write += idc.ItemSize(ea_write)

            else:
                #print '>Assemble:AsmAndWrite - GetRefsFrom(%08x)' % instr.GetOriginEA(), [hex(x) for x in function.GetRefsFrom(instr.GetOriginEA()) if x != None]
                print '>Assemble:AsmAndWrite - refs_from', refs_from
                print '>Assemble:AsmAndWrite - ea_write [%08x]' % ea_write
                print '>Assemble:AsmAndWrite - mnem', mnem
                print '>Assemble:AsmAndWrite - instr.GetMnem', instr.GetMnem()
                print '>Assemble:AsmAndWrite - instr.GetDisasm', instr.GetDisasm()
                raise MiscError
        else:
            if idc.MakeCode(ea_write) == 0:
                raise MiscError

            ea_write += idc.ItemSize(ea_write)

        if write_ea == None:
            self.free_ea = ea_write
Ejemplo n.º 32
0
 def tag_write(ea, key, value, repeatable=0):
     dict = tag_read(ea, repeatable=repeatable)
     dict[key] = value
     res = _comment.toString(dict)
     return idaapi.set_cmt(ea, res, int(bool(repeatable)))
Ejemplo n.º 33
0
 def repeat(self, comment):
     idaapi.set_cmt(self._ea, comment, 1)
Ejemplo n.º 34
0
 def regular(self, comment):
     idaapi.set_cmt(self._ea, comment, 0)
Ejemplo n.º 35
0
def load_file(f, neflags, format):
    idaapi.set_processor_type("arm:armv8", idaapi.SETPROC_LOADER)

    f.seek(-0x20, os.SEEK_END)
    nseg, = struct.unpack("<12xI16x", f.read(0x20))
    print(f"Number of segments: {nseg}")

    for sno in range(nseg):
        f.seek(-0x20-0x20*(nseg-sno), os.SEEK_END)
        mem_addr, file_addr, size, name = struct.unpack("<QII8x8s", f.read(0x20))
        name, _, _ = name.partition(b'\0')
        name = name.decode()
        print(f"Segment {sno}: {name} at mem={hex(mem_addr)} file={hex(file_addr)} size={hex(size)}")

        ida_seg_type = None
        if name == "__TEXT":
            ida_seg_type = "CODE"
        if name == "__DATA":
            ida_seg_type = "DATA"

        idaapi.add_segm(0, mem_addr, mem_addr + size, name, ida_seg_type)
        f.file2base(file_addr, mem_addr, mem_addr + size, True)

    f.seek(-0x20-0x20*nseg, os.SEEK_END)
    footer_start = f.tell()
    footer_end = footer_start + 0x20 + 0x20 * nseg
    idaapi.add_segm(0, footer_start, footer_end, "__FOOTER", "DATA")
    f.file2base(footer_start, footer_start, footer_end, True)

    header_start = footer_start + 0x20 * nseg
    idaapi.add_extra_line(header_start, True, "")
    idaapi.add_extra_cmt(header_start, True, f"File Header")
    idaapi.create_strlit(header_start, 4, 0)
    idaapi.set_cmt(header_start, "Magic", False)
    idaapi.create_dword(header_start + 4, 4)
    idaapi.set_cmt(header_start + 4, "Version?", False)
    idaapi.create_dword(header_start + 8, 4)
    idaapi.set_cmt(header_start + 8, "File length minus headers", False)
    idaapi.create_dword(header_start + 12, 4)
    idaapi.set_cmt(header_start + 12, "Section count", False)
    for sno in range(nseg):
        header_start = footer_start + 0x20 * sno
        idaapi.add_extra_line(header_start, True, "")
        idaapi.add_extra_cmt(header_start, True, f"Segment {sno + 1}")
        idaapi.create_qword(header_start, 8)
        idaapi.set_cmt(header_start, "Memory Address", False)
        idaapi.create_dword(header_start + 8, 4)
        idaapi.set_cmt(header_start + 8, "File Offset", False)
        idaapi.create_dword(header_start + 12, 4)
        idaapi.create_qword(header_start + 16, 8)
        idaapi.set_cmt(header_start + 12, "Segment Length", False)
        idaapi.create_strlit(header_start + 24, 8, 0)
        idaapi.set_cmt(header_start + 24, "Segment Name", False)

    idaapi.add_entry(0, 0, "start", 1)

    return 1
Ejemplo n.º 36
0
def process_data_result(start, data):
    # 16 bytes on a line
    # one byte take 4 char: 2 hex char, a space and a char if isalnum
    # one line take 3 char addtion: two space and \n, and ea hex address

    BYTES_PER_LINE = 16
    MAX_BYTES_HEX_DUMP = BYTES_PER_LINE * 64    # 64 lines

    printLen = len(data)
    if printLen > MAX_BYTES_HEX_DUMP:
        printLen = MAX_BYTES_HEX_DUMP
        plg_print("Only hexdump first %d bytes" % MAX_BYTES_HEX_DUMP)

    nLines = printLen // BYTES_PER_LINE     # Number of lines
    nOdd = printLen % BYTES_PER_LINE    # Number of bytes at last line
    isStr = True
    sHex = str()
    for i in range(printLen):
        if isStr and chr(data[i]) not in string.printable:
            isStr = False

        if i % BYTES_PER_LINE == 0:
            sHex += "%s: " % idaapi.ea2str(start + i)

        sHex += "%02X " % data[i]

        if (i % BYTES_PER_LINE == BYTES_PER_LINE - 1) or (i == printLen - 1):
            # add the end of data or end of a line
            if nLines:
                lineIdx = i // BYTES_PER_LINE   # current line number
                low = lineIdx * BYTES_PER_LINE
                high = i + 1
            else:
                low = 0
                high = printLen

            sHex += " "

            # Padding last line
            if i == printLen - 1 and nLines and nOdd:
                sHex += " " * (BYTES_PER_LINE - nOdd) * 3

            for j in range(low, high):
                ch = chr(data[j])
                sHex += ch if ch.isalnum() else "."

            sHex += "\n"

    # Print out the hexdump string
    print(sHex)

    if isStr:
        txt = str(data)
        print("String result: '%s'" % txt)
        idaapi.set_cmt(start, txt, 1)

    if idaapi.ask_yn(idaapi.ASKBTN_NO, "Do you want to patch selected range with result data ?") == idaapi.ASKBTN_YES:
        idaapi.patch_bytes(start, bytes(data))

    if idaapi.ask_yn(idaapi.ASKBTN_YES, "Do you want to dump result data to file ?") == idaapi.ASKBTN_YES:
        dump_data_to_file("Dump_At_0x%X_Size_%d.dump" % (start, len(data)), data)
Ejemplo n.º 37
0
    def AsmAndWrite(self, mnem, instr=None, write_ea=None, function=None):
        if mnem == '':
            return

        if write_ea != None:
            ea_write = write_ea
        else:
            ea_write = self.free_ea

        idc.MakeUnkn(ea_write, 0)
        #tmp = idaapi.assemble(self.free_ea, self.segment_start, self.free_ea, 1, mnem)

        if debug:
            print ">Assemble:AsmAndWrite - !Writing @ ea[%08x] ip[%08x] instr[%s]" % (
                ea_write, ea_write, mnem)
        tmp = idaapi.assemble(ea_write, 0, ea_write, 1, mnem)

        if instr != None:
            idaapi.set_cmt(ea_write, "%08x" % instr.GetOriginEA(), 0)

        if tmp == 0:
            if instr == None and function != None:
                raise MiscError

            if debug:
                print '>Assemble:AsmAndWrite - !Messy instruction', mnem
                print '>Assemble:AsmAndWrite - Trying original opcodes!'

            refs_from = [
                x for x in function.GetRefsFrom(instr.GetOriginEA())
                if x != None
            ]
            if len(refs_from) == 0:
                if instr.GetIsModified() == True:
                    raise MiscError

                instr_op = instr.GetOpcode()
                for pos in xrange(0, len(instr_op)):
                    idc.PatchByte(ea_write + pos, ord(instr_op[pos]))

                if idc.MakeCode(ea_write) == 0:
                    raise MiscError

                ea_write += idc.ItemSize(ea_write)

            elif len(refs_from) == 1:
                instr_op = instr.GetOpcode()
                for pos in xrange(0, len(instr_op)):
                    idc.PatchByte(ea_write + pos, ord(instr_op[pos]))

                if idc.MakeCode(ea_write) == 0:
                    raise MiscError

                ea_write += idc.ItemSize(ea_write)

            else:
                #print '>Assemble:AsmAndWrite - GetRefsFrom(%08x)' % instr.GetOriginEA(), [hex(x) for x in function.GetRefsFrom(instr.GetOriginEA()) if x != None]
                print '>Assemble:AsmAndWrite - refs_from', refs_from
                print '>Assemble:AsmAndWrite - ea_write [%08x]' % ea_write
                print '>Assemble:AsmAndWrite - mnem', mnem
                print '>Assemble:AsmAndWrite - instr.GetMnem', instr.GetMnem()
                print '>Assemble:AsmAndWrite - instr.GetDisasm', instr.GetDisasm(
                )
                raise MiscError
        else:
            if idc.MakeCode(ea_write) == 0:
                raise MiscError

            ea_write += idc.ItemSize(ea_write)

        if write_ea == None:
            self.free_ea = ea_write