Ejemplo n.º 1
0
def create_section(start_ea, end_ea, perm, name, all_thumb=True):
    """
    Create section in IDA Pro

    :param start_ea: start address of secion
    :type start_ea: str

    :param end_ea: end address of secion
    :type end_ea: str

    :param perm: Permissions of section (1:ex, 2:read, 4:write)
    :type perm: int

    :param name: name of section
    :type name: str

    :return: success
    :rtype: bool
    """

    try:
        start, end = parse_range(start_ea, end_ea)
    except ValueError:
        return False
    if idc.add_segm_ex(start, end, 0, 1, 1, 0, 0):
        idc.set_segm_name(start, name)
        idc.set_segm_attr(start, idc.SEGATTR_PERM, perm)
        if all_thumb:
            idc.split_sreg_range(start, "T", 1, idc.SR_autostart)
        return True
    return False
Ejemplo n.º 2
0
def append_segment(segment_name):
    """ Add a new segment to the IDB file and return its starting address.
    Information about function arguments will be stored here. Only works if the
    segment name is not used yet. This does not affect the original binary.

    Arguments:
    segment_name -- the name of the segment to be added
    """
    for segment in idautils.Segments():
        if idc.get_segm_name(segment) == segment_name:
            g_logger.warning('Segment ' + segment_name + ' already exists')
            return idc.get_segm_start(segment)

    new_segment_start = get_end_of_last_segment()
    g_logger.debug('Adding new segment at 0x%08x' % new_segment_start)
    if not idc.AddSeg(new_segment_start,
                      (new_segment_start + NEW_SEGMENT_SIZE), 0, 1, 0,
                      idaapi.scPub) == 1:
        raise FailedToAppendSegmentException('Could not add segment')
    # set new segment's attributes
    if not idc.set_segm_name(new_segment_start, segment_name):
        raise FailedToAppendSegmentException('Could not rename segment')
    if not idc.set_segm_class(new_segment_start, 'DATA'):
        raise FailedToAppendSegmentException('Could not set segment class')
    if not idc.set_segm_alignment(new_segment_start, idc.saRelPara):
        raise FailedToAppendSegmentException('Could not align segment')
    if not idc.set_segm_addressing(new_segment_start, 1):  # 1 -- 32 bit
        raise FailedToAppendSegmentException(
            'Could not set segment addressing')
    return new_segment_start
Ejemplo n.º 3
0
def main(argv=None):
    if argv is None:
        argv = sys.argv[:]

    try:
        seg = prompt_for_segment()
    except BadInputError:
        logger.error('bad input, exiting...')
        return -1

    with open(seg.path, 'rb') as f:
        buf = f.read()

    seglen = len(buf)
    if seglen % 0x1000 != 0:
        seglen = seglen + (0x1000 - (seglen % 0x1000))

    if not idc.AddSeg(seg.addr, seg.addr + seglen, 0, 1, 0, idaapi.scPub):
        logger.error('failed to add segment: 0x%x', seg.addr)
        return -1

    if not idc.set_segm_name(seg.addr, seg.name):
        logger.warning('failed to rename segment: %s', seg.name)

    if not idc.set_segm_class(seg.addr, 'CODE'):
        logger.warning('failed to set segment class CODE: %s', seg.name)

    if not idc.set_segm_attr(seg.addr, SEGATTR_ALIGN, idc.saRelPara):
        logger.warning('failed to align segment: %s', seg.name)

    ida_bytes.patch_bytes(seg.addr, buf)
Ejemplo n.º 4
0
def __create_load_data_segment(data, seg_addr, seg_name):
    # This function creates a data segment located in a pre-specified address
    # and fills this new segment with data

    seglen = len(data)
    if seglen % 0x1000 != 0:
        seglen = seglen + (0x1000 - (seglen % 0x1000))

    if not idc.AddSeg(seg_addr, seg_addr + seglen, 0, 1, 0, idaapi.scPub):
        logger.error('failed to add segment: 0x%x', seg_addr)
        return False

    if not idc.set_segm_name(seg_addr, seg_name):
        logger.warning('failed to rename segment: %s', seg_name)
        return False

    if not idc.set_segm_class(seg_addr, 'DATA'):
        logger.warning('failed to set segment class DATA: %s', seg_name)
        return False

    if not idc.set_segm_attr(seg_addr, idc.SEGATTR_ALIGN, idc.saRelPara):
        logger.warning('failed to align segment: %s', seg_name)
        return False

    if data:
        idaapi.patch_bytes(seg_addr, data)

    return True
Ejemplo n.º 5
0
    def set_text_segment_rwe():
        """
        Update name, class, permissions of CODE segment to resolve elimination of "dead" code.
        Also set compiler to VC++.
        """
        for seg in Segments():
            if get_segm_name(seg) == ".text":
                set_segm_name(seg, ".code")
                set_segm_class(seg, "DATA")
                set_segm_attr(seg, SEGATTR_PERM, 0b111)  # RWE

                print("Updating segment at " + hex(seg) +
                      ":\nsegment name .text -> .code" +
                      "\nsegment class = DATA" + "\nsegment permissions = RWE")

                break

        set_compiler_id(1)  # Visual C++
Ejemplo n.º 6
0
 def process_region(segname, name, start, end):
     assert end >= start
     if segname in skip:
         _log(2, 'Skipping segment {}', segname)
         return
     newname = '{}.{}'.format(segname, name)
     if kext:
         newname = '{}:{}'.format(kext, newname)
     if start == end:
         _log(2, 'Skipping empty region {} at {:x}', newname, start)
         return
     ida_segstart = idc.get_segm_start(start)
     if ida_segstart == idc.BADADDR:
         _log(0, "IDA doesn't think this is a real segment: {:x} - {:x}",
              start, end)
         return
     ida_segend = idc.get_segm_end(ida_segstart)
     if start != ida_segstart or end != ida_segend:
         _log(0, 'IDA thinks segment {} {:x} - {:x} should be {:x} - {:x}',
              newname, start, end, ida_segstart, ida_segend)
         return
     _log(2, 'Rename {:x} - {:x}: {} -> {}', start, end,
          idc.get_segm_name(start), newname)
     idc.set_segm_name(start, newname)
