Ejemplo n.º 1
0
def is_func_prolog(ea, reg_check=True):
    if ea % 2 != 0:
        return NONE

    # function prolog requires at least four bytes
    if any(not ida_bytes.is_mapped(ea + i) for i in range(4)):
        return NONE

    word = ida_bytes.get_word(ea)
    next_word = ida_bytes.get_word(ea + 2)

    # check thumb PUSH.W
    if word == 0xE92D:
        # PUSH LR
        if not reg_check or is_valid_reglist(next_word, False):
            return THUMB

    # check thumb PUSH
    elif (word >> 8) == 0xB5:
        if not reg_check or is_valid_reglist(word, True):
            return THUMB

    # check arm PUSH
    elif next_word == 0xE92D:
        if ea % 4 == 0:
            # PUSH LR
            if not reg_check or is_valid_reglist(word, False):
                return ARM

    return NONE
Ejemplo n.º 2
0
def get_regs(ea):
    if is_thumb(ea):
        # 1  --- 1 (LSB)
        # R7 --- R0
        reg_bits = ida_bytes.get_word(ea) & 0x1FF
        reg_list = ["R{0}".format(idx) for idx in range(8)]
        reg_list.append("LR")
        # reg_list.extend(['SP', 'LR'])
        # TODO: add 32 bit Thumb handling
    else:
        # 1   --- 1 (LSB)
        # R12 --- R0
        reg_bits = ida_bytes.get_word(ea) & 0xFFFF
        reg_list = ["R{0}".format(idx) for idx in range(13)]
        reg_list.extend(["SP", "LR", "PC"])

    regs = []
    idx = 0
    while reg_bits:
        if reg_bits & 0x1:
            regs.append(reg_list[idx])
        reg_bits = reg_bits >> 1
        idx += 1

    return regs
Ejemplo n.º 3
0
    def search_idb(self):
        """Search IDB for possible MZ/PE headers"""
        # Search all segments
        for seg in idautils.Segments():
            s = idc.get_segm_start(seg)
            e = idc.get_segm_end(seg)
            addr = s

            while True:
                # Find first byte of MZ header
                addr = ida_bytes.find_byte(addr, e-addr, 0x4d, 0)

                if addr == ida_idaapi.BADADDR or addr >= e:
                    break

                # Check for MZ magic
                if ida_bytes.get_word(addr) == 0x5a4d:
                    # Ensure the PE header is in the segment
                    e_lfanew = ida_bytes.get_dword(addr + 0x3c)

                    if addr + e_lfanew + 1 < e:
                        # Check for PE magic
                        if ida_bytes.get_word(addr + e_lfanew) == 0x4550:
                            # Found possible MZ/PE file
                            self.form.runtime.log("0x{:08x} - {}".format(addr, idc.get_segm_name(s)))

                            self.form.map_pe(image_base=addr)

                # Resume search from next address
                addr += 1
Ejemplo n.º 4
0
    def find_pe(self, cursor=False):
        """Search IDB for possible MZ/PE headers"""
        info = idaapi.get_inf_structure()

        mz_headers = []

        # Check current cursor for MZ/PE?
        if cursor:
            # Get IDA cursor address
            addr = idc.here()

            # Get segment and end address
            s = idaapi.getseg(addr)
            e = idc.get_segm_end(addr)

            # Check for MZ magic
            if ida_bytes.get_word(addr) == 0x5a4d:
                # Ensure the PE header is in the segment
                e_lfanew = ida_bytes.get_dword(addr + 0x3c)

                if addr + e_lfanew + 1 < e:
                    # Check for PE magic
                    if ida_bytes.get_word(addr + e_lfanew) == 0x4550:
                        # Found possible MZ/PE header
                        mz_headers.append([addr, idc.get_segm_name(addr), info.is_64bit()])

            self.ret = mz_headers
            return self.ret

        # Search all segments
        for seg in idautils.Segments():
            s = idc.get_segm_start(seg)
            e = idc.get_segm_end(seg)
            addr = s

            while True:
                # Find first byte of MZ header
                addr = ida_bytes.find_byte(addr, e-addr, 0x4d, 0)

                if addr == ida_idaapi.BADADDR or addr >= e:
                    break

                # Check for MZ magic
                if ida_bytes.get_word(addr) == 0x5a4d:
                    # Ensure the PE header is in the segment
                    e_lfanew = ida_bytes.get_dword(addr + 0x3c)

                    if addr + e_lfanew + 1 < e:
                        # Check for PE magic
                        if ida_bytes.get_word(addr + e_lfanew) == 0x4550:
                            # Found possible MZ/PE header
                            mz_headers.append([addr, idc.get_segm_name(s), info.is_64bit()])

                # Resume search from next address
                addr += 1

        self.ret = mz_headers
        return self.ret
