- Implements application tracing module which allows to send arbitrary data to host over JTAG. This feature is useful for analyzing program modules behavior, dumping run-time application data etc. - Implements printf-like logging functions on top of apptrace module. This feature is a kind of semihosted printf functionality with lower overhead and impact on system behaviour as compared to standard printf.
216 lines
5.2 KiB
Python
216 lines
5.2 KiB
Python
import sys
|
|
import os
|
|
from .. import *
|
|
from ..constants import *
|
|
from ..types import *
|
|
from ..util import *
|
|
from ctypes import *
|
|
|
|
def sections(elf, **kwargs):
|
|
i = None
|
|
ndx = 0 # we skip the first null section
|
|
if 'info' in kwargs:
|
|
if (isinstance(kwargs['info'], Elf_Scn)):
|
|
info = elf_ndxscn(kwargs['info'])
|
|
else:
|
|
info = kwargs['info']
|
|
else:
|
|
info = None
|
|
while 1:
|
|
i = elf_nextscn(elf, i)
|
|
ndx += 1
|
|
|
|
if (not bool(i)):
|
|
break
|
|
|
|
try:
|
|
if ('name' in kwargs and section_name(elf, i) != kwargs['name']):
|
|
continue
|
|
|
|
if ('type' in kwargs and section_type(elf, i) != kwargs['type']):
|
|
continue
|
|
|
|
if ('link' in kwargs and section_link(elf, i) != kwargs['link']):
|
|
continue
|
|
|
|
if (info != None and section_hdr(elf, i).sh_info != info):
|
|
continue
|
|
except ValueError:
|
|
print "Error iterating over section ", i
|
|
continue
|
|
|
|
if ('ndx' in kwargs and kwargs['ndx']):
|
|
yield (ndx, i.contents)
|
|
else:
|
|
yield i.contents
|
|
|
|
|
|
def shdrs(elf):
|
|
i = None
|
|
while 1:
|
|
i = elf_nextscn(elf, i)
|
|
if (not bool(i)):
|
|
break
|
|
|
|
yield select(elf, 'getshdr')(i.contents).contents
|
|
|
|
def phdrs(elf):
|
|
phdrTbl = select(elf, "getphdr")(elf)
|
|
ehdr = select(elf, "getehdr")(elf).contents
|
|
phdrCnt = ehdr.e_phnum
|
|
|
|
for i in xrange(0, phdrCnt):
|
|
yield phdrTbl[i]
|
|
|
|
def data(elf_scn):
|
|
i = None
|
|
while 1:
|
|
i = elf_getdata(elf_scn, i)
|
|
|
|
if (not bool(i)):
|
|
break
|
|
|
|
yield i.contents
|
|
|
|
def strings(v):
|
|
if (isinstance(v, Elf_Data)):
|
|
strtab_data = v
|
|
size = strtab_data.d_size
|
|
buf = cast(strtab_data.d_buf, POINTER(c_char))
|
|
start = 0;
|
|
while start < size:
|
|
end = start;
|
|
while buf[end] != '\x00': end += 1
|
|
yield (strtab_data.d_off + start, buf[start:end])
|
|
|
|
start = end+1
|
|
elif (isinstance(v, Elf_Scn)):
|
|
for d in data(v):
|
|
strtab_data = d
|
|
size = strtab_data.d_size
|
|
buf = cast(strtab_data.d_buf, POINTER(c_char))
|
|
start = 0;
|
|
while start < size:
|
|
end = start;
|
|
while buf[end] != '\x00': end += 1
|
|
yield (strtab_data.d_off + start, buf[start:end])
|
|
|
|
start = end+1
|
|
|
|
|
|
def arr_iter(data, itemT, ind = False):
|
|
size = data.d_size
|
|
|
|
if size % sizeof(itemT) != 0:
|
|
raise Exception("Data size not a multiple of symbol size!")
|
|
|
|
buf = cast(data.d_buf, POINTER(itemT))
|
|
nelems = size / sizeof(itemT)
|
|
|
|
for i in xrange(0, nelems):
|
|
if ind:
|
|
yield (i, buf[i])
|
|
else:
|
|
yield buf[i]
|
|
|
|
def syms(elf, v = None):
|
|
symT = Elf32_Sym if (is32(elf)) else Elf64_Sym
|
|
if v == None:
|
|
for s in sections(elf):
|
|
hdr = section_hdr(elf, s)
|
|
|
|
if (hdr.sh_type != SHT_SYMTAB and hdr.sh_type != SHT_DYNSYM):
|
|
continue
|
|
|
|
for d in data(s):
|
|
for (ind, sym) in arr_iter(d, symT, True):
|
|
yield (ind, sym)
|
|
elif isinstance(v, Elf_Scn):
|
|
for d in data(v):
|
|
for (ind, sym) in arr_iter(d, symT, True):
|
|
yield (ind, sym)
|
|
else:
|
|
assert isinstance(v, Elf_Data)
|
|
for (ind, sym) in arr_iter(v, symT, True):
|
|
yield (ind, sym)
|
|
|
|
def rels(elf, **kwargs):
|
|
relT = Elf32_Rel if (is32(elf)) else Elf64_Rel
|
|
if 'section' in kwargs:
|
|
secl = sections(elf, type = SHT_REL, info = kwargs['section'])
|
|
else:
|
|
secl = sections(elf, type = SHT_REL)
|
|
|
|
|
|
if 'range' in kwargs:
|
|
for scn in secl:
|
|
for d in data(scn):
|
|
for rel in arr_iter(d, relT):
|
|
if (rel.r_offset >= kwargs['range'][0] and
|
|
rel.r_offset < kwargs['range'][1]):
|
|
yield (rel, section_hdr(elf, scn).sh_link)
|
|
else:
|
|
for scn in secl:
|
|
for d in data(scn):
|
|
for rel in arr_iter(d, relT):
|
|
yield (rel, section_hdr(elf, scn).sh_link)
|
|
|
|
def relas(elf, **kwargs):
|
|
relT = Elf32_Rela if (is32(elf)) else Elf64_Rela
|
|
if 'section' in kwargs:
|
|
scn = kwargs['section']
|
|
if (type(scn) == str): scn = list(sections(elf, name=scn))[0]
|
|
if (isinstance(scn, Elf_Scn)): scn = elf_ndxscn(byref(scn))
|
|
secl = list(sections(elf, type = SHT_RELA, info = scn))
|
|
else:
|
|
secl = list(sections(elf, type = SHT_RELA))
|
|
|
|
if 'range' in kwargs:
|
|
for scn in secl:
|
|
for d in data(scn):
|
|
for rel in arr_iter(d, relT):
|
|
if (rel.r_offset + rel.r_addend >= kwargs['range'][0] and
|
|
rel.r_offset + rel.r_addend < kwargs['range'][1]):
|
|
yield (rel, section_hdr(elf, scn).sh_link)
|
|
else:
|
|
addSecId = kwargs['withSectionId']==True \
|
|
if 'withSectionId' in kwargs \
|
|
else False
|
|
if not addSecId:
|
|
for scn in secl:
|
|
for d in data(scn):
|
|
for rel in arr_iter(d, relT):
|
|
yield (rel, section_hdr(elf, scn).sh_link)
|
|
else:
|
|
for scn in secl:
|
|
for d in data(scn):
|
|
for rel in arr_iter(d, relT):
|
|
yield (rel, section_hdr(elf, scn).sh_info)
|
|
|
|
def getOnlyData(scn):
|
|
d = elf_getdata(scn, None);
|
|
assert bool(elf_getdata(scn, d)) == False
|
|
return d
|
|
|
|
def dyns(elf):
|
|
relT = Elf64_Dyn
|
|
for scn in sections(elf, name=".dynamic"):
|
|
for d in data(scn):
|
|
for dyn in arr_iter(d, relT):
|
|
yield dyn
|
|
|
|
def elfs(fname):
|
|
fd = os.open(fname, os.O_RDONLY)
|
|
ar = elf_begin(fd, ELF_C_READ, None)
|
|
|
|
i = None
|
|
while 1:
|
|
i = elf_begin(fd, ELF_C_READ, ar)
|
|
if (not bool(i)):
|
|
break
|
|
|
|
yield i
|
|
|
|
elf_end(ar)
|
|
os.close(fd)
|
|
|