-
Notifications
You must be signed in to change notification settings - Fork 378
Results of derived constraints #15
Comments
Here |
Hi, thanks for the quick response! Ok, lets change it to initial = b.factory.blank_state(addr=start_address)
[...]
found_state = pg.found[0].state If I get you right, then Perhaps I misunderstand the logic, but I expect to derive a set of constraints that depend on the input. For instance, assume the following pseucode:
Assume I want to reach Or do I have to declare Thanks in advance! :) |
I think |
For instance, this C code and the corresponding assembly code. Then, applying the script below, the initial regs will be zero. Those values don't satisfy the path to the return 1. import angr
b = angr.Project("./test")
initial_state = b.factory.blank_state(addr=0x400546)
pg = b.factory.path_group(initial_state, immutable=False)
pg.explore(find=0x400587)
found_state = pg.found[0].state
# does not work
print found_state.se.any_int(initial_state.regs.rdi)
print found_state.se.any_int(initial_state.regs.rsi)
# works for this case
print found_state.se.any_int(found_state.regs.rdi)
print found_state.se.any_int(found_state.regs.rsi) |
I think the confusion stems from the fact that
|
And I just noticed that I basically repeated what Fish said :-)
|
@mrphrazer Can I get a copy of the binary that you are working on? I'll write an angr script for you. @zardus When are you coming? |
Oh awesome guys, thanks for your help! Indeed, I expected different behaviour which caused the confusion. Since the path is satisfiable, there exist valid inputs. I should restate the questions how to parse those exactly. So, seeing a working example will be help for sure. Here is the binary. Thanks, again! :) |
Here it is: import angr
num_0 = None
num_1 = None
def hook_atoi(state):
if state.se.is_true(state.ip == 0x4005b2):
state.regs.rax = state.se.ZeroExt(32, num_0)
elif state.se.is_true(state.ip == 0x4005c8):
state.regs.rax = state.se.ZeroExt(32, num_1)
else:
# Should never get here
raise Exception('Oops')
def main():
p = angr.Project("test_binary", load_options={'auto_load_libs': False})
s = p.factory.blank_state(addr=0x400595)
global num_0, num_1
num_0 = s.se.BVS('num_0', 32)
num_1 = s.se.BVS('num_1', 32)
# Set two arguments by hooking atoi and returning the corresponding variable
p.hook(0x4005b2, hook_atoi, length=5)
p.hook(0x4005c8, hook_atoi, length=5)
pg = p.factory.path_group(s, immutable=False)
pg.explore(find=0x4005ed)
# Now we should have one path found
assert len(pg.found) == 1
# There are many solutions... we take an arbitrary one from them, and
# further constrain num_0 to be that single solution
num_0_ints = pg.found[0].state.se.any_n_int(num_0, 20)
print "num_0 has more than %d solutions" % len(num_0_ints)
num_0_int = num_0_ints[0]
# With out constraining, there are many possible solutions to num_1
num_1_ints = pg.found[0].state.se.any_n_int(num_1, 20)
print "num_1 has more than %d solutions" % len(num_1_ints)
# Here is how you can further constrain it
copied_state = pg.found[0].state.copy()
copied_state.add_constraints(num_0 == num_0_int)
num_1_ints = copied_state.se.any_n_int(num_1, 20)
print "After constraining variable num_0, there are %d solutions to num_1" % len(num_1_ints)
print "Try running ./test_binary %d %d!" % (num_0_int, num_1_ints[0])
if __name__ == "__main__":
main() And there is the output on my machine:
Some words:
|
@ltfish Really nice, thank you very much! I got the idea and were able to apply this successfully to the other test cases :) |
Hi,
I assume x86_64 architecture and code similar to this one:
My goal is to retrieve the inputs for
a
andb
, stored inRDI
andRSI
such that 1 will be returned.My code for that looks similar to
The returned values of
RDI
andRSI
do not work, in the most cases. Therefore, should this approach work similary as described above or do I misunderstand something?The text was updated successfully, but these errors were encountered: