That's because by doing so, you accidentally make the crackme unsolvable. Due to how scanf
works with %s
.
As per the C reference sheet, documentation and multiple sources (seriously, google is full of scanf documentation pages describing that):
%s
: Scan a character string. The scan terminates at whitespace. A null character is stored at the end of the string, which means that the buffer supplied must be at least one character longer than the specified input length.
scanf will immediately stop reading characters into a string denoted with %s
once a whitespace character (space included, obviously) is encountered. Even if you manually enter the correct password by hand into your newly created executable you'll get the error message instead of the success.
Additionally, gets
behaves the same when it comes to whitespaces.
But you can solve the crackme by hand, it appears
Although this appears not to be the behavior you experience in your program, for some unknown reason, this is still the behavior angr assumes when handling scanf
and scanf
-like library functions. It is perhaps not widely known that angr, to avoid path explosion at the first encounter of a string library function, does not "natively" handle those functions like any other encountered function. In favor of efficiency and speed, angr "cheats" around library functions, format string functions included.
For that purpose angr has its own scanf function implementation in python, and that implementation follows the standard. You can see that scanf
delimiters are defined and used to delimit scanf
s possible output. Issues with scanf
are even documented in angr's gotchas page:
For example, our scanf implementation is not complete, but if you just need to support a single, known format string, you can write a hook to do exactly that.
One way to avoid that is to modify the scanf
implementation to something that does not consider whitespaces as delimiters. Another option is to disable that behavior by passing exclude_sim_procedures_list=['scanf']
as argument to your Project
. You could also, as the gotcha's page suggest, implement something specific for your scenario.