Skip to content

Commit 24a8d6b

Browse files
committed
Update formats
1 parent 3798bb0 commit 24a8d6b

File tree

5 files changed

+287
-23
lines changed

5 files changed

+287
-23
lines changed

pytai/kaitai/formats/efivar_signature_list.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,22 @@
136136

137137
class EfivarSignatureList(KaitaiStruct):
138138
"""Parse UEFI variables db and dbx that contain signatures, certificates and
139-
hashes. On a Linux system using UEFI, these variables are readable from
140-
/sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f,
141-
/sys/firmware/efi/efivars/dbDefault-8be4df61-93ca-11d2-aa0d-00e098032b8c,
142-
/sys/firmware/efi/efivars/dbx-d719b2cb-3d3a-4596-a3bc-dad00e67656f and
143-
/sys/firmware/efi/efivars/dbxDefault-8be4df61-93ca-11d2-aa0d-00e098032b8c.
144-
("d719b2cb-3d3a-4596-a3bc-dad00e67656f" is defined as
145-
EFI_IMAGE_SECURITY_DATABASE_GUID and "8be4df61-93ca-11d2-aa0d-00e098032b8c"
146-
as EFI_GLOBAL_VARIABLE).
139+
hashes. On a Linux system using UEFI, these variables are readable from:
140+
141+
```
142+
/sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f
143+
/sys/firmware/efi/efivars/dbDefault-8be4df61-93ca-11d2-aa0d-00e098032b8c
144+
/sys/firmware/efi/efivars/dbx-d719b2cb-3d3a-4596-a3bc-dad00e67656f
145+
/sys/firmware/efi/efivars/dbxDefault-8be4df61-93ca-11d2-aa0d-00e098032b8c
146+
```
147+
148+
Note:
149+
150+
* `d719b2cb-3d3a-4596-a3bc-dad00e67656f` is defined as `EFI_IMAGE_SECURITY_DATABASE_GUID`
151+
* `8be4df61-93ca-11d2-aa0d-00e098032b8c` is defined as `EFI_GLOBAL_VARIABLE`
152+
147153
Each file contains an EFI attribute (32-bit integer) followed by a list of
148-
EFI_SIGNATURE_LIST structures.
154+
`EFI_SIGNATURE_LIST` structures.
149155
150156
.. seealso::
151157
Source - https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf

pytai/kaitai/formats/glibc_utmp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def _read(self):
187187
self.ut_type = KaitaiStream.resolve_enum(GlibcUtmp.EntryType, self._io.read_s4le())
188188
self._debug['ut_type']['end'] = self._io.pos()
189189
self._debug['pid']['start'] = self._io.pos()
190-
self.pid = self._io.read_u4le()
190+
self.pid = self._io.read_s4le()
191191
self._debug['pid']['end'] = self._io.pos()
192192
self._debug['line']['start'] = self._io.pos()
193193
self.line = (self._io.read_bytes(32)).decode(u"UTF-8")
@@ -229,7 +229,7 @@ def __init__(self, _io, _parent=None, _root=None):
229229

230230
def _read(self):
231231
self._debug['sec']['start'] = self._io.pos()
232-
self.sec = self._io.read_s4le()
232+
self.sec = self._io.read_u4le()
233233
self._debug['sec']['end'] = self._io.pos()
234234
self._debug['usec']['start'] = self._io.pos()
235235
self.usec = self._io.read_s4le()

pytai/kaitai/formats/vlq_base128_le.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,21 @@ class VlqBase128Le(KaitaiStruct):
149149
<https://lucene.apache.org/core/3_5_0/fileformats.html#VInt>
150150
* Apache Avro uses this as a basis for integer encoding, adding ZigZag on
151151
top of it for signed ints
152-
<https://avro.apache.org/docs/current/spec.html#binary_encode_primitive>
152+
<https://avro.apache.org/docs/1.12.0/specification/#primitive-types-1>
153153
154154
More information on this encoding is available at <https://en.wikipedia.org/wiki/LEB128>
155155
156-
This particular implementation supports serialized values to up 8 bytes long.
156+
This particular implementation supports integer values up to 64 bits (i.e. the
157+
maximum unsigned value supported is `2**64 - 1`), which implies that serialized
158+
values can be up to 10 bytes in length.
159+
160+
If the most significant 10th byte (`groups[9]`) is present, its `has_next`
161+
must be `false` (otherwise we would have 11 or more bytes, which is not
162+
supported) and its `value` can be only `0` or `1` (because a 9-byte VLQ can
163+
represent `9 * 7 = 63` bits already, so the 10th byte can only add 1 bit,
164+
since only integers up to 64 bits are supported). These restrictions are
165+
enforced by this implementation. They were inspired by the Protoscope tool,
166+
see <https://github.com/protocolbuffers/protoscope/blob/8e7a6aafa2c9958527b1e0747e66e1bfff045819/writer.go#L644-L648>.
157167
"""
158168
SEQ_FIELDS = ["groups"]
159169
def __init__(self, _io, _parent=None, _root=None):
@@ -170,7 +180,7 @@ def _read(self):
170180
if not 'arr' in self._debug['groups']:
171181
self._debug['groups']['arr'] = []
172182
self._debug['groups']['arr'].append({'start': self._io.pos()})
173-
_t_groups = VlqBase128Le.Group(self._io, self, self._root)
183+
_t_groups = VlqBase128Le.Group(i, (self.groups[(i - 1)].interm_value if i != 0 else 0), ((9223372036854775808 if i == 9 else (self.groups[(i - 1)].multiplier * 128)) if i != 0 else 1), self._io, self, self._root)
174184
_t_groups._read()
175185
_ = _t_groups
176186
self.groups.append(_)
@@ -184,19 +194,34 @@ class Group(KaitaiStruct):
184194
"""One byte group, clearly divided into 7-bit "value" chunk and 1-bit "continuation" flag.
185195
"""
186196
SEQ_FIELDS = ["has_next", "value"]
187-
def __init__(self, _io, _parent=None, _root=None):
197+
def __init__(self, idx, prev_interm_value, multiplier, _io, _parent=None, _root=None):
188198
self._io = _io
189199
self._parent = _parent
190200
self._root = _root if _root else self
201+
self.idx = idx
202+
self.prev_interm_value = prev_interm_value
203+
self.multiplier = multiplier
191204
self._debug = collections.defaultdict(dict)
192205

193206
def _read(self):
194207
self._debug['has_next']['start'] = self._io.pos()
195208
self.has_next = self._io.read_bits_int_be(1) != 0
196209
self._debug['has_next']['end'] = self._io.pos()
210+
if not self.has_next == (False if self.idx == 9 else self.has_next):
211+
raise kaitaistruct.ValidationNotEqualError((False if self.idx == 9 else self.has_next), self.has_next, self._io, u"/types/group/seq/0")
197212
self._debug['value']['start'] = self._io.pos()
198213
self.value = self._io.read_bits_int_be(7)
199214
self._debug['value']['end'] = self._io.pos()
215+
if not self.value <= (1 if self.idx == 9 else 127):
216+
raise kaitaistruct.ValidationGreaterThanError((1 if self.idx == 9 else 127), self.value, self._io, u"/types/group/seq/1")
217+
218+
@property
219+
def interm_value(self):
220+
if hasattr(self, '_m_interm_value'):
221+
return self._m_interm_value
222+
223+
self._m_interm_value = (self.prev_interm_value + (self.value * self.multiplier))
224+
return getattr(self, '_m_interm_value', None)
200225

201226

202227
@property
@@ -213,27 +238,23 @@ def value(self):
213238
if hasattr(self, '_m_value'):
214239
return self._m_value
215240

216-
self._m_value = (((((((self.groups[0].value + ((self.groups[1].value << 7) if self.len >= 2 else 0)) + ((self.groups[2].value << 14) if self.len >= 3 else 0)) + ((self.groups[3].value << 21) if self.len >= 4 else 0)) + ((self.groups[4].value << 28) if self.len >= 5 else 0)) + ((self.groups[5].value << 35) if self.len >= 6 else 0)) + ((self.groups[6].value << 42) if self.len >= 7 else 0)) + ((self.groups[7].value << 49) if self.len >= 8 else 0))
241+
self._m_value = self.groups[-1].interm_value
217242
return getattr(self, '_m_value', None)
218243

219244
@property
220245
def sign_bit(self):
221246
if hasattr(self, '_m_sign_bit'):
222247
return self._m_sign_bit
223248

224-
self._m_sign_bit = (1 << ((7 * self.len) - 1))
249+
self._m_sign_bit = (9223372036854775808 if self.len == 10 else (self.groups[-1].multiplier * 64))
225250
return getattr(self, '_m_sign_bit', None)
226251

227252
@property
228253
def value_signed(self):
229-
"""
230-
.. seealso::
231-
Source - https://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend
232-
"""
233254
if hasattr(self, '_m_value_signed'):
234255
return self._m_value_signed
235256

236-
self._m_value_signed = ((self.value ^ self.sign_bit) - self.sign_bit)
257+
self._m_value_signed = (-((self.sign_bit - (self.value - self.sign_bit))) if ((self.sign_bit > 0) and (self.value >= self.sign_bit)) else self.value)
237258
return getattr(self, '_m_value_signed', None)
238259

239260

0 commit comments

Comments
 (0)