Last active
April 2, 2025 16:43
-
-
Save CypherpunkSamurai/4de429b1bf6136f9405b1086c562c2bd to your computer and use it in GitHub Desktop.
Spreadtrum Unisoc VBMeta DHTB Padding Finder
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
#!/usr/bin/env python3 | |
""" | |
DHTB Finder - Utility to find DHTB headers in binary files and extract information | |
Author: CypherpunkSamurai - github.com/CypherpunkSamurai | |
Email: [email protected] | |
credits: https://www.hovatek.com/forum/thread-32664-post-194145.html#pid194145 | |
""" | |
import argparse | |
import binascii | |
import os | |
import struct | |
import sys | |
from pathlib import Path | |
def convert_little_endian(value): | |
"""Convert a little endian hex value to integer.""" | |
return int.from_bytes(value, byteorder='little') | |
def find_dhtb_headers(file_path): | |
""" | |
Search for DHTB headers in the given binary file and extract relevant information. | |
Read header pad and convert to little endian from hex padding value. (https://www.scadacore.com/tools/programming-calculators/online-hex-converter/) | |
Known padding sizes: | |
00 50 00 00 = 20480 | |
00 40 00 00 = 16384 | |
00 30 00 00 = 12288 | |
""" | |
padding_sizes = { | |
b'\x00\x50\x00\x00': 20480, | |
b'\x00\x40\x00\x00': 16384, | |
b'\x00\x30\x00\x00': 12288, | |
} | |
print(f"Analyzing file: {file_path}") | |
file_size = os.path.getsize(file_path) | |
print(f"File size: {file_size} bytes") | |
with open(file_path, 'rb') as f: | |
data = f.read() | |
# Search for "DHTB" magic | |
dhtb_positions = [] | |
pos = 0 | |
while True: | |
pos = data.find(b'DHTB', pos) | |
if pos == -1: | |
break | |
dhtb_positions.append(pos) | |
pos += 4 | |
if not dhtb_positions: | |
print("No DHTB headers found in the file.") | |
return | |
print( | |
f"Found {len(dhtb_positions)} DHTB headers at positions: {dhtb_positions}") | |
for idx, pos in enumerate(dhtb_positions): | |
print(f"\n--- DHTB Header #{idx+1} at offset 0x{pos:X} ---") | |
# Extract DHTB header data (assuming a common structure) | |
# Assuming header is 64 bytes, adjust as needed | |
header_data = data[pos:pos+64] | |
# Display header in hex | |
print("DHTB Header (hex):") | |
for i in range(0, len(header_data), 16): | |
hex_values = ' '.join(f'{b:02X}' for b in header_data[i:i+16]) | |
ascii_values = ''.join(chr(b) if 32 <= b <= | |
126 else '.' for b in header_data[i:i+16]) | |
print(f"{i:04X}: {hex_values:<48} | {ascii_values}") | |
# Check for padding values after DHTB magic | |
for padding_bytes, padding_size in padding_sizes.items(): | |
padding_pos = data.find(padding_bytes, pos, pos+64) | |
if padding_pos != -1: | |
print( | |
f"Found padding value at offset 0x{padding_pos:X}: {binascii.hexlify(padding_bytes).decode()} = {padding_size} bytes") | |
print( | |
f"Little-endian value: {convert_little_endian(padding_bytes)}") | |
break | |
def main(): | |
parser = argparse.ArgumentParser( | |
description='Find DHTB headers in binary files') | |
parser.add_argument('file', help='Binary file to analyze') | |
args = parser.parse_args() | |
file_path = Path(args.file) | |
if not file_path.exists(): | |
print(f"Error: File '{file_path}' not found.") | |
return 1 | |
find_dhtb_headers(file_path) | |
return 0 | |
if __name__ == '__main__': | |
sys.exit(main()) |
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
#!/usr/bin/env python3 | |
""" | |
DHTB Finder - Utility to find DHTB headers in binary files and extract information | |
Author: CypherpunkSamurai - github.com/CypherpunkSamurai | |
Email: [email protected] | |
credits: https://www.hovatek.com/forum/thread-32664-post-194145.html#pid194145 | |
""" | |
import argparse | |
import binascii | |
import os | |
import struct | |
import sys | |
from pathlib import Path | |
# Try to import colorama for cross-platform colored output | |
try: | |
from colorama import Fore, Style, init | |
has_colorama = True | |
init() | |
except ImportError: | |
has_colorama = False | |
# Define padding sizes dictionary | |
PADDING_SIZES = { | |
b'\x00\x50\x00\x00': 20480, | |
b'\x00\x40\x00\x00': 16384, | |
b'\x00\x30\x00\x00': 12288, | |
} | |
def convert_little_endian(value): | |
"""Convert a little endian hex value to integer.""" | |
return int.from_bytes(value, byteorder='little') | |
def hex_dump(data, start_offset=0, colorize=True): | |
"""Format data as a hexdump with offset, hex values, and ASCII representation.""" | |
result = [] | |
use_color = colorize and has_colorama | |
for i in range(0, len(data), 16): | |
chunk = data[i:i+16] | |
# Format offset | |
offset_str = f"{start_offset+i:04X}: " | |
# Format hex values | |
hex_parts = [] | |
for b in chunk: | |
if use_color: | |
# Colorize special bytes | |
if b == 0x00: | |
hex_parts.append(f"{Fore.BLUE}{b:02X}{Fore.RESET}") | |
elif b == 0xFF: | |
hex_parts.append(f"{Fore.RED}{b:02X}{Fore.RESET}") | |
elif 32 <= b <= 126: # Printable ASCII | |
hex_parts.append(f"{Fore.GREEN}{b:02X}{Fore.RESET}") | |
else: | |
hex_parts.append(f"{b:02X}") | |
else: | |
hex_parts.append(f"{b:02X}") | |
hex_values = ' '.join(hex_parts) | |
# Format ASCII representation | |
ascii_parts = [] | |
for b in chunk: | |
if 32 <= b <= 126: # Printable ASCII | |
ascii_parts.append(chr(b)) | |
else: | |
ascii_parts.append('.') | |
ascii_values = ''.join(ascii_parts) | |
result.append(f"{offset_str}{hex_values:<48} | {ascii_values}") | |
return result | |
def print_with_color(text, color=None, style=None, enabled=True): | |
"""Print text with color if colorama is available.""" | |
if not enabled or not has_colorama: | |
print(text) | |
return | |
color_code = getattr(Fore, color.upper()) if color else '' | |
style_code = getattr(Style, style.upper()) if style else '' | |
print(f"{color_code}{style_code}{text}{Style.RESET_ALL}") | |
def print_padding_info(padding_bytes, padding_pos, matched_size): | |
"""Print padding information in a tree-like structure with colors.""" | |
padding_hex = ' '.join(f'{b:02X}' for b in padding_bytes) | |
print_with_color(f"+-- Padding Hex Value: {padding_hex}", "cyan", "BRIGHT") | |
print_with_color(f"+-- Hex Position: 0x{padding_pos:X}", "cyan") | |
print_with_color(f"+-- Padding Size: {matched_size} bytes", "cyan") | |
print_with_color("|", "cyan") | |
# Display all known padding values, highlighting the matched one | |
for pad_bytes, pad_size in PADDING_SIZES.items(): | |
pad_hex = ' '.join(f'{b:02X}' for b in pad_bytes) | |
if pad_bytes == padding_bytes: | |
print_with_color( | |
f"| > {pad_hex} = {pad_size}", "white", "BRIGHT") | |
else: | |
print_with_color( | |
f"| x {pad_hex} = {pad_size}", "white", "DIM") | |
print_with_color("|", "cyan") | |
print_with_color( | |
f"+-- Little-Endian Value: {convert_little_endian(padding_bytes)}", "cyan") | |
print_with_color( | |
f"\nPadding Value is: {matched_size} bytes", "green", "BRIGHT") | |
def find_dhtb_headers(file_path): | |
""" | |
Search for DHTB headers in the given binary file and extract relevant information. | |
""" | |
print(f"Analyzing file: {file_path}") | |
file_size = os.path.getsize(file_path) | |
print(f"File size: {file_size} bytes") | |
with open(file_path, 'rb') as f: | |
data = f.read() | |
# Search for "DHTB" magic | |
dhtb_positions = [] | |
pos = 0 | |
while True: | |
pos = data.find(b'DHTB', pos) | |
if pos == -1: | |
break | |
dhtb_positions.append(pos) | |
pos += 4 | |
if not dhtb_positions: | |
print("No DHTB headers found in the file.") | |
return | |
print( | |
f"Found {len(dhtb_positions)} DHTB headers at positions: {dhtb_positions}") | |
for idx, pos in enumerate(dhtb_positions): | |
print(f"\n--- DHTB Header #{idx+1} at offset 0x{pos:X} ---") | |
# Extract DHTB header data (assuming a common structure) | |
# Assuming header is 64 bytes, adjust as needed | |
header_data = data[pos:pos+64] | |
# Display header in hex | |
print("DHTB Header (hex):") | |
for line in hex_dump(header_data, pos): | |
print(line) | |
# Check for padding values after DHTB magic | |
padding_found = False | |
for padding_bytes, padding_size in PADDING_SIZES.items(): | |
padding_pos = data.find(padding_bytes, pos, pos+64) | |
if padding_pos != -1: | |
print("\nPadding Information:") | |
print_padding_info(padding_bytes, padding_pos, padding_size) | |
padding_found = True | |
break | |
if not padding_found: | |
print("\nNo known padding value found in this DHTB header.") | |
def main(): | |
parser = argparse.ArgumentParser( | |
description='Find DHTB headers in binary files') | |
parser.add_argument('file', help='Binary file to analyze') | |
parser.add_argument('--no-color', action='store_true', | |
help='Disable colored output') | |
global args # Make args available to other functions | |
args = parser.parse_args() | |
file_path = Path(args.file) | |
if not file_path.exists(): | |
print(f"Error: File '{file_path}' not found.") | |
return 1 | |
find_dhtb_headers(file_path) | |
return 0 | |
if __name__ == '__main__': | |
sys.exit(main()) |
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
#!/usr/bin/env python3 | |
""" | |
DHTB Finder - Utility to find DHTB headers in binary files and extract information | |
Author: CypherpunkSamurai - github.com/CypherpunkSamurai | |
Email: [email protected] | |
credits: https://www.hovatek.com/forum/thread-32664-post-194145.html#pid194145 | |
""" | |
import argparse | |
import binascii | |
import os | |
import struct | |
import sys | |
from pathlib import Path | |
# Try to import colorama for cross-platform colored output | |
try: | |
from colorama import init, Fore, Style | |
has_colorama = True | |
init() | |
except ImportError: | |
has_colorama = False | |
# Define padding sizes dictionary | |
PADDING_SIZES = { | |
b'\x00\x50\x00\x00': 20480, | |
b'\x00\x40\x00\x00': 16384, | |
b'\x00\x30\x00\x00': 12288, | |
} | |
def convert_little_endian(value): | |
"""Convert a little endian hex value to integer.""" | |
return int.from_bytes(value, byteorder='little') | |
def hex_dump(data, start_offset=0): | |
"""Format data as a hexdump with offset, hex values, and ASCII representation.""" | |
result = [] | |
for i in range(0, len(data), 16): | |
hex_values = ' '.join(f'{b:02X}' for b in data[i:i+16]) | |
ascii_values = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in data[i:i+16]) | |
result.append(f"{start_offset+i:04X}: {hex_values:<48} | {ascii_values}") | |
return result | |
def print_with_color(text, color=None, style=None, enabled=True): | |
"""Print text with color if colorama is available.""" | |
if not enabled or not has_colorama: | |
print(text) | |
return | |
color_code = getattr(Fore, color.upper()) if color else '' | |
style_code = getattr(Style, style.upper()) if style else '' | |
print(f"{color_code}{style_code}{text}{Style.RESET_ALL}") | |
def print_padding_info(padding_bytes, padding_pos, matched_size): | |
"""Print padding information in a tree-like structure with colors.""" | |
padding_hex = ' '.join(f'{b:02X}' for b in padding_bytes) | |
print_with_color(f"+-- Padding Hex Value: {padding_hex}", "cyan", "BRIGHT") | |
print_with_color(f"+-- Hex Position: 0x{padding_pos:X}", "cyan") | |
print_with_color(f"+-- Padding Size: {matched_size} bytes", "cyan") | |
print_with_color("|", "cyan") | |
# Display all known padding values, highlighting the matched one | |
for pad_bytes, pad_size in PADDING_SIZES.items(): | |
pad_hex = ' '.join(f'{b:02X}' for b in pad_bytes) | |
if pad_bytes == padding_bytes: | |
print_with_color(f"| > {pad_hex} = {pad_size}", "white", "BRIGHT") | |
else: | |
print_with_color(f"| x {pad_hex} = {pad_size}", "white", "DIM") | |
print_with_color("|", "cyan") | |
print_with_color(f"+-- Little-Endian Value: {convert_little_endian(padding_bytes)}", "cyan") | |
print_with_color(f"\nPadding Value is: {matched_size} bytes", "green", "BRIGHT") | |
def find_dhtb_headers(file_path): | |
""" | |
Search for DHTB headers in the given binary file and extract relevant information. | |
""" | |
print(f"Analyzing file: {file_path}") | |
file_size = os.path.getsize(file_path) | |
print(f"File size: {file_size} bytes") | |
with open(file_path, 'rb') as f: | |
data = f.read() | |
# Search for "DHTB" magic | |
dhtb_positions = [] | |
pos = 0 | |
while True: | |
pos = data.find(b'DHTB', pos) | |
if pos == -1: | |
break | |
dhtb_positions.append(pos) | |
pos += 4 | |
if not dhtb_positions: | |
print("No DHTB headers found in the file.") | |
return | |
print(f"Found {len(dhtb_positions)} DHTB headers at positions: {dhtb_positions}") | |
for idx, pos in enumerate(dhtb_positions): | |
print(f"\n--- DHTB Header #{idx+1} at offset 0x{pos:X} ---") | |
# Extract DHTB header data (assuming a common structure) | |
# Assuming header is 64 bytes, adjust as needed | |
header_data = data[pos:pos+64] | |
# Display header in hex | |
print("DHTB Header (hex):") | |
for line in hex_dump(header_data, pos): | |
print(line) | |
# Check for padding values after DHTB magic | |
padding_found = False | |
for padding_bytes, padding_size in PADDING_SIZES.items(): | |
padding_pos = data.find(padding_bytes, pos, pos+64) | |
if padding_pos != -1: | |
print("\nPadding Information:") | |
print_padding_info(padding_bytes, padding_pos, padding_size) | |
padding_found = True | |
break | |
if not padding_found: | |
print("\nNo known padding value found in this DHTB header.") | |
def main(): | |
parser = argparse.ArgumentParser(description='Find DHTB headers in binary files') | |
parser.add_argument('file', help='Binary file to analyze') | |
parser.add_argument('--no-color', action='store_true', help='Disable colored output') | |
args = parser.parse_args() | |
file_path = Path(args.file) | |
if not file_path.exists(): | |
print(f"Error: File '{file_path}' not found.") | |
return 1 | |
# Set global color flag | |
global use_color | |
use_color = not args.no_color | |
find_dhtb_headers(file_path) | |
return 0 | |
if __name__ == '__main__': | |
sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment