You were on the right track, but you didn’t quite reach the right conclusion.

First off, don’t call this a virus. A virus is malware. This is just a bug.

The bug is that the car’s code is calling “printf(str)” where “str” is untrusted and unsanitized data. It should be calling “printf(“%s”, str)” or even just “puts(str)”. This is a really basic security bug; the code should never have been checked in, let alone shipped.

“%I” is not the problem. “%n” is the problem. “%In” means [paraphrased from https://en.wikipedia.org/wiki/Printf_format_string#Type_field%5D “read the next pointer-sized parameter from the stack and write the number of characters successfully written so far to that address”. Since there is no parameter on the stack, the code reads random stack garbage, tries to write to that address, and crashes. “%s” would also exploit this bug, because that also causes printf to read stack garbage, treat it as a pointer, and dereference it.

“%i” and “%p” don’t crash because those format specifiers don’t dereference pointers. They read stack garbage, but they just print the value of that garbage.