test@localhost ~/pycparser-1.07 $ cat rofl.c #include #define __(a) goto a; #define ___(a) putchar(a); #define _(a,b) ___(a) __(b); main() { _:__(t)a:_('r',g)b:_('$',p) c:_('l',f)d:_(' ',s)e:_('a',s) f:_('o',q)g:_('l',h)h:_('d',n) i:_('e',w)j:_('e',x)k:_('\n',z) l:_('H',l)m:_('X',i)n:_('!',k) o:_('z',q)p:_('q',b)q:_(',',d) r:_('i',l)s:_('w',v)t:_('H',j) u:_('a',a)v:_('o',a)w:_(')',k) x:_('l',c)y:_('\t',g)z:___(0x0)} test@localhost ~/pycparser-1.07 $ vi rofl.c test@localhost ~/pycparser-1.07 $ cat rofl.c #include #define __(a) goto a; #define ___(a) putchar(a); #define _(a,b) ___(a) __(b); main() { _:__(t)a:_('r',g)b:_('$',p) c:_('l',f)d:_(' ',s)e:_('a',s) f:_('o',q)g:_('l',h)h:_('d',n) i:_('e',w)j:_('e',x)k:_('\n',z) l:_('H',l)m:_('X',i)n:_('!',k) o:_('z',q)p:_('q',b)q:_(',',d) r:_('i',l)s:_('w',v)t:_('H',j) u:_('a',a)v:_('o',a)w:_(')',k) x:_('l',c)y:_('\t',g)z:___(0x0)} test@localhost ~/pycparser-1.07 $ gcc -E rofl.c > processed.c test@localhost ~/pycparser-1.07 $ head -n 2 processed.c # 1 "rofl.c" # 1 "" test@localhost ~/pycparser-1.07 $ tail -n 2 processed.c main() { _:goto t;a:putchar('r'); goto g;;b:putchar('$'); goto p;; c:putchar('l'); goto f;;d:putchar(' '); goto s;;e:putchar('a'); goto s;; f:putchar('o'); goto q;;g:putchar('l'); goto h;;h:putchar('d'); goto n;; i:putchar('e'); goto w;;j:putchar('e'); goto x;;k:putchar('\n'); goto z;; l:putchar('H'); goto l;;m:putchar('X'); goto i;;n:putchar('!'); goto k;; o:putchar('z'); goto q;;p:putchar('q'); goto b;;q:putchar(','); goto d;; r:putchar('i'); goto l;;s:putchar('w'); goto v;;t:putchar('H'); goto j;; u:putchar('a'); goto a;;v:putchar('o'); goto a;;w:putchar(')'); goto k;; x:putchar('l'); goto c;;y:putchar('\t'); goto g;;z:putchar(0x0);} test@localhost ~/pycparser-1.07 $ tail -n 1 processed.c > wat test@localhost ~/pycparser-1.07 $ mv wat processed.c test@localhost ~/pycparser-1.07 $ cat processed.c main() { _:goto t;a:putchar('r'); goto g;;b:putchar('$'); goto p;; c:putchar('l'); goto f;;d:putchar(' '); goto s;;e:putchar('a'); goto s;; f:putchar('o'); goto q;;g:putchar('l'); goto h;;h:putchar('d'); goto n;; i:putchar('e'); goto w;;j:putchar('e'); goto x;;k:putchar('\n'); goto z;; l:putchar('H'); goto l;;m:putchar('X'); goto i;;n:putchar('!'); goto k;; o:putchar('z'); goto q;;p:putchar('q'); goto b;;q:putchar(','); goto d;; r:putchar('i'); goto l;;s:putchar('w'); goto v;;t:putchar('H'); goto j;; u:putchar('a'); goto a;;v:putchar('o'); goto a;;w:putchar(')'); goto k;; x:putchar('l'); goto c;;y:putchar('\t'); goto g;;z:putchar(0x0);} test@localhost ~/pycparser-1.07 $ cat lolz.py from pycparser import CParser from pycparser.c_ast import Goto, Label, FuncCall if __name__ == '__main__': with open('processed.c') as f: source = f.read() tree = CParser().parse(source) main = tree.children()[0] compound = main.children()[1] first = compound.children()[0] assert isinstance(first, Label) assert len(first.children()) == 1 first_goto = first.children()[0] assert isinstance(first_goto, Goto) goto = first_goto.name output = [] children = compound.children() while True: for (i, child) in enumerate(children): if isinstance(child, Label) and child.name == goto: break else: assert False, "couldn't find label to jump to" func = child.stmt assert isinstance(func, FuncCall) func_id = func.children()[0] assert func_id.name == 'putchar' args = func.args assert len(args.exprs) == 1 arg = args.exprs[0] if arg.type == 'int': assert arg.value == '0x0' # wtf... output.append(chr(int(arg.value, 16))) else: assert arg.type == 'char' output.append(arg.value[1:-1]) try: goto = children[i + 1] except IndexError: break assert isinstance(goto, Goto) goto = goto.name print 'program will output the following:' print repr(''.join(output)) test@localhost ~/pycparser-1.07 $ python lolz.py program will output the following: 'Hello, world!\\n\x00'