Ejemplo n.º 5
0
    def map_pe_from_cursor(self):
        """Map PE file from current cursor position"""
        # Is the cursor on an MZ file?
        current = idc.here()

        if ida_bytes.get_word(current) == 0x5a4d:
            self.form.map_pe(image_base=current, priority=1)
Ejemplo n.º 6
0
    def search_idb(self):
        """Search IDB for possible MZ/PE headers"""
        # Determine pointer display width
        info = idaapi.get_inf_structure()

        if info.is_64bit():
            width = 16
        else:
            width = 8

        # Search all segments
        for seg in idautils.Segments():
            s = idc.get_segm_start(seg)
            e = idc.get_segm_end(seg)
            addr = s

            while True:
                # Find first byte of MZ header
                addr = ida_bytes.find_byte(addr, e - addr, 0x4d, 0)

                if addr == ida_idaapi.BADADDR or addr >= e:
                    break

                # Check for MZ magic
                if ida_bytes.get_word(addr) == 0x5a4d:
                    # Ensure the PE header is in the segment
                    e_lfanew = ida_bytes.get_dword(addr + 0x3c)

                    if addr + e_lfanew + 1 < e:
                        # Check for PE magic
                        if ida_bytes.get_word(addr + e_lfanew) == 0x4550:
                            # Found possible MZ/PE file
                            self.form.runtime.log("0x{:0{w}x} - {}".format(
                                addr, idc.get_segm_name(s), w=width))

                            self.form.map_pe(image_base=addr,
                                             filename="{} - 0x{:0{w}x}".format(
                                                 idc.get_segm_name(s),
                                                 addr,
                                                 w=width))

                # Resume search from next address
                addr += 1
Ejemplo n.º 7
0
    def read_xword(self):
        if bitness == 32:
            res = ida_bytes.get_dword(self.addr)
        elif bitness == 64:
            res = ida_bytes.get_qword(self.addr)
        else:  # bitness == 16
            res = ida_bytes.get_word(self.addr)
        self.inc(self.bitness >> 3)

        return res
Ejemplo n.º 8
0
 def get_word(self, offset):
     """Read word from IDB"""
     self.ret = ida_bytes.get_word(offset)
     return self.ret
Ejemplo n.º 9
0
def get_int16(ea):
    return struct.unpack("h", struct.pack("H", ida_bytes.get_word(ea)))[0]
Ejemplo n.º 10
0
def load_file(f, neflags, format):
    f.seek(0)

    ida_idp.set_processor_type("metapc", ida_idp.SETPROC_LOADER)
    MGROUPStart = 0
    magic = f.read(2)

    if magic == MZ_HEADER_MAGIC:
        f.seek(0x22)
        MGROUPStart = DW(f) * 16
        f.seek(MGROUPStart)
        magic = f.read(2)

    headerSize = DW(f)
    segmentDataAlignment = DW(f)
    nextExeOff = DD(f)
    SegDataOff = DD(f)

    f.file2base(MGROUPStart, 0, SegDataOff, True)
    ida_segment.add_segm(0, 0, 0x50, "HEADER", "MODULE")
    f.seek(MGROUPStart + 2)

    headerSize = rnDW(f, "headerSize", MGROUPStart)
    segmentDataAlignment = rnDW(f, "segmentDataAlignment", MGROUPStart)
    nextExeOff = rnDD(f, "nextExeOff", MGROUPStart)
    SegDataOff = rnDD(f, "SegDataOff", MGROUPStart)

    ResDataOff = rnDD(f, "ResDataOff", MGROUPStart)
    flags = rnDW(f, "flags", MGROUPStart)
    version = rnDB(f, "version", MGROUPStart)
    revision = rnDB(f, "revision", MGROUPStart)
    AutoDataSegNo = rnDW(f, "AutoDataSegNo", MGROUPStart)
    HeapSize = rnDW(f, "HeapSize", MGROUPStart)
    StackSize = rnDW(f, "StackSize", MGROUPStart)
    StartProc = rnDD(f, "StartProc", MGROUPStart)
    LoadProc = rnDD(f, "LoadProc", MGROUPStart)
    FreeProc = rnDD(f, "FreeProc", MGROUPStart)
    nSegments = rnDW(f, "nSegments", MGROUPStart)
    pSegTable = rnDW(f, "pSegTable", MGROUPStart)
    cbResTab = rnDW(f, "cbResTab", MGROUPStart)
    pResTab = rnDW(f, "pResTab", MGROUPStart)
    cbEntTab = rnDW(f, "cbEntTab", MGROUPStart)
    pEntTab = rnDW(f, "pEntTab", MGROUPStart)
    cbNamTab = rnDW(f, "cbNamTab", MGROUPStart)
    pNamTab = rnDW(f, "pNamTab", MGROUPStart)
    cbStrTab = rnDW(f, "cbStrTab", MGROUPStart)
    pStrTab = rnDW(f, "pStrTab", MGROUPStart)
    cbNRNamTab = rnDW(f, "cbNRNamTab", MGROUPStart)
    pNRNamTab = rnDW(f, "pNRNamTab", MGROUPStart)

    ida_segment.add_segm(0, pSegTable,
                         pSegTable + (nSegments * SEG_STRUCT_SIZE), "SEGTABLE",
                         "MODULE")
    ida_segment.add_segm(0, pResTab, pResTab + cbResTab, "RESOURCES", "MODULE")
    ida_segment.add_segm(0, pEntTab, pEntTab + cbEntTab, "ENTTABLE", "MODULE")
    ida_segment.add_segm(0, pNamTab, pNamTab + cbNamTab, "ENTNAME", "MODULE")
    ida_segment.add_segm(0, pStrTab, pStrTab + cbStrTab, "IMPORTS", "MODULE")
    ida_segment.add_segm(0, pNRNamTab, pNRNamTab + cbNRNamTab, "NRENTNAME",
                         "MODULE")

    #parse segtable
    segentsid = defSEGENT()
    base = SegDataOff // 16

    importCount = 0
    for i in range(nSegments):
        segEntStart = pSegTable + i * SEG_STRUCT_SIZE
        ida_bytes.create_struct(segEntStart, SEG_STRUCT_SIZE, segentsid)
        segStart = ida_bytes.get_word(segEntStart + 2)
        segLen = ida_bytes.get_word(segEntStart + 4)
        segImports = ida_bytes.get_word(segEntStart + 6)
        importCount += segImports
        f.file2base(MGROUPStart + SegDataOff + segStart * 16,
                    SegDataOff + segStart * 16,
                    SegDataOff + (segStart + segLen) * 16, True)

        segBase = (base + segStart) * 16
        #segmentDef = ida_segment.segment_t()
        #segmentDef.start_ea = segBase
        #segmentDef.end_ea = (base+segStart+segLen)*16
        #ida_segment.set_selector()
        print(base + segStart)
        ida_segment.add_segm(base + segStart, segBase,
                             (base + segStart + segLen) * 16, "", "", 0)
        sel = ida_segment.find_selector(base + segStart)
        seg = ida_segment.getseg(segBase)
        ida_segment.set_segm_addressing(seg, 0)
        segtable[i] = seg
        segimportstable[i] = segImports
        if i + 1 == AutoDataSegNo:
            ida_segment.set_segm_name(seg, "DATA", 0)
            ida_segment.set_segm_class(seg, "DATA", 0)
            dataSel = sel
        else:
            ida_segment.set_segm_name(seg, "TEXT", 0)
            ida_segment.set_segm_class(seg, "CODE", 0)
            if AutoDataSegNo == 0:
                dataSel = sel
    ida_segregs.set_default_dataseg(dataSel)

    #parse enttable
    pENT = pEntTab
    currord = 1
    while pENT < pEntTab + cbEntTab:
        bundleCount = ida_bytes.get_byte(pENT)
        bundleFlags = ida_bytes.get_byte(pENT + 1)
        if bundleCount == 0 and bundleFlags == 0:
            break
        pENT += 2
        for i in range(bundleCount):
            if bundleFlags == 0xFF:
                ordFlags = ida_bytes.get_byte(pENT)
                if ordFlags & 0x80:
                    toexport.append(currord)
                segNo = ida_bytes.get_byte(pENT + 3)
                segOff = ida_bytes.get_word(pENT + 4)

                enttable[currord] = (segtable[segNo - 1].start_ea // 16,
                                     segOff)
                pENT += 6
            else:
                ordFlags = ida_bytes.get_byte(pENT)
                if ordFlags & 0x80:
                    toexport.append(currord)
                segOff = ida_bytes.get_word(pENT + 1)
                enttable[currord] = (segtable[bundleFlags - 1].start_ea // 16,
                                     segOff)
                pENT += 3

            currord += 1

    modulename = readPASSTR(pNamTab)

    make_entry(StartProc, modulename + "_start")
    make_entry(LoadProc, modulename + "_load")
    make_entry(FreeProc, modulename + "_free")

    #export named ordinals
    namedordtable = loadExportsF(f)

    for i in toexport:
        if i in namedordtable:
            name = namedordtable[i]
        else:
            name = "Ordinal" + str(i)
        (base, off) = enttable[i]
        addr = base * 16 + off
        ida_entry.add_entry(i, addr, name, 1)

    #process imports

    ida_segment.add_segm(0xF000, 0xF0000, 0xF0000 + importCount * 2, "IMPORTS",
                         "XTRN", 0)

    import_ea = 0xF0000

    for seg in segtable:
        segend = segtable[seg].end_ea
        f.seek(MGROUPStart + segend)

        for i in range(segimportstable[seg]):
            count = DB(f)
            mode = DB(f)
            relocStart = DW(f)
            module = DW(f)
            proc = DW(f)

            if (module == 0xFFFF):
                (base, off) = enttable[proc]
            else:
                modulestr = readPASSTR(pStrTab + module)
                if (proc & 0x8000) != 0:  # read by ord
                    ordinal = proc & 0x7FFF
                    procname = modulestr + "_Ordinal" + str(ordinal)
                    if not modulestr in importedmodules:
                        if os.path.isfile(modulestr + ".EXE"):
                            importedmodules[modulestr] = loadExports(
                                modulestr + ".EXE")
                        else:
                            filename = ida_kernwin.ask_file(
                                0, modulestr + ".EXE",
                                "Select file to name exports")
                            if filename is not None and os.path.isfile(
                                    filename):
                                importedmodules[modulestr] = loadExports(
                                    filename)
                            else:
                                importedmodules[modulestr] = None
                    if modulestr in importedmodules and (
                            importedmodules[modulestr] is not None
                    ) and ordinal in importedmodules[modulestr]:
                        procname = importedmodules[modulestr][ordinal]
                else:
                    procname = readPASSTR(pStrTab + proc)
                ida_bytes.create_data(import_ea, ida_bytes.FF_WORD, 2,
                                      ida_idaapi.BADADDR)
                ida_name.force_name(import_ea, procname)
                ida_bytes.set_cmt(import_ea, "Imported from " + modulestr, 1)
                base = 0xF000
                off = import_ea - 0xF0000
                import_ea += 2

            for xx in range(count):
                next = ida_bytes.get_word(segtable[seg].start_ea + relocStart)
                if mode == 0x20:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart + 2,
                                       base)
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       off)
                elif mode == 0x10:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       off)
                elif mode == 0x0:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       base)
                relocStart = next

            #print "import %d: seg %d mode %s count %d relocStart %s module %s proc %s" % (i, seg, hex(mode), count, hex(relocStart), modulestr, hex(proc))

    return 1
Ejemplo n.º 11
0
        break
    print(hex(ea))
    ea=search_ea(addr_to_bhex(ea),"",None)[0]

create_cmdref()
sid = ida_struct.get_struc_id("cmd_ref")
if sid == idaapi.BADADDR:
    print("Structure {} does not exist".format(name))

i=0
lastea=0
names={}
firstcmdid=0
for ea in references:
    nameptr=ida_bytes.get_dword(ea)
    cmdid=ida_bytes.get_word(ea+0xA)
    if firstcmdid==0:
        firstcmdid=cmdid
    name=get_string(nameptr)
    names[cmdid]=name
    ida_bytes.del_items(ea, ida_bytes.DELIT_DELNAMES,0x10)
    ida_bytes.create_struct(ea, 0x10, sid)
    print(f"EA:{hex(ea)} Name:{name} Cmdid:{hex(cmdid)}")
    #idc.set_cmt(ea, str(i),0)
    i+=1
    lastea=ea

create_cmdptr()
sid = ida_struct.get_struc_id("cmd_ptr")
ssize = ida_struct.get_struc_size(sid)
eas=search_ea("FC 3A 00 00","",None,startea-0x3000,lastea)
Ejemplo n.º 12
0
def get_vector(vec):
    return get_word(vec)
Ejemplo n.º 13
0
 def read_word(self):
     res = ida_bytes.get_word(self.addr)
     self.inc(2)
     return res