noise (line)
+SLICE_START = 1 # ordering is important to have starts of intervals
+SLICE_END = 0 # sorted before equal ends
+
+def find_overlaps (slices):
+ """
+ Find overlapping slices: iterate open/close points of intervals, tracking
+ the ones open at any time.
+ """
+ bounds = []
+ inside = set () # of indices into bounds
+ ovrlp = set () # of indices into bounds
+
+ for i, s in enumerate (slices):
+ bounds.append ((s [0], SLICE_START, i))
+ bounds.append ((s [1], SLICE_END , i))
+ bounds = sorted (bounds)
+
+ for val in bounds:
+ i = val [2]
+ if val [1] == SLICE_START:
+ inside.add (i)
+ else:
+ if len (inside) > 1: # closing one that overlapped
+ ovrlp |= inside
+ inside.remove (i)
+
+ return [ slices [i] for i in ovrlp ]
+
+
def mode_scan (secret, fname, outs=None, nacl=None):
"""
Dissect a binary file, looking for PDTCRYPT headers and objects.
os.close (ifd)
raise
- junk, todo = [], []
+ junk, todo, slices = [], [], []
try:
nobj = 0
for cand in cands:
nobj += 1
vdt, hdr = inspect_hdr (ifd, cand)
+
if vdt == HDR_CAND_JUNK:
junk.append (cand)
else:
ofname = PDTCRYPT_RESCUENAME % nobj
ofd = open2_dump_file (ofname, outs, force=PDTCRYPT_OVERWRITE)
+ ctsize = hdr ["ctsize"]
try:
- ok = try_decrypt (ifd, off0, hdr, secret, ofd=ofd) == hdr ["ctsize"]
+ l = try_decrypt (ifd, off0, hdr, secret, ofd=ofd)
+ ok = l == ctsize
+ slices.append ((off0, off0 + l))
finally:
if ofd != -1:
os.close (ofd)
if vdt == HDR_CAND_GOOD and ok is True:
noise ("PDT: %d → ✓ valid object %d–%d"
- % (cand, off0, off0 + hdr ["ctsize"]))
+ % (cand, off0, off0 + ctsize))
elif vdt == HDR_CAND_FISHY and ok is True:
noise ("PDT: %d → × object %d–%d, corrupt header"
- % (cand, off0, off0 + hdr ["ctsize"]))
+ % (cand, off0, off0 + ctsize))
elif vdt == HDR_CAND_GOOD and ok is False:
noise ("PDT: %d → × object %d–%d, problematic payload"
- % (cand, off0, off0 + hdr ["ctsize"]))
+ % (cand, off0, off0 + ctsize))
elif vdt == HDR_CAND_FISHY and ok is False:
noise ("PDT: %d → × object %d–%d, corrupt header, problematic "
- "ciphertext" % (cand, off0, off0 + hdr ["ctsize"]))
+ "ciphertext" % (cand, off0, off0 + ctsize))
else:
raise Unreachable
finally:
noise ("PDT: %d candidates not parseable as headers:" % len (junk))
noise_output_candidates (junk)
+ overlap = find_overlaps (slices)
+ if len (overlap) > 0:
+ noise ("PDT: %d objects overlapping others" % len (overlap))
+ for slice in overlap:
+ noise ("PDT: × %d→%d" % (slice [0], slice [1]))
+
def usage (err=False):
out = print
if err is True: