1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
from chrysacase import ChrysalideTestCase
from pychrysalide import SourceEndian
from pychrysalide.analysis import BinContent
from pychrysalide.arch import vmpa
class CustomContent(BinContent):
def __init__(self, size):
super(CustomContent, self).__init__()
self._start = 10
self._size = size * 8
def _describe(self, full):
return 'my_desc' + ('_full' if full else '')
def _compute_checksum(self, checksum):
checksum.update(b'xxxxx')
def _compute_size(self):
return int(self._size / 8)
def _compute_start_pos(self):
return vmpa(self._start, vmpa.VmpaSpecialValue.NO_VIRTUAL)
def _compute_end_pos(self):
return vmpa(self._start + self._size, vmpa.VmpaSpecialValue.NO_VIRTUAL)
def _seek(self, addr, length):
addr += length
return True
def _read_uxxx(self, addr, sizeof):
assert(addr >= self.start_pos and addr < self.end_pos)
val = int((addr - self.start_pos).phys / sizeof)
addr += sizeof
return val
def _read_u8(self, addr):
return self._read_uxxx(addr, 1)
def _read_u16(self, addr, endian):
return self._read_uxxx(addr, 2)
def _read_u32(self, addr, endian):
return self._read_uxxx(addr, 4)
def _read_u64(self, addr, endian):
return self._read_uxxx(addr, 8)
def _read_uleb128(self, addr):
return 128
def _read_leb128(self, addr):
return -128
class TestCustomContent(ChrysalideTestCase):
"""TestCase for custom implementation of analysis.BinContent."""
def testBasicImplementations(self):
"""Involve all implemented basic wrappers for a custom content."""
cnt = CustomContent(1)
self.assertEqual(cnt._describe(False), 'my_desc')
self.assertEqual(cnt._describe(True), 'my_desc_full')
# $ echo -n 'xxxxx' | sha256sum
# eaf16bc07968e013f3f94ab1342472434a39fc3475f11cf341a6c3965974f8e9 -
expected = 'eaf16bc07968e013f3f94ab1342472434a39fc3475f11cf341a6c3965974f8e9'
self.assertEqual(cnt.checksum, expected)
self.assertEqual(cnt.size, 1)
addr = cnt.start_pos
offset = 13
cnt.seek(addr, offset)
self.assertEqual(addr.phys, cnt.start_pos.phys + offset)
def testReadImplementations(self):
"""Involve main implemented read wrappers for a custom content."""
cnt = CustomContent(8)
def _run_check_read_implem(fn, args):
last = None
pos = cnt.start_pos
while pos < cnt.end_pos:
val = fn(pos, *args)
if not(last is None):
self.assertEqual(last + 1, val)
else:
self.assertEqual(val, 0)
last = val
checks = [
[ cnt.read_u8, [] ],
[ cnt.read_u16, [ SourceEndian.LITTLE ] ],
[ cnt.read_u32, [ SourceEndian.LITTLE ] ],
[ cnt.read_u64, [ SourceEndian.LITTLE ] ],
]
for f, a in checks:
_run_check_read_implem(f, a)
def testLEB128Implementations(self):
"""Involve [U]LEB128 implemented wrappers for a custom content."""
cnt = CustomContent(1)
addr = cnt.start_pos
self.assertEqual(cnt.read_uleb128(addr), 128)
self.assertEqual(cnt.read_leb128(addr), -128)
|