Ejemplo n.º 1
0
def getSymbolsList(sample, strs):
    endian = utils.getEndianFormat(sample)
    count = 0
    symbols = {}
    symbolsList = []
    step = 0
    desc = utils.getCommandInfos(sample, "LC_SYMTAB")
    baseStrAddr = desc.get("stroff")
    symAddress = desc.get("symoff")
    nsym = desc.get("nsyms")
    if utils.is64Bit(sample):
        step = 16
        utils.getPartOfFile(sample, symAddress, nsym * 16)
    else:
        step = 12
        utils.getPartOfFile(sample, symAddress, nsym * 12)
    os.rename("temp", "tmp")
    offset = 0
    while count < nsym:
        count += 1

        byte, data = ReadWrite.readInt32("tmp", endian, offset)
        offset += step
        value = strs.get(hex(baseStrAddr + data).rstrip("L"))
        if value is None:
            value = ""
        symbolsList.append(value)
    os.remove("tmp")
    return symbolsList
Ejemplo n.º 2
0
def createPointersNode(sample, section, symbolNames):
    endian = utils.getEndianFormat(sample)
    pointers = {}
    address = section.offset
    utils.getPartOfFile(sample, section.offset, section.size)
    offset = 0
    length = os.path.getsize("temp")
    os.rename("temp", "pointers")
    s = "->"
    sectionInfos = utils.getSectionInfoMaps(sample)
    while offset < length:
        byte, ptr = ReadWrite.readInt32("pointers", endian, offset)
        offset += byte

        if section.sectname.rstrip('\x00') == "__objc_selrefs":
            symbolName = symbolNames.get(hex(ptr).rstrip("L"))
            if symbolName == None:
                pointers[hex(address).rstrip("L")] = hex(ptr)
            else:
                seq = (hex(ptr), symbolName)
                pointers[hex(address).rstrip("L")] = s.join(seq)
        else:
            pointers[hex(address).rstrip("L")] = hex(ptr)

        address += byte

    os.remove("pointers")
    pointers = collections.OrderedDict(sorted(pointers.items()))
    return pointers
Ejemplo n.º 3
0
def createLiteralsNode(sample, section, stride):
    endian = utils.getEndianFormat(sample)
    literals = {}
    address = section.offset
    getPartOfFile(sample, section.offset, section.size)
    offset = 0
    length = os.path.getsize("temp")
    while offset < length:
        byte, data = ReadWrite.readInt8("temp", endian, offset)
        offset += byte
        literalStr = ""
        if stride == 4:
            literalStr = float(data)

        elif stride == 8:
            literalStr = double(data)
        else:
            literalStr = long(data)

        literals[hex(address).rstrip("L")] = literalStr
        address += byte

    os.remove("temp")
    literals = collections.OrderedDict(sorted(literals.items()))
    return literals
Ejemplo n.º 4
0
def getISymbols(sample):
    endian = utils.getEndianFormat(sample)
    symbols = utils.getSymbolStrs(sample)
    symbolsList = getSymbolsList(sample, symbols)
    sections = utils.getSections(sample)
    is64 = utils.is64Bit(sample)
    count = 0
    inSymbols = {}
    offset = 0
    desc = utils.getCommandInfos(sample, "LC_DYSYMTAB")
    inSymAddress = desc.get("indirectsymoff")
    nSymbol = desc.get("nindirectsyms")
    utils.getPartOfFile(sample, inSymAddress, nSymbol * 4)
    os.rename("temp", "tmp")
    while count < nSymbol:
        nsect = len(sections)
        while nsect > 0:
            nsect -= 1
            section = sections[nsect]
            flag = section.flags
            #             print(section.reserved1)
            if (flag & SECTION_TYPE != S_SYMBOL_STUBS \
            and flag & SECTION_TYPE != S_LAZY_SYMBOL_POINTERS \
            and flag & SECTION_TYPE != S_LAZY_DYLIB_SYMBOL_POINTERS \
            and flag & SECTION_TYPE != S_NON_LAZY_SYMBOL_POINTERS) \
            or section.reserved1 > count:
                #section type or indirect symbol index mismatch
                continue

            nsect = 0
            #calculate stub or pointer length
            if section.reserved2 > 0:
                length = section.reserved2
            else:
                if is64:
                    length = 8
                else:
                    length = 4

            #calculate indirect value location
            indirectOffset = section.offset + (count -
                                               section.reserved1) * length

            #read indirect symbol index
            byte, indirectIndex = ReadWrite.readInt32("tmp", endian, offset)
            offset += byte

            if indirectIndex & (INDIRECT_SYMBOL_LOCAL
                                | INDIRECT_SYMBOL_ABS) == 0:
                if indirectIndex >= len(symbolsList):
                    raise Exception("index is out of range " +
                                    str(indirectIndex))
                symbolName = utils.getSymbolByIndex(symbolsList, indirectIndex)
                inSymbols[hex(indirectOffset).rstrip("L")] = symbolName

        count += 1
    os.remove("tmp")
    return inSymbols
Ejemplo n.º 5
0
def createIndPointers64Node(sample, section, inSymbols):
    endian = utils.getEndianFormat(sample)
    pointers = {}
    offset = 0
    addr = section.offset
    utils.getPartOfFile(sample, addr, section.size)
    while offset < section.size:
        byte, data = ReadWrite.readInt64("temp", endian, offset)
        offset += byte

        symbolName = inSymbols.get(hex(addr).rstrip("L"))
        if symbolName is None:
            symbolName = hex(data).rstrip("L")
        pointers[hex(addr).rstrip("L")] = symbolName

        addr += byte
    os.remove("temp")
    pointers = collections.OrderedDict(sorted(pointers.items()))
    return pointers
Ejemplo n.º 6
0
def getFunctionNames(sample, strs):
    endian = utils.getEndianFormat(sample)
    sectionInfos = utils.getSectionInfoMaps(sample)
    desc = utils.getCommandInfos(sample, "LC_SYMTAB")
    baseStrAddr = desc.get("stroff")
    symAddress = desc.get("symoff")
    nsym = desc.get("nsyms")
    if utils.is64Bit(sample):
        step = 16
        utils.getPartOfFile(sample, symAddress, nsym * 16)
    else:
        step = 12
        utils.getPartOfFile(sample, symAddress, nsym * 12)
    os.rename("temp", "tmp")
    count = 0
    names = {}
    offset = 0
    is64 = utils.is64Bit(sample)
    while count < nsym:
        count += 1

        byte, data = ReadWrite.readInt32("tmp", endian, offset)
        offset += 8
        value = strs.get(hex(baseStrAddr + data).rstrip("L"))
        if value is None:
            continue

        if is64:
            byte, n_value = ReadWrite.readInt64("tmp", endian, offset)
        else:
            byte, n_value = ReadWrite.readInt32("tmp", endian, offset)
        offset += byte
        key = utils.addressToFileOffset(sample, sectionInfos, n_value)
        names[hex(key)] = value
    os.remove("tmp")
    return names
Ejemplo n.º 7
0
def getClassSymbols(sample):
    endian = utils.getEndianFormat(sample)
    strs = utils.getSymbolStrs(sample)
    desc = utils.getCommandInfos(sample, "LC_SYMTAB")
    baseStrAddr = desc.get("stroff")
    symAddress = desc.get("symoff")
    nsym = desc.get("nsyms")
    is64 = utils.is64Bit(sample)
    if is64:
        utils.getPartOfFile(sample, symAddress, nsym * 16)
    else:
        utils.getPartOfFile(sample, symAddress, nsym * 12)
    count = 0
    classSymbols = {}
    offset = 0
    while count < nsym:
        count += 1

        byte, data = ReadWrite.readInt32("temp", endian, offset)
        offset += byte
        description = "String Table Index"
        value = strs.get(hex(baseStrAddr + data).rstrip("L"))
        if value is None:
            value = ""

        offset += 4

        if is64:
            byte, n_value = ReadWrite.readInt64("temp", endian, offset)
        else:
            byte, n_value = ReadWrite.readInt32("temp", endian, offset)
        offset += byte
        classSymbols[hex(n_value).rstrip("L")] = value

    classSymbols = collections.OrderedDict(sorted(classSymbols.items()))
    return classSymbols
