Created
June 21, 2020 12:40
-
-
Save msuhanov/44ea8a306ad8488d7ebdb6a2b1af7c67 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/usr/bin/env python3 | |
# (c) Maxim Suhanov | |
# 2020 | |
import sys | |
if len(sys.argv) != 4: | |
print('Usage: extract_unallocated.py <bitmap file> <flat image> <cluster size (in bytes)') | |
sys.exit(0) | |
with open(sys.argv[1], 'rb') as bitmap: | |
bitmap_buffer = bitmap.read() | |
volume = open(sys.argv[2], 'rb') | |
cluster_size = int(sys.argv[3]) | |
if cluster_size <= 0 or cluster_size % 512 != 0: | |
raise ValueError('Invalid cluster size') | |
sector_size = 512 | |
sectors_per_cluster = cluster_size // sector_size | |
empty_sector = b'EMPTY ' * 32 | |
original_sector = b'ORIGINAL ' * 32 | |
null_sector = b'\x00' * 512 | |
cnt_empty = 0 | |
cnt_original = 0 | |
cnt_valid = 0 | |
cnt_null = 0 | |
bit_index = 0 | |
while True: | |
try: | |
current_bitmap_byte = bitmap_buffer[bit_index // 8] | |
except IndexError: | |
break | |
current_bitmap_bit = (current_bitmap_byte >> (bit_index % 8)) & 1 | |
if current_bitmap_bit == 0: | |
volume.seek(bit_index * cluster_size) | |
for __ in range(sectors_per_cluster): | |
unallocated_sector = volume.read(sector_size) | |
truncated_read = len(unallocated_sector) != sector_size | |
if unallocated_sector == empty_sector: | |
cnt_empty += 1 | |
elif unallocated_sector == original_sector: | |
cnt_original += 1 | |
else: | |
cnt_valid += 1 | |
sys.stdout.buffer.write(unallocated_sector) | |
if unallocated_sector == null_sector: | |
cnt_null += 1 | |
if truncated_read: | |
break | |
if truncated_read: | |
break | |
bit_index += 1 | |
volume.close() | |
print('Empty (null) sectors: {}, original sectors: {}, valid unallocated sectors: {}, valid sectors with nulls: {}\n'.format(cnt_empty, cnt_original, cnt_valid, cnt_null), file = sys.stderr) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment