Пример #1
0
    def populate_struc_enum_ids(self):
        logger.debug("Populating hash cache with current values")
        # force hash generation of struc and enums (without use_time)
        idx = idc.GetFirstStrucIdx()
        while idx != idc.BADADDR:
            self.get_struc_enum_object_id(idc.GetStrucId(idx), use_time=False)
            idx = idc.GetNextStrucIdx(idx)

        for idx in xrange(0, idc.GetEnumQty()):
            enum_id = idc.GetnEnum(idx)
            self.get_struc_enum_object_id(enum_id, use_time=False)

            enum_name = idc.GetEnumName(enum_id)
            for (const_id, const_value,
                 bmask) in enum_member_iterate_all(enum_id):
                const_name = idc.GetConstName(const_id)
                self.get_enum_member_id(enum_id,
                                        enum_name,
                                        const_id,
                                        const_name,
                                        const_value,
                                        bmask,
                                        use_time=False)

        _yatools_hash_provider.populate_persistent_cache()
Пример #2
0
 def yacheck_enums(self):
     values = yaunit.load('enums')
     for flag in flags:
         for prefix, enum_width, is_bitfield, num_fields in tests:
             name, ea, values = str(values[0][0]), values[0][1], values[1:]
             eid = idc.GetEnum(name)
             self.assertNotEqual(eid, idaapi.BADADDR)
             self.assertEqual(idc.GetEnumFlag(eid), flag)
             self.assertEqual(idc.GetEnumName(eid), name)
             self.assertEqual(idc.IsBitfield(eid), is_bitfield)
             self.assertEqual(idc.GetEnumCmt(eid, False), prefix + 'cmt')
             self.assertEqual(idc.GetEnumCmt(eid, True),  prefix + 'rpt')
             if enum_width != 0:
                 self.assertEqual(idc.GetEnumWidth(eid), enum_width)
             n = 0
             for value, bmask in walk_enum(eid):
                 self.assertLessEqual(n, num_fields)
                 v = 1 << n if is_bitfield else n
                 self.assertEqual(value, value, v)
                 cid = idc.GetConstEx(eid, v, 0, bmask)
                 self.assertNotEqual(cid, idaapi.BADADDR)
                 field = '%s_%d' % (name, n)
                 self.assertEqual(idc.GetConstName(cid), field)
                 # FIXME comments are not working
                 #self.assertEqual(idc.GetConstCmt(cid, False), field + 'cmt')
                 #self.assertEqual(idc.GetConstCmt(cid, True),  field + 'rpt')
                 n += 1
             self.assertEqual(n, num_fields)
             if ea != None:
                 self.assertEqual(idaapi.get_enum_id(ea, 1)[0], eid)
Пример #3
0
 def getName(self, val, reload=False):
     if not self._names or reload:
         self._names = {}
         cns = self.getConsts(reload)
         for x in cns:
             for y in cns[x]:
                 self._names[y] = idc.GetConstName(cns[x][y])
     return self._names.get(val)
Пример #4
0
 def enum_member_created(self, enum, cid):
     ename = idc.GetEnumName(enum)
     cname = idc.GetConstName(cid)
     self.ctrl._handle_action({
         'action': 'enum_member_created',
         'enum': enum,
         'cid': cid,
         'ename': ename,
         'cname': cname
     })
     return 0
    def fix_names(self):
        """ 
            Fix the table of imports and map enums to apis.
        """
        start_addr  = idc.AskAddr(idc.here(), "Enter table start address")

        ## check if address is within the base address and maximum address
        if (start_addr < idc.MinEA()) or (start_addr > idc.MaxEA()):
            idc.Warning("You have entered an invalid start address")
            idc.Exit

        self.start_addr = start_addr    
        current_addr = self.start_addr

        #Current size of PoisonIvy IAT
        end_addr = current_addr + 568

        # Walk the table 8 bytes at a time
        while current_addr <= end_addr:

            idc.MakeQword(current_addr)
            print "DEBUG: Current address - 0x%08x" % current_addr
            addr = idc.Qword(current_addr)
            print "DEBUG: address - 0x%08x" % addr
            if addr == -1:
                print "[!] Skipping address 0x%08x - 0x%08x" % (current_addr, addr)
                current_addr += 8
                continue

            # Make the current address an offset
            idc.OpOff(current_addr,0,0)
            # We need to undefine the bytes incase IDA autoanalysis had converted an incorrect byte
            idc.MakeUnkn(addr, 1)
            # Create code at this address 
            idc.MakeCode(addr)
            # Create function at the same address
            idc.MakeFunction(addr, addr+16)
            # Read the second operand at the address which should be the negative API address value
            imp_addr = idc.GetOperandValue(addr, 1)

            if imp_addr == -1:
                print "[!] Couldn't get operand at address - 0x%08x" % addr
                current_addr +=8
                continue             

            # try:
            #     int_addr = int(imp_addr,16)
            # except ValueError as e:
            #     print "[!] Failed on: %s - %s\n" % (imp_addr, e)
            #     current_addr +=8 
            #     continue
            
            # if we know about this value then let's do the work
            if imp_addr in self.enums.keys():
                enum_id = self.enums[imp_addr]
                # Convert operand to enum 
                idc.OpEnumEx(addr, 1, enum_id,0)
                const_id = idc.GetConstEx(enum_id, imp_addr, 0, -1)
                fn_name = "fn_"+idc.GetConstName(const_id)
                off_name = "ptr_"+idc.GetConstName(const_id)
                # Rename the function to the symbol name.
                # We append fn_ to the symbol for the function name
                # and ptr_ to the offset in the table.
                if not idc.MakeNameEx(addr, fn_name, idaapi.SN_NOWARN):
                    print "[!] Failed to rename function %s at 0x%08x\n" % (fn_name, addr)
                if not idc.MakeNameEx(current_addr, off_name, idaapi.SN_NOWARN):
                    print "[!] Failed to rename offset %s at 0x%08x\n" % (off_name,current_addr)

            current_addr += 8

        return 
Пример #6
0
    def make_enum(self, object_version, address):
        enum_name = object_version.get_name()
        object_id = object_version.get_id()

        # build flags
        bitfield = False
        flags = object_version.get_object_flags()
        if flags & 0x1 == 0x1:
            bitfield = True
        flags = flags & ~0x1

        try:
            enum_width = object_version.get_size()
        except KeyError:
            enum_width = None

        # check if enum already exists
        enum_id = idc.GetEnum(enum_name)
        enum_xrefs_ids = object_version.get_xrefed_ids()
        logger.debug(
            "%s:%d : Check here that enum_xrefs_ids is a set(YaToolObjectId) and correctly used"
            % (__file__, inspect.currentframe().f_lineno))
        if enum_id != idc.BADADDR:
            # enum already exists, deleting all members
            for (const_id, const_value,
                 bmask) in YaToolIDATools.enum_member_iterate_all(enum_id):
                if bmask == idc.BADADDR:
                    bmask = -1
                const_name = idc.GetConstName(const_id)

                if (enum_name, const_name,
                        const_value) not in self.enum_member_ids:
                    idc.DelConstEx(enum_id, const_value, 0, bmask)
                elif self.hash_provider.get_enum_member_id(
                        enum_id, enum_name, const_id, const_name,
                        const_value) not in enum_xrefs_ids:
                    logger.debug("deleting not found constant : %s/%s" %
                                 (enum_name, const_name))
                    idc.DelConstEx(enum_id, const_value, 0, bmask)
            """
            if the enum "bitfield" state has changed : change it!
            We can't access the functions
            """
            if idc.IsBitfield(enum_id) != bitfield:
                idaapi.set_enum_bf(enum_id, bitfield)
        else:
            # create enum
            # SetEnumFlag return "'module' object has no attribute 'set_enum_flag'".
            enum_id = idc.AddEnum(address, enum_name, flags)

        if enum_width is not None:
            idc.SetEnumWidth(enum_id, enum_width)

        if bitfield:
            idc.SetEnumBf(enum_id, 1)

        # process comment
        try:
            repeatable_headercomment = self.sanitize_comment_to_ascii(
                object_version.get_header_comment(True))
            idc.SetEnumCmt(enum_id, repeatable_headercomment, 1)
        except KeyError:
            pass
        try:
            nonrepeatable_headercomment = self.sanitize_comment_to_ascii(
                object_version.get_header_comment(False))
            idc.SetEnumCmt(enum_id, nonrepeatable_headercomment, 0)
        except KeyError:
            pass

        self.enum_ids[object_id] = enum_id

        self.hash_provider.put_hash_struc_or_enum(enum_id, object_id)

        logger.debug("adding enum id %s : '0x%.016X'" %
                     (self.hash_provider.hash_to_string(object_id), enum_id))