Skip to content

Instantly share code, notes, and snippets.

@chipx86
Created September 19, 2021 03:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chipx86/d471b828e0a64a8dd87502e3439a5be9 to your computer and use it in GitHub Desktop.
Save chipx86/d471b828e0a64a8dd87502e3439a5be9 to your computer and use it in GitHub Desktop.
Evil Python/C cross-language code generator
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define __file__ __FILE__
#define import void*
#define def int
import codecs;
import os;
import subprocess;
import tempfile;
#if PYTHON
LANG = 'Python'
FROM_C = globals().get('FROM_C', False)
START = None
END = None
PYTHON_CODE = lambda x: eval(compile('if 1:\n%s' % x[2:-3], '<string>', 'exec'),
globals(), globals())
C_CODE = lambda *args: None
PRINT_PREFIX, PRINT_SUFFIX = ('printf("', '\\n");') if FROM_C else ('', '')
write = lambda s, *args: print('%s%s%s' % (PRINT_PREFIX, s % args, PRINT_SUFFIX))
#else
# define LANG "C"
# define START int main() {
# define END }
# define PYTHON_CODE(x)
# define C_CODE(a, b, c) b
# ifdef FROM_PYTHON
# define PRINT_PREFIX "print(\"\"\""
# define PRINT_SUFFIX "\"\"\")"
#else
# define PRINT_PREFIX
# define PRINT_SUFFIX
#endif
# define write(x, ...) printf(PRINT_PREFIX x PRINT_SUFFIX "\n", __VA_ARGS__)
#endif
START
PYTHON_CODE((""" "
if FROM_C:
print("#include <stdio.h>")
print("int main() {");
" """))
write("%s: %s: Hello, world!", LANG, __file__);
PYTHON_CODE((""" "
def decode_c(text):
fd, out_file = tempfile.mkstemp()
os.close(fd)
try:
subprocess.check_output([
'clang', '-x', 'c',
'-DFROM_PYTHON=1',
__file__, '-o', out_file,
])
result = subprocess.check_output(out_file)
return result, len(result)
finally:
os.unlink(out_file)
if FROM_C:
print("}");
else:
codecs.register(lambda name: codecs.CodecInfo(lambda text: "",
decode_c,
name='c'))
exec(codecs.decode(open(__file__, 'r'), encoding='c'))
" """))
C_CODE(""" ",
#if !FROM_PYTHON
fflush(stdout);
popen("python3.8 -c \"FROM_C=True ; __file__ = '" __FILE__ "'; "
"exec(open('" __FILE__ "').read())\""
"| clang -x c -o .generated-evil -",
"r");
system("./.generated-evil");
unlink(".generated-evil");
#endif
," """)
END
@chipx86
Copy link
Author

chipx86 commented Sep 19, 2021

This is a Python script that prints a "Hello, world!", identified as coming from Python. Simple enough.

But then it passes itself to Python and says "Hey, this is a c text encoding. You may be unfamiliar with this, so I'll help you convert it!" Which involves taking the code it lives in, compiling it as C in a mode that results in the output being Python code, and then running it to generate that code.

The result of that is then run, printing another "Hello, world!", this time identified as coming from C.

$ python3.9 evil.py.c
Python: /Users/chipx86/evil.py.c: Hello, world!
C: /Users/chipx86/evil.py.c: Hello, world!

But we're not done yet.

This is a C program that prints a "Hello, world!", identified as coming from C. Simple enough.

But then it passes itself to Python and says "Hey, this is a Python script. Run it with these settings!" Which involves taking the code it lives in, running it as Python code in a mode that results in the output being C code, and then compiling that result.

The result of that is then run, printing another "Hello, world!", this time identified as coming from Python.

$ clang -x c evil.py.c -o evil
$ ./evil
C: evil.py.c: Hello, world!
Python: evil.py.c: Hello, world!

I regret nothing.

@chipx86
Copy link
Author

chipx86 commented Sep 19, 2021

For a more practical application of some fun Python trickery, see our unit test helper library, kgb, which allows tests to spy on functions, track calls and results, and override functionality, all through in-memory function bytecode manipulation.

A nicer alternative to mocks, in many cases. We use it in many thousands of unit tests for Review Board and other projects at Beanbag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment