Skip to content

Commit 3f062db

Browse files
committed
version 2.9.7:
* drop python <3.8 support * improve structs package for bitfield support and computation of fields' offsets for chosen pointer size (32 or 64 bits)
1 parent dac8e00 commit 3f062db

File tree

15 files changed

+294
-131
lines changed

15 files changed

+294
-131
lines changed

.travis.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
language: python
22
python:
3-
- '3.6'
4-
- '3.7'
53
- '3.8'
64
branches:
75
only:

README.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Amoco
2727
Description
2828
===========
2929

30-
Amoco is a python (>=3.7) package dedicated to symbolic analysis of binaries.
30+
Amoco is a python (>=3.8) package dedicated to symbolic analysis of binaries.
3131

3232
It features:
3333

@@ -96,6 +96,12 @@ Please see `LICENSE`_.
9696
Changelog
9797
=========
9898

99+
- `v2.9.7`_
100+
101+
* drop python <3.8 support
102+
* improve structs package for bitfield support and computation of
103+
fields' offsets for chosen pointer size (32 or 64 bits)
104+
99105
- `v2.9.6`_
100106

101107
* merge Qt GUI ImageView
@@ -385,6 +391,7 @@ Changelog
385391
.. _sqlalchemy: http://www.sqlalchemy.org
386392
.. _QDarkStyleSheet: https://github.com/ColinDuquesnoy/QDarkStyleSheet
387393
.. _LICENSE: https://github.com/bdcht/amoco/blob/release/LICENSE
394+
.. _v2.9.7: https://github.com/bdcht/amoco/releases/tag/v2.9.7
388395
.. _v2.9.6: https://github.com/bdcht/amoco/releases/tag/v2.9.6
389396
.. _v2.9.5: https://github.com/bdcht/amoco/releases/tag/v2.9.5
390397
.. _v2.9.4: https://github.com/bdcht/amoco/releases/tag/v2.9.4

amoco/sa/ghidra.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
b = ghidra_bridge.GhidraBridge(namespace=__module__.__dict__)
44

55
def select_range(begin,end):
6-
from ghidra.program.model.address import setCurrentSelection, AddressSet
6+
setCurrentSelection = ghidra.program.model.address.setCurrentSelection
7+
AddressSet = ghidra.program.model.address.AddressSet
78
setCurrentSelection(AddressSet(toAddr(begin),toAddr(end)))
89

910
def add_memory_block(name,start,size,val=None,access="rw"):
@@ -19,35 +20,32 @@ def add_memory_block(name,start,size,val=None,access="rw"):
1920
return blk
2021

2122
def setPointer(address,size=4):
22-
from ghidra.program.model.data import PointerDataType
23+
PointerDataType = ghidra.program.model.data.PointerDataType
2324
if isinstance(address,int):
2425
address = toAddr(address)
2526
ls = currentProgram.getListing()
2627
ls.createData(address, PointerDataType.dataType, size)
2728

2829
def setFunctionName(address,name):
29-
from ghidra.program.model.symbol.SourceType import USER_DEFINED
30+
USER_DEFINED = ghidra.program.model.symbol.SourceType.USER_DEFINED
3031
if isinstance(address,int):
3132
address = toAddr(address)
3233
f = getFunctionAt(address)
3334
f.setName(name, USER_DEFINED)
3435

3536
def create_labels(labels):
36-
from ghidra.program.model.symbol.SourceType import USER_DEFINED
37+
USER_DEFINED = ghidra.program.model.symbol.SourceType.USER_DEFINED
3738
sym = currentProgram.symbolTable
3839
for a,r in labels.items():
3940
if isinstance(a,int):
4041
a = toAddr(a)
4142
sym.createLabel(a, r, USER_DEFINED)
4243

4344
def get_decompiled(func_name):
44-
from ghidra.app.decompiler import DecompileOptions
45-
from ghidra.app.decompiler import DecompInterface
46-
from ghidra.util.task import ConsoleTaskMonitor
4745
func = getGlobalFunctions(func_name)[0]
48-
options = DecompileOptions()
49-
monitor = ConsoleTaskMonitor()
50-
ifc = DecompInterface()
46+
options = ghidra.app.decompiler.DecompileOptions()
47+
monitor = ghidra.util.task.ConsoleTaskMonitor()
48+
ifc = ghidra.app.decompiler.DecompInterface()
5149
ifc.setOptions(options)
5250
ifc.openProgram(func.getProgram())
5351
res = ifc.decompileFunction(func, 1000, monitor)
@@ -79,11 +77,10 @@ def get_decompiled_symbols(func_name):
7977
print(" nameLocked: {}".format(symbol.nameLocked))
8078

8179
def get_ast_nodes(func_name):
82-
from ghidra.app.decompiler import ClangStatement
8380
res = get_decompiled(func_name)
8481
# get (decompiled) high-function object from res:
8582
def walk(node,L):
86-
if type(node) == ClangStatement:
83+
if type(node) == ghidra.app.decompiler.ClangStatement:
8784
L.append(node)
8885
else:
8986
for i in range(node.numChildren()):

amoco/system/baremetal/imx6.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def __init__(self, data="", offset=0):
178178
if data:
179179
self.unpack(data, offset)
180180

181-
def unpack(self, data, offset=0):
181+
def unpack(self, data, offset=0, psize=0):
182182
StructFormatter.unpack(self, data, offset)
183183
offset += 12
184184
self.modulus = data[offset : offset + self.nlen]
@@ -205,7 +205,7 @@ def __init__(self, data="", offset=0):
205205
if data:
206206
self.unpack(data, offset)
207207

208-
def unpack(self, data, offset=0):
208+
def unpack(self, data, offset=0, psize=0):
209209
StructFormatter.unpack(self, data, offset)
210210
assert self.header.tag == HAB_TAG_CRT
211211
crtend = offset + self.header.length
@@ -241,7 +241,7 @@ def __init__(self, data="", offset=0):
241241
if data:
242242
self.unpack(data, offset)
243243

244-
def unpack(self, data, offset=0):
244+
def unpack(self, data, offset=0, psize=0):
245245
StructFormatter.unpack(self, data, offset)
246246
assert self.header.tag == HAB_TAG_CSF
247247
csfend = offset + self.header.length
@@ -298,7 +298,7 @@ def __init__(self, data="", offset=0):
298298
if data:
299299
self.unpack(data, offset)
300300

301-
def unpack(self, data, offset=0):
301+
def unpack(self, data, offset=0, psize=0):
302302
StructFormatter.unpack(self, data, offset)
303303
assert self.cmd == HAB_CMD_CHK_DAT
304304
self.flags = self.par >> 3
@@ -355,7 +355,7 @@ def __init__(self, data="", offset=0):
355355
if data:
356356
self.unpack(data, offset)
357357

358-
def unpack(self, data, offset=0):
358+
def unpack(self, data, offset=0, psize=0):
359359
StructFormatter.unpack(self, data, offset)
360360
assert self.cmd == HAB_CMD_UNLK
361361
if self.len > self.size():
@@ -400,7 +400,7 @@ def __init__(self, data="", offset=0):
400400
if data:
401401
self.unpack(data, offset)
402402

403-
def unpack(self, data, offset=0):
403+
def unpack(self, data, offset=0, psize=0):
404404
StructFormatter.unpack(self, data, offset)
405405
assert self.cmd == HAB_CMD_INS_KEY
406406
if self.len > self.size():
@@ -458,7 +458,7 @@ def blks_format(k, x, cls=None):
458458
s.append((Token.Literal, ")"))
459459
return highlight(s)
460460

461-
def unpack(self, data, offset=0):
461+
def unpack(self, data, offset=0, psize=0):
462462
StructFormatter.unpack(self, data, offset)
463463
assert self.cmd == HAB_CMD_AUT_DAT
464464
if self.len > self.size():

amoco/system/baremetal/psx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def __init__(self, data=None,offset=0):
3838
if data:
3939
self.unpack(data,offset)
4040

41-
def unpack(self, data, offset=0):
41+
def unpack(self, data, offset=0, psize=0):
4242
super().unpack(data, offset)
4343
if self.magic != b"PS-X EXE":
4444
raise TypeError("Wrong magic number, not a PS-X EXE file ?")

amoco/system/elf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ def __init__(self, data=None):
476476
if data:
477477
self.unpack(data)
478478

479-
def unpack(self, data, offset=0):
479+
def unpack(self, data, offset=0, psize=0):
480480
StructFormatter.unpack(self, data, offset)
481481
if self.ELFMAG0 != 0x7F or self.ELFMAG != b"ELF":
482482
raise ElfError("Wrong magic number, not an ELF file ?")
@@ -543,7 +543,7 @@ def __init__(self, data=None):
543543
if data:
544544
self.unpack(data)
545545

546-
def unpack(self, data, offset=0):
546+
def unpack(self, data, offset=0, psize=0):
547547
f0 = self.fields[0]
548548
self._v.e_ident = f0.unpack(data, offset)
549549
offset += f0.size()

amoco/system/fs/ufs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ def __init__(self, data="", offset=0):
344344
if data:
345345
self.unpack(data, offset)
346346

347-
def unpack(self, data, offset=0):
347+
def unpack(self, data, offset=0, psize=0):
348348
sz = 0
349349
for f in self.fields[:2]:
350350
setattr(self, f.name, f.unpack(data, offset + sz, self.order))
@@ -385,7 +385,7 @@ def __init__(self, data="", offset=0):
385385
if data:
386386
self.unpack(data, offset)
387387

388-
def unpack(self, data, offset=0):
388+
def unpack(self, data, offset=0, psize=0):
389389
sz = 0
390390
for f in self.fields[:3]:
391391
setattr(self, f.name, f.unpack(data, offset + sz, self.order))
@@ -429,7 +429,7 @@ def __init__(self, data="", offset=0):
429429
if data:
430430
self.unpack(data, offset)
431431

432-
def unpack(self, data, offset=0):
432+
def unpack(self, data, offset=0, psize=0):
433433
sz = 0
434434
for f in self.fields[:-1]:
435435
setattr(self, f.name, f.unpack(data, offset + sz, self.order))

amoco/system/pe.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ def __init__(self, data=None, offset=0):
447447
if data:
448448
self.unpack(data, offset)
449449

450-
def unpack(self, data, offset=0):
450+
def unpack(self, data, offset=0, psize=0):
451451
magic = data[offset : offset + 2]
452452
if magic == b"\x0b\x01":
453453
logger.verbose("PE32 Magic found")

