Advertisement
Guest User

binsearch.py: Binary file search

a guest
Feb 11th, 2024
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.24 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. import sys, os, argparse
  4. import mmap, codecs, re
  5. import signal
  6.  
  7. if os.name != 'posix':
  8.     exit('Platform is not supported')
  9.  
  10. # Reset SIGINT handler to default value since Python's
  11. # handler do not respond to the signal during search
  12. signal.signal(signal.SIGINT, signal.SIG_DFL)
  13.  
  14. def parse_args():
  15.     p = argparse.ArgumentParser(description='Binary file search')
  16.     p.add_argument('pattern', type=str, help='pattern to search for', metavar='PATTERN')
  17.     p.add_argument('file', type=str, help='regular file or block device', metavar='FILE')
  18.     p.add_argument('-r', '--regexp', action='store_true', help='do regexp search instead of fixed string')
  19.     p.add_argument('-i', '--ignore_case', action='store_true', help='do case insensitive search (regexp)')
  20.     p.add_argument('-p', '--print_match', action='store_true', help='print matched substring (regexp)')
  21.     p.add_argument('-o', '--output', type=str, default='/dev/stdout', help='output file (default=stdout)')
  22.     p.add_argument('--license', action='store_true', help='show license')
  23.     if '--license' in sys.argv: print('Public domain') or exit(0)
  24.     a = p.parse_args()
  25.     a.pattern = codecs.escape_decode(a.pattern)[0]
  26.     return a
  27.  
  28. def mmap_file(file):
  29.     if os.stat(file).st_mode >> 12 not in (6, 8):
  30.         exit('Only regular files and block devices are supported')
  31.     fd = os.open(file, os.O_RDONLY)
  32.     file_size = os.lseek(fd, 0, os.SEEK_END)
  33.     return mmap.mmap(fd, file_size, prot=mmap.PROT_READ)
  34.  
  35. def gen_regex(a, mm):
  36.     flags = re.DOTALL | (a.ignore_case and re.I)
  37.     for mo in re.finditer(a.pattern, mm, flags=flags):
  38.         yield mo.start(), mo.group(0)
  39.        
  40. def gen_fixed(a, mm):
  41.     offset = 0
  42.     while (offset := mm.find(a.pattern, offset+1)) >= 0:
  43.         yield offset, None
  44.  
  45. def do_all():
  46.     a = parse_args()
  47.     mm = mmap_file(a.file)
  48.     gen = gen_regex if a.regexp else gen_fixed
  49.     f = open(a.output, 'wb')
  50.     print_match = a.regexp and a.print_match
  51.     exit_status = 1
  52.    
  53.     for offset,match in gen(a, mm):
  54.         f.write(f'@ 0x{offset:010x} ({offset})\n'.encode())
  55.         if print_match:
  56.             f.write(match + b'\n')
  57.         f.flush()
  58.         exit_status = 0
  59.    
  60.     return exit_status
  61.  
  62. exit(do_all())
  63.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement