/extra/safe2bin/safe2bin.py
Python | 120 lines | 114 code | 1 blank | 5 comment | 0 complexity | 6ac48a437824451bf6ab3a194846ba6b MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
- #!/usr/bin/env python
- """
- safe2bin.py - Simple safe(hex) to binary format converter
- Copyright (c) 2006-2012 sqlmap developers (http://sqlmap.org/)
- See the file 'doc/COPYING' for copying permission
- """
- import binascii
- import re
- import string
- import os
- import sys
- from optparse import OptionError
- from optparse import OptionParser
- # Regex used for recognition of hex encoded characters
- HEX_ENCODED_CHAR_REGEX = r"(?P<result>\\x[0-9A-Fa-f]{2})"
- # Raw chars that will be safe encoded to their slash (\) representations (e.g. newline to \n)
- SAFE_ENCODE_SLASH_REPLACEMENTS = "\t\n\r\x0b\x0c"
- # Characters that don't need to be safe encoded
- SAFE_CHARS = "".join(filter(lambda x: x not in SAFE_ENCODE_SLASH_REPLACEMENTS, string.printable.replace('\\', '')))
- # String used for temporary marking of slash characters
- SLASH_MARKER = "__SLASH__"
- def safecharencode(value):
- """
- Returns safe representation of a given basestring value
- >>> safecharencode(u'test123')
- u'test123'
- >>> safecharencode(u'test\x01\x02\xff')
- u'test\\01\\02\\03\\ff'
- """
- retVal = value
- if isinstance(value, basestring):
- if any(_ not in SAFE_CHARS for _ in value):
- retVal = re.sub(r'(?i)(?!\\x[0-9A-F]{2})\\', SLASH_MARKER, value)
- for char in SAFE_ENCODE_SLASH_REPLACEMENTS:
- retVal = retVal.replace(char, repr(char).strip('\''))
- retVal = retVal.replace(SLASH_MARKER, '\\\\')
- retVal = reduce(lambda x, y: x + (y if (y in string.printable or ord(y) > 255) else '\\x%02x' % ord(y)), retVal, unicode())
- elif isinstance(value, list):
- for i in xrange(len(value)):
- retVal[i] = safecharencode(value[i])
- return retVal
- def safechardecode(value):
- """
- Reverse function to safecharencode
- """
- retVal = value
- if isinstance(value, basestring):
- regex = re.compile(HEX_ENCODED_CHAR_REGEX)
- while True:
- match = regex.search(retVal)
- if match:
- retVal = retVal.replace(match.group("result"), unichr(ord(binascii.unhexlify(match.group("result").lstrip('\\x')))))
- else:
- break
- retVal = retVal.replace('\\\\', SLASH_MARKER)
- for char in SAFE_ENCODE_SLASH_REPLACEMENTS[::-1]:
- retVal = retVal.replace(repr(char).strip('\''), char)
- retVal = retVal.replace(SLASH_MARKER, '\\')
- elif isinstance(value, (list, tuple)):
- for i in xrange(len(value)):
- retVal[i] = safechardecode(value[i])
- return retVal
- def main():
- usage = '%s -i <input file> [-o <output file>]' % sys.argv[0]
- parser = OptionParser(usage=usage, version='0.1')
- try:
- parser.add_option('-i', dest='inputFile', help='Input file')
- parser.add_option('-o', dest='outputFile', help='Output file')
- (args, _) = parser.parse_args()
- if not args.inputFile:
- parser.error('Missing the input file, -h for help')
- except (OptionError, TypeError), e:
- parser.error(e)
- if not os.path.isfile(args.inputFile):
- print 'ERROR: the provided input file \'%s\' is not a regular file' % args.inputFile
- sys.exit(1)
- f = open(args.inputFile, 'r')
- data = f.read()
- f.close()
- if not args.outputFile:
- args.outputFile = args.inputFile + '.bin'
- f = open(args.outputFile, 'wb')
- f.write(safechardecode(data))
- f.close()
- if __name__ == '__main__':
- main()