Ejemplo n.º 7
0
def load_file(li, neflags, format):
    """
    Load the file into database

    @param li: a file-like object which can be used to access the input data
    @param neflags: options selected by the user, see loader.hpp
    @return: 0-failure, 1-ok
    """
    if format == AtariSTTOSImageName:
        idaapi.set_processor_type('68K', ida_idp.SETPROC_LOADER)

        li.seek(0)
        header = read_struct(li, tos_image_header)

        li.seek(0, idaapi.SEEK_END)
        filesize = li.tell()

        idc.add_segm_ex(header.os_beg, header.os_beg + filesize, 0, 1,
                        idaapi.saRelPara, idaapi.scPub, idc.ADDSEG_NOSREG)
        idc.set_segm_name(header.os_beg, 'TOS')

        li.seek(0)
        li.file2base(0, header.os_beg, header.os_beg + filesize, 0)

        idaapi.add_entry(header.os_beg, header.os_beg, "ostext", 1)
        idc.set_cmt(header.os_beg, 'branch to reset handler', 0)
        idc.set_name(header.os_beg + 2, 'os_version')
        idc.create_word(header.os_beg + 2)
        idc.set_cmt(header.os_beg + 2, 'OS version number', 0)
        idc.set_cmt(header.os_beg + 4, '-> system reset handler', 0)
        reseth = ida_bytes.get_dword(header.os_beg + 4)
        idc.set_name(reseth, 'reseth')
        idc.set_name(header.os_beg + 8, 'os_beg')
        idc.set_cmt(header.os_beg + 8, '-> base of OS', 0)
        idc.set_name(header.os_beg + 12, 'os_end')
        idc.set_cmt(header.os_beg + 12, '-> end of OS memory usage', 0)
        os_end = ida_bytes.get_dword(header.os_beg + 12)
        idc.add_segm_ex(0x0, os_end, 0, 1, idaapi.saRelPara, idaapi.scPub,
                        idc.ADDSEG_NOSREG)
        idc.set_segm_name(0x0, 'DOSRAM')
        idc.set_name(os_end, 'endos')
        idc.set_name(header.os_beg + 16, 'os_exec')
        idc.set_cmt(header.os_beg + 16, '-> default shell', 0)
        idc.set_name(header.os_beg + 20, 'os_magic')
        idc.set_cmt(header.os_beg + 20, '-> GEM magic (or NULL)', 0)
        idc.set_name(header.os_beg + 24, 'os_date')
        idc.create_dword(header.os_beg + 24)
        idc.set_cmt(header.os_beg + 24, 'date the system was built', 0)
        idc.set_name(header.os_beg + 28, 'os_conf')
        idc.create_word(header.os_beg + 28)
        idc.set_cmt(header.os_beg + 28, 'configuration bits', 0)
        idc.set_name(header.os_beg + 30, 'os_dosdate')
        idc.create_word(header.os_beg + 30)
        idc.set_cmt(header.os_beg + 30, 'DOS-format date the system was built',
                    0)
        addr = header.os_beg + 32
        while addr < reseth:
            if addr == header.os_beg + 0x20:
                idc.set_cmt(addr, 'base of GEMDOS pool', 0)
                idc.set_name(ida_bytes.get_dword(addr), '_root')
            elif addr == header.os_beg + 0x24:
                idc.set_cmt(addr, '-> keyboard shift-state byte', 0)
                idc.set_name(ida_bytes.get_dword(addr), 'kbshift')
            elif addr == header.os_beg + 0x28:
                idc.set_cmt(addr, '-> current process', 0)
                idc.set_name(ida_bytes.get_dword(addr), '_run')
            elif addr == header.os_beg + 0x2c:
                idc.set_cmt(addr, 'reserved for future use', 0)
            idc.create_dword(addr)
            addr += 4

        the_magic = ida_bytes.get_dword(header.os_beg + 20)
        gem_end = ida_bytes.get_dword(the_magic + 4)
        aes_init = ida_bytes.get_dword(the_magic + 8)
        idc.add_segm_ex(os_end, gem_end + 1, 0, 1, idaapi.saRelPara,
                        idaapi.scPub, idc.ADDSEG_NOSREG)
        idc.set_segm_name(os_end, 'GEMRAM')

        idc.set_name(the_magic, 'the_magic')
        idc.create_dword(the_magic)
        idc.set_cmt(the_magic, '$87654321 if GEM present', 0)
        idc.create_dword(the_magic + 4)
        idc.set_cmt(the_magic + 4, 'End address of OS RAM usage', 0)
        idc.create_dword(the_magic + 8)
        idc.set_cmt(the_magic + 8, 'Execution address of GEM', 0)
        idaapi.add_entry(aes_init, aes_init, "gem_entry", 1)
        idc.set_name(gem_end, 'gem_end')

        idaapi.auto_wait()
        return 1

    elif format == AtariSTProgramName:
        idaapi.set_processor_type('68K', ida_idp.SETPROC_LOADER)

        li.seek(0)
        header = read_struct(li, gemdos_executable_header)

        base_addr = AtariSTBaseAddress

        text_addr = base_addr
        data_addr = text_addr + header.PRG_tsize
        bss_addr = data_addr + header.PRG_dsize
        idc.add_segm_ex(text_addr, text_addr + header.PRG_tsize, 0, 1,
                        idaapi.saRelPara, idaapi.scPub, idc.ADDSEG_NOSREG)
        idc.set_segm_name(text_addr, 'tseg')
        idc.add_segm_ex(data_addr, data_addr + header.PRG_dsize, 0, 1,
                        idaapi.saRelPara, idaapi.scPub, idc.ADDSEG_NOSREG)
        idc.set_segm_name(data_addr, 'dseg')
        idc.add_segm_ex(bss_addr, bss_addr + header.PRG_bsize, 0, 1,
                        idaapi.saRelPara, idaapi.scPub, idc.ADDSEG_SPARSE)
        idc.set_segm_name(bss_addr, 'bseg')
        li.file2base(ctypes.sizeof(gemdos_executable_header), text_addr,
                     text_addr + header.PRG_tsize + header.PRG_dsize, 0)

        # relocate the application
        li.seek(0, idaapi.SEEK_END)
        filesize = li.tell()
        li.seek(0, idaapi.SEEK_SET)
        relocDataOffset = ctypes.sizeof(
            gemdos_executable_header
        ) + header.PRG_tsize + header.PRG_dsize + header.PRG_ssize
        li.seek(relocDataOffset)
        relocData = li.read(filesize - relocDataOffset)
        roffset = 4
        rea = struct.unpack('>I', relocData[:roffset])[0]
        if rea != 0:
            rea = rea + base_addr
            idc.patch_dword(rea, ida_bytes.get_dword(rea) + base_addr)
            if rea >= data_addr:  # in the DATA segment, make sure it is an actual pointer
                idc.create_dword(rea)
            while True:
                offset = ord(relocData[roffset])
                roffset += 1
                if offset == 0:  # end of the relocation table
                    break
                if offset == 1:  # odd numbers are not valid, 1 is a special case to skip 254 bytes without relocating
                    rea += 254
                    continue
                rea += offset
                idc.patch_dword(rea, ida_bytes.get_dword(rea) + base_addr)
                if rea >= data_addr:  # in the DATA segment, make sure it is an actual pointer
                    idc.create_dword(rea)

        # apply a symbol table, if part of the file
        if header.PRG_ssize:
            symboltableDataOffset = ctypes.sizeof(
                gemdos_executable_header) + header.PRG_tsize + header.PRG_dsize
            li.seek(symboltableDataOffset)
            symboltableData = li.read(header.PRG_ssize)
            soffset = 0
            while soffset < header.PRG_ssize:
                entry = symboltableData[soffset:soffset + 14]
                soffset += 14
                name = entry[:8]
                flags, value = struct.unpack('>HL', entry[8:])
                if (
                        flags & 0x0048
                ) and soffset + 14 < header.PRG_ssize:  # GST extended DRI symbol format?
                    entry = symboltableData[soffset:soffset + 14]
                    soffset += 14
                    name += entry[:8]
                if (
                        flags & 0xf000
                ) == 0xa000:  # global defined symbol? (registers, etc are not supported)
                    value += text_addr  # relocate the value
                    if (flags & 0xf00) == 0x0100:  # BSS
                        idc.set_name(value, name)
                    elif (flags & 0xf00) == 0x0200:  # TEXT
                        idaapi.add_entry(value, value, name, 1)
                    elif (flags & 0xf00) == 0x0400:  # DATA
                        idc.set_name(value, name)

        idaapi.add_entry(text_addr, text_addr, "start", 1)
        idaapi.plan_and_wait(text_addr, text_addr + header.PRG_tsize)
        idaapi.auto_wait()
        return 1

    return 0