amoco/system/structs/__init__.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,13 @@ class that inherits StructCore, in which case the previous class is used
164164
"H": 2,
165165
"i": 4,
166166
"I": 4,
167-
"l": 4,
168-
"L": 4,
167+
"l": 0,
168+
"L": 0,
169169
"f": 4,
170170
"q": 8,
171171
"Q": 8,
172172
"d": 8,
173-
"P": 8,
173+
"P": 0,
174174
}
175175
integer = pp.Regex(r"[0-9][0-9]*")
176176
integer.setParseAction(lambda r: int(r[0]))
@@ -229,6 +229,9 @@ def __init__(self, fmt, **kargs):
229229
f_align = self.alignments[f_type]
230230
else:
231231
f_cls = Field
232+
if isinstance(f_count, list):
233+
f_cls = BitFieldEx
234+
f_name = f_name.split('/')
232235
f_type = kargs.get(f_type, f_type)
233236
f_align = 0
234237
self.fields.append(
@@ -273,7 +276,7 @@ def TypeDefine(newname, typebase, typecount=0, align_value=0):
273276
if typecount:
274277
t.fields[0].count = typecount
275278
if align_value:
276-
t.fields[0].align_value = align_value
279+
t.fields[0]._align_value = align_value
277280
return t
278281

279282
# ------------------------------------------------------------------------------

amoco/system/structs/core.py

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,21 @@ def format(cls):
8181
return cls.fields[cls.union].format()
8282

8383
@classmethod
84-
def size(cls):
84+
def size(cls, psize=0):
8585
"""
8686
This is a class method that basically computes the sum of
8787
the sizes of fields (or the largest field if a union) while
8888
taking into account the possible alignements constraints.
8989
It uses the *class* fields instances so that the resulting
9090
value is infinite if any of these field is a VarField.
9191
"""
92-
A = cls.align_value()
92+
psize = {32:4, 64:8}.get(psize,psize)
93+
A = cls.align_value(psize)
9394
sz = 0
9495
for f in cls.fields:
9596
if cls.union is False and not cls.packed:
96-
sz = f.align(sz)
97-
fsz = f.size()
97+
sz = f.align(sz, psize)
98+
fsz = f.size(psize)
9899
if cls.union is False:
99100
sz += fsz
100101
elif fsz > sz:
@@ -146,15 +147,15 @@ def __eq__(self, other):
146147
return False
147148

148149
@classmethod
149-
def align_value(cls):
150-
return max([f.align_value for f in cls.fields])
150+
def align_value(cls,psize=0):
151+
return max([f.align_value(psize) for f in cls.fields])
151152

152-
def unpack(self, data, offset=0):
153+
def unpack(self, data, offset=0, psize=0):
153154
for f in self.fields:
154155
if self.union is False and not self.packed:
155-
offset = f.align(offset)
156+
offset = f.align(offset, psize)
156157
try:
157-
value = f.unpack(data, offset)
158+
value = f.unpack(data, offset, psize)
158159
except Exception:
159160
name = self.__class__.__name__
160161
logger.error("error unpacking %s %s"%(name,str(f)))
@@ -172,10 +173,10 @@ def unpack(self, data, offset=0):
172173
# is a dict with subnames/subvalues:
173174
self._v.__dict__.update(value)
174175
if self.union is False:
175-
offset += f.size()
176+
offset += f.size(psize)
176177
return self
177178

178-
def pack(self, data=None):
179+
def pack(self, data=None, psize=0):
179180
if data is None:
180181
data = []
181182
for f in self.fields:
@@ -190,29 +191,49 @@ def pack(self, data=None):
190191
parts = []
191192
offset = 0
192193
for f, v in zip(self.fields, data):
193-
p = f.pack(v)
194+
p = f.pack(v,psize)
194195
if not self.packed:
195-
pad = f.align(offset) - offset
196+
pad = f.align(offset,psize) - offset
196197
p = b"\0" * pad + p
197198
parts.append(p)
198199
if self.union is False:
199200
res = b"".join(parts)
200201
if not self.packed:
201-
res = res.ljust(self.size(), b"\0")
202+
res = res.ljust(self.size(psize), b"\0")
202203
return res
203204
else:
204205
return parts[self.union]
205206

206-
def offset_of(self, name):
207+
def offset_of(self, name, psize=0):
207208
if self.union is not False:
208209
return 0
209210
o = 0
210211
for f in self.fields:
212+
o = f.align(o,psize)
211213
if f.name == name:
212214
return o
213-
o = f.align(o) + f.size()
215+
o += f.size(psize)
214216
raise AttributeError(name)
215217

218+
def offsets(self,psize=0):
219+
if self.union is not False:
220+
return [(0,f.size(psize)) for f in self.fields]
221+
o = 0
222+
offsets = []
223+
for f in self.fields:
224+
o = f.align(o,psize)
225+
if hasattr(f,'subsizes'):
226+
oo = 0
227+
for x in f.subsizes:
228+
xo = float("%d.%d"%(o,oo))
229+
so = float(".%d"%x)
230+
oo += x
231+
offsets.append((xo,so))
232+
else:
233+
offsets.append((o,f.size(psize)))
234+
o += f.size(psize)
235+
return offsets
236+
216237
# ------------------------------------------------------------------------------
217238

218239

0 commit comments

Comments
 (0)