Compilare codice python da buffer o stringa [PoC]
Premettendo che la compilazione di un file python non e’ assolutamente obbligatoria e che l’interprete riesce a riconoscere benessimo come e quando richiamare un file precompilato quando si fa l’import di un modulo, è possbile modificare la funzione py_compile.compile() in modo tale da permette la compilazione di un sorgente contenuto in un buffer anzichè in un file sorgente. Esempio:
[Proof of concept]
import __builtin__ import imp import marshal import os import sys import traceback MAGIC = imp.get_magic() # Define an internal helper according to the platform if os.name == "mac": import MacOS def set_creator_type(file): MacOS.SetCreatorAndType(file, 'Pyth', 'PYC ') else: def set_creator_type(file): pass def wr_long(f, x): """Internal; write a 32-bit int to a file in little-endian order.""" f.write(chr( x & 0xff)) f.write(chr((x >> 8) & 0xff)) f.write(chr((x >> 16) & 0xff)) f.write(chr((x >> 24) & 0xff)) def compileString(code, filename, ext=".pyc"): if type(code) is not str: raise "Error, code malformed -> type_code(buffer)"; if code and code[-1] != '\n': code = code + '\n'; try: codeobject = __builtin__.compile(code, filename, 'exec') print codeobject.co_code except Exception: print "Error in the code" cfile = filename + ext; fc = open(cfile, 'wb') fc.write('\0\0\0\0') timestamp = long(os.fstat(fc.fileno()).st_mtime) wr_long(fc,timestamp) marshal.dump(codeobject, fc) fc.flush() fc.seek(0,0) fc.write(MAGIC) fc.close() set_creator_type(cfile) compileString("print 0;", "pppr");