--- /dev/null
+#!/usr/bin/env python3
+#
+# Interpret a file that crashes an fuzz_ndr_X binary.
+#
+# Copyright (C) Catalyst IT Ltd. 2019
+
+
+import sys
+import os
+from base64 import b64encode
+import struct
+import argparse
+
+
+TYPE_MASK = 3
+TYPES = ['struct', 'in', 'out']
+
+FLAGS = [
+ (4, 'ndr64', '--ndr64'),
+]
+
+def process_one_file(f):
+ b = f.read()
+ flags, function = struct.unpack('<HH', b[:4])
+ if opnum is not None and opnum != function:
+ return
+
+ t = TYPES[flags & TYPE_MASK]
+ if ndr_type and ndr_type != t:
+ return
+
+ print(f.name)
+ print('-' * len(f.name))
+
+ payload = b[4:]
+
+ cmd = ['bin/ndrdump', pipe, str(function), t]
+ for flag, name, option in FLAGS:
+ if flags & flag:
+ print("flag: %s" % name)
+ cmd.append(option)
+ data64 = b64encode(payload)
+ print("length: %d" % len(payload))
+ cmdstr = ("echo -n '%s' | base64 -d | %s" % (data64.decode('utf-8'),
+ ' '.join(cmd)))
+ print()
+ print(cmdstr)
+ print()
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-p', '--pipe', default='$PIPE',
+ help='pipe name (for output command line)')
+ parser.add_argument('-t', '--type', default=None, choices=TYPES,
+ help='restrict to this type')
+ parser.add_argument('-o', '--opnum', default=None, type=int,
+ help='restrict to this function/struct number')
+ parser.add_argument('FILES', nargs='*', default ='-',
+ help="read from these files")
+ parser.add_argument('-k', '--ignore-errors', action='store_true',
+ help='do not stop on errors')
+
+ args = parser.parse_args()
+
+ global pipe, opnum, ndr_type
+ pipe = args.pipe
+ opnum = args.opnum
+ ndr_type = args.type
+
+
+ if not args.FILES and not args.honggfuzz_file:
+ parser.print_usage()
+ sys.exit(1)
+
+ for fn in args.FILES:
+ try:
+ if fn == '-':
+ process_one_file(sys.stdin)
+ else:
+ with open(fn, 'rb') as f:
+ process_one_file(f)
+ except Exception:
+ print("Error processing %s\n" % fn)
+ if args.ignore_errors:
+ continue
+ raise
+
+main()