Skip to content

Commit

Permalink
update to v2.9.3
Browse files Browse the repository at this point in the history
  * add codeblock view
  * fix PE32+ DataDirectories
  * update win64 OS class
  * update documentation
  • Loading branch information
bdcht committed May 16, 2020
1 parent 0a6ba6a commit f80e4f3
Show file tree
Hide file tree
Showing 33 changed files with 607 additions and 143 deletions.
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ Changelog
* add MIPS architecture (R3000 only)
* improve support for changes in config
* rework ext/stub interface
* fixing sparc formatter
* fixing PE32+ DataDirectories parsing

- `v2.9.2`_

Expand Down
19 changes: 11 additions & 8 deletions amoco/arch/x64/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ def opers(i):
s = []
for op in i.operands:
if op._is_mem:
if i.misc["rip_rel"] is not None:
s.append((Token.Memory, "[%s]" % i.misc["rip_rel"]))
else:
s.append((Token.Memory, deref(op)))
if i.misc['rip_rel']:
op = i.misc['rip_rel']
elif op.a.base._is_reg and op.a.base.etype & regtype.PC:
if i.address is not None:
op = op.__class__(i.address+i.length+op.a.disp,op.size,seg=op.a.seg)
i.misc['rip_rel'] = op
s.append((Token.Memory, deref(op)))
elif op._is_cst:
if i.misc["imm_ref"] is not None:
s.append((Token.Address, str(i.misc["imm_ref"])))
Expand All @@ -61,11 +64,11 @@ def opers(i):
def oprel(i):
to = i.misc["to"]
if to is not None:
return [(Token.Address, "*" + str(to))]
return [(Token.Address, str(to))]
if (i.address is not None) and i.operands[0]._is_cst:
v = i.address + i.operands[0].signextend(64) + i.length
i.misc["to"] = v
return [(Token.Address, "*" + str(v))]
return [(Token.Address, str(v))]
return [(Token.Constant, ".%+d" % i.operands[0].value)]


Expand Down Expand Up @@ -150,11 +153,11 @@ def opers_att(i):
def oprel_att(i):
to = i.misc["to"]
if to is not None:
return [(Token.Address, "*" + str(to))]
return [(Token.Address, str(to))]
if (i.address is not None) and i.operands[0]._is_cst:
v = i.address + i.operands[0].signextend(64) + i.length
i.misc["to"] = v
return [(Token.Address, "*" + str(v))]
return [(Token.Address, str(v))]
return [(Token.Constant, "$.%+d" % i.operands[0].value)]


Expand Down
13 changes: 8 additions & 5 deletions amoco/arch/x86/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def opers(i):
s = []
for op in i.operands:
if op._is_mem:
if op.a.base._is_reg and op.a.base.etype & regtype.PC:
if i.address is not None:
op = op.__class__(i.address+i.length+op.a.disp,op.size,seg=op.a.seg)
s.append((Token.Memory, deref(op)))
elif op._is_cst:
if i.misc["imm_ref"] is not None:
Expand All @@ -58,11 +61,11 @@ def opers(i):
def oprel(i):
to = i.misc["to"]
if to is not None:
return [(Token.Address, "*" + str(to))]
return [(Token.Address, str(to))]
if (i.address is not None) and i.operands[0]._is_cst:
v = i.address + i.operands[0].signextend(32) + i.length
i.misc["to"] = v
return [(Token.Address, "*" + str(v))]
return [(Token.Address, str(v))]
return [(Token.Constant, ".%+d" % i.operands[0].value)]


Expand Down Expand Up @@ -147,11 +150,11 @@ def opers_att(i):
def oprel_att(i):
to = i.misc["to"]
if to is not None:
return [(Token.Address, "*" + str(to))]
return [(Token.Address, str(to))]
if (i.address is not None) and i.operands[0]._is_cst:
v = i.address + i.operands[0].signextend(32) + i.length
i.misc["to"] = v
return [(Token.Address, "*" + str(v))]
return [(Token.Address, str(v))]
return [(Token.Constant, "$.%+d" % i.operands[0].value)]


Expand Down Expand Up @@ -849,7 +852,7 @@ def att_opers(i, operands=None):
def att_oprel(i):
to = i.misc["to"]
if to is not None:
return [(Token.Address, "*" + str(to))]
return [(Token.Address, str(to))]
op = i.operands[0]
if op._is_lab:
return [(Token.Address, str(op.ref))]
Expand Down
2 changes: 1 addition & 1 deletion amoco/cas/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1505,7 +1505,7 @@ def __init__(self, x, pos, size, ref=None):

def setref(self, ref):
if self.x._is_reg:
self.etype |= et_reg
self.etype |= self.x.etype
if ref is None:
ref = self.x._subrefs.get((self.pos, self.size), None)
else:
Expand Down
4 changes: 3 additions & 1 deletion amoco/cas/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ def inputs(self):
"list antecedent locations (used in the mapping)"
r = []
for l, v in iter(self.__map.items()):
if (l==v):
continue
for lv in locations_of(v):
if lv._is_reg and l._is_reg:
if (lv == l) or (lv.etype & l.etype & regtype.FLAGS):
if (lv.etype & l.etype & regtype.FLAGS):
continue
r.append(lv)
return r
Expand Down
4 changes: 4 additions & 0 deletions amoco/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
- 'helper' will use codeblock helper functions to pretty print code if True (default)
- 'header' will show a dashed header line including the address of the block if True (default)
- 'footer' will show a dashed footer line if True
- 'segment' will show memory section/segment name in codeblock view if True (default)
- 'bytecode' will show the hex encoded bytecode string of every instruction if True (default)
- 'padding' will add the specified amount of blank chars to between address/bytecode/instruction (default 4).
- 'hist' number of instruction's history shown in emulator view (default 3).
- 'Cas' which deals with parameters of the algebra system:
Expand Down Expand Up @@ -89,6 +91,7 @@ class Code(Configurable):
helper (Bool): use block helpers if True.
header (Bool): display block header dash-line with its name if True.
footer (Bool): display block footer dash-line if True.
segment (Bool): display memory section/segment name if True.
bytecode (Bool): display instructions' bytes.
padding (int): add space-padding bytes to bytecode (default=4).
hist (int): number of history instructions to show in
Expand All @@ -98,6 +101,7 @@ class Code(Configurable):
header = Bool(True, config=True)
footer = Bool(True, config=True)
bytecode = Bool(True, config=True)
segment = Bool(True, config=True)
padding = Integer(4, config=True)
hist = Integer(3, config=True)

Expand Down
2 changes: 1 addition & 1 deletion amoco/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
Setting all modules loggers to ``'ERROR'`` level::
In [2]: amoco.set_quiet()
In [2]: amoco.logger.set_quiet()
Note:
All loggers can be configured to log both to *stderr* with selected level
Expand Down
1 change: 1 addition & 0 deletions amoco/system/baremetal/psx.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def __init__(self, conf=None):
conf = System()
self.tasks = []
self.abi = None
self.symbols = {}

@classmethod
def loader(cls, bprm, conf=None):
Expand Down
28 changes: 26 additions & 2 deletions amoco/system/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,27 @@ def read_instruction(self, vaddr, **kargs):
i.xdata(i, xdata)
return i

def symbol_for(self,address):
info = None
if address in self.bin.variables:
info = self.bin.variables[address]
if isinstance(info,tuple):
info = info[0]
info = "$%s"%info
elif address in self.bin.functions:
info = self.bin.functions[address]
if isinstance(info,tuple):
info = info[0]
info = "<%s>"%info
elif self.OS and (address in self.OS.symbols):
info = self.OS.symbols[address]
info = "#%s"%info
return info or ""

def segment_for(self,address,stype=None):
s = self.bin.getinfo(address)[0]
return s.name if hasattr(s,'name') else ""

def getx(self, loc, size=8, sign=False):
"""
high level method to get the expressions value associated
Expand Down Expand Up @@ -261,8 +282,8 @@ class BinFormat(object):
symtab = None
strtab = None
reltab = None
functions = None
variables = None
functions = {}
variables = {}

@property
def entrypoints(self):
Expand All @@ -275,6 +296,9 @@ def filename(self):
def loadsegment(self, S, pagesize=None, raw=None):
raise NotImplementedError

def getinfo(self, target):
return (None, 0, 0)


class DataIO(BinFormat):
"""
Expand Down
16 changes: 11 additions & 5 deletions amoco/system/elf.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,13 @@ def getinfo(self, target):
# but this may lead to errors because what really matters are segments
# loaded by the kernel binfmt_elf.c loader.
if self.Shdr:
for s in self.Shdr[::-1]:
if s.sh_type == SHT_NULL:
for s in reversed(self.Shdr):
if s.sh_type != SHT_PROGBITS:
continue
if s.sh_addr <= addr < s.sh_addr + s.sh_size:
return s, addr - s.sh_addr, s.sh_addr
##
elif self.Phdr:
for s in self.Phdr[::-1]:
for s in reversed(self.Phdr):
if s.p_type != PT_LOAD:
continue
if s.p_vaddr <= addr < s.p_vaddr + s.p_filesz:
Expand Down Expand Up @@ -423,7 +422,8 @@ def checksec(self):
R["PIE"] = 1
R["Full RelRO"] = 0
for d in self.readsection(".dynamic") or []:
if d.d_tag == DT_BIND_NOW:
if d.d_tag == DT_BIND_NOW or\
(d.d_tag == DT_FLAGS and d.d_un==DF_BIND_NOW):
R["Full RelRO"] = 1
break
return R
Expand Down Expand Up @@ -1156,6 +1156,12 @@ def DT_ADDRTAGIDX(self, tag):
DT_ADDRRNGHI = 0x6FFFFEFF
DT_ADDRNUM = 10

DF_ORIGIN = 0x1
DF_SYMBOLIC = 0x2
DF_TEXTREL = 0x4
DF_BIND_NOW = 0x8
DF_STATIC_TLS = 0x10


@StructDefine(
"""
Expand Down
26 changes: 26 additions & 0 deletions amoco/system/linux32/x86.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def __init__(self, conf=None):

self.abi = cdecl
self.tasks = []
self.symbols = {}

@classmethod
def loader(cls, bprm, conf=None):
Expand Down Expand Up @@ -126,6 +127,31 @@ def load_elf_interp(self, p, interp):
xf = cpu.ext(f, size=32)
xf.stub = p.OS.stub(f)
p.state.mmap.write(k, xf)
# we want to add .plt addresses as symbols as well
# to improve asm block views:
plt = got = None
for s in p.bin.Shdr:
if s.name=='.plt':
plt = s
elif s.name=='.got':
got = s
if plt and got:
address = plt.sh_addr
pltco = p.bin.readsection(plt)
while(pltco):
i = p.cpu.disassemble(pltco)
if i.mnemonic=='JMP' and i.operands[0]._is_mem:
target = i.operands[0].a
if target.base is p.cpu.eip:
target = address+target.disp
elif target.base._is_reg:
target = got.sh_addr+target.disp
elif target.base._is_cst:
target = target.base.value+target.disp
if target in p.bin.functions:
p.bin.functions[address] = p.bin.functions[target]
pltco = pltco[i.length:]
address += i.length

def stub(self, refname):
return self.stubs.get(refname, self.default_stub)
Expand Down
26 changes: 26 additions & 0 deletions amoco/system/linux64/x64.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def __init__(self, conf=None):
self.NX = conf.nx
self.tasks = []
self.abi = None
self.symbols = {}

@classmethod
def loader(cls, bprm, conf=None):
Expand Down Expand Up @@ -136,6 +137,31 @@ def load_elf_interp(self, p, interp):
xfunc = cpu.ext(f, size=64)
xfunc.stub = p.OS.stub(f)
p.state.mmap.write(k, xfunc)
# we want to add .plt addresses as symbols as well
# to improve asm block views:
plt = got = None
for s in p.bin.Shdr:
if s.name=='.plt':
plt = s
elif s.name=='.got':
got = s
if plt and got:
address = plt.sh_addr
pltco = p.bin.readsection(plt)
while(pltco):
i = p.cpu.disassemble(pltco)
if i.mnemonic=='JMP' and i.operands[0]._is_mem:
target = i.operands[0].a
if target.base is p.cpu.rip:
target = address+target.disp
elif target.base._is_reg:
target = got.sh_addr+target.disp
elif target.base._is_cst:
target = target.base.value+target.disp
if target in p.bin.functions:
p.bin.functions[address] = p.bin.functions[target]
pltco = pltco[i.length:]
address += i.length

def stub(self, refname):
return self.stubs.get(refname, self.default_stub)
Expand Down
Loading

0 comments on commit f80e4f3

Please sign in to comment.