-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Changes to have file parsers use binary data format super class (#25)
- Loading branch information
1 parent
70d020a
commit b228967
Showing
7 changed files
with
184 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# -*- coding: utf-8 -*- | ||
'''Shared functionality for parsing binary data formats.''' | ||
|
||
from __future__ import unicode_literals | ||
|
||
import datetime | ||
import struct | ||
|
||
from UnifiedLog import logger | ||
|
||
|
||
class BinaryDataFormat(object): | ||
'''Binary data format.''' | ||
|
||
def _ReadAPFSTime(self, mac_apfs_time): # Mac APFS timestamp is nano second time epoch beginning 1970/1/1 | ||
'''Returns datetime object, or empty string upon error''' | ||
if mac_apfs_time not in ( 0, None, ''): | ||
try: | ||
if type(mac_apfs_time) in (str, unicode): | ||
mac_apfs_time = float(mac_apfs_time) | ||
return datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=mac_apfs_time/1000000000.) | ||
except Exception as ex: | ||
logger.error("ReadAPFSTime() Failed to convert timestamp from value " + str(mac_apfs_time) + " Error was: " + str(ex)) | ||
return '' | ||
|
||
def _ReadCString(self, data, max_len=1024): | ||
'''Returns a C utf8 string (excluding terminating null)''' | ||
pos = 0 | ||
max_len = min(len(data), max_len) | ||
string = '' | ||
try: | ||
null_pos = data.find(b'\x00', 0, max_len) | ||
if null_pos == -1: | ||
logger.warning("Possible corrupted string encountered") | ||
string = data.decode('utf8') | ||
else: | ||
string = data[0:null_pos].decode('utf8') | ||
except: | ||
logger.exception('Error reading C-String') | ||
|
||
return string | ||
|
||
def _ReadCStringAndEndPos(self, data, max_len=1024): | ||
'''Returns a tuple containing a C utf8 string (excluding terminating null) | ||
and the end position in the data | ||
("utf8-string", pos) | ||
''' | ||
pos = 0 | ||
max_len = min(len(data), max_len) | ||
string = '' | ||
null_pos = -1 | ||
try: | ||
null_pos = data.find(b'\x00', 0, max_len) | ||
if null_pos == -1: | ||
logger.warning("Possible corrupted string encountered") | ||
string = data.decode('utf8') | ||
else: | ||
string = data[0:null_pos].decode('utf8') | ||
except: | ||
logger.exception('Error reading C-String') | ||
return string, null_pos | ||
|
||
def _ReadNtSid(self, data): | ||
'''Reads a windows SID from its raw binary form''' | ||
sid = '' | ||
size = len(data) | ||
if size < 8: | ||
logger.error('Not a windows sid') | ||
rev = struct.unpack("<B", data[0])[0] | ||
num_sub_auth = struct.unpack("<B", data[1])[0] | ||
authority = struct.unpack(">I", data[4:8])[0] | ||
|
||
if size < (8 + (num_sub_auth * 4)): | ||
logger.error('buffer too small or truncated - cant fit all sub_auth') | ||
return '' | ||
sub_authorities = struct.unpack('<{}I'.format(num_sub_auth), data[8:8*num_sub_auth]) | ||
sid = 'S-{}-{}-'.format(rev, authority) + '-'.join([str(sa) for sa in sub_authorities]) | ||
return sid |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
'''Tests for the Shared-Cache strings (dsc) file parser.''' | ||
|
||
from __future__ import unicode_literals | ||
|
||
import unittest | ||
|
||
from UnifiedLog import data_format | ||
|
||
from tests import test_lib | ||
|
||
|
||
class BinaryDataFormat(test_lib.BaseTestCase): | ||
'''Tests for the binary data format.''' | ||
|
||
# TODO: add tests for _ReadAPFSTime | ||
|
||
def testReadCString(self): | ||
'''Tests the _ReadCString function.''' | ||
test_format = data_format.BinaryDataFormat() | ||
|
||
string = test_format._ReadCString(b'test\0bogus') | ||
self.assertEqual(string, 'test') | ||
|
||
string = test_format._ReadCString(b'\xff\xff\xff') | ||
self.assertEqual(string, '') | ||
|
||
def testReadCStringAndEndPos(self): | ||
'''Tests the _ReadCStringAndEndPos function.''' | ||
test_format = data_format.BinaryDataFormat() | ||
|
||
string, end_pos = test_format._ReadCStringAndEndPos(b'test\0bogus') | ||
self.assertEqual(string, 'test') | ||
self.assertEqual(end_pos, 4) | ||
|
||
string, end_pos = test_format._ReadCStringAndEndPos(b'\xff\xff\xff') | ||
self.assertEqual(string, '') | ||
self.assertEqual(end_pos, -1) | ||
|
||
# TODO: add tests for _ReadNtSid | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
Oops, something went wrong.