update to ida 7.6, add builds
This commit is contained in:
218
idasdk76/ldr/script_ldrs/uimage.py
Normal file
218
idasdk76/ldr/script_ldrs/uimage.py
Normal file
@@ -0,0 +1,218 @@
|
||||
# a file loader for U-Boot "uImage" flash images
|
||||
# Copyright (c) 2011-2021 Hex-Rays
|
||||
# ALL RIGHTS RESERVED.
|
||||
|
||||
import idaapi
|
||||
import idc
|
||||
import zlib
|
||||
import ida_idp
|
||||
import ida_typeinf
|
||||
|
||||
IH_TYPE_INVALID = 0 # /* Invalid Image */
|
||||
IH_TYPE_STANDALONE = 1 # /* Standalone Program */
|
||||
IH_TYPE_KERNEL = 2 # /* OS Kernel Image */
|
||||
IH_TYPE_RAMDISK = 3 # /* RAMDisk Image */
|
||||
IH_TYPE_MULTI = 4 # /* Multi-File Image */
|
||||
IH_TYPE_FIRMWARE = 5 # /* Firmware Image */
|
||||
IH_TYPE_SCRIPT = 6 # /* Script file */
|
||||
IH_TYPE_FILESYSTEM = 7 # /* Filesystem Image (any type) */
|
||||
|
||||
ImageTypeNames = [ "Invalid", "Standalone Program", "OS Kernel", "RAMDisk",
|
||||
"Multi-File", "Firmware", "Script file", "Filesystem" ]
|
||||
|
||||
IH_ARCH_INVALID = 0 # /* Invalid CPU */
|
||||
IH_ARCH_ALPHA = 1 # /* Alpha */
|
||||
IH_ARCH_ARM = 2 # /* ARM */
|
||||
IH_ARCH_I386 = 3 # /* Intel x86 */
|
||||
IH_ARCH_IA64 = 4 # /* IA64 */
|
||||
IH_ARCH_MIPS = 5 # /* MIPS */
|
||||
IH_ARCH_MIPS64 = 6 # /* MIPS 64 Bit */
|
||||
IH_ARCH_PPC = 7 # /* PowerPC */
|
||||
IH_ARCH_S390 = 8 # /* IBM S390 */
|
||||
IH_ARCH_SH = 9 # /* SuperH */
|
||||
IH_ARCH_SPARC = 10 # /* Sparc */
|
||||
IH_ARCH_SPARC64 = 11 # /* Sparc 64 Bit */
|
||||
IH_ARCH_M68K = 12 # /* M68K */
|
||||
IH_ARCH_NIOS = 13 # /* Nios-32 */
|
||||
IH_ARCH_MICROBLAZE = 14 # /* MicroBlaze */
|
||||
IH_ARCH_NIOS2 = 15 # /* Nios-II */
|
||||
IH_ARCH_BLACKFIN = 16 # /* */
|
||||
IH_ARCH_AVR32 = 17 # /* */
|
||||
IH_ARCH_ST200 = 18 # /* */
|
||||
IH_ARCH_SANDBOX = 19 # /* */
|
||||
IH_ARCH_NDS32 = 20 # /* */
|
||||
IH_ARCH_OPENRISC = 21 # /* */
|
||||
IH_ARCH_ARM64 = 22 # /* */
|
||||
IH_ARCH_ARC = 23 # /* */
|
||||
|
||||
CPUNames = [ "Invalid", "Alpha", "ARM", "x86", "IA64", "MIPS", "MIPS64", "PowerPC",
|
||||
"IBM S390", "SuperH", "Sparc", "Sparc64", "M68K", "Nios-32", "MicroBlaze", "Nios-II",
|
||||
"Blackfin", "AVR32", "ST200","Sandbox","NDS32", "OpenRISC", "ARM64", "ARC" ]
|
||||
|
||||
IDACPUNames = { IH_ARCH_ALPHA: "alphab",
|
||||
IH_ARCH_ARM:"ARM",
|
||||
IH_ARCH_I386: "metapc",
|
||||
IH_ARCH_IA64: "ia64b",
|
||||
IH_ARCH_MIPS:"mipsl",
|
||||
IH_ARCH_MIPS64:"mipsl",
|
||||
IH_ARCH_PPC: "ppc",
|
||||
IH_ARCH_SH: "SH4",
|
||||
IH_ARCH_SPARC: "sparcb",
|
||||
IH_ARCH_SPARC64:"sparcb",
|
||||
IH_ARCH_M68K:"68K",
|
||||
IH_ARCH_ARM64:"ARM",
|
||||
IH_ARCH_ARC: "arcmpct" }
|
||||
|
||||
IDAABINames = { IH_ARCH_MIPS:"n32",
|
||||
IH_ARCH_MIPS64:"n64" }
|
||||
|
||||
IH_COMP_NONE = 0 # /* No Compression Used */
|
||||
IH_COMP_GZIP = 1 # /* gzip Compression Used */
|
||||
IH_COMP_BZIP2 = 2 # /* bzip2 Compression Used */
|
||||
IH_COMP_LZMA = 3 # /* lzma Compression Used */
|
||||
IH_COMP_LZO = 4 # /* lzo Compression Used */
|
||||
CompTypeNames = [ "", "gzip", "bzip2", "lzma", "lzo" ]
|
||||
|
||||
IH_MAGIC = 0x27051956 # Image Magic Number
|
||||
IH_NMLEN = 32 # Image Name Length
|
||||
|
||||
import ctypes
|
||||
|
||||
uint8_t = ctypes.c_byte
|
||||
uint32_t = ctypes.c_uint
|
||||
|
||||
class image_header(ctypes.BigEndianStructure):
|
||||
_fields_ = [
|
||||
("ih_magic", uint32_t), # Image Header Magic Number
|
||||
("ih_hcrc", uint32_t), # Image Header CRC Checksum
|
||||
("ih_time", uint32_t), # Image Creation Timestamp
|
||||
("ih_size", uint32_t), # Image Data Size
|
||||
("ih_load", uint32_t), # Data Load Address
|
||||
("ih_ep", uint32_t), # Entry Point Address
|
||||
("ih_dcrc", uint32_t), # Image Data CRC Checksum
|
||||
("ih_os", uint8_t), # Operating System
|
||||
("ih_arch", uint8_t), # CPU architecture
|
||||
("ih_type", uint8_t), # Image Type
|
||||
("ih_comp", uint8_t), # Compression Type
|
||||
("ih_name", uint8_t * IH_NMLEN), # Image Name
|
||||
]
|
||||
RomFormatName = "U-Boot image"
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
def dwordAt(li, off):
|
||||
li.seek(off)
|
||||
s = li.read(4)
|
||||
if len(s) < 4:
|
||||
return 0
|
||||
return struct.unpack('<I', s)[0]
|
||||
|
||||
def read_struct(li, struct):
|
||||
s = struct()
|
||||
s.ih_magic = 0
|
||||
slen = ctypes.sizeof(s)
|
||||
if li.size() >= slen:
|
||||
bytes = li.read(slen)
|
||||
fit = min(len(bytes), slen)
|
||||
ctypes.memmove(ctypes.addressof(s), bytes, fit)
|
||||
return s
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
def accept_file(li, filename):
|
||||
"""
|
||||
Check if the file is of supported format
|
||||
|
||||
@param li: a file-like object which can be used to access the input data
|
||||
@param filename: name of the file, if it is an archive member name then the actual file doesn't exist
|
||||
@return: 0 - no more supported formats
|
||||
string "name" - format name to display in the chooser dialog
|
||||
dictionary { 'format': "name", 'options': integer }
|
||||
options: should be 1, possibly ORed with ACCEPT_FIRST (0x8000)
|
||||
to indicate preferred format
|
||||
"""
|
||||
|
||||
header = read_struct(li, image_header)
|
||||
# check the signature
|
||||
if header.ih_magic == IH_MAGIC:
|
||||
# accept the file
|
||||
t = header.ih_type
|
||||
c = header.ih_arch
|
||||
if t >= len(ImageTypeNames):
|
||||
t = "unknown type(%d)" % t
|
||||
else:
|
||||
t = ImageTypeNames[t]
|
||||
|
||||
if c >= len(CPUNames):
|
||||
cname = "unknown CPU(%d)" % c
|
||||
else:
|
||||
cname = CPUNames[c]
|
||||
|
||||
fmt = "%s (%s for %s)" % (RomFormatName, t, cname)
|
||||
comp = header.ih_comp
|
||||
if comp != IH_COMP_NONE:
|
||||
if comp >= len (CompTypeNames):
|
||||
cmpname = "unknown compression(%d)"
|
||||
else:
|
||||
cmpname = "%s compressed" % CompTypeNames[comp]
|
||||
fmt += " [%s]" % cmpname
|
||||
|
||||
proc = ''
|
||||
if c in IDACPUNames:
|
||||
proc = IDACPUNames[c]
|
||||
|
||||
return {'format': fmt, 'processor': proc}
|
||||
|
||||
# unrecognized format
|
||||
return 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.startswith(RomFormatName):
|
||||
li.seek(0)
|
||||
header = read_struct(li, image_header)
|
||||
c = header.ih_arch
|
||||
cname = IDACPUNames.get(c)
|
||||
if not cname:
|
||||
idc.warning("Unsupported CPU")
|
||||
#return
|
||||
|
||||
if not header.ih_comp in (IH_COMP_NONE, IH_COMP_GZIP):
|
||||
idc.warning("Can only handle uncompressed or gzip-compressed images")
|
||||
return
|
||||
|
||||
if cname:
|
||||
idaapi.set_processor_type(cname, ida_idp.SETPROC_LOADER)
|
||||
|
||||
idc.AddSeg(header.ih_load, header.ih_load + header.ih_size, 0, 1, idaapi.saRelPara, idaapi.scPub)
|
||||
|
||||
# copy bytes to the database
|
||||
|
||||
if header.ih_comp == IH_COMP_NONE:
|
||||
li.file2base(ctypes.sizeof(header), header.ih_load, header.ih_load + header.ih_size, 0)
|
||||
else:
|
||||
cdata = li.read(header.ih_size)
|
||||
d = zlib.decompressobj(zlib.MAX_WBITS|32)
|
||||
udata = d.decompress(cdata)
|
||||
udata += d.flush()
|
||||
# expand segment to fit uncompressed data
|
||||
idc.set_segment_bounds(header.ih_load, header.ih_load, header.ih_load+len(udata), idc.SEGMOD_KEEP)
|
||||
idaapi.put_bytes(header.ih_load, udata)
|
||||
|
||||
if cname == "ARM" and (header.ih_ep & 1) != 0:
|
||||
# Thumb entry point
|
||||
header.ih_ep -= 1
|
||||
split_sreg_range(header.ih_ep, "T", 1)
|
||||
idaapi.add_entry(header.ih_ep, header.ih_ep, "start", 1)
|
||||
aname = IDAABINames.get(header.ih_arch)
|
||||
if aname:
|
||||
ida_typeinf.set_abi_name(aname)
|
||||
print("Load OK")
|
||||
return 1
|
||||
Reference in New Issue
Block a user