Created
May 7, 2024 11:25
-
-
Save yosignals/860da7a7bbdc1efbdc00d62db7b1cd8b to your computer and use it in GitHub Desktop.
File Folding with folders and files and extension preferences
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
import os | |
import argparse | |
import hashlib | |
import json | |
from itertools import islice | |
def file_to_hex(filename): | |
"""Convert file content to a hex string.""" | |
with open(filename, 'rb') as file: | |
content = file.read() | |
return content.hex(), content | |
def calculate_sha256(file_content): | |
"""Calculate SHA-256 hash of the given file content.""" | |
sha256 = hashlib.sha256() | |
sha256.update(file_content) | |
return sha256.hexdigest() | |
def chunked(iterable, size): | |
"""Yield successive chunks of a given size from an iterable.""" | |
iterable = iter(iterable) | |
return iter(lambda: tuple(islice(iterable, size)), ()) | |
def create_subfolders(base_path, subfolder_prefix): | |
"""Create a subfolder and return its path.""" | |
subfolder_name = f"{subfolder_prefix}" | |
subfolder_path = os.path.join(base_path, subfolder_name) | |
os.makedirs(subfolder_path, exist_ok=True) | |
return subfolder_path | |
def create_hierarchical_folders_with_metadata(hex_data, base_path, max_length=230, split_percent=25, extension='json'): | |
"""Create a hierarchical structure of folders and files with metadata.""" | |
num_segments = (len(hex_data) + max_length - 1) // max_length | |
segments = [hex_data[i * max_length:(i + 1) * max_length] for i in range(num_segments)] | |
num_subfolders = (num_segments * split_percent) // 100 or 1 | |
chunk_size = (num_segments + num_subfolders - 1) // num_subfolders | |
folder_metadata = {} | |
file_metadata = {} | |
for i, segment_chunk in enumerate(chunked(segments, chunk_size)): | |
subfolder_prefix = segment_chunk[0][:8] if segment_chunk else 'empty' | |
subfolder_name = f"{i:04d}_{subfolder_prefix}" | |
subfolder_path = create_subfolders(base_path, subfolder_name) | |
folder_metadata[subfolder_name] = [] | |
for j, segment in enumerate(segment_chunk): | |
filename = f"{j:04d}_{segment[:max_length]}.{extension}" | |
file_path = os.path.join(subfolder_path, filename) | |
with open(file_path, 'w') as file: | |
file.write(segment[:max_length]) | |
segment_hash = hashlib.sha256(segment[:max_length].encode()).hexdigest() | |
file_metadata[file_path] = segment_hash | |
folder_metadata[subfolder_name].append({'file': filename, 'checksum': segment_hash}) | |
metadata = {'folders': folder_metadata, 'files': file_metadata} | |
with open(os.path.join(base_path, 'metadata.json'), 'w') as meta_file: | |
json.dump(metadata, meta_file, indent=4) | |
return len(folder_metadata), len(file_metadata) | |
def hex_to_binary(hex_str): | |
"""Convert hexadecimal string to binary data.""" | |
return bytes.fromhex(hex_str) | |
def rebuild_file_from_metadata(base_path, output_filename): | |
"""Rebuild a file from a hierarchical folder structure using a metadata file.""" | |
base_path = os.path.abspath(base_path) | |
metadata_file = os.path.join(base_path, 'metadata.json') | |
if not os.path.exists(metadata_file): | |
print("Error: Metadata file is missing.") | |
return | |
with open(metadata_file, 'r') as meta_file: | |
metadata = json.load(meta_file) | |
all_segments = [] | |
for folder, files in metadata['folders'].items(): | |
folder_path = os.path.join(base_path, folder) | |
for entry in files: | |
file_name = entry['file'] | |
file_path = os.path.join(folder_path, file_name) | |
expected_checksum = entry['checksum'] | |
with open(file_path, 'r') as file: | |
segment = file.read().strip() | |
actual_checksum = hashlib.sha256(segment.encode()).hexdigest() | |
if actual_checksum != expected_checksum: | |
print(f"Warning: Segment checksum mismatch for file {file_name}. Skipping.") | |
else: | |
all_segments.append(segment) | |
if not all_segments: | |
print("Error: No valid segments found for reconstruction.") | |
else: | |
hex_data = ''.join(all_segments) | |
binary_data = hex_to_binary(hex_data) | |
with open(output_filename, 'wb') as file: | |
file.write(binary_data) | |
def main(): | |
parser = argparse.ArgumentParser( | |
description="File Folding: Create or rebuild files from hierarchical folders.", | |
epilog=("Examples:\n" | |
" python3 Folding.py create input.txt --output out --split_percent 25 --extension json\n" | |
" python3 Folding.py rebuild out --output rebuilt_input.txt"), | |
formatter_class=argparse.RawTextHelpFormatter) | |
parser.add_argument('mode', choices=['create', 'rebuild'], help='Operation mode: "create" or "rebuild"') | |
parser.add_argument('path', help='Path to the input file or directory') | |
parser.add_argument('--output', help='Output file or directory', required=True) | |
parser.add_argument('--split_percent', type=int, default=25, help='Percentage of files per subfolder (default is 25%)') | |
parser.add_argument('--extension', default='json', help='File extension for the segments (default is "json")') | |
args = parser.parse_args() | |
if args.mode == 'create': | |
hex_data, original_content = file_to_hex(args.path) | |
folder_count, file_count = create_hierarchical_folders_with_metadata(hex_data, args.output, max_length=230, split_percent=args.split_percent, extension=args.extension) | |
file_size = os.path.getsize(args.path) | |
file_sha256 = calculate_sha256(original_content) | |
print(f"Created hierarchical folder structure in {args.output} based on the file {args.path}") | |
print(f"Original file size: {file_size} bytes") | |
print(f"SHA-256 hash of the original file: {file_sha256}") | |
print(f"Summary: {folder_count} folders and {file_count} files created.") | |
# Write the checksum to a file | |
with open(os.path.join(args.output, 'checksum.txt'), 'w') as checksum_file: | |
checksum_file.write(file_sha256) | |
elif args.mode == 'rebuild': | |
rebuild_file_from_metadata(args.path, args.output) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
python3 Folding.py file.exe --output out --split_percent 25 --extension json
python3 Folding.py rebuild out --output mimikatz.exe