Advertisement
opexxx

bin2py.py

May 26th, 2014
324
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.42 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. # Convert binary files to data embedded in Python sources
  4. # by Mario Vilas (mvilas at gmail.com)
  5.  
  6. # Copyright (c) 2009-2011, Mario Vilas
  7. # All rights reserved.
  8. #
  9. # Redistribution and use in source and binary forms, with or without
  10. # modification, are permitted provided that the following conditions are met:
  11. #     * Redistributions of source code must retain the above copyright
  12. #       notice, this list of conditions and the following disclaimer.
  13. #     * Redistributions in binary form must reproduce the above copyright
  14. #       notice, this list of conditions and the following disclaimer in the
  15. #       documentation and/or other materials provided with the distribution.
  16. #     * Neither the name of the copyright holder nor the
  17. #       names of its contributors may be used to endorse or promote products
  18. #       derived from this software without specific prior written permission.
  19. #
  20. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY
  21. # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23. # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
  24. # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  25. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  27. # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  
  31. import os
  32. import sys
  33. import glob
  34. import string
  35. import base64
  36. import zlib
  37. import gzip
  38.  
  39. try:
  40.     import cStringIO as StringIO
  41. except ImportError:
  42.     import StringIO
  43.  
  44.  
  45. helpMessage = '''Convert binary files to data embedded in Python sources
  46. by Mario Vilas (mvilas at gmail.com)
  47.  
  48. Usage:
  49.  
  50.    ./%s {input} [switches]
  51.  
  52. Where "input" is a glob-style filename list, and "switches" can be a combination of the following:
  53.  
  54.    -a                  Append output instead of overwriting
  55.    -b                  Encode with base64
  56.    -d                  Add python code to decode the string
  57.    -g                  Compress with gzip
  58.    -o filename         Specify a single output file
  59.    -x                  Convert to hexadecimal, instead of using repr()
  60.    -z                  Compress with zlib'''
  61.  
  62.  
  63. def showHelp(e = None):
  64.     if e: print "Error: %s\n" % e
  65.     print helpMessage % os.path.basename(sys.argv[0])
  66.  
  67.  
  68. def parseCommandLine():
  69.    
  70.     argv = []
  71.     for i in range(1, len(sys.argv)):
  72.         token = sys.argv[i]
  73.         if token[0] in ('-', '/'):
  74.             for c in token[1:]:
  75.                 argv.append('-' + c)
  76.         else:
  77.             argv.append(token)
  78.    
  79.     if not argv: raise Exception, "no parameters supplied"
  80.    
  81.     input       = []
  82.     output      = []
  83.    
  84.     appendflag  = False
  85.     hexaflag    = False
  86.     zlibflag    = False
  87.     gzipflag    = False
  88.     base64flag  = False
  89.     decoderflag = False
  90.    
  91.     i = 0
  92.     while i < len(argv):
  93.         token = argv[i]
  94.         if token[0] == '-':
  95.             s = token[1].lower()
  96.             if s == 'o':                                                                    # output filename
  97.                 if output: raise Exception, "inconsistent switch: %s" % s
  98.                 i += 1
  99.                 if i >= len(argv): raise Exception, "expected parameter after switch -%s" % s
  100.                 output_filename = argv[i]
  101.                 if output_filename[0] == '-': raise Exception, "unexpected argument: %r" % token
  102.                 output_filename = os.path.abspath(output_filename)
  103.                 output.append(output_filename)
  104.             elif s == 'a':                                                                  # append output
  105.                 appendflag = True
  106.             elif s == 'b':                                                                  # base64 encoding
  107.                 base64flag = True
  108.             elif s == 'd':                                                                  # write decoder
  109.                 decoderflag = True
  110.             elif s == 'g':                                                                  # gzip compression
  111.                 if zlibflag: raise Exception, "inconsistent switch -%s" % s
  112.                 gzipflag = True
  113.             elif s == 'x':                                                                  # use hexadecimal
  114.                 hexaflag = True
  115.             elif s == 'z':                                                                  # zlib compression
  116.                 if gzipflag: raise Exception, "inconsistent switch -%s" % s
  117.                 zlibflag = True
  118.             else:
  119.                 raise Exception, "unknown switch -%s" % s
  120.         else:                                                                               # input filename list
  121.             filelist = glob.glob(token)
  122.             if not filelist: raise Exception, "can't find file(s): %r" % token
  123.             input += filelist
  124.         i += 1
  125.    
  126.     if decoderflag and not (gzipflag or zlibflag or base64flag): decoderflag = False
  127.    
  128.     return input, output, appendflag, hexaflag, zlibflag, gzipflag, base64flag, decoderflag
  129.  
  130.  
  131. def gzipCompress(data):
  132.     sf = StringIO.StringIO()
  133.     gf = gzip.GzipFile('', 'wb', 9, sf)
  134.     gf.write(data)
  135.     gf.close()
  136.     sf.seek(0)
  137.     data = sf.read()
  138.     sf.close()
  139.     return data
  140.  
  141.  
  142. def sanitizeVariableName(dirty):
  143.     valid  = string.digits
  144.     valid += string.letters
  145.     valid += '_'
  146.     clean = ''
  147.     for c in dirty:
  148.         if not c in valid:
  149.             c = '_'
  150.         clean += c
  151.     return clean
  152.  
  153.  
  154. def hexData(data, varname = 'document', align = 32):
  155.     hexdata  = '%s  = ""\n' % varname
  156.     if align > 0:
  157.         r = range(0, len(data), align)
  158.     else:
  159.         r = range(0, len(data))
  160.     for i in r:
  161.         hexdata += '%s += "' % varname
  162.         for c in data[i:i+align]:
  163.             hexdata += r'\x%s' % hex(ord(c))[2:].zfill(2)
  164.         hexdata += '"\n'
  165.     return hexdata
  166.  
  167.  
  168. def reprData(data, varname = 'document', max = 32):
  169.     reprdata = '%s  = %r\n' % (varname, '')
  170.     prefix   = '%s += ' % varname
  171.     suffix   = '\n'
  172.     if max > 0:
  173.         for i in range(0, len(data), max):
  174.             reprdata += prefix + repr(data[i:i+max]) + suffix
  175.     else:
  176.         reprdata += prefix + repr(data) + suffix
  177.     return reprdata
  178.  
  179.  
  180. def putDecoder(zlibflag, gzipflag, base64flag):
  181.     code = ''
  182.     if zlibflag:
  183.         code += 'import zlib\n'
  184.     if gzipflag:
  185.         code += 'import gzip\n'
  186.         code += 'import StringIO\n'
  187.     if base64flag:
  188.         code += 'import base64\n'
  189.     code += '\n'
  190.     code += 'def decode(data):\n'
  191.     if base64flag:
  192.         code += '    data = base64.decodestring(data)\n'
  193.     if zlibflag:
  194.         code += '    data = zlib.decompress(data)\n'
  195.     elif gzipflag:
  196.         code += '    sf = StringIO.StringIO()\n'
  197.         code += '    sf.write(data)\n'
  198.         code += '    sf.seek(0)\n'
  199.         code += '    gf = gzip.GzipFile("", "rb", 9, sf)\n'
  200.         code += '    data = gf.read()\n'
  201.         code += '    gf.close()\n'
  202.         code += '    sf.close()\n'
  203.     code += '    return data\n'
  204.     code += '\n'
  205.     return code
  206.  
  207.  
  208. def main():
  209.    
  210.     try:
  211.         input, output, appendflag, hexaflag, zlibflag, gzipflag, base64flag, decoderflag = parseCommandLine()
  212.     except Exception, e:
  213.         showHelp(e)
  214.         return
  215.    
  216.     single_output = bool(output)
  217.    
  218.     if single_output:
  219.         if appendflag:
  220.             ofile = open(output[0], 'a')
  221.         else:
  222.             ofile = open(output[0], 'w')
  223.         if decoderflag:
  224.             ofile.write(putDecoder(zlibflag, gzipflag, base64flag))
  225.    
  226.     count = 0
  227.     for filename in input:
  228.        
  229.         filename = os.path.abspath(filename)
  230.        
  231.         if filename in output: continue
  232.        
  233.         data = open(filename, 'rb').read()
  234.        
  235.         if zlibflag:
  236.             data = zlib.compress(data, 9)
  237.         elif gzipflag:
  238.             data = gzipCompress(data)
  239.        
  240.         if single_output:
  241.             varname = os.path.splitext(os.path.basename(filename))[0]
  242.             varname = sanitizeVariableName(varname)
  243.         else:
  244.             varname = 'document'
  245.        
  246.         if base64flag:
  247.             data = '%s = %r\n' % (varname, base64.encodestring(data))
  248.         elif hexaflag:
  249.             data = hexData(data, varname)
  250.         else:
  251.             data = reprData(data, varname)
  252.        
  253.         if decoderflag:
  254.             data += '%s = decode(%s)\n' % (varname, varname)
  255.        
  256.         if single_output:
  257.             data += '\n'
  258.             ofile.write(data)
  259.         else:
  260.             filename += '.py'
  261.             if decoderflag:
  262.                 data = putDecoder(zlibflag, gzipflag, base64flag) + data
  263.             if appendflag:
  264.                 open(filename, 'a').write(data)
  265.             else:
  266.                 open(filename, 'w').write(data)
  267.             output.append(filename)
  268.        
  269.         count += 1
  270.    
  271.     if single_output:
  272.         ofile.close()
  273.    
  274.     if count == 1:
  275.         print "1 file processed."
  276.     else:
  277.         print "%i files processed." % count
  278.  
  279.  
  280. if __name__ == '__main__':
  281.     try:
  282.         import psyco
  283.         psyco.bind(main)
  284.     except ImportError:
  285.         pass
  286.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement