예제 #1
0
def load_file(li, neflags, format):
    
    # Select the PC processor module
    idaapi.set_processor_type("BPF", SETPROC_ALL|SETPROC_FATAL)
    
    buf = read_whole_file(li, 8)
    if not buf:
        return 0

    start = 0x0
    seg = idaapi.segment_t()
    size = len(buf)
    end  = start + size
    
    # Create the segment
    seg.startEA = start
    seg.endEA   = end
    seg.bitness = 1 # 32-bit
    idaapi.add_segm_ex(seg, "bpf_c", "CODE", 0)

    # Copy the bytes
    idaapi.mem2base(buf, start, end)

    # add entry point
    idaapi.add_entry(start, start, "start", 1) 

    # add comment to beginning of disassembly
    idaapi.describe(start, True, "BPF bytecode disassembly")

    # Mark for analysis
    AutoMark(start, AU_CODE)

    setup_enums()
    return 1
예제 #2
0
def create_segment(context_dir: str, segment: dict, is_be: bool):
    """Create segment in IDA and map in the data from the file

    :param context_dir: Parent directory of the context files
    :param segment: Segment information from _index.json
    :param is_be: True if processor is big endian, otherwise False
    """

    input_name = get_input_name()
    if Path(segment["name"]).name != input_name:
        ida_seg = idaapi.segment_t()
        ida_seg.start_ea = segment["start"]
        ida_seg.end_ea = segment["end"]
        ida_seg.bitness = 1 if is_be else 0
        if segment["permissions"]["r"]:
            ida_seg.perm |= ida_segment.SEGPERM_READ
        if segment["permissions"]["w"]:
            ida_seg.perm |= ida_segment.SEGPERM_WRITE
        if segment["permissions"]["x"]:
            ida_seg.perm |= ida_segment.SEGPERM_EXEC
            idaapi.add_segm_ex(ida_seg,
                               Path(segment["name"]).name, "CODE",
                               idaapi.ADDSEG_OR_DIE)
        else:
            idaapi.add_segm_ex(ida_seg,
                               Path(segment["name"]).name, "DATA",
                               idaapi.ADDSEG_OR_DIE)

    if segment["content_file"]:
        write_segment_bytes(segment["start"],
                            PurePath(context_dir, segment["content_file"]))
예제 #3
0
def create_load_seg(li,
                    start,
                    end,
                    modificationType,
                    name,
                    segmentType="CODE"):
    # add_segm(0, start, end, name, "")
    seg = idaapi.segment_t()
    seg.start_ea = start
    seg.end_ea = end
    seg.bitness = 1  # 32-bit
    idaapi.add_segm_ex(seg, name, "", 0)
    # AddSeg(start, end, 0, 1, idaapi.saAbs, idaapi.scPub)
    offset = li.tell()
    # li.file2base(offset, start, end, 0)
    data = li.read(end - start)

    # put_dword

    if modificationType == 2:
        byteswapped = bytearray([0]) * len(data)
        byteswapped[0::2] = data[1::2]
        byteswapped[1::2] = data[0::2]
        # idaapi.mem2base(str(byteswapped), start, end)
        for i in range(0, end - start):
            idaapi.put_byte(start + i, byteswapped[i])
    else:
        idaapi.mem2base(data, start, end)
예제 #4
0
def load_file(li, neflags, format):
    idaapi.set_processor_type("n2t-hack", idaapi.SETPROC_ALL|idaapi.SETPROC_FATAL)

    li.seek(0)
    hack_data = li.read(li.size())

    hack_instructions = [int(instruction, 2) for instruction in hack_data.splitlines()]
    hack_instructions_bin = ''.join(struct.pack("!H", instruction) for instruction in hack_instructions)
    print "Found %d hack instructions" % len(hack_instructions)


    seg = idaapi.segment_t()
    seg.startEA= 0
    seg.endEA = len(hack_instructions)

    seg.align = idaapi.saAbs
    seg.comb = idaapi.scPriv
    seg.bitness = 0 # 16-bit

    idaapi.add_segm_ex(seg, "Hack-ROM", "CODE", idaapi.ADDSEG_OR_DIE)

    # This method seems to change in next versions.
    #idaapi.mem2base(hack_instructions_bin, 0, -1)
    idaapi.mem2base(hack_instructions_bin, 0)

    return 1
예제 #5
0
def add_segment(start, end, name, type_):
    segment = idaapi.segment_t()
    segment.startEA = start
    segment.endEA = end
    segment.bitness = 1  # 32-bit

    idaapi.add_segm_ex(segment, name, type_,
                       idaapi.ADDSEG_SPARSE | idaapi.ADDSEG_OR_DIE)
예제 #6
0
def myAddSeg(startea, endea, base, use32, name, clas):
    s = idaapi.segment_t()
    s.startEA = startea
    s.endEA = endea
    s.sel = idaapi.setup_selector(base)
    s.bitness = use32
    s.align = idaapi.saRelPara
    s.comb = idaapi.scPub
    idaapi.add_segm_ex(s, name, clas, idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
예제 #7
0
def load_file(li, neflags, format):

    # Select the PC processor module
    idaapi.set_processor_type("EVM", SETPROC_ALL | SETPROC_FATAL)

    # TODO: detect and emulate contract creation code
    li.seek(0)
    buf = li.read(li.size())
    if not buf:
        return 0

    if buf[0:2] == '0x':
        print "Detected hex"
        new_buf = buf[2:].strip().rstrip()
        buf_set = set()
        for c in new_buf:
            buf_set.update(c)
        hex_set = set(list('0123456789abcdef'))
        if buf_set <= hex_set:  # subset
            print "Replacing original buffer with hex decoded version"
            buf = new_buf.decode('hex')

    # Load all shellcode into different segments
    start = 0x0
    seg = idaapi.segment_t()
    size = len(buf)
    end = start + size

    # Create the segment
    seg.startEA = start
    seg.endEA = end
    seg.bitness = 1  # 32-bit
    idaapi.add_segm_ex(seg, "evm", "CODE", 0)

    # TODO: make segments for stack, memory, storage

    # Copy the bytes
    idaapi.mem2base(buf, start, end)

    # check for swarm hash and make it data instead of code
    swarm_hash_address = buf.find('ebzzr0')
    if swarm_hash_address != -1:
        print "Swarm hash detected, making it data"
        for i in range(swarm_hash_address - 1, swarm_hash_address + 42):
            MakeByte(i)
        ida_bytes.set_cmt(swarm_hash_address - 1, "swarm hash", True)
    # add entry point
    idaapi.add_entry(start, start, "start", 1)

    # add comment to beginning of disassembly
    idaapi.describe(start, True, "EVM bytecode disassembly")

    # Mark for analysis
    AutoMark(start, AU_CODE)

    #setup_enums()
    return 1
예제 #8
0
def seg(fd, segm, ss, se, ft, lf):
    base = segm.start_ea
    del_segm(segm.start_ea)
    text = idaapi.segment_t()
    text.bitness = 1  # 32-bit
    text.end_ea = lf + 0x8
    text.start_ea = base

    idaapi.add_segm_ex(text, "__text", "CODE", idaapi.ADDSEG_OR_DIE)
예제 #9
0
    def create_segment(segment: Segment):

        segm = idaapi.segment_t()
        segm.bitness = segment.seg_bitness
        segm.start_ea = segment.start
        segm.end_ea = segment.end

        segm_type = segment.seg_type.name.upper()

        idaapi.add_segm_ex(segm, segment.name, segm_type, idaapi.ADDSEG_OR_DIE)
예제 #10
0
def myAddSeg(startea, endea, base, use32, name, clas):
    s = idaapi.segment_t()
    s.start_ea = startea
    s.end_ea = endea
    s.sel = idaapi.setup_selector(base)
    s.bitness = use32
    s.align = idaapi.saRelPara
    s.comb = idaapi.scPub
    idaapi.add_segm_ex(s, name, clas,
                       idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
예제 #11
0
def add_seg(startea, endea, bank, name):
    s = idaapi.segment_t()
    s.start_ea = startea + bank * 0x10000
    s.end_ea = endea + bank * 0x10000
    s.sel = idaapi.setup_selector(bank * 0x1000)
    s.bitness = 0
    s.align = idaapi.saRelPara
    s.comb = idaapi.scPub
    idaapi.add_segm_ex(s, name, "",
                       idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
예제 #12
0
def AddWasmSegment(startea, endea, name, cls=None, base=0):
    s = segment_t()
    s.start_ea = startea
    s.end_ea = endea
    s.sel = setup_selector(base)
    s.use32 = 0
    s.align = saRelByte  # saRelDble
    s.perm = SEGPERM_EXEC | SEGPERM_WRITE | SEGPERM_READ
    fl = ADDSEG_OR_DIE
    idaapi.add_segm_ex(s, name, cls, fl)
    return
예제 #13
0
def make_seg(start, size):
    seg = idaapi.segment_t()
    seg.bitness = 1  # 32bit
    seg.startEA = start
    seg.endEA = start + size
    seg.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE | idaapi.SEGPERM_EXEC
    # NOTE: we have no real way to determine what is code or not. for example, 40010001 kinda looks
    # like it begins with code, but really the entire thing is data.
    seg.type = idaapi.SEG_CODE
    # they never seem to use dflash anyways
    idaapi.add_segm_ex(seg, 'cflash' if start < 0x80000 else 'dflash', 'CODE',
                       0)
예제 #14
0
 def __call__(self):
     s = idaapi.segment_t()
     s.start_ea = self.start_ea
     s.end_ea = self.end_ea
     s.orgbase = self.orgbase
     s.align = self.align
     s.comb = self.comb
     s.perm = self.perm
     s.bitness = self.bitness
     s.flags = self.flags
     idaapi.add_segm_ex(s, self.name.encode('utf-8'), self.class_,
                        idaapi.ADDSEG_QUIET | idaapi.ADDSEG_NOSREG)
예제 #15
0
def make_segment(base, size, name):
    s = idc.get_segm_by_sel(base)
    if not s == 0xffffffff:
        return

    s = idaapi.segment_t()
    s.startEA = base
    s.endEA = base+size
    s.sel = 0
    s.bitness = 1
    s.comb = idaapi.scPub
    idaapi.add_segm_ex(s, name.strip('.').upper(), "", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_SPARSE)
예제 #16
0
def make_seg(addr_range, record_type = 0):
        seg = idaapi.segment_t()
        seg.bitness = 1 # 32bit
        seg.startEA = addr_range[0]
        seg.endEA = addr_range[1]
        seg.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE | idaapi.SEGPERM_EXEC
        seg.type = idaapi.SEG_CODE
        seg.align = idaapi.saRelByte
        # Force regions to be CODE
        if record_type == 1:
            idaapi.add_segm_ex(seg, 'ROM', 'CODE', idaapi.ADDSEG_NOSREG)
        else:
            idaapi.add_segm_ex(seg, 'RAM', 'CODE', idaapi.ADDSEG_NOSREG)
예제 #17
0
def AdditionalSegment(size, offset, name):
    s = idaapi.segment_t()
    step = 0x1000000 - 1
    s.startEA = idaapi.freechunk(0x1000000, size, step)
    s.endEA = s.startEA + size
    s.sel = idaapi.setup_selector((s.startEA - offset) >> 4)
    s.type = idaapi.SEG_DATA
    if byte_size("X") > 2:
        s.bitness = 1
    else:
        s.bitness = 0
    idaapi.add_segm_ex(s, name, "DATA", idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
    return s.startEA - offset
예제 #18
0
def AdditionalSegment(size, offset, name):
  s = idaapi.segment_t()
  step = 0x1000000-1
  s.startEA = idaapi.freechunk(0x1000000, size, step)
  s.endEA   = s.startEA + size
  s.sel     = idaapi.setup_selector((s.startEA-offset) >> 4)
  s.type    = idaapi.SEG_DATA
  if byte_size('X') > 2:
    s.bitness = 1
  else:
    s.bitness = 0
  idaapi.add_segm_ex(s, name, "DATA", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_OR_DIE)
  return s.startEA - offset
예제 #19
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
    """

    li.seek(0)
    vmlinux = li.read(li.size())

    do_get_bits(kallsyms, vmlinux)
    do_kallsyms(kallsyms, vmlinux)
    # print_kallsyms(kallsyms, vmlinux)
    if kallsyms['arch'] == 'arm':
        idaapi.set_processor_type('arm',
                                  idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL)
    elif kallsyms['arch'] == 'mips' and not kallsyms['is_big_endian']:
        idaapi.set_processor_type('mipsl',
                                  idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL)
    elif kallsyms['arch'] == 'mips' and not kallsyms['is_big_endian']:
        idaapi.set_processor_type('mipsb',
                                  idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL)
    elif kallsyms['arch'] == 'x86':
        idaapi.set_processor_type('metapc', idaapi.SETPROC_ALL
                                  | idaapi.SETPROC_FATAL)  #NOT tested

    if kallsyms['bits'] == 64:
        idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT

    li.file2base(0, kallsyms['_start'], kallsyms['_start'] + li.size(), True)

    s = idaapi.segment_t()
    s.bitness = kallsyms['bits'] / 32
    s.startEA = kallsyms['_start']
    s.endEA = kallsyms['_start'] + li.size()
    idaapi.add_segm_ex(s, ".text", "CODE", idaapi.ADDSEG_OR_DIE)

    for i in xrange(kallsyms['numsyms']):
        if kallsyms['type'][i] in ['t', 'T']:
            idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i],
                             kallsyms['name'][i], 1)
        else:
            idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i],
                             kallsyms['name'][i], 0)

    print "Android/Linux vmlinux loaded..."
    return 1
예제 #20
0
    def _AddSegment(self, name, base_address, data=None):
        """Add a segment to the IDB with some basic options set for convenience."""
        s = idaapi.segment_t()

        s.startEA = base_address
        s.endEA = base_address + len(data)
        s.bitness = 1  # 32-bit
        s.align = idaapi.saRelByte
        s.comb = idaapi.scPub
        s.sel = idaapi.setup_selector(0)

        # We mark the segments as code, as we know these are loops in memory
        idaapi.add_segm_ex(s, name, "CODE",
                           idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
        idaapi.mem2base(data, base_address)
def AddSegment(name, base_address, data):
    """Add a segment to the IDB with some basic options set for convenience."""
    s = idaapi.segment_t()
    
    s.startEA = base_address
    s.endEA = base_address + len(data)
    
    s.bitness = 1 # 32-bit
    
    s.align = idaapi.saRelByte
    s.comb = idaapi.scPub
    
    s.sel = idaapi.setup_selector(0)
    
    idaapi.add_segm_ex(s, name, None, idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
    idaapi.mem2base(data, base_address)
예제 #22
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
    """

    # Select the PC processor module
    idaapi.set_processor_type("metapc", ida_idp.SETPROC_LOADER)

    # read MBR into buffer
    li.seek(0, os.SEEK_SET)
    buf = li.read(li.size())

    seg = idaapi.segment_t()
    start = 0x7C00

    size = len(buf)
    end = start + size

    # Create the segment
    seg.start_ea = start
    seg.end_ea = end
    seg.bitness = 0  # 16-bit
    idaapi.add_segm_ex(seg, "seg0", "CODE", 0)

    # Copy the bytes
    idaapi.mem2base(buf, start, end)

    # add entry point
    idaapi.add_entry(start, start, "start", 1)

    strid = add_struct_def()
    idaapi.set_name(start + 0x1BE, "MBR_PARTITION_TABLE", idaapi.SN_CHECK)
    str_size = idaapi.get_struc_size(strid)
    idaapi.create_struct(start + 0x1BE, str_size, strid)

    idaapi.set_name(510, "MBR_SIGN", idaapi.SN_CHECK)

    # Mark for analysis
    AutoMark(start, AU_CODE)

    load_debugger("bochs", 0)

    return 1
예제 #23
0
def AddSegment(name, base_address, data):
    """Add a segment to the IDB with some basic options set for convenience."""
    s = idaapi.segment_t()

    s.startEA = base_address
    s.endEA = base_address + len(data)

    s.bitness = 1  # 32-bit

    s.align = idaapi.saRelByte
    s.comb = idaapi.scPub

    s.sel = idaapi.setup_selector(0)

    idaapi.add_segm_ex(s, name, None,
                       idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
    idaapi.mem2base(data, base_address)
예제 #24
0
def add_seg(start_ea, end_ea, name, cls, use32, align, comb):
    s = idaapi.segment_t()
    s.startEA     = start_ea
    s.endEA       = end_ea
    s.sel         = idaapi.setup_selector(0)
    s.bitness     = use32
    s.align       = align
    s.comb        = comb
    return idaapi.add_segm_ex(s, name, cls, idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_OR_DIE)
예제 #25
0
def add_seg(start_ea, end_ea, name, cls, use32, align, comb):
    s = idaapi.segment_t()
    s.startEA = start_ea
    s.endEA = end_ea
    s.sel = idaapi.setup_selector(0)
    s.bitness = use32
    s.align = align
    s.comb = comb
    return idaapi.add_segm_ex(s, name, cls, idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
예제 #26
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
    """

    # Select the PC processor module
    idaapi.set_processor_type("metapc", SETPROC_ALL|SETPROC_FATAL)

    buf = read_whole_file(li)
    r = extract_pdf_shellcode(buf)
    if not r:
        return 0

    # Load all shellcode into different segments
    start = 0x10000
    seg = idaapi.segment_t()
    for id, ver, n, sc in r:
        size = len(sc)
        end  = start + size
        
        # Create the segment
        seg.startEA = start
        seg.endEA   = end
        seg.bitness = 1 # 32-bit
        idaapi.add_segm_ex(seg, "obj_%d_%d_%d" % (id, ver, n), "CODE", 0)

        # Copy the bytes
        idaapi.mem2base(sc, start, end)

        # Mark for analysis
        AutoMark(start, AU_CODE)

        # Compute next loading address
        start = ((end / 0x1000) + 1) * 0x1000

    # Select the bochs debugger
    LoadDebugger("bochs", 0)

    return 1
예제 #27
0
def create(offset, size, name, **kwds):
    '''Create a segment at /offset/ and /size/ and name it /name/

    /bits/ can be used to specify the bit size of the segment
    /comb/ can be used to specify any flags (idaapi.sc*)
    /align/ can be used to specify paragraph alignment (idaapi.sa*)
    /org/ specifies the origin of the segment (must be paragraph aligned due to ida)
    '''
    s = idaapi.get_segm_by_name(name)
    if s is not None:
        logging.fatal(
            "segment.create(%x, %x, %r, %r) : a segment with the specified name already exists : %s",
            offset, size, name, kwds, name)
        return None

    bits = kwds.get(
        'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).
        abits())  # FIXME: use disassembler default bit length instead of 32

    if bits == 16:
        ## create a selector with the requested origin
        org = kwds.get('org', 0)
        if org & 0xf > 0:
            logging.fatal(
                "segment.create(%x, %x, %r, %r) : origin (.org) is not aligned to the size of a paragraph (0x10):%x",
                offset, size, name, kwds, org)
            return None

        para = offset / 16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para - kwds.get('org', 0) / 16) & 0xffffffff)
    else:
        ## auto-create a selector for everything else
        sel = idaapi.setup_selector(
            kwds['selector']
        ) if 'selector' in kwds else idaapi.find_free_selector()

    # create segment. ripped from idc
    s = idaapi.segment_t()
    s.startEA = offset
    s.endEA = offset + size
    s.sel = sel
    s.bitness = {16: 0, 32: 1, 64: 2}[bits]
    s.comb = kwds.get('comb', idaapi.scPub)  # public
    s.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    res = idaapi.add_segm_ex(s, name, "",
                             idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_SPARSE)
    if res == 0:
        logging.warn(
            "segment.create(%x, %x, %r, %r) : unable to add a new segment",
            offset, size, name, kwds)
        res = idaapi.del_selector(sel)
        #assert res != 0
        return None
    return s
예제 #28
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
    """

    # Select the PC processor module
    idaapi.set_processor_type("metapc", SETPROC_LOADER)

    buf = read_whole_file(li)
    r = extract_pdf_shellcode(buf)
    if not r:
        return 0

    # Load all shellcode into different segments
    start = 0x10000
    seg = idaapi.segment_t()
    for id, ver, n, sc in r:
        size = len(sc)
        end = start + size

        # Create the segment
        seg.start_ea = start
        seg.end_ea = end
        seg.bitness = 1  # 32-bit
        idaapi.add_segm_ex(seg, "obj_%d_%d_%d" % (id, ver, n), "CODE", 0)

        # Copy the bytes
        idaapi.mem2base(sc, start, end)

        # Mark for analysis
        AutoMark(start, AU_CODE)

        # Compute next loading address
        start = ((end / 0x1000) + 1) * 0x1000

    # Select the bochs debugger
    load_debugger("bochs", 0)

    return 1
예제 #29
0
def load_file(li, neflags, format):
    """Load the file into database
    
    Args:
        li: a file-like object which can be used to access the input data
        neflags: options selected by the user, see loader.hpp
    Returns: 
        0-failure
        1-ok
    """

    idaapi.set_processor_type("sh4", SETPROC_ALL | SETPROC_FATAL)

    li.seek(0, idaapi.SEEK_END)
    size = li.tell()
    li.seek(0)
    rom_data = li.read(size)

    s = idaapi.segment_t()
    s.startEA = 0
    s.endEA = size
    s.bitness = 1  # 32-bit
    s.align = idaapi.saRelByte
    s.comb = idaapi.scPub
    s.sel = idaapi.setup_selector(0)

    idaapi.add_segm_ex(s, "ROM", "DATA",
                       idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
    idaapi.mem2base(rom_data, 0)

    headr = JasperThe2kCat()
    headr.AnotateHeader(binary_file=li)
    headr.MakeStrings(binary_file=li)
    gentries = gameEntries()

    gentries.readGameLoops(binary_file=li)
    gentries.CreateSegments(binary_file=li)
    gentries.makeDWordTables()
    gentries.makeDWordTables(start_address=0x2a0, end_address=0x1000)
    gentries.addIDA_entry()

    print("load ok")
    return 1
예제 #30
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
    """

    li.seek(0)
    vmlinux = li.read(li.size())

    do_get_arch(kallsyms, vmlinux)
    do_kallsyms(kallsyms, vmlinux)
    # print_kallsyms(kallsyms, vmlinux)
    
    if kallsyms['numsyms'] == 0:
        print '[!]get kallsyms error...'
        return 0
    
    idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL)
    if kallsyms['arch'] == 64:
        idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT

    li.file2base(0, kallsyms['_start'], kallsyms['_start']+li.size(), True)

    s = idaapi.segment_t()
    s.bitness = kallsyms['arch'] / 32
    s.startEA = kallsyms['_start']
    s.endEA = kallsyms['_start']+li.size()
    idaapi.add_segm_ex(s,".text","CODE",ADDSEG_OR_DIE)
    
    for i in xrange(kallsyms['numsyms']):
        if kallsyms['type'][i] in ['t','T']:
            idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 1)
        else:
            idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 0)

    print "Android vmlinux loaded..."
    return 1
예제 #31
0
def process(fd, bitness):
    enable_auto(False)
    base_addr = 0x0
    if bitness == 1:
        idaapi.set_processor_type('ARM:ARMv7-A',
                                  idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL)
        idaapi.get_inf_structure().lflags |= idaapi.LFLG_PC_FLAT
    elif bitness == 2:
        idaapi.set_processor_type("arm", idaapi.SETPROC_LOADER_NON_FATAL)
        idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT

    fd.seek(0, idaapi.SEEK_END)
    size = fd.tell()
    segm = idaapi.segment_t()
    segm.bitness = bitness
    segm.start_ea = 0
    segm.end_ea = size

    if base_addr != 0:
        print("[*] Rebasing to address 0x%x" % (base_addr))
        idaapi.rebase_program(base_addr, MSF_NOFIX)
        idaapi.autoWait()

    idaapi.add_segm_ex(segm, "SecureROM", "CODE", idaapi.ADDSEG_OR_DIE)

    fd.seek(0)
    fd.file2base(0, 0, size, False)
    print("[*] Pass One")
    print("[*] Defining functions")
    #locate_functions(segm)
    print("[*] Defining early initialation instructions")
    build_jump_table(segm)
    print("[*] Attempting to force string definitons")
    global string_start, string_end
    string_start, string_end = process_strings(segm)
    print("[*] Pass Two")
    print("[*] Hunting for and defining symbols")
    symbolicate(segm)
예제 #32
0
    def AddDefaultSH4Segments(self):
        """Add a segment to the IDB with some basic options set for convenience."""
        base_address = 0x0C000000
        # Create segments on the range of 0x04000000 bytes
        for segment in range(5):
            name = "Area_%d" % (segment + 3)
            s = idaapi.segment_t()
            s.startEA = base_address
            s.endEA = base_address + 0x04000000
            s.bitness = 1  # 32-bit
            s.align = idaapi.saRelByte
            s.comb = idaapi.scPub
            s.sel = idaapi.setup_selector(0)
            # We mark the segments as code, as we know these are loops in memory
            idaapi.add_segm_ex(s, name, 'CODE',
                               idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
            base_address += 0x04000000

        # Second set of segments (now is the privileged ones)
        base_address = 0x80000000
        # Create segments on the range of 0x04000000 bytes
        for segment in range(4):
            name = "Priv_%d" % (segment + 1)
            s = idaapi.segment_t()
            s.startEA = base_address
            if base_address == 0xE0000000:
                s.endEA = base_address + 0x10000000
            else:
                s.endEA = base_address + 0x20000000
            s.bitness = 1  # 32-bit
            s.align = idaapi.saRelByte
            s.comb = idaapi.scPub
            s.sel = idaapi.setup_selector(0)
            # We mark the segments as code, as we know these are loops in memory
            idaapi.add_segm_ex(s, name, None,
                               idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
            base_address += 0x20000000
예제 #33
0
def create(offset, size, name, **kwds):
    '''Create a segment at /offset/ and /size/ and name it /name/

    /bits/ can be used to specify the bit size of the segment
    /comb/ can be used to specify any flags (idaapi.sc*)
    /align/ can be used to specify paragraph alignment (idaapi.sa*)
    /org/ specifies the origin of the segment (must be paragraph aligned due to ida)
    '''
    s = idaapi.get_segm_by_name(name)
    if s is not None:
        logging.fatal("segment.create(%x, %x, %r, %r) : a segment with the specified name already exists : %s", offset, size, name, kwds, name)
        return None

    bits = kwds.get( 'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).abits()) # FIXME: use disassembler default bit length instead of 32

    if bits == 16:
        ## create a selector with the requested origin
        org = kwds.get('org',0)
        if org&0xf > 0:
            logging.fatal("segment.create(%x, %x, %r, %r) : origin (.org) is not aligned to the size of a paragraph (0x10):%x", offset, size, name, kwds, org)
            return None

        para = offset/16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para-kwds.get('org',0)/16)&0xffffffff)
    else:
        ## auto-create a selector for everything else
        sel = idaapi.setup_selector(kwds['selector']) if 'selector' in kwds else idaapi.find_free_selector()

    # create segment. ripped from idc
    s = idaapi.segment_t()
    s.startEA = offset
    s.endEA = offset+size
    s.sel = sel
    s.bitness = {16:0,32:1,64:2}[bits]
    s.comb = kwds.get('comb', idaapi.scPub)       # public
    s.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    res = idaapi.add_segm_ex(s, name, "", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_SPARSE)
    if res == 0:
        logging.warn("segment.create(%x, %x, %r, %r) : unable to add a new segment", offset, size, name, kwds)
        res = idaapi.del_selector(sel)
        #assert res != 0
        return None
    return s
예제 #34
0
def new(offset, size, name, **kwds):
    """Create a segment at ``offset`` with ``size`` and name it according to ``name``.
    ``bits`` can be used to specify the bit size of the segment
    ``comb`` can be used to specify any flags (idaapi.sc*)
    ``align`` can be used to specify paragraph alignment (idaapi.sa*)
    ``org`` specifies the origin of the segment (must be paragraph aligned due to ida)
    """
    s = idaapi.get_segm_by_name(name)
    if s is not None:
        logging.fatal("{:s}.new({:x}, {:x}, {!r}, {!r}) : a segment with the specified name already exists : {:s}".format(__name__, offset, size, name, kwds, name))
        return None

    bits = kwds.get( 'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).abits()) # FIXME: use disassembler default bit length instead of 32

    if bits == 16:
        ## create a selector with the requested origin
        org = kwds.get('org',0)
        if org&0xf > 0:
            logging.fatal("{:s}.new({:x}, {:x}, {!r}, {!r}) : origin (.org) is not aligned to the size of a paragraph (0x10) : {:x}".format(__name__, offset, size, name, kwds, org))
            return None

        para = offset/16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para-kwds.get('org',0)/16)&0xffffffff)
    else:
        ## auto-create a selector for everything else
        sel = idaapi.setup_selector(kwds['selector']) if 'selector' in kwds else idaapi.find_free_selector()

    # create segment. ripped from idc
    s = idaapi.segment_t()
    s.startEA = offset
    s.endEA = offset+size
    s.sel = sel
    s.bitness = {16:0,32:1,64:2}[bits]
    s.comb = kwds.get('comb', idaapi.scPub)       # public
    s.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    res = idaapi.add_segm_ex(s, name, "", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_SPARSE)
    if res == 0:
        logging.warn("{:s}.new({:x}, {:x}, {!r}, {!r}) : unable to add a new segment".format(__name__, offset, size, name, kwds))
        res = idaapi.del_selector(sel)
        #assert res != 0
        return None
    return s
예제 #35
0
def load_file(li, neflags, format):
    """
    Load the SEGA Master System ROM
    :param li: Loader input
    :param neflags:
    :param format:
    :return: 1 on success, otherwise 0
    """

    idaapi.set_processor_type('z80', idaapi.SETPROC_LOADER)
    is_reload = (neflags & idaapi.NEF_RELOAD) != 0
    if is_reload:
        return 1

    # Create ROM segment
    rom_seg = idaapi.segment_t()
    rom_seg.start_ea = 0x0000
    rom_seg.end_ea = 0xbfff
    rom_seg.bitness = 0
    idaapi.add_segm_ex(rom_seg, 'ROM', 'CODE', idaapi.ADDSEG_OR_DIE)

    # Read file into ROM segment
    li.seek(0)
    li.file2base(0, 0, li.size(), False)

    # Create RAM Segment
    ram_seg = idaapi.segment_t()
    ram_seg.start_ea = 0xc000
    ram_seg.end_ea = 0xdfff
    ram_seg.bitness = 0
    idaapi.add_segm_ex(ram_seg, 'RAM', 'DATA', idaapi.ADDSEG_OR_DIE)

    # Create RAM mirror segment
    ram_mirror_seg = idaapi.segment_t()
    ram_mirror_seg.start_ea = 0xe000
    ram_mirror_seg.end_ea = 0xffff
    ram_mirror_seg.bitness = 0
    idaapi.add_segm_ex(ram_mirror_seg, 'RAM_MIRROR', 'DATA',
                       idaapi.ADDSEG_OR_DIE)

    # Define the I/O ports
    create_io_ports()

    # Disassemble reset vectors
    create_reset_vectors()

    # Specify entry
    idaapi.add_entry(0x0000, 0x0000, 'RST0', 1)
    return 1
예제 #36
0
def new(offset, size, name, **kwds):
    """Create a segment at `offset` with `size` and name it according to `name`.

    The keyword `bits` can be used to specify the bit size of the segment
    The keyword `comb` can be used to specify any flags (idaapi.sc*)
    The keyword `align` can be used to specify paragraph alignment (idaapi.sa*)
    The keyword `org` specifies the origin of the segment (must be paragraph aligned due to ida)
    """
    res = utils.string.to(name)

    # find the segment according to the name specified by the user
    seg = idaapi.get_segm_by_name(res)
    if seg is not None:
        raise E.DuplicateItemError(u"{:s}.new({:#x}, {:+#x}, \"{:s}\"{:s}) : A segment with the specified name (\"{:s}\") already exists.".format(__name__, offset, size, utils.string.escape(name, '"'), u", {:s}".format(utils.string.kwargs(kwds)) if kwds else '', utils.string.escape(name, '"')))

    # FIXME: use disassembler default bit length instead of 32
    bits = kwds.get( 'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).abits())

    ## create a selector with the requested origin
    if bits == 16:
        org = kwds.get('org',0)
        if org & 0xf > 0:
            raise E.InvalidTypeOrValueError(u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : The specified origin ({:#x}) is not aligned to the size of a paragraph (0x10).".format(__name__, offset, size, name, u", {:s}".format(utils.string.kwargs(kwds)) if kwds else '', org))

        para = offset/16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para-kwds.get('org',0)/16)&0xffffffff)

    ## if the user specified a selector, then use it
    elif 'sel' in kwds or 'selector' in kwds:
        sel = kwds.get('sel', kwds.get('selector', idaapi.find_free_selector()))

    ## choose the paragraph size defined by the user
    elif 'para' in kwds or 'paragraphs' in kwds:
        para = kwds.get('paragraph', kwds.get('para', 1))
        sel = idaapi.setup_selector(para)

    ## find a selector that is 1 paragraph size,
    elif idaapi.get_selector_qty():
        sel = idaapi.find_selector(1)

    # otherwise find a free one and set it.
    else:
        sel = idaapi.find_free_selector()
        idaapi.set_selector(sel, 1)

    # populate the segment_t using code ripped from the idc module
    seg = idaapi.segment_t()
    seg.startEA = offset
    seg.endEA = offset+size
    seg.sel = sel
    seg.bitness = {16:0,32:1,64:2}[bits]
    seg.comb = kwds.get('comb', idaapi.scPub)       # public
    seg.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    # now we can add our segment_t to the database
    res = utils.string.to(name)
    ok = idaapi.add_segm_ex(seg, res, "", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_SPARSE)
    if not ok:
        ok = idaapi.del_selector(sel)
        if not ok:
            logging.warn(u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to delete the created selector ({:#x}) for the new segment.".format(__name__, offset, size, name, u", {:s}".format(utils.string.kwargs(kwds)) if kwds else '', sel))
        raise E.DisassemblerError(u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to add a new segment.".format(__name__, offset, size, name, u", {:s}".format(utils.string.kwargs(kwds)) if kwds else ''))
    return seg
예제 #37
0
파일: loader.py 프로젝트: isra17/nrs
def load_file(li, netflags, format):
    nsis = nsisfile.NSIS.from_path(idaapi.get_input_file_path())

    # Create NSIS netnode.
    nsis_netnode = idaapi.netnode("$ NSIS", 0, True)
    nsis_netnode.hashset("VERSION_MAJOR", nsis.version_major)
    nsis_netnode.hashset("VERSION_MINOR", nsis.version_minor)

    # Create blocks segments.
    for name, n, sclass in BLOCKS:
        offset = nsis.header.blocks[n].offset
        if offset == 0:
            continue
        content = nsis.block(n)
        # Create block segment
        seg = idaapi.segment_t()
        seg.startEA = offset
        seg.endEA = offset + len(content)
        idaapi.add_segm_ex(seg, name, sclass, 0)
        idaapi.mem2base(content, offset)

    # Add one virtual segment to hold variables.
    var_seg = idaapi.segment_t()
    var_start = align(nsis.size())
    var_seg.startEA = var_start
    var_seg.endEA = var_start + 0x1000  # Size chosen arbitrarily, should be enough.
    idaapi.add_segm_ex(var_seg, "VARS", "BSS", 0)
    # Create standard vars.
    for i, v in enumerate(nrs.strings.SYSVAR_NAMES.values()):
        idaapi.do_name_anyway(var_seg.startEA + i + 20, "$" + v)

    code_base = nsis.header.blocks[fileform.NB_ENTRIES].offset
    # Create sections functions.
    for i, section in enumerate(nsis.sections):
        if section.code == PTR_NONE:
            continue
        name = nsis.get_string(section.name_ptr)
        if not name:
            name = "_section" + str(i)
        ea = code_base + nrs.entry_to_offset(section.code)
        cname = canonize_name(name)
        AddEntryPoint(ea, ea, cname, 1)

    # Mark pages handlers.
    for i, page in enumerate(nsis.pages):
        for fn in ["prefunc", "showfunc", "leavefunc"]:
            addr = getattr(page, fn)
            if addr != PTR_NONE:
                name = "_page_{}_{}".format(i, fn)
                ea = code_base + nrs.entry_to_offset(addr)
                AddEntryPoint(ea, ea, name, 1)

    # Mark installer handlers.
    for event in [
        "Init",
        "InstSuccess",
        "InstFailed",
        "UserAbort",
        "GUIInit",
        "GUIEnd",
        "MouseOverSection",
        "VerifyInstDir",
        "SelChange",
        "RebootFailed",
    ]:
        addr = getattr(nsis.header, "code_on" + event)
        if addr != PTR_NONE:
            name = "_on" + event
            ea = code_base + nrs.entry_to_offset(addr)
            AddEntryPoint(ea, ea, name, 1)

    # Create strings.
    """
    strings_data = nsis.block(fileform.NB_STRINGS)
    strings_off = nsis.header.blocks[fileform.NB_STRINGS].offset
    i = 0
    while i < len(strings_data):
        decoded_string, length = \
            nrs.strings.decode(strings_data, i, nsis.version_major)
        decoded_string = str(decoded_string)
        string_name = canonize_name(decoded_string)
        idaapi.make_ascii_string(strings_off + i, length, ASCSTR_C)
        idaapi.set_cmt(strings_off + i, decoded_string, True)
        idaapi.do_name_anyway(strings_off + i, string_name)
        i += length
    #"""

    # Set processor to nsis script.
    SetProcessorType("nsis", SETPROC_ALL | SETPROC_FATAL)
    return 1
예제 #38
0
파일: vmlinux.py 프로젝트: idl3r/droidimg
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
    """

    li.seek(0)
    vmlinux = li.read(li.size())

    do_get_arch(kallsyms, vmlinux)
    do_kallsyms(kallsyms, vmlinux)
    
    if kallsyms['numsyms'] == 0:
        print_log('[!]get kallsyms error...')
        return 0
    
    idaapi.set_processor_type("arm", idaapi.SETPROC_ALL|idaapi.SETPROC_FATAL)
    if kallsyms['arch'] == 64:
        idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT

    li.file2base(0, kallsyms['_start'], kallsyms['_start']+li.size(), True)

    sinittext_addr = 0
    max_sym_addr = 0
    for i in range(kallsyms['numsyms']):
        if kallsyms['arch'] == 32:
            if kallsyms['address'][i] > 0xd0000000:
                continue

        if kallsyms['name'][i] == '_sinittext':
            sinittext_addr = kallsyms['address'][i]
        if kallsyms['address'][i] > max_sym_addr:
            max_sym_addr = kallsyms['address'][i]
    max_sym_addr = max_sym_addr + 1024
    print_log("max_sym_addr = ", hex(max_sym_addr))

    if (kallsyms['_start']+li.size()) > max_sym_addr:
        max_sym_addr = kallsyms['_start']+li.size()


    s = idaapi.segment_t()
    s.bitness = kallsyms['arch'] // 32
    s.startEA = kallsyms['_start']
    if sinittext_addr == 0:
        s.endEA = max_sym_addr
    else:
        s.endEA = sinittext_addr
    s.perm = 5
    idaapi.add_segm_ex(s,".text","CODE",idaapi.ADDSEG_OR_DIE)
    
    if sinittext_addr > 0:
        s = idaapi.segment_t()
        s.bitness = kallsyms['arch'] // 32
        s.startEA = sinittext_addr
        s.endEA = max_sym_addr
        s.perm = 7
        idaapi.add_segm_ex(s,".data","DATA",idaapi.ADDSEG_OR_DIE)

    for i in range(kallsyms['numsyms']):
        if kallsyms['type'][i] in ['t','T']:
            idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 1)
        else:
            idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 0)

    print_log("Android/Linux vmlinux loaded...")
    return 1
예제 #39
0
def load_file(li, neflags, format):
    """
    Load the SG/SMD ROM

    :param li: Loader input
    :param neflags:
    :param format:
    :return: 1 on success, otherwise 0
    """

    idaapi.set_processor_type('68000', idaapi.SETPROC_LOADER)
    is_reload = (neflags & idaapi.NEF_RELOAD) != 0
    if is_reload:
        return 1

    # Get ROM end
    li.seek(0x1a4)
    rom_end = struct.unpack('>I', li.read(4))[0]

    # Create ROM segment
    rom_seg = idaapi.segment_t()
    rom_seg.start_ea = 0
    rom_seg.end_ea = rom_end
    rom_seg.bitness = 1
    idaapi.add_segm_ex(rom_seg, 'ROM', 'CODE', idaapi.ADDSEG_OR_DIE)

    # Get RAM start/end
    li.seek(0x1a8)
    ram_start = struct.unpack('>I', li.read(4))[0]
    ram_end = struct.unpack('>I', li.read(4))[0]

    # Create RAM segment
    ram_seg = idaapi.segment_t()
    ram_seg.start_ea = ram_start
    ram_seg.end_ea = ram_end
    ram_seg.bitness = 1
    idaapi.add_segm_ex(ram_seg, 'RAM', 'DATA', idaapi.ADDSEG_OR_DIE)

    # Read file into ROM segment
    li.seek(0)
    li.file2base(0, 0, rom_end, False)

    # Create Z80 memory segment
    z80_seg = idaapi.segment_t()
    z80_seg.start_ea = 0xa00000
    z80_seg.end_ea = 0xa1ffff  # Actually ends at 0xa0ffff, but for the sake of applying labels we make it 0xa1ffff
    z80_seg.bitness = 0  # 16 bit
    idaapi.add_segm_ex(z80_seg, 'Z80', 'DATA', idaapi.ADDSEG_OR_DIE)
    label_z80_memory()

    # Create a segment so we can create labels for VDP ports and debug registers
    misc_ports_regs = idaapi.segment_t()
    misc_ports_regs.start_ea = 0xc00000
    misc_ports_regs.end_ea = 0xc00020
    misc_ports_regs.bitness = 1
    idaapi.add_segm_ex(misc_ports_regs, 'MISC', 'DATA', idaapi.ADDSEG_OR_DIE)
    label_misc_regs_ports()

    # Create interrupt vector table
    create_dword_and_name(0, 'StackOffset')
    create_dword_and_name(4, 'ProgramStart')
    create_interrupt_table()
    create_interrupt_handlers(li)

    # Create ROM info
    create_rom_info_block()

    # Set entry
    program_start = get_dword_at(li, 4)
    idaapi.add_entry(program_start, program_start, '_start', 1)
    return 1
예제 #40
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
    '''
    idaapi.set_processor_type('cLEMENCy',
                              idaapi.SETPROC_USER | idaapi.SETPROC_FATAL)
    li.seek(0)
    fileLen = li.size()
    data = convert(li.read(fileLen))
    if len(data) > 0x4000000:
        # program too large
        return 0

    idaname = "ida64" if __EA64__ else "ida"
    if sys.platform == "win32":
        _mod = ctypes.windll[idaname + ".wll"]
    elif sys.platform == "linux2":
        _mod = ctypes.cdll["lib" + idaname + ".so"]
    elif sys.platform == "darwin":
        _mod = ctypes.cdll["lib" + idaname + ".dylib"]
    create_bytearray_linput = _mod.create_bytearray_linput
    create_bytearray_linput.argtypes = (idaapi.POINTER(ctypes.c_ubyte),
                                        ctypes.c_int)
    create_bytearray_linput.restype = ctypes.c_int
    bufPointer = idaapi.cast(data, idaapi.POINTER(ctypes.c_ubyte))
    retlinput = create_bytearray_linput(bufPointer,
                                        int(fileLen * 8 / 9 * 16 / 8))
    file2base = _mod.file2base
    file2base.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.c_int,
                          ctypes.c_int, ctypes.c_int)
    file2base.restype = ctypes.c_int
    file2base(retlinput, 0, 0, int(fileLen * 8 / 9), idaapi.FILEREG_PATCHABLE)

    seg = idaapi.segment_t()
    seg.startEA = 0
    seg.endEA = 0x4000000
    # seg.bitness = 1
    idaapi.add_segm_ex(seg, "PROGRAM", "CODE", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x4000000
    seg.endEA = 0x400001e
    idaapi.add_segm_ex(seg, "CLOCKIO", "RAM", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x4010000
    seg.endEA = 0x4011000
    idaapi.add_segm_ex(seg, "FLAGIO", "RAM", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x5000000
    seg.endEA = 0x5002000
    idaapi.add_segm_ex(seg, "RDATA", "RAM", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x5002000
    seg.endEA = 0x5002003
    idaapi.add_segm_ex(seg, "RDATASZ", "RAM", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x5010000
    seg.endEA = 0x5012000
    idaapi.add_segm_ex(seg, "SDATA", "RAM", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x5012000
    seg.endEA = 0x5012003
    idaapi.add_segm_ex(seg, "SDATASZ", "RAM", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x6000000
    seg.endEA = 0x6800000
    idaapi.add_segm_ex(seg, "SHMEM", "RAM", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x6800000
    seg.endEA = 0x7000000
    idaapi.add_segm_ex(seg, "NVRAM", "RAM", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x7FFFF00
    seg.endEA = 0x7FFFF1C
    idaapi.add_segm_ex(seg, "IVEC", "RAM", idaapi.ADDSEG_SPARSE)
    seg = idaapi.segment_t()
    seg.startEA = 0x7FFFF80
    seg.endEA = 0x8000000
    idaapi.add_segm_ex(seg, "PROCID", "RAM", idaapi.ADDSEG_SPARSE)
    idaapi.add_entry(0, 0, "_start", True)
    # idc.AutoMark( 0, AU_CODE )
    idaapi.cvar.inf.tribyte_order = idaapi.tbo_213
    return 1
예제 #41
0
파일: xvldrida.py 프로젝트: comex/xap
def load_file(li, neflags, format):
    idaapi.set_processor_type('xap2csr', idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL)
    li.seek(0)
    lines = li.read(li.size()).split('\n')
    segs = {}
    for seg in ('code', 'data'):
        segs[seg] = {'chunks': [], 'syms': []}
    def handle_line(line):
        raise ValueError('got non-commented line before title: %r' % (line,))
    for line in lines:
        #print repr(line)
        line = line.strip()
        if not line:
            continue
        if not line.startswith('// '):
            line = re.sub('\s*//.*', '', line)
            handle_line(line)
            continue
        m = re.match('^// Title +: "(Code|Constant|Symbol) Table"', line)
        if not m:
            continue
        kind = m.group(1)
        if kind in ('Code', 'Constant'):
            chunks = segs['code' if kind == 'Code' else 'data']['chunks']
            if chunks != []:
                raise ValueError('more than one %s table in file' % (kind,))
            cur_addr_box = [None]
            cur_chunk_box = [None]
            def handle_line(line):
                m = re.match('^@([0-9A-Fa-f]+)\s+([0-9A-Fa-f]{4})$', line)
                if not m:
                    raise ValueError('unrecognized seg line: %r' % (line,))
                addr, word = [int(x, 16) for x in m.groups()]
                cur_addr, cur_chunk = cur_addr_box[0], cur_chunk_box[0]
                if cur_addr is None or addr > cur_addr:
                    cur_chunk = cur_chunk_box[0] = []
                    chunks.append((addr, cur_chunk))
                elif addr < cur_addr:
                    raise ValueError('going backwards with addresses (cur_addr=0x%x): %r' % (cur_addr, line,))
                cur_chunk.append(word)
                cur_addr_box[0] = addr + 1
        else:
            assert kind == 'Symbol'
            cur_syms_box = [None]
            def handle_line(line):
                if line in ('.CODE', '.DATA'):
                    cur_syms_box[0] = segs[line[1:].lower()]['syms']
                else:
                    m = re.match('^([^,]+), ([0-9a-fA-F]+)*$', line)
                    if not m:
                        raise ValueError('unknown symbol line: %r' % (line,))
                    cur_syms = cur_syms_box[0]
                    if cur_syms is None:
                        raise ValueError('symbols without a segment: %r' % (line,))
                    cur_syms.append((int(m.group(2), 16), m.group(1))) # (addr, name)
    for (segname, info) in segs.iteritems():
        kind = {'code': 0, 'data': 1}[segname]
        base_addr = (0, 0x1000000)[kind]
        if segname == 'code' and info['chunks'] == [] and info['syms'] == []:
            continue
        if not idaapi.set_selector(kind + 1, base_addr >> 4):
            raise Exception("couldn't set selector for segment %s" % (name,))
        for addr, chunk in info['chunks']:
            seg = idaapi.segment_t()
            seg.startEA = base_addr + addr
            seg.endEA = base_addr + addr + len(chunk)
            seg.bitness = 1 # 32-bit (we can have more than 16 bits of code, so just use for both)
            seg.sel = kind + 1
            name = '%s_%x' % (segname, addr)
            klass = segname.upper()
            #print '%s from %x to %x' % (name, seg.startEA, seg.endEA)
            if not idaapi.add_segm_ex(seg, name, klass, ADDSEG_NOSREG):
                raise Exception("couldn't add segment %s" % (name,))
            ea = seg.startEA
            for word in chunk:
                idaapi.put_byte(ea, word)
                ea += 1
            if segname == 'code':
                idaapi.autoMark(seg.startEA, AU_CODE)
        if segname == 'data':
            # fill in the remaining area with BSS
            spaces = zip([0] + [addr+len(chunk) for (addr, chunk) in info['chunks']],
                         [addr for (addr, chunk) in info['chunks']] + [0x10000])
            for start, end in spaces:
                if end - start < 0x10:
                    continue
                assert end > start
                seg = idaapi.segment_t()
                seg.startEA = base_addr + start
                seg.endEA = base_addr + end
                seg.bitness = 1
                seg.sel = kind + 1
                name = 'bss_%x' % (start,)
                #print '%s from %x to %x' % (name, seg.startEA, seg.endEA)
                if not idaapi.add_segm_ex(seg, name, 'BSS', idaapi.ADDSEG_SPARSE | ADDSEG_NOSREG):
                    raise Exception("couldn't add segment %s" % (name,))
    return 1
def new(offset, size, name, **kwds):
    """Create a segment at `offset` with `size` and name it according to `name`.

    The keyword `bits` can be used to specify the bit size of the segment
    The keyword `comb` can be used to specify any flags (idaapi.sc*)
    The keyword `align` can be used to specify paragraph alignment (idaapi.sa*)
    The keyword `org` specifies the origin of the segment (must be paragraph aligned due to ida)
    """
    res = utils.string.to(name)

    # find the segment according to the name specified by the user
    seg = idaapi.get_segm_by_name(res)
    if seg is not None:
        raise E.DuplicateItemError(
            u"{:s}.new({:#x}, {:+#x}, \"{:s}\"{:s}) : A segment with the specified name (\"{:s}\") already exists."
            .format(
                __name__, offset, size, utils.string.escape(name, '"'),
                u", {:s}".format(utils.string.kwargs(kwds)) if kwds else '',
                utils.string.escape(name, '"')))

    # FIXME: use disassembler default bit length instead of 32
    bits = kwds.get(
        'bits',
        32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).abits())

    ## create a selector with the requested origin
    if bits == 16:
        org = kwds.get('org', 0)
        if org & 0xf > 0:
            raise E.InvalidTypeOrValueError(
                u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : The specified origin ({:#x}) is not aligned to the size of a paragraph (0x10)."
                .format(
                    __name__, offset, size, name, u", {:s}".format(
                        utils.string.kwargs(kwds)) if kwds else '', org))

        para = offset // 16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel,
                            (para - kwds.get('org', 0) // 16) & 0xffffffff)

    ## if the user specified a selector, then use it
    elif 'sel' in kwds or 'selector' in kwds:
        sel = kwds.get('sel', kwds.get('selector',
                                       idaapi.find_free_selector()))

    ## choose the paragraph size defined by the user
    elif 'para' in kwds or 'paragraphs' in kwds:
        para = kwds.get('paragraph', kwds.get('para', 1))
        sel = idaapi.setup_selector(para)

    ## find a selector that is 1 paragraph size,
    elif idaapi.get_selector_qty():
        sel = idaapi.find_selector(1)

    # otherwise find a free one and set it.
    else:
        sel = idaapi.find_free_selector()
        idaapi.set_selector(sel, 1)

    # populate the segment_t for versions of IDA prior to 7.0
    if idaapi.__version__ < 7.0:
        seg = idaapi.segment_t()
        seg.startEA, seg.endEA = offset, offset + size

    # now for versions of IDA 7.0 and newer
    else:
        seg = idaapi.segment_t()
        seg.start_ea, seg.end_ea = offset, offset + size

    # assign the rest of the necessary attributes
    seg.sel = sel
    seg.bitness = {16: 0, 32: 1, 64: 2}[bits]
    seg.comb = kwds.get('comb', idaapi.scPub)  # public
    seg.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    # now we can add our segment_t to the database
    res = utils.string.to(name)
    ok = idaapi.add_segm_ex(seg, res, "",
                            idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_SPARSE)
    if not ok:
        ok = idaapi.del_selector(sel)
        if not ok:
            logging.warning(
                u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to delete the created selector ({:#x}) for the new segment."
                .format(
                    __name__, offset, size, name, u", {:s}".format(
                        utils.string.kwargs(kwds)) if kwds else '', sel))
        raise E.DisassemblerError(
            u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to add a new segment."
            .format(
                __name__, offset, size, name,
                u", {:s}".format(utils.string.kwargs(kwds)) if kwds else ''))
    return seg
예제 #43
0
def findAllKEXT():
	"""
	findAllKEXT:
	
	Finds all KEXT contained in the kernelcache file. The mach-o
	headers will be converted into the appropiate structs, the
	new sections will be defined and the name and version number
	of the KEXT are extracted. In the end a window is shown that
	shows all contained KEXT.
	"""
	
	# Ask the user if he wants to add all the KEXT sections
	# to the IDA database. 
	answer = idc.AskYN(0, """Do you want to add all the KEXT sections to the IDA database?
	
If this was already done before or there was already code or data in the same place in the IDA database, IDA might react very slow, crash or just stop to work.""")
	
	# KEXT cache starts behind the __LINKEDIT segment
	# NOTE: IDA calls the segment __LINKEDIT_hidden
	
	linkedit = idaapi.get_segm_by_name("__LINKEDIT_hidden")
	if not linkedit:
		print "[-] cannot find KEXTCACHE: __LINKEDIT segment not found"
		return
	kextcache = idaapi.get_next_seg(linkedit.endEA)
	if not kextcache:
		print "[-] cannot find KEXTCACHE: __LINKEDIT not followed by any segment"
		return
	
	dummyName = idaapi.get_segm_name(kextcache)
	if dummyName != "__text":
		print "[-] cannot find KEXTCACHE: __LINKEDIT not followed by __text segment"
		return
	
	if answer == 1:
		# Destroy everything in the kextcache area
		idaapi.do_unknown_range(kextcache.startEA, kextcache.endEA-kextcache.startEA, DOUNK_DELNAMES)
	
	startEA = kextcache.startEA
	kextlist = []
	while True:
		sig = idc.Dword(startEA)
		if sig != 0xfeedface:
			"[-] expected the next KEXT but did not find correct signature"
			break
		
		seg_lc = None
		
		sections = []
		added = 0
		
		next = forceStruct(startEA, "mach_header")
		ncmds = get_member_from_struct(startEA, "mach_header", "ncmds")
		for i in range(ncmds):
			lc_addr = next
			cmd = get_member_from_struct(next, "load_command", "cmd")
			if cmd == 1:
				seg_lc = next
				next = forceStruct(seg_lc, "segment_command")
				nsecs = get_member_from_struct(seg_lc, "segment_command", "nsects")
				for j in range(nsecs):
					section = next
					next = forceStruct(section, "section")
					
					# Get basic information about segment (needed for ALL the code below)
					secStart = get_member_from_struct(section, "section", "addr")
					secEnd = secStart + get_member_from_struct(section, "section", "size")
					secname = idc.GetString(section)
					
					# We should tell IDA about what this section is
					s = idaapi.segment_t()
					s.startEA	  = secStart
					s.endEA		  = secEnd
					s.sel		  = idaapi.setup_selector(0)
					if secname == "__text":
						s.bitness = 0
					else:
						s.bitness = 1
					s.align		  = get_member_from_struct(section, "section", "align")
					s.comb		  = 0 # ???
					
					if secname == "__text" or secname == "stubs":
						sclass = "CODE"
					elif secname == "__bss":
						sclass = "BSS"
					else:
						sclass = "DATA"
					
					if len(sections) == 0:
						sec = {}
						sec["name"] = "MACH-O HEADER"
						sec["start"] = "%08X" % (startEA)
						sec["end"] = "%08X" % (secStart-1)
						sections.append(sec)
					
					sec = {}
					sec["name"] = secname
					sec["start"] = "%08X" % (secStart)
					sec["end"] = "%08X" % (secEnd-1)
					sections.append(sec)
					
					if answer == 1:
						# Destroy everything inside the segment
						idaapi.do_unknown_range(secStart, secEnd-secStart, DOUNK_DELNAMES)
					
						# Ensure that the whole section is undefined
						idaapi.add_segm_ex(s, secname, sclass, idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_QUIET)
					
					if secname == "__text":
						idc.SetRegEx(secStart, "T", 1, 0)

					# special handling of constructor and destructor
					if secname == "__constructor" or secname == "__destructor":
						for z in range(secStart, secEnd, 4):
							idc.OpOffEx(z, -1, REF_OFF32, 0xFFFFFFFF, 0, 0)
					
					# We have to check for __data section because we want
					# to find the kmod_info structure
					if secname != "__data":
						continue
						
					kextName = None
					for z in range(secStart, secEnd, 4):
						k = z
						# We assume that all KEXT name start with "com."
						kextNameSig = idc.Dword(k)
						if kextNameSig == 0x2e6d6f63:
							forceStruct(k-12, "kmod_info")
							kextName = idc.GetString(k)
							kextVersion = idc.GetString(k+64)
							#print "-> %s - version: %s" % (kextName, kextVersion)
							
							dic = {}
							dic["addr"] = "%08X" % (startEA)
							dic["name"] = kextName
							dic["version"] = kextVersion
							kextlist.append(dic)
							added = 1
							break
					if kextName == None:
						print "ERROR COULD NOT FIND NAME"
					
			elif cmd == 0x1b:
				next = forceStruct(lc_addr, "uuid_command")
			elif cmd == 0x2:
				next = forceStruct(lc_addr, "symtab_command")
				#print "Found symbol table KEXT at %08x" % (startEA)
			else:
				print "Unknown load command %08x" % (cmd)
			
			if added:
				kextlist[len(kextlist)-1]["sections"] = sections
			
			next = lc_addr + get_member_from_struct(lc_addr, "load_command", "cmdsize")
		
		if seg_lc == None:
			startEA += 4
			while idc.Dword(startEA) != 0xfeedface:
				startEA += 4
			continue
		
		startEA = get_member_from_struct(seg_lc, "segment_command", "vmaddr")
		startEA += get_member_from_struct(seg_lc, "segment_command", "vmsize")

	c = MySelectionDialog("Retrieved KEXT", [ ["Address", 10], [ "Name", 65 ], ["Version", 65] ], formatKEXTresults(kextlist))
	selected_row = c.Show(True)
	if selected_row >= 0:
		sel = kextlist[selected_row]
		
		c = MySelectionDialog("Sections inside " + sel["name"], [ ["Name", 16], [ "Start", 10 ], ["End", 10] ], formatSECTIONresults(sel["sections"]))
		selected_row = c.Show(True)
		if selected_row >= 0:
			sel = sel["sections"][selected_row]
			
			idc.Jump(int(sel["start"], 16))