Ejemplo n.º 8
0
def load_file(li, neflags, format):
    if format != ROM_FORMAT_NAME:
        Warning("Unknown format name: '%s'" % format)
        return 0
    jump = dwordAt(li, 0)
    # Test ARM branch
    if jump & 0xFF000000 != 0xEA000000:
        Warning("Unknown format name: '%s'" % format)
        return 0
    idaapi.set_processor_type("arm", idc.SETPROC_LOADER_NON_FATAL|idc.SETPROC_LOADER)
    li.seek(0, idaapi.SEEK_END)
    size = li.tell()

    # Adding Header Section
    idc.AddSeg(ROM_START, ROM_START + SIZE_HEADER, 0, 1, idaapi.saRelPara, idaapi.scPub)
    idc.set_segm_name(ROM_START, "HEADER")
    idc.set_segm_type(ROM_START, idc.SEG_CODE)
    li.seek(0)
    li.file2base(0, ROM_START, ROM_START + SIZE_HEADER, 0)

    # Adding OEP
    idaapi.add_entry(ROM_START, ROM_START, "start", 1)
    idaapi.cvar.inf.startIP = ROM_START
    idaapi.cvar.inf.beginEA = ROM_START

    # Adding ROM Section
    idc.AddSeg(ROM_START + SIZE_HEADER, ROM_START + (ROM_SIZE - SIZE_HEADER), 0, 1, idaapi.saRelPara, idaapi.scPub)
    idc.set_segm_name(ROM_START + SIZE_HEADER, "ROM")
    idc.set_segm_type(ROM_START + SIZE_HEADER, idc.SEG_CODE)
    li.seek(SIZE_HEADER)
    li.file2base(0, ROM_START + SIZE_HEADER, ROM_START + size, 0)

    # Adding EWRAM
    idc.AddSeg(0x02000000, 0x02040000, 0, 1, idaapi.saRelPara, idaapi.scPub)
    idc.set_segm_name(0x02000000, "EWRAM")
    memset_seg(0x02000000, 0x40000)

    # Adding IWRAM
    idc.AddSeg(0x03000000, 0x03008000, 0, 1, idaapi.saRelPara, idaapi.scPub)
    idc.set_segm_name(0x03000000, "IWRAM")
    memset_seg(0x03000000, 0x8000)

    # Adding IO / Registers
    idc.AddSeg(0x04000000, 0x04000400, 0, 1, idaapi.saRelPara, idaapi.scPub)
    idc.set_segm_name(0x04000000, "IOregisters")
    memset_seg(0x04000000, 0x400)

    # Adding BIOS System ROM
    idc.AddSeg(0x00000000, 0x00004000, 0, 1, idaapi.saRelPara, idaapi.scPub)
    idc.set_segm_name(0x00000000, "BIOS")
    memset_seg(0x00000000, 0x4000)
    idc.set_segm_type(0x0000000, idc.SEG_CODE)

    idaapi.add_extra_cmt(ROM_START, True, "ROM HEADER")
    li.seek(0xA0)
    idc.update_extra_cmt(ROM_START, 1,  "; Game Title : %s" % li.read(12))
    idc.update_extra_cmt(ROM_START, 2,  "; Game Code : %s" % li.read(4))
    idc.update_extra_cmt(ROM_START, 3,  "; Marker Code : %s" % li.read(2))
    idc.update_extra_cmt(ROM_START, 4,  "; Fixed value : %02X" % struct.unpack("<B", li.read(1))[0])
    idc.update_extra_cmt(ROM_START, 5,  "; Main unit code : %02X" % struct.unpack("<B", li.read(1))[0])
    idc.update_extra_cmt(ROM_START, 6,  "; Device type : %02X" % struct.unpack("<B", li.read(1))[0])
    idc.update_extra_cmt(ROM_START, 7,  "; Reserved Area : db 7 dup(0)")
    li.read(7)
    idc.update_extra_cmt(ROM_START, 8,  "; Software version %02X" % struct.unpack("<B", li.read(1))[0])
    idc.update_extra_cmt(ROM_START, 9,  "; Complement Check %02X" % struct.unpack("<B", li.read(1))[0])
    idc.update_extra_cmt(ROM_START, 10,  "; Reserved Area : db 2 dup(0)")
    
    io_naming()
    print("[+] Load OK")
    return 1