>>>>> "CC" == christophcmichael <
christop...@gmail.com> writes:
CC> Hi, I'm trying to add conditions to constrain the fuzzball's
CC> search, and it seems like the -extra-condition flag is the right
CC> way to do that. But I can't figure out the syntax for anything but
CC> numeric constants. For registers, temps and symbolic variables the
CC> parser complains about undeclared variables, and for variable
CC> declarations it complains about "var". Does anyone have any
CC> examples of how to do this? thanks
I think there might be a couple of pitfalls you're running into here.
First, the kind of variables it makes sense to have in an
-extra-condition are symbolic input variables. The argument to
-extra-condition is a mathematical condition of the sort that goes in
the path condition, so it has to always have the same meaning. The
contents of registers change over time, and -extra-condition doesn't
have any way of specifying at what point in time the condition should
be evaluated, so it wouldn't be sensible to put a variable
representing a machine register in the condition.
Second, the symbolic input variables that it currently works to put
into an -extra-condition are restricted by some implementation details
of FuzzBALL. We try to parse the extra-condition condition at the time
we switch into symbolic mode for the first time. So it will only work
with symbolic variables that are also introduced at that early stage
(the relevant code is the function make_symbolic_init in
execution/
exec_set_options.ml). Some options introduce their symbolic
variables later, which is too late for the -extra-condition parsing to
succeed.
My first impulse was to demonstrate -extra-condition using the
"examples/simplie-func" example from the README file, but in fact
-skip-call-ret-symbol is an example of a symbolic-input-introducing
option that currently doesn't work with -extra-condition, because the
symbolic variable isn't introduced until the call instruction is
encountered in the program.
So instead it might be useful to demonstrate another relatively easy
way of introducing symbolic inputs into a program you control, which
is to make global variables that you initialize by address. Here's a
variant of simple.c I'll call simple-global.c:
#include <stdio.h>
#include <stdlib.h>
int the_input;
int simple(int x) {
int path = 0;
if (x & 1) {
printf("x is odd\n");
path++;
} else {
printf("x is even\n");
}
path <<= 1;
if (x % 11 == 0) {
printf("x is a multiple of 11\n");
path++;
} else {
printf("x is not a multiple of 11\n");
}
printf("Took path %d\n", path);
}
int main(int argc, char **argv) {
int input;
if (argc == 1) {
input = the_input;
} else if (argc == 2) {
input = atoi(argv[1]);
} else {
fprintf(stderr, "Usage: simple [<integer>]\n");
exit(-1);
}
simple(input + 10);
return 0;
}
Notice that the code doesn't write to "the_input", but if you run the
program without command-line arguments it will take the input from
that global variable. Normally the kernel (or FuzzBALL simulating the
kernel) would initialize the memory to zero, but you can make it
symbolic with -symbolic-word ("word" = 32-bit value in FuzzBALL). You
need to know the address of the global, which you can get with "nm":
% nm simple-global | fgrep the_input
0804a038 B the_input
This kind of symbolic variable works as expected with
-extra-condition. For instance here's how you can require that the
input be even:
% fuzzball -linux-syscalls -symbolic-word 0x0804a038=n \
-trace-stopping simple-global \
-extra-condition '(n:reg32_t & 0x1:reg32_t) == 0:reg32_t' -- \
./simple-global
x is even
x is a multiple of 11
Took path 1
Stopping when program called exit() at 0xb7f01010
x is even
x is not a multiple of 11
Took path 0
Stopping when program called exit() at 0xb7f01010
You see that of the four execution paths that are possible when n is
unconstrained, only two are possible when it is required to be even.
I can see why it might be confusing that not all of these options work
conveniently together. Perhaps the above example will be enough to get
you starting doing what you'd like to do, or perhaps you could
describe more about your use case to think about whether it motivates
enhancements or new features that would be more broadly useful.
One possibility that occurs to me would be to create a new option that
combines some of the features of -extra-condition and
-check-condition-at. As I mentioned before -extra-condition takes a
condition over symbolic inputs which will be required to be true at
all times. The use of "condition" is a little bit different in
-check-condition-at, which takes a condition expressed in terms of
machine state (registers and memory, rather than symbolic variables)
and a program location specified by an instruction address. Every time
that condition is reached, we evaluate the machine state condition
into a symbolic expression condition, and then check whether that
condition (or its negation) are satisfiable. We could take ideas from
both of these options to create something that might be called
-extra-condition-at, which could take a machine-state condition
instead of a symbolic expression condition. It would take a code
location, and every time that code location was hit, we could create a
new extra condition based on the evaluation of the machine-state
condition at that point.
Hope this helps,
-- Stephen