
A Brainfuck interpreter inside a single printf statement - Cieplak
https://github.com/HexHive/printbf
======
vortico
I thought I knew printf format strings, but I suppose not because I have no
idea what %1$.*1$d %2$hn does. Can anyone explain why that increments the
value behind a pointer?

~~~
userbinator
The trick is in the 'n' conversion specifier:

[http://pubs.opengroup.org/onlinepubs/009695399/functions/fpr...](http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html)

"The argument shall be a pointer to an integer into which is written the
number of bytes written to the output so far by this call to one of the
fprintf() functions. No argument is converted."

The * parameter provides the "input", since it allows controlling the number
of bytes written with its parameter, which is then written to the n parameter.

------
w4rh4wk5
For reference, this was has been presented by Mathias Payer at 32c3.

[https://youtu.be/n_tpc7bvPXU?t=2643](https://youtu.be/n_tpc7bvPXU?t=2643)

------
partycoder
So printf is turing complete?

~~~
rurban
Let's say it's insecure. printf_s should be used instead.

------
klez

        [ == if (*dataptr == 0) goto ]
    

Isn't this wrong? I mean, `[` starts a loop, it doesn't mean goto `]`. Unless
I'm getting the semantics wrong, at least one iteration should execute, even
if the current cell is set at zero.

~~~
kiriakasis
no, if the current cell is zero the loop is not run

------
millstone
It's unclear how much stack-smashing is involved here. The "Control Flow
Bending" paper clearly requires overwriting pointers internal to printf.

Is this possible without invoking undefined behavior? FWIW the demos just
crash with SIGILL on macOS.

~~~
akkat
This works by taking advantage of a format string exploit. It is by definition
undefined behavior. It just so happens that this behavior is constant an gives
the ability to change the flow of the program. At least in the popular glibc.
However if someone were to rewrite how printf works but didn't allow the
format string vulnerability, it would still be a valid c compiler.

------
AceJohnny2
Well, shit.

/me adds this to his embedded vsnprintf regression testsuite

------
digi_owl
Ah yes, Brainfuck. For when assembly is too easy...

------
basdp
No. There are a lot of lines of code that are not inside a single printf
statement. This is nothing special, just an unreadable clutter of random code.

~~~
Sir_Cmpwn
Not sure who spit in your frosted flakes this morning. The other code is
support code that sets up a runtime environment of sorts, and the actual
interpretation of the input brainfuck happens in a single printf statement.

~~~
cdancette
Would it work with just this printf statement and all the other code removed?

Edit : why the downvotes? This is a real question, I'm didn't get why they
were used for here.

~~~
Sir_Cmpwn
Would any other brainfuck compiler work without libc? Without the kernel?
Without x86 microcode? This question has no meaning, in my opinion. What's
important is that the printf statement is doing the logical work to calculate
the next state of the machine.

~~~
cdancette
I see what you mean. I don't know C, so I had no idea why the printf was doing
all the work after looking at the code. I'm just wondering what all those
other lines are doing.

