예제 #1
0
파일: imports.py 프로젝트: nihilus/idataco
    def renameDword(self):
        proc_addr = self._import_table.item(self._import_table.currentRow(), 3).text()
        proc_name = str(self._import_table.item(self._import_table.currentRow(), 2).text())
        renamed = 0
        if proc_addr:
            try:
                proc_addr = int(proc_addr, 16)
                proc_bin_str = " ".join([x.encode("hex") for x in struct.pack("<I", proc_addr)])
                next_dword = idc.FindBinary(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, proc_bin_str)
                while next_dword != idc.BADADDR:
                    log.debug("Trying to fix-up 0x{:08x}".format(next_dword))
                    # DWORDs can be "inaccessible" for many reasons and it requires "breaking up" the data blobs
                    # and manually fixing them

                    # Reason 1: In a dword array in an unknown section
                    if idc.isUnknown(next_dword):
                        idc.MakeUnkn(next_dword, idc.DOUNK_EXPAND)
                        idc.MakeDword(next_dword)
                    # Reason 2: In a dword array in a data section
                    elif idc.isData(next_dword):
                        hd = idc.ItemHead(next_dword)
                        idc.MakeDword(hd)
                        idc.MakeDword(next_dword)
                    # Reason 3: In a dword array in a code section (validate via "dd <dword>,")
                    elif idc.isCode(next_dword) and idc.GetDisasm(next_dword).startswith("dd "):
                        hd = idc.ItemHead(next_dword)
                        idc.MakeDword(hd)
                        idc.MakeDword(next_dword)

                    # Only perform
                    if idc.Name(next_dword).startswith(("off_", "dword_")) or idc.Name(next_dword) == "":
                        success = idc.MakeNameEx(next_dword, proc_name, idc.SN_NOWARN|idc.SN_NON_AUTO)
                        i = 0
                        new_proc_name = proc_name
                        while not success and i < 10:
                            new_proc_name = "{}{}".format(proc_name, i)
                            success = idc.MakeNameEx(next_dword, new_proc_name, idc.SN_NOWARN|idc.SN_NON_AUTO)
                            i += 1
                        if success:
                            renamed += 1
                            item = self._import_table.item(self._import_table.currentRow(), 5)
                            item.setText("{}, {}".format(str(item.text()), new_proc_name))
                            log.debug("DWORD @ 0x{:08x} now has name {}".format(next_dword, new_proc_name))
                        else:
                            log.error("Unable to auto-rename successfully, terminating search")
                            break
                    else: log.debug("Value at 0x{:08x} does not meet renaming requirements".format(next_dword))
                    next_dword = idc.FindBinary(next_dword+4, idc.SEARCH_DOWN|idc.SEARCH_NEXT, proc_bin_str)
            except Exception, e:
                log.error("Error encountered: {}".format(e))
            log.debug("Renamed {:d} instances of {}".format(renamed, proc_name))
예제 #2
0
def read_mem(addr, forced_addr_sz=None, read_only=False):
    global ADDR_SZ

    if not read_only:
        if forced_addr_sz:
            idc.MakeUnknown(addr, forced_addr_sz, idc.DOUNK_SIMPLE)
        else:
            idc.MakeUnknown(addr, ADDR_SZ, idc.DOUNK_SIMPLE)
        idaapi.autoWait()

    if forced_addr_sz == 2:
        if not read_only:
            idc.MakeWord(addr)
            idaapi.autoWait()
        return idc.Word(addr)
    if forced_addr_sz == 4 or ADDR_SZ == 4:
        if not read_only:
            idc.MakeDword(addr)
            idaapi.autoWait()
        return idc.Dword(addr)
    if forced_addr_sz == 8 or ADDR_SZ == 8:
        if not read_only:
            idc.MakeQword(addr)
            idaapi.autoWait()
        return idc.Qword(addr)
예제 #3
0
파일: decv.py 프로젝트: sourav-txt/decv
def make_dwords_in_handlers_tab(handlers_tab, count):

    ea = handlers_tab
    for i in range(count):
        undefDword(ea)
        idc.MakeDword(ea)
        ea += 4
예제 #4
0
 def readDefinition(self, ea):
     # Read all the fields from the stream.
     self.fields_address = MakeAndGetDword(ea, "fields address")
     self.index = MakeAndGetDword(ea + 4, "index")
     self.upgrade_proc = MakeAndGetDword(ea + 8, "upgrade function")
     idc.MakeDword(ea + 12)
     self.size_of = MakeAndGetDword(ea + 16, "size of field set")
예제 #5
0
    def parse_hdr(self):
        '''
        Refer: function [go12Init()] in https://golang.org/src/debug/gosym/pclntab.go
        '''
        magic = idc.Dword(self.start_addr) & 0xFFFFFFFF
        if magic != Pclntbl.MAGIC:
            print magic, Pclntbl.MAGIC
            common._error("Invalid pclntbl header magic number!")
            idc.Exit(1)
            #raise Exception("Invalid pclntbl header magic number!")
        idc.MakeDword(self.start_addr)
        idc.MakeComm(self.start_addr, "Magic Number")
        idc.MakeNameEx(self.start_addr,
                       "runtime_symtab",
                       flags=idaapi.SN_FORCE)
        idaapi.autoWait()

        if idc.Word(self.start_addr + 4) & 0xFFFF != 0:
            raise Exception("Invalid pclntbl header")
        idc.MakeWord(self.start_addr + 4)

        self.min_lc = idc.Byte(self.start_addr + 6) & 0xFF
        if (self.min_lc != 1) and (self.min_lc != 2) and (self.min_lc != 4):
            raise Exception("Invalid pclntbl minimum LC!")
        idc.MakeComm(self.start_addr + 6, "instruction size quantum")
        idaapi.autoWait()

        self.ptr_sz = idc.Byte(self.start_addr + 7) & 0xFF
        if (self.ptr_sz != 4) and (self.ptr_sz != 8):
            raise Exception("Invalid pclntbl pointer size!")
        idc.MakeComm(self.start_addr + 7, "ptr size")
        idaapi.autoWait()
예제 #6
0
 def makeDQWord(self, api):
     match = re.search(r"\((?P<bitness>..)bit\)", api[2])
     if match:
         bitness = int(match.group("bitness"))
     if bitness == 32:
         idc.MakeDword(api[0])
     elif bitness == 64:
         idc.MakeQword(api[0])
예제 #7
0
def MakeReg(name, offset, size, count=0):
    idc.MakeNameEx(offset, name, idc.SN_NOCHECK | idc.SN_NOWARN)
    if (size == 1):
        idc.MakeByte(offset)
    elif size == 2:
        idc.MakeWord(offset)
    elif size == 4:
        idc.MakeDword(offset)
    else:
        raise NotImplementedError("Register size invalid! Name: " + name)

    if (count != 0):
        idc.make_array(offset, count)
def make_data(addr, index, name, classname):
    if index == 0:
        print('    %s[%d] = %X' % (name, index, addr))
        print('      :')

    if addr == 0:
        return

    if classname == 'int':
        idc.MakeDword(addr)
    else:
        idc.MakeStruct(addr, classname)

    idc.MakeNameEx(addr, 'g_%s_%X' % (name, addr), idc.SN_NOWARN | idc.SN_AUTO)
예제 #9
0
def rngmkd(start_ea, end_ea):
    """
    Turns the data in the range to words. If not aligned with words, turns into bytes instead
    :param start_ea: start of the range
    :param end_ea: end of the range
    """
    ea = start_ea
    while ea % 4 != 0:
        print('%07X: -> byte' % ea)
        idc.MakeByte(ea)
        ea += 1
    while ea < end_ea:
        print('%07X: -> word' % ea)
        idc.MakeDword(ea)
        ea += 4
예제 #10
0
def main():
    for segstart, segend, segname in enum_segments():
        if segname not in ('.text', '.data'):
            continue

        for src, dst in find_pointers(segstart, segend):
            if is_code(src):
                # ignore instructions like:
                #
                #     call    ds:__vbaGenerateBoundsError
                #print('code pointer: 0x%x -> 0x%x' % (src, dst))
                continue

            # TODO: fix this: just look at the few previous bytes and ensure they are ASCII/Unicode
            if is_in_string(src):
                # for example, the following contains 0x444974 (a common valid offset):
                #
                #     text:004245B0 aRequestid    db 'requestID',
                #
                # enable or disable this behavior as you wish
                print('string pointer: 0x%x -> 0x%x' % (src, dst))
                pass
                #continue

            print('pointer from 0x%x to 0x%x' % (src, dst))

            if is_unknown(dst):
                print('destination unknown, making byte: 0x%x' % (dst))
                idc.MakeByte(dst)

            elif is_head(dst):
                # things are good
                pass

            else:
                # need to undefine head, and make byte
                head_va = get_head(dst)
                print('destination overlaps with head: 0x%x' % (head_va))
                idc.MakeUnkn(head_va, dst - head_va)
                idc.MakeByte(head_va)
                idc.MakeByte(dst)

            idc.MakeUnkn(src, 4)
            idc.MakeDword(src)
            # this doesn't seem to always work :-(
            # ref: https://reverseengineering.stackexchange.com/questions/17798/how-can-i-mark-a-global-variable-as-an-offset-using-idapython
            #idc.OpOffset(src, 0)
            ida_offset.op_offset(src, 0, idc.REF_OFF32)
예제 #11
0
def MakeN(addr, size):
    '''
    Make a integer with the given size at the given address.

    Args:
      addr (int): effective address.
      size (int): the size of the integer, one of 1, 2, 4, or 8.
    '''
    if size == 1:
        idc.MakeByte(addr)
    elif size == 2:
        idc.MakeWord(addr)
    elif size == 4:
        idc.MakeDword(addr)
    elif size == 8:
        idc.MakeQword(addr)
예제 #12
0
파일: codatify.py 프로젝트: tmr232/ida
    def datify(self):
        ea = self.get_start_ea(self.DATA)
        if ea == idc.BADADDR:
            ea = idc.FirstSeg()

        print "Converting remaining data to DWORDs...",

        while ea != idc.BADADDR:
            flags = idc.GetFlags(ea)

            if idc.isUnknown(flags) or idc.isByte(flags):
                idc.MakeDword(ea)
                idc.OpOff(ea, 0, 0)

            ea = idc.NextAddr(ea)

        print "done."
예제 #13
0
def MakeAndGetDword(ea, comment=None):
    """
    Creates a dword at the specified address and returns the dword value.
    :param ea: address to make dword at
    :param comment: optional comment to place at the specified address
    :return: the value of the dword at the specified address
    """

    # Make the dword.
    idc.MakeDword(ea)

    # Check if the comment is valid and if so place it at the address.
    if comment is not None:
        idc.MakeComm(ea, comment)

    # Get the dword value.
    return idc.Dword(ea)
예제 #14
0
def main():
    for segstart, segend, segname in enum_segments():
        if segname not in ('.text', '.data'):
            continue

        for src, dst in find_pointers(segstart, segend):
            if is_code(src):
                # ignore instructions like:
                #
                #     call    ds:__vbaGenerateBoundsError
                #print('code pointer: 0x%x -> 0x%x' % (src, dst))
                continue

            if is_in_string(src):
                # for example, the following contains 0x444974 (a common valid offset):
                #
                #     text:004245B0 aRequestid    db 'requestID',
                #
                # enable or disable this behavior as you wish
                print('string pointer: 0x%x -> 0x%x' % (src, dst))
                pass
                #continue

            print('pointer from 0x%x to 0x%x' % (src, dst))

            if is_unknown(dst):
                print('destination unknown, making byte: 0x%x' % (dst))
                idc.MakeByte(dst)

            elif is_head(dst):
                # things are good
                pass

            else:
                # need to undefine head, and make byte
                head_va = get_head(dst)
                print('destination overlaps with head: 0x%x' % (head_va))
                idc.MakeUnkn(head_va, dst - head_va)
                idc.MakeByte(head_va)
                idc.MakeByte(dst)

            idc.MakeUnkn(src, 4)
            idc.MakeDword(src)
            # this doesn't seem to always work :-(
            idc.OpOffset(src, 0)
예제 #15
0
    def datify(self):
        ea = self.get_start_ea(self.DATA)
        if ea == idc.BADADDR:
            ea = idc.FirstSeg()

        self.say("Converting remaining data to DWORDs...", )

        while ea != idc.BADADDR:
            flags = idc.GetFlags(ea)

            if (idc.isUnknown(flags) or idc.isByte(flags)) and ((ea % 4) == 0):
                idc.MakeDword(ea)
                idc.OpOff(ea, 0, 0)

            ea = idc.NextAddr(ea)

        self.say("done.")

        self._fix_data_offsets()
예제 #16
0
    def arr2dword(pointerRange):
        d = Data.Data(pointerRange[0])
        outputStatus = True
        while (d.ea < pointerRange[1]):
            content = d.getContent()

            # case: byte array that's 4 elements. Likely a word
            if type(content) == list and len(content) == 4 and (d.getSize() / len(content) == 1):
                # transform to dword
                status = idc.del_items(d.ea)
                status = status and idc.MakeDword(d.ea)
                outputStatus = outputStatus and status
                if status:
                    print('[OK] %07X: u8[4] -> u32 %07X' % (d.ea, d.getContent()))
                else:
                    print('[FAIL] %07X: u8[4] -> u32' % d.ea)
                # advance 4 bytes
                d = Data.Data(d.ea + 4)
            else:
                d = Data.Data(d.ea + d.getSize())
        return outputStatus
    def annotate_vector_table(self, vtoffset=0x0000000000):
        '''
        Name the vector table entries according to docs:
        http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABIFJFG.html
    
        Vector tables can appear in mulitple places in device flash
        Functions are not renamed because multiple vectors might point to a single function
        Append the address of the VT entry to the name from self.annotations to keep unique names
    
        '''

        for annotation_index in range(len(self.annotations)):
            entry_addr = vtoffset + 4 * annotation_index
            entry_name = "%s_%08x" % (self.annotations[annotation_index],
                                      entry_addr)

            idc.MakeDword(entry_addr)
            ida_name.set_name(entry_addr, entry_name, 0)

            # get the bytes of the vt entry
            dword = idc.Dword(entry_addr)

            if dword != 0:
                # print "ea %08x = 0x%08x" % (ea, dword)
                idc.MakeCode(dword - 1)
                idc.MakeFunction(dword - 1)
                # TODO fix the offsets created here
                # for thumb, they show to be off by a byte
                # one of the end args controls stuff about this
                idc.OpOffEx(entry_addr, 0, idaapi.REF_OFF32, -1, 0, 0)

                instruction = idc.Word(dword - 1)

                # functions like this are common
                if instruction == 0xe7fe:
                    idc.SetFunctionCmt(dword - 1, 'Infinite Loop', 1)
예제 #18
0
def scanDataForRelocs(M, D, start, end, new_eas, seg_offset):
    i = start
    while i < end:
        more_dref = [d for d in idautils.DataRefsFrom(i)]
        dref_size = idc.ItemSize(i) or 1
        if len(more_dref) == 0 and dref_size == 1:
            dword = readDword(i)
            DEBUG("Testing address: {0:x}... ".format(i))
            # check for unmakred references
            if isInData(dword, dword+1):
                idc.MakeDword(i)
                idc.add_dref(i, dword, idc.XREF_USER|idc.dr_O)
                DEBUG("making New Data Reference at: {0:x} => {1:x}\n".format(i, dword))
                dref_size = 4
            elif isInternalCode(dword):
                idc.MakeDword(i)
                idc.AddCodeXref(i, dword, idc.XREF_USER|idc.fl_F)
                DEBUG("making New Code Reference at: {0:x} => {1:x}\n".format(i, dword))
                dref_size = 4
            else:
                DEBUG("not code or data ref\n")

        i += dref_size

    def insertReference(M, D, ea, pointsto, seg_offset, new_eas):
        # do not make code references for mid-function code accessed via a JMP -- 
        # they will be found via the jumptable code. This prevents the insertion
        # of lots of extra code, but could be wrong for some cases
        if ea in ACCESSED_VIA_JMP and not isStartOfFunction(pointsto):
            # bail only if we are access via JMP and not the start
            # of a function
            DEBUG("\t\tNOT ADDING REF: {:08x} -> {:08x}\n".format(ea, pointsto))
            return

        DEBUG("\t\tFound a probable ref from: {0:x} => {1:x}\n".format(ea, pointsto))
        real_size = idc.ItemSize(pointsto)
        DEBUG("\t\tReal Ref: {0:x}, size: {1}\n".format(pointsto, real_size))
        insertRelocatedSymbol(M, D, pointsto, ea, seg_offset, new_eas, real_size)

    def checkIfJumpData(ea, size):
        """
        Loop through ea to ea+size, and if 
        every dword there points to code, this is a jump data section

        returns true or false and list of recovered ea => destination mappings
        """
        table_map = {}
        for jea in xrange(ea, ea+size, 4):
            dword = readDword(jea)
            if not isInternalCode(dword):
                DEBUG("Dword {:x} does not point to code, not a table\n".format(dword))
                return False, table_map

            table_map[jea] = dword

        return True, table_map

    i = start
    while i < end:
        DEBUG("Checking address: {:x}\n".format(i))
        dref_size = idc.ItemSize(i) or 1
        if dref_size > 4 and dref_size % 4 == 0:
            DEBUG("Possible table data at {:x}; size: {:x}\n".format(i, dref_size))
            (is_table, addrs) = checkIfJumpData(i, dref_size)
            if is_table:
                DEBUG("Its a table, adding {} references\n".format(len(addrs)));
                for ta in sorted(addrs.keys()):
                    insertReference(M, D, ta, addrs[ta], seg_offset, new_eas)
            else:
                DEBUG("Its not a table\n");

        elif dref_size == 4:
            more_cref = [c for c in idautils.CodeRefsFrom(i,0)]
            more_dref = [d for d in idautils.DataRefsFrom(i)]
            more_dref.extend(more_cref)
            if len(more_dref) > 0:
                DEBUG("\t\tFound a probable ref from: {0:x} => {1:x}\n".format(i, more_dref[0]))
                if len(more_dref) == 1:
                    insertReference(M, D, i, more_dref[0], seg_offset, new_eas)
                else: 
                    DEBUG("\t\tWARNING: Possible data ref problem\n");
                    insertReference(M, D, i, more_dref[0], seg_offset, new_eas)

        i += dref_size
예제 #19
0
파일: nxo64.py 프로젝트: tiliarou/loaders
 def ida_make_offset(f, ea):
     if f.armv7:
         idc.MakeDword(ea)
     else:
         idc.MakeQword(ea)
     idc.OpOff(ea, 0, 0)
예제 #20
0
        idc.set_name(ea, memory_region, idc.SN_PUBLIC)
    else:
        idc.set_name(ea, "MR_" + memory_region, idc.SN_PUBLIC)
        
# for iLO5 1.30.35
START_ADDR = 0x410CCC74

# for iLO5 1.20.33
START_ADDR = 0x410CBC74

# for iLO5 1.37.06
START_ADDR = 0x410CCC84


ea = START_ADDR
mod_base = START_ADDR

print "> parsing memory region entries:\n"

while True:
    idc.MakeDword(ea)
    struct_addr = idc.Dword(ea)
    if struct_addr == 0:
        break

    x = idc.SetType(ea, "MEMORY_REGION *")
    dump_memory_region(struct_addr)
    ea += 4

print "[+] job done captain!"
예제 #21
0
    def readDefinition(self, ea):
        # Read all the fields from the stream.
        self.address = ea
        self.display_name_address = MakeAndGetDword(ea)
        self.name_address = MakeAndGetDword(ea + 4)
        self.flags = MakeAndGetDword(ea + 8, "flags")
        self.maximum_element_count = MakeAndGetDword(ea + 12,
                                                     "maximum element count")
        self.maximum_element_count_string_address = MakeAndGetDword(
            ea + 16, "maximum element count string")
        self.field_sets_address = MakeAndGetDword(ea + 20, "field sets")
        self.field_set_count = MakeAndGetDword(ea + 24, "number of field sets")
        self.field_set_latest_address = MakeAndGetDword(
            ea + 28, "latest field set")
        idc.MakeDword(ea + 32)
        self.postprocess_proc = MakeAndGetDword(ea + 36,
                                                "postprocessing function")
        self.format_proc = MakeAndGetDword(ea + 40, "format function")
        self.generate_default_proc = MakeAndGetDword(
            ea + 44, "generate default function")
        self.dispose_element_proc = MakeAndGetDword(
            ea + 48, "dispose element function")

        # Read the strings.
        self.display_name_str = ReadString(self.display_name_address)
        self.name_str = ReadString(self.name_address)
        self.maximum_elements_count_str = ReadString(
            self.maximum_element_count_string_address)

        # Name the definition address.
        idc.MakeNameEx(self.address, self.name_str, idc.SN_NON_PUBLIC)

        # Check if we should comment the display name.
        if self.display_name_address < g_BaseAddress:
            idc.MakeComm(ea, self.display_name_str)

        # Check if we should comment the name.
        if self.name_address < g_BaseAddress:
            idc.MakeComm(ea + 4, self.name_str)

        # Check if we should comment the maximum elements count.
        if self.maximum_element_count_string_address < g_BaseAddress:
            idc.MakeComm(ea + 12, self.maximum_elements_count_str)

        # Create the postprocess function.
        if self.postprocess_proc != 0:
            idc.MakeNameEx(self.postprocess_proc,
                           "%s_postprocess" % self.name_str, idc.SN_NON_PUBLIC)

        # Create the format proc.
        if self.format_proc != 0:
            idc.MakeNameEx(self.format_proc, "%s_format" % self.name_str,
                           idc.SN_NON_PUBLIC)

        # Create the generate default proc.
        if self.generate_default_proc != 0:
            idc.MakeNameEx(self.generate_default_proc,
                           "%s_generate_default" % self.name_str,
                           idc.SN_NON_PUBLIC)

        # Create the dispose element proc.
        if self.dispose_element_proc != 0:
            idc.MakeNameEx(self.dispose_element_proc,
                           "%s_dispose_element" % self.name_str,
                           idc.SN_NON_PUBLIC)

        # Check for the special case sound_block.
        if self.name_str == "sound_block":
            return

        # Loop through all of the field sets and read each one.
        for i in range(self.field_set_count):
            # Get the address of the current field set.
            fieldSetAddress = self.field_sets_address + (i *
                                                         tag_field_set.kSizeOf)

            # Read the current field set.
            fieldSet = tag_field_set()
            fieldSet.readDefinition(fieldSetAddress)

            # Check if this is the latest version field set.
            if fieldSetAddress == self.field_set_latest_address:
                idc.MakeNameEx(fieldSetAddress, "%s_latest" % self.name_str,
                               idc.SN_NON_PUBLIC)
            else:
                idc.MakeNameEx(fieldSetAddress, "%s_v%d" % (self.name_str, i),
                               idc.SN_NON_PUBLIC)

            # Add the field set to the field set list.
            self.field_sets.append(fieldSet)
예제 #22
0
파일: findcrypt.py 프로젝트: nevermoe/ida
def main():
    print("[*] loading crypto constants")
    for const in non_sparse_consts:
        const["byte_array"] = convert_to_byte_array(const)

    for start in idautils.Segments():
        print("[*] searching for crypto constants in %s" % idc.SegName(start))

        ea = start
        while ea < idc.SegEnd(start):
            bbbb = list(
                struct.unpack("BBBB",
                              idc.GetManyBytes(ea, 4) or "AAAA"))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if map(
                        lambda x: ord(x),
                        idc.GetManyBytes(ea, len(const["byte_array"]))
                        or list()) == const["byte_array"]:
                    print(("0x%0" + str(digits) +
                           "X: found const array %s (used in %s)") %
                          (ea, const["name"], const["algorithm"]))
                    idc.MakeName(ea, const["name"])
                    if const["size"] == "B":
                        idc.MakeByte(ea)
                    elif const["size"] == "L":
                        idc.MakeDword(ea)
                    elif const["size"] == "Q":
                        idc.MakeQword(ea)
                    MakeArray(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4
            #print "ea: 0x%x " % ea

        ea = start
        if idc.GetSegmentAttr(ea, SEGATTR_TYPE) == 2:
            while ea < idc.SegEnd(start):
                d = idc.Dword(ea)
                for const in sparse_consts:
                    if d != const["array"][0]:
                        continue
                    tmp = ea + 4
                    for val in const["array"][1:]:
                        for i in range(8):
                            if idc.Dword(tmp + i) == val:
                                tmp = tmp + i + 4
                                break
                        else:
                            break
                    else:
                        print(("0x%0" + str(digits) +
                               "X: found sparse constants for %s") %
                              (ea, const["algorithm"]))
                        cmt = idc.GetCommentEx(idc.prev_head(ea), 0)
                        if cmt:
                            idc.CommentEx(idc.prev_head(ea),
                                          cmt + ' ' + const["name"], 0)
                        else:
                            idc.CommentEx(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1
    print("[*] finished")
예제 #23
0
 def MakeDWord(self, ea):
     if idaapi.IDA_SDK_VERSION < 700:
         return idc.MakeDword(ea)
     else:
         return ida_bytes.create_data(ea, FF_DWORD, 4, idaapi.BADADDR)
    def locateLocalConstants(self, scs, sds):
        """Locate and define all of the local strings / numeric constants, that match our observed pattern.

        Args:
            scs (list): List of (sark) code segments.
            sds (list): List of (sark) data segments.
        """
        self._analyzer.logger.info(
            "Locating local strings / constants in the code sections")
        for sc in scs:
            cur_ea = pad(sc.startEA, self._local_alignment)
            while cur_ea < sc.endEA:
                # check for a data constant
                if self.isDataConstant(cur_ea):
                    # check for a string (refs already checked)
                    if self._analyzer.str_identifier.isLocalAsciiString(
                            cur_ea, check_refs=False):
                        length = self._analyzer.str_identifier.defineAsciiString(
                            cur_ea)
                        padded_length = pad(length, self._local_alignment)
                        if padded_length != length:
                            idc.MakeUnknown(cur_ea + length,
                                            padded_length - length, 0)
                            idc.MakeData(cur_ea + length, 0,
                                         padded_length - length, 0)
                        cur_ea += padded_length
                    # This means it is a constant
                    else:
                        if self._local_pad is None:
                            idc.MakeData(cur_ea, 0, self._local_alignment, 0)
                        else:
                            # check the size of the constant using the byte padding
                            for offset in xrange(self._local_alignment - 1, -1,
                                                 -1):
                                if idc.Byte(cur_ea +
                                            offset) != self._local_pad:
                                    break
                            # prepare the bytes
                            idc.MakeUnknown(cur_ea, self._local_alignment, 0)
                            # the data constant - try to make it pretty
                            if offset + 1 == 2:
                                idc.MakeWord(cur_ea)
                            elif offset + 1 == 4:
                                idc.MakeDword(cur_ea)
                            elif offset + 1 == 8:
                                idc.MakeQword(cur_ea)
                            else:
                                idc.MakeData(cur_ea, 0, offset + 1, 0)
                            # the padding
                            idc.MakeData(cur_ea + offset + 1, 0,
                                         self._local_alignment - offset + 1, 0)
                            # Now check for a pointer (only supports code pointers for now)
                            if offset + 1 == self._analyzer.addressSize():
                                value = self._analyzer.parseAdderss(cur_ea)
                                # only support pointers inside our local segment (more probable)
                                if sc.startEA <= value and value < sc.endEA:
                                    self._analyzer.markCodePtr(
                                        cur_ea, value, aggressive=False)
                                # try a pointer to a declared string
                                else:
                                    for sd in sds:
                                        if sd.startEA <= value and value <= sd.endEA:
                                            line = sark.Line(value)
                                            if line.is_string and line.startEA == value:
                                                self._analyzer.markDataPtr(
                                                    cur_ea,
                                                    value,
                                                    aggressive=False)
                                            break
                        # now move onward
                        cur_ea += self._local_alignment
                # found nothing, move on
                else:
                    cur_ea += self._local_alignment
예제 #25
0
                if (xr2.type == 19) and (xr2.to == next_next):

                    db = head + idaapi.get_item_size(head)

                    if idc.Byte(head) == 0x0F:
                        idaapi.patch_byte(head, 0x90)
                        idaapi.patch_byte(head + 1, 0xE9)
                    else:
                        idaapi.patch_byte(head, 0xEB)

                    idc.MakeUnknown(db, xr.to - db + 0x10, idaapi.DOUNK_SIMPLE)
                    idc.MakeCode(xr.to)

                    i = db
                    while i < xr.to:
                        if (i + 4) < xr.to:
                            idc.MakeDword(i)
                            i += 4
                        else:
                            idc.MakeByte(i)
                            i += 1

                    idaapi.analyze_area(head - 0x40, head + 0x40)
                    idaapi.analyze_area(xr.to - 0x40, xr.to + 0x40)

for head in idautils.Heads():
    if idc.Byte(head) == 0xE8:
        for xr in idautils.XrefsFrom(head, 0):
            # Find direct call targets
            if not (xr.type == 21):
                idc.MakeFunction(xr.to)
def map_metadata(file, addr):
    flags = 0
    flags |= 0x0001  # NEF_SEGS
    size = os.stat(file).st_size

    li = idaapi.open_linput(file, False)

    #print('li = %s' % str(li))

    rc = idaapi.load_binary_file(file, li, flags, 0, 0, addr, size)

    #print('rc = %d' % rc)

    names = [
        'stringLiteral',
        'stringLiteralData',
        'strings',
        'events',
        'properties',
        'methods',
        'parameterDefaultValues',
        'fieldDefaultValues',
        'fieldAndParameterDefaultValueData',
        'fieldMarshaledSizes',
        'parameters',
        'fields',
        'genericParameters',
        'genericParameterConstraints',
        'genericContainers',
        'nestedTypes',
        'interfaces',
        'vtableMethods',
        'interfaceOffsets',
        'typeDefinitions',
        'rgctxEntries',
        'images',
        'assemblies',
        'metadataUsageLists',
        'metadataUsagePairs',
        'fieldRefs',
        'referencedAssemblies',
        'attributesInfo',
        'attributeTypes',
    ]

    baseaddr = addr

    idc.MakeDword(addr + 0)
    idc.MakeNameEx(addr + 0, 'META_Sig', idc.SN_NOWARN | idc.SN_AUTO)
    idc.MakeDword(addr + 4)
    idc.MakeNameEx(addr + 0, 'META_Version', idc.SN_NOWARN | idc.SN_AUTO)

    for i in range(len(names)):
        descaddr = baseaddr + 8 + i * 8

        idc.MakeStruct(descaddr, 'OffsetAndCount')
        idc.MakeNameEx(descaddr, 'META_%sDesc' % names[i],
                       idc.SN_NOWARN | idc.SN_AUTO)

        dataaddr = baseaddr + idc.Dword(descaddr + 0)
        datasize = idc.Dword(descaddr + 4)

        idc.MakeNameEx(dataaddr, 'META_%s' % names[i],
                       idc.SN_NOWARN | idc.SN_AUTO)

    # string literal
    descaddr = idc.LocByName('META_stringLiteralDesc')
    size1 = idc.Dword(descaddr + 4)
    addr1 = idc.LocByName('META_stringLiteral')
    addr1end = addr1 + size1
    addr2 = idc.LocByName('META_stringLiteralData')

    #print('addr1: %X' % (addr1))
    #print('addr2: %X' % (addr2))

    while addr1 < addr1end:
        strsize = idc.Dword(addr1 + 0)
        stroff = idc.Dword(addr1 + 4)

        #print('%X - %X' % (addr2 + stroff, addr2 + stroff + strsize))

        idc.MakeStr(addr2 + stroff, addr2 + stroff + strsize)

        addr1 += 8

    idc.Jump(baseaddr)
예제 #27
0
def load_file(f, neflags, format):
    '''
    load the given file into the current IDA Pro database.

    Args:
      f (file): the file-like object to load.
      neflags (Any): unused
      format (Any): unused

    Returns:
      int: 1 on success, 0 on failure
    '''

    # compute file size, then read the entire contents
    f.seek(0x0, os.SEEK_END)
    flen = f.tell()
    f.seek(0x0)
    buf = f.read(flen)

    # mark the proc type, so IDA can invoke the correct disassembler/processor.
    # this must match `processor.wasm_processor_t.psnames`
    idaapi.set_processor_type('wasm', idaapi.SETPROC_ALL)

    f.seek(0x0)
    # load the entire file directly at address zero.
    f.file2base(0, 0, len(buf), True)

    p = 0
    sections = wasm.decode.decode_module(buf)
    for i, section in enumerate(sections):
        if i == 0:
            sname = 'header'
        else:
            if section.data.id == 0:
                # fetch custom name
                sname = ''
            else:
                sname = idawasm.const.WASM_SECTION_NAMES.get(
                    section.data.id, 'unknown')

        if sname != 'header' and section.data.id in (
                wasm.wasmtypes.SEC_CODE, wasm.wasmtypes.SEC_GLOBAL):
            stype = 'CODE'
        else:
            stype = 'DATA'

        # add IDA segment with type, name, size as appropriate
        slen = sum(section.data.get_decoder_meta()['lengths'].values())
        idaapi.add_segm(0, p, p + slen, sname, stype)

        if sname != 'header':
            loader = SECTION_LOADERS.get(section.data.id)
            if loader is not None:
                loader(section, p)

            load_section(section, p)

        p += slen

    # magic
    idc.MakeDword(0x0)
    idc.MakeName(0x0, 'WASM_MAGIC')
    # version
    idc.MakeDword(0x4)
    idc.MakeName(0x4, 'WASM_VERSION')

    return 1