Guest User

Untitled

a guest
Dec 14th, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.44 KB | None | 0 0
  1. import datetime
  2. import os
  3.  
  4. from bitstring import ConstBitStream
  5.  
  6.  
  7. class HikvisionDrive:
  8.  
  9. def __init__(self, file_loc):
  10. # create data stream of hard drive
  11. self.file = file_loc
  12. self.data = ConstBitStream(filename=self.file)
  13.  
  14. # get information from master sector
  15. self.data.pos = 584 * 8
  16. self.capacity = self.data.read('uintle:64')
  17.  
  18. self.data.pos += 56 * 8
  19. self.data_block_size = self.data.read('uintle:64')
  20. self.total_data_blocks = self.data.read('uintle:32')
  21.  
  22. self.data.pos += 4 * 8
  23. self.hikbtree_offset = self.data.read('uintle:64')
  24. self.hikbtree_size = self.data.read('uintle:32')
  25.  
  26. # get information from hikbtree
  27. self.data.pos = (self.hikbtree_offset + 80) * 8
  28. self.page_list_offset = self.data.read('uintle:64')
  29.  
  30. # initialise list for data blocks
  31. self.data_blocks = []
  32.  
  33. def show_info(self):
  34. print('-Hard Drive Information-')
  35. print('File: ' + str(self.file))
  36. print('Capacity: ' + str(self.capacity) + ' bytes')
  37. print('Data Block Size: ' + str(self.data_block_size) + ' bytes')
  38. print('Number of Data Blocks: ' + str(self.total_data_blocks))
  39. print('HikBTree Offset: ' + str(self.hikbtree_offset))
  40. print('HikBTree Size: ' + str(self.hikbtree_size) + ' bytes')
  41. print('Page List Offset: ' + str(self.page_list_offset))
  42.  
  43. def save_blocks(self, save_directory):
  44. # loop through data blocks and save the data into a structured directory
  45. # setup progress counter
  46. x = 1
  47. with open(self.file, 'rb') as f1:
  48. for data_block in self.data_blocks[:1000]:
  49. # update progress
  50. print('saving data block #', x, 'of', self.total_data_blocks, '...')
  51. # set directory
  52. date = data_block['start_time']
  53. save_dir = save_directory + '\' + str(date.year) + '-' + date.strftime('%B') + '\'
  54. + date.strftime('%d')
  55. if not os.path.exists(save_dir):
  56. os.makedirs(save_dir)
  57. # save the data to a file
  58. file_name = 'CH' + str(data_block['channel']) + '_' + date.strftime('%H') + '-' + date.strftime(
  59. '%M') + '-' + date.strftime('%S') + '_block' + str(x) + '.raw'
  60. length = self.data_block_size
  61. f1.seek(data_block['offset'])
  62. with open(str(save_dir + '\' + file_name), 'wb') as f2:
  63. while length:
  64. chunk = min(1024 * 1024, length)
  65. data = f1.read(chunk)
  66. f2.write(data)
  67. length -= chunk
  68. f2.close()
  69. x += 1
  70. f1.close()
  71.  
  72. def scan_pages(self):
  73. # create list of page offsets
  74. page_offsets = []
  75. # get the offset to Page #1
  76. self.data.pos = (self.page_list_offset + 24) * 8
  77. page_offsets.append(self.data.read('uintle:64'))
  78. # loop through the rest of the list
  79. self.data.pos += 64 * 8
  80. page_offset = self.data.read('uintle:64')
  81. while page_offset != 0:
  82. page_offsets.append(page_offset)
  83. self.data.pos += 40 * 8
  84. page_offset = self.data.read('uintle:64')
  85. # create list of data blocks from the pages
  86. for page in page_offsets:
  87. self.data.pos = (page + 96) * 8
  88. entry = True if self.data.read('hex:64') == 'ffffffffffffffff' else False
  89. while entry:
  90. video_exists = True if self.data.read('hex:64') == '0000000000000000' else False
  91. self.data.pos += 1 * 8
  92. channel = self.data.read('uint:8')
  93. self.data.pos += 6 * 8
  94. start_time = datetime.datetime.fromtimestamp(self.data.read('uintle:32'))
  95. end_time = datetime.datetime.fromtimestamp(self.data.read('uintle:32'))
  96. data_offset = self.data.read('uintle:64')
  97. self.data_blocks.append({'channel': channel, 'has_video': video_exists, 'start_time': start_time,
  98. 'end_time': end_time, 'offset': data_offset})
  99. # move to next block entry
  100. self.data.pos += 8 * 8
  101. entry = True if self.data.read('hex:64') == 'ffffffffffffffff' else False
  102.  
  103.  
  104. drive = HikvisionDrive(r'D:213_HDD.001')
  105. drive.show_info()
  106. drive.scan_pages()
  107. drive.save_blocks(r'D:Carved Files')
Add Comment
Please, Sign In to add comment