Ejemplo n.º 8
0
def createISymbolsNode(sample, symbolsList, path, baseAddr, nindsym):
    endian = utils.getEndianFormat(sample)
    sections = utils.getSections(sample)
    is64 = utils.is64Bit(sample)
    count = 0
    inSymbols = {}
    addr = baseAddr
    offset = 0

    while count < nindsym:
        desc = []
        nsect = len(sections)
        while nsect > 0:
            nsect -= 1
            section = sections[nsect]
            flag = section.flags
            #             print(section.reserved1)
            if (flag & SECTION_TYPE != S_SYMBOL_STUBS \
            and flag & SECTION_TYPE != S_LAZY_SYMBOL_POINTERS \
            and flag & SECTION_TYPE != S_LAZY_DYLIB_SYMBOL_POINTERS \
            and flag & SECTION_TYPE != S_NON_LAZY_SYMBOL_POINTERS) \
            or section.reserved1 > count:
                #section type or indirect symbol index mismatch
                continue

            nsect = 0
            #calculate stub or pointer length
            if section.reserved2 > 0:
                length = section.reserved2
            else:
                if is64:
                    length = 8
                else:
                    length = 4

            #calculate indirect value location
            indirectOffset = section.offset + (count -
                                               section.reserved1) * length

            #read indirect symbol index
            byte, indirectIndex = ReadWrite.readInt32(path, endian, offset)
            offset += byte

            if indirectIndex & (INDIRECT_SYMBOL_LOCAL
                                | INDIRECT_SYMBOL_ABS) == 0:
                if indirectIndex >= len(symbolsList):
                    raise Exception("index is out of range " +
                                    str(indirectIndex))
                symbolName = utils.getSymbolByIndex(symbolsList, indirectIndex)
                description = "Symbol"
                value = symbolName
                desc.append(utils.getDict(description, value))
            else:
                description = "Symbol"
                value = []

                if indirectIndex == INDIRECT_SYMBOL_LOCAL:
                    value.append("80000000  INDIRECT_SYMBOL_LOCAL")
                elif indirectIndex == INDIRECT_SYMBOL_ABS:
                    value.append("40000000  INDIRECT_SYMBOL_ABS")
                else:
                    value.append("80000000  INDIRECT_SYMBOL_LOCAL")
                    value.append("40000000  INDIRECT_SYMBOL_ABS")
                desc.append(utils.getDict(description, value))

            description = "Section"
            value = "(" + section.segname.rstrip(
                '\x00') + "," + section.sectname.rstrip('\x00') + ")"
            desc.append(utils.getDict(description, value))

            description = "Indirect Address"
            value = hex(indirectOffset).rstrip("L") + "($+" + str(
                indirectOffset - section.offset) + ")"
            desc.append(utils.getDict(description, value))
            inSymbols[hex(addr)] = desc
            addr += byte

        count += 1

    inSymbols = collections.OrderedDict(sorted(inSymbols.items()))
    return inSymbols
