Skip to content

Instantly share code, notes, and snippets.

@atucom
Created June 11, 2025 21:36
Show Gist options
  • Save atucom/c6fb250cb88e2449474c672bb492a66c to your computer and use it in GitHub Desktop.
Save atucom/c6fb250cb88e2449474c672bb492a66c to your computer and use it in GitHub Desktop.
Get a consensus agreed rebuild of a firmware dump from multiple noisy dumps
import argparse
import numpy as np
from collections import Counter
# atucom
# example: $ python3 clean_firmware.py --threshold=0.8 firmware-dump/full_backup*.bin
def load_dumps(paths):
dumps = [np.fromfile(path, dtype=np.uint8) for path in paths]
lengths = [len(d) for d in dumps]
if len(set(lengths)) != 1:
raise ValueError("All dumps must be the same length")
return np.vstack(dumps)
def majority_vote(data, threshold=0.5):
clean = []
no_consensus = []
num_dumps, num_bytes = data.shape
required_votes = int(threshold * num_dumps)
for i in range(num_bytes):
column = data[:, i]
counts = Counter(column)
byte, freq = counts.most_common(1)[0]
if freq > required_votes:
clean.append(byte)
else:
clean.append(0xFF) # placeholder for unresolved
no_consensus.append((i, dict(counts)))
return np.array(clean, dtype=np.uint8), no_consensus
def write_output(clean, no_consensus, out_file, log_file):
clean.tofile(out_file)
with open(log_file, 'w') as f:
for offset, variants in no_consensus:
variants_str = ', '.join(f"{k:#04x}:{v}" for k, v in variants.items())
f.write(f"Offset {offset:#08x}: No consensus [{variants_str}]\n")
def main():
parser = argparse.ArgumentParser(description="Clean firmware from multiple noisy dumps.")
parser.add_argument('dumps', nargs='+', help="Paths to firmware dump files")
parser.add_argument('--out', default='reconstructed.bin', help="Output cleaned firmware")
parser.add_argument('--log', default='no_consensus.log', help="Log file for disagreements")
parser.add_argument('--threshold', type=float, default=0.5, help="Consensus threshold (0-1)")
args = parser.parse_args()
data = load_dumps(args.dumps)
clean, no_consensus = majority_vote(data, threshold=args.threshold)
write_output(clean, no_consensus, args.out, args.log)
print(f"✅ Cleaned firmware saved to {args.out}")
if no_consensus:
print(f"⚠️ {len(no_consensus)} bytes had no consensus. See {args.log} for details.")
else:
print("🎉 Full consensus across all bytes.")
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment