Skip to content

Commit

Permalink
Move value parsing into its own function (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
Schamper committed Aug 2, 2023
1 parent 6758cb2 commit 14cfb86
Showing 1 changed file with 47 additions and 47 deletions.
94 changes: 47 additions & 47 deletions dissect/regf/regf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import sys
from functools import lru_cache
from io import BytesIO
from typing import Union

from dissect.util.ts import wintimestamp

Expand Down Expand Up @@ -322,56 +323,10 @@ def data(self):
self._data = data
return self._data

def parse_value(self):
data = self.data

if self.kv.data_type in (REG_DWORD, REG_DWORD_BIG_ENDIAN):
if len(data) == 0:
return 0

if self.kv.data_type == REG_DWORD:
return c_regf.uint32(data[:4])
elif self.kv.data_type == REG_DWORD_BIG_ENDIAN:
return struct.unpack(">I", data[:4])[0]

if self.kv.data_type in (REG_SZ, REG_EXPAND_SZ):
return try_decode_sz(data)

if self.kv.data_type in (REG_BINARY, REG_NONE):
return data

if self.kv.data_type == REG_MULTI_SZ:
data_len = len(data)
data = BytesIO(data)

multi_string = []
while data.tell() < data_len:
string = read_null_terminated_wstring(data)
if string == "":
break

multi_string.append(string)

return multi_string

if self.kv.data_type == REG_QWORD:
return c_regf.uint64(data) if len(data) else 0

if self.kv.data_type == REG_FULL_RESOURCE_DESCRIPTOR:
log.warning("Unimplemented REG_FULL_RESOURCE_DESCRIPTOR")
return data

if self.kv.data_type == REG_RESOURCE_REQUIREMENTS_LIST:
log.warning("Unimplemented REG_RESOURCE_REQUIREMENTS_LIST")
return data

log.warning("Data type 0x%x not supported", self.kv.data_type)
return data

@property
def value(self):
if self._value is None:
self._value = self.parse_value()
self._value = parse_value(self.kv.data_type, self.data)
return self._value

def __repr__(self):
Expand Down Expand Up @@ -532,6 +487,51 @@ def try_decode_sz(data):
return data.decode("utf-16-le", "ignore").strip("\x00")


def parse_value(data_type: int, data: bytes) -> Union[int, str, list[str], bytes]:
if data_type in (REG_DWORD, REG_DWORD_BIG_ENDIAN):
if len(data) == 0:
return 0

if data_type == REG_DWORD:
return c_regf.uint32(data[:4])
elif data_type == REG_DWORD_BIG_ENDIAN:
return struct.unpack(">I", data[:4])[0]

if data_type == REG_QWORD:
return c_regf.uint64(data) if len(data) else 0

if data_type in (REG_SZ, REG_EXPAND_SZ):
return try_decode_sz(data)

if data_type in (REG_BINARY, REG_NONE):
return data

if data_type == REG_MULTI_SZ:
data_len = len(data)
data = BytesIO(data)

multi_string = []
while data.tell() < data_len:
string = read_null_terminated_wstring(data)
if string == "":
break

multi_string.append(string)

return multi_string

if data_type == REG_FULL_RESOURCE_DESCRIPTOR:
log.warning("Unimplemented REG_FULL_RESOURCE_DESCRIPTOR")
return data

if data_type == REG_RESOURCE_REQUIREMENTS_LIST:
log.warning("Unimplemented REG_RESOURCE_REQUIREMENTS_LIST")
return data

log.warning("Data type 0x%x not supported", data_type)
return data


def read_null_terminated_wstring(stream, encoding="utf-16-le"):
"""Adapted function to read null terminated wide strings.
Expand Down

0 comments on commit 14cfb86

Please sign in to comment.