Ejemplo n.º 9
0
def createSymbolsNode(sample, strs, path, baseAddr, baseStrAddr, nsym):
    endian = utils.getEndianFormat(sample)
    frameworks = utils.getAllFrameworks(sample)
    sections = utils.getSections(sample)
    count = 0
    symbols = {}
    addr = baseAddr
    offset = 0
    while count < nsym:
        count += 1
        byte, data = ReadWrite.readInt32(path, endian, offset)
        offset += byte
        description = "String Table Index"
        value = strs.get(hex(baseStrAddr + data).rstrip("L"))
        if value is None:
            value = ""
        symbols[hex(addr)] = utils.getDict(description, value)
        addr += byte

        byte, n_type = ReadWrite.readInt8(path, endian, offset)
        offset += byte
        types = []
        description = "Type"

        if n_type & N_STAB:
            types.append("E0  N_STAB")
        else:
            if n_type & N_TYPE == N_UNDF:
                types.append("00  N_UNDF")
            elif n_type & N_TYPE == N_ABS:
                types.append("02  N_ABS")
            elif n_type & N_TYPE == N_SECT:
                types.append("0E  N_SECT")
            elif n_type & N_TYPE == N_PBUD:
                types.append("0C  N_PBUD")
            elif n_type & N_TYPE == N_INDR:
                types.append("0A  N_INDR")

            if n_type & N_PEXT:
                types.append("10  N_PEXT")
            if n_type & N_EXT:
                types.append("01  N_EXT")

        symbols[hex(addr)] = utils.getDict(description, types)
        addr += byte

        byte, n_sect = ReadWrite.readInt8(path, endian, offset)
        offset += byte
        section = utils.getSectionByIndex(sections, n_sect)
        description = "Section Index"
        if n_sect == NO_SECT or section is None:
            value = "NO_SECT"
        else:
            value = str(n_sect) + "(" + section.segname.rstrip(
                '\x00') + "," + section.sectname.rstrip('\x00') + ")"
        symbols[hex(addr)] = utils.getDict(description, value)
        addr += byte

        byte, n_desc = ReadWrite.readInt16(path, endian, offset)
        offset += byte
        descriptions = []
        description = "Description"

        if n_type & N_STAB == 0 and n_type & N_TYPE == N_UNDF or n_type & N_TYPE == N_PBUD and n_type & N_EXT:
            if n_desc & REFERENCE_TYPE == REFERENCE_FLAG_UNDEFINED_NON_LAZY:
                descriptions.append("0  REFERENCE_FLAG_UNDEFINED_NON_LAZY")
            elif n_desc & REFERENCE_TYPE == REFERENCE_FLAG_UNDEFINED_LAZY:
                descriptions.append("1  REFERENCE_FLAG_UNDEFINED_LAZY")
            elif n_desc & REFERENCE_TYPE == REFERENCE_FLAG_DEFINED:
                descriptions.append("2  REFERENCE_FLAG_DEFINED")
            elif n_desc & REFERENCE_TYPE == REFERENCE_FLAG_PRIVATE_DEFINED:
                descriptions.append("3  REFERENCE_FLAG_PRIVATE_DEFINED")
            elif n_desc & REFERENCE_TYPE == REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY:
                descriptions.append(
                    "4  REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY")
            elif n_desc & REFERENCE_TYPE == REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY:
                descriptions.append("5  REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY")
            else:
                descriptions.append(n_desc & REFERENCE_TYPE, "???")

            libOrdinal = get_library_ordinal(n_desc)
            framework = frameworks.get(libOrdinal)
            if framework is None:
                descriptions.append("Library Ordinal " + str(libOrdinal))
            else:
                descriptions.append("Library Ordinal " + str(libOrdinal) +
                                    "(" + framework + ")")

        if n_desc & N_ARM_THUMB_DEF == N_ARM_THUMB_DEF:
            descriptions.append("0008  N_ARM_THUMB_DEF")
        if n_desc & REFERENCED_DYNAMICALLY == REFERENCED_DYNAMICALLY:
            descriptions.append("0010  REFERENCED_DYNAMICALLY")
        if n_desc & N_NO_DEAD_STRIP == N_NO_DEAD_STRIP:
            descriptions.append("0020  N_NO_DEAD_STRIP")
        if n_desc & N_WEAK_REF == N_WEAK_REF:
            descriptions.append("0040  N_WEAK_REF")
        if n_type & N_TYPE == N_UNDF:
            if n_desc & N_REF_TO_WEAK == N_REF_TO_WEAK:
                descriptions.append("0080  N_REF_TO_WEAK")
        else:
            if n_desc & N_WEAK_DEF == N_WEAK_DEF:
                descriptions.append("0080  N_WEAK_DEF")
            if n_desc & N_SYMBOL_RESOLVER == N_SYMBOL_RESOLVER:
                descriptions.append("0100  N_SYMBOL_RESOLVER")
        symbols[hex(addr)] = utils.getDict(description, descriptions)
        addr += byte

        byte, n_value = ReadWrite.readInt32(path, endian, offset)
        offset += byte
        if n_type & N_TYPE == N_SECT:
            description = "Value"
            if n_type & N_STAB or section is None:
                if n_value == 0:
                    value = "0"
                else:
                    value = n_value
            else:
                value = str(n_value) + "(s+" + str(n_value -
                                                   section.addr) + ")"
        else:
            description = "Value"
            value = n_value
        symbols[hex(addr)] = utils.getDict(description, value)
        addr += byte

    symbols = collections.OrderedDict(sorted(symbols.items()))
    return symbols
Ejemplo n.º 10
0
def printSymbols(filePath, path, baseAddr):
    endian = utils.getEndianFormat(filePath)
    length = os.path.getsize(path)
    opcodes = {}
    offset = 0
    addr = baseAddr
    while offset < length:
        byte, terminalSize = ReadWrite.readInt8(path, endian, offset)
        offset += byte

        description = "Terminal Size"
        value = str(terminalSize)
        opcodes[hex(addr)] = utils.getDict(description, value)
        addr += byte

        if terminalSize != 0 and offset < length:
            byte, flags = ReadWrite.read_uleb128(path, offset)
            offset += byte
            value = []

            if (flags & EXPORT_SYMBOL_FLAGS_KIND_MASK
                ) == EXPORT_SYMBOL_FLAGS_KIND_REGULAR:
                value.append("00  EXPORT_SYMBOL_FLAGS_KIND_REGULAR")
            if (flags & EXPORT_SYMBOL_FLAGS_KIND_MASK
                ) == EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL:
                value.append("01  EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL")
            if flags & EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION:
                value.append("04  EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION")
            if flags & EXPORT_SYMBOL_FLAGS_REEXPORT:
                value.append("08  EXPORT_SYMBOL_FLAGS_REEXPORT")
            if flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER:
                value.append("10  EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER")
            description = "Flags"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break

            byte, offsets = ReadWrite.read_uleb128(path, offset)
            offset += byte
            description = "Symbol Offset"
            value = hex(offsets)
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

        if offset >= length:
            break
        byte, childCount = ReadWrite.readInt8(path, endian, offset)
        offset += byte

        if terminalSize == 0 and childCount == 0:
            break

        description = "Child Count"
        value = str(childCount)
        opcodes[hex(addr)] = utils.getDict(description, value)
        addr += byte

        while childCount > 0 and offset < length:
            byte, label = ReadWrite.readString(path, offset)
            offset += byte
            description = "Node Label"
            value = label
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            byte, skip = ReadWrite.read_uleb128(path, offset)
            offset += byte
            description = "Next Node"
            value = hex(baseAddr + skip)
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            childCount -= 1

    return opcodes
