SimFile(the base class is actually called
SimFileBase), which stores files as a flat address-space of data, and
SimPackets, which stores a sequence of variable-sized reads. The former is best for modeling programs that need to perform seeks on their files, and is the default storage for opened files, while the latter is best for modeling programs that depend on short-reads or use scanf, and is the default storage for stdin/stdout/stderr.
SimFile.readreturns a tuple (bitvector data, actual size, new pos):
state.memory, so you can load data directly:
has_endis implicitly true here)
scanfN times to read in N strings. With a traditional SimFile, as we do not know the length of each input string, there does not exist any clear boundary in the file between these symbolic input strings. In this case, angr will perform N symbolic reads where each read will generate a gigantic tree of claripy ASTs, with string lengths being symbolic. This is a nightmare for constraint solving. Nevertheless, the fact that
scanfis used on a stream (stdin) dictates that there will be zero overlap between individual reads, regardless of the sizes of each symbolic input string. We may as well model stdin as a stream that comprises of consecutive packets, instead of a file containing a sequence of bytes. Each of the packet can be of a fixed length or a symbolic length. Since there will be absolutely no byte overlap between packets, the constraints that angr will produce after executing this example program will be a lot simpler.
nbytes but actually get back fewer bytes than that. We use a different class implementing SimFileBase,
SimPackets, to automatically enable support for short reads. By default, stdin, stdout, and stderr are all SimPackets objects.
simfile.concretize()to generate a testcase to reach that state. Keep in mind that
concretize()returns different types depending on the file type - for a SimFile it's a bytestring and for SimPackets it's a list of bytestrings.
state.posix, which stores all abstractions relevant to a POSIX-compliant environment. You can always get a state's stdin SimFile with
state.posix.stdin, but you can't just replace it - as soon as the state is created, references to this file are created in the file descriptors. Because of this you need to specify it at the time the POSIX plugin is created: