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");

Leave a Reply

*
To prove that you're not a bot, enter this code
Anti-Spam Image