Ejemplo n.º 11
0
def createBindingNode(filePath, path, baseAddr):
    endian = utils.getEndianFormat(filePath)
    length = os.path.getsize(path)
    opcodes = {}
    offset = 0
    addr = baseAddr
    while offset < length:
        byte, data = ReadWrite.readInt8(path, endian, offset)
        offset += byte

        opcode = data & BIND_OPCODE_MASK
        immediate = data & BIND_IMMEDIATE_MASK

        if opcode == BIND_OPCODE_DONE:
            description = "BIND_OPCODE_DONE"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

        elif opcode == BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
            libOrdinal = immediate
            description = "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM"
            value = "dylib (" + str(libOrdinal) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

        elif opcode == BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
            description = "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, libOrdinal = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "dylib (" + str(libOrdinal) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        elif opcode == BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:

            #Special means negative
            if immediate == 0:
                libOrdinal = 0
            else:
                signExtended = immediate | BIND_OPCODE_MASK  #This sign extends the value
                libOrdinal = signExtended

            description = "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM"
            value = "dylib (" + str(libOrdinal) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

        elif opcode == BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
            symbolFlags = immediate
            description = "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM"
            value = "flags (" + str(symbolFlags) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, symbolName = ReadWrite.readString(path, offset)
            offset += newByte
            description = "string"
            value = "name (" + symbolName + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        elif opcode == BIND_OPCODE_SET_TYPE_IMM:
            typeValue = immediate
            description = "BIND_OPCODE_SET_TYPE_IMM"
            typeString = ""
            if typeValue == BIND_TYPE_POINTER:
                typeString = "BIND_TYPE_POINTER"
            elif typeValue == BIND_TYPE_TEXT_ABSOLUTE32:
                typeString = "BIND_TYPE_TEXT_ABSOLUTE32"
            elif typeValue == BIND_TYPE_TEXT_PCREL32:
                typeString = "BIND_TYPE_TEXT_PCREL32"
            else:
                typeString = "???"
            value = "type (" + typeString + ")"
            opcodes[hex(addr)] = utils.getDict(description, typeString)
            addr += byte
        elif opcode == BIND_OPCODE_SET_ADDEND_SLEB:
            description = "BIND_OPCODE_SET_ADDEND_SLEB"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, addend = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "sleb128"
            value = "addend (" + str(addend) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        elif opcode == BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
            segmentIndex = immediate
            description = "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB"
            value = "segment (" + str(segmentIndex) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, val = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "offset (" + str(val) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        elif opcode == BIND_OPCODE_ADD_ADDR_ULEB:
            description = "BIND_OPCODE_ADD_ADDR_ULEB"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, val = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "offset (" + str(val) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        elif opcode == BIND_OPCODE_DO_BIND:
            description = "BIND_OPCODE_DO_BIND"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

        elif opcode == BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
            description = "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, val = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "offset (" + str(val) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        elif opcode == BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
            scale = immediate
            description = "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED"
            value = "scale (" + str(scale) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

        elif opcode == BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
            description = "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, count = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "count (" + str(count) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

            if offset >= length:
                break
            newByte, skip = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "skip (" + str(skip) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        else:
            addr += byte

    return opcodes
Ejemplo n.º 12
0
def createRebaseNode(sample, path, baseAddr):
    endian = utils.getEndianFormat(sample)
    length = os.path.getsize(path)
    opcodes = {}
    actions = []
    offset = 0
    addr = baseAddr
    address = 0
    scale = 0
    typeValue = 0
    while offset < length:
        byte, data = ReadWrite.readInt8(path, endian, offset)
        offset += byte

        opcode = data & REBASE_OPCODE_MASK
        immediate = data & REBASE_IMMEDIATE_MASK

        if opcode == REBASE_OPCODE_DONE:
            description = "REBASE_OPCODE_DONE"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte
        elif opcode == REBASE_OPCODE_SET_TYPE_IMM:
            typeValue = immediate
            typeString = ""
            if typeValue == REBASE_TYPE_POINTER:
                typeString = "REBASE_TYPE_POINTER"
            elif typeValue == REBASE_TYPE_TEXT_ABSOLUTE32:
                typeString = "REBASE_TYPE_TEXT_ABSOLUTE32"
            elif typeValue == REBASE_TYPE_TEXT_PCREL32:
                typeString = "REBASE_TYPE_TEXT_PCREL32"
            else:
                typeString = "Unknown"

            description = "REBASE_OPCODE_SET_TYPE_IMM"
            value = "type (" + str(typeValue) + "," + typeString + ")"

            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

        elif opcode == REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
            segmentIndex = immediate
            description = "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB"
            value = "segment (" + str(segmentIndex) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, newData = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "offset (" + str(newData) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

            segments = utils.getSegments(sample)
            if segmentIndex > len(segments):
                raise Exception("index is out of range " + str(segmentIndex))

        elif opcode == REBASE_OPCODE_ADD_ADDR_ULEB:
            description = "REBASE_OPCODE_ADD_ADDR_ULEB"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, newData = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "offset (" + str(newData) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        elif opcode == REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
            scale = immediate
            description = "REBASE_OPCODE_ADD_ADDR_IMM_SCALED"
            value = "scale (" + str(scale) + ")"
            opcodes[hex(addr)] = utils.getDict(description, "")
            addr += byte

        elif opcode == REBASE_OPCODE_DO_REBASE_IMM_TIMES:
            count = immediate
            description = "REBASE_OPCODE_DO_REBASE_IMM_TIMES"
            value = "count (" + str(count) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

        elif opcode == REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
            description = "REBASE_OPCODE_DO_REBASE_ULEB_TIMES"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, newData = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "count (" + str(newData) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        elif opcode == REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
            description = "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, newData = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "offset (" + str(newData) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        elif opcode == REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
            description = "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB"
            value = ""
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += byte

            if offset >= length:
                break
            newByte, newData = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "count (" + str(newData) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

            if offset >= length:
                break
            newByte, skip = ReadWrite.read_uleb128(path, offset)
            offset += newByte
            description = "uleb128"
            value = "skip (" + str(skip) + ")"
            opcodes[hex(addr)] = utils.getDict(description, value)
            addr += newByte

        else:
            addr += byte

    return opcodes