I'm new to angr, trying to solve a simple executable, it reads 3 characters and compare to string 'abc'.
#include <iostream>
using namespace std;
int main() {
char v[3];
scanf("%3s", v);
if(v[0] == 'a' && v[1] == 'b' && v[2] == 'c') { // should be 'abc'
printf("yes\n");
} else {
printf("no\n");
}
}
The angr script:
import angr
import claripy
p = angr.Project("/e/c/1/kali/test")
main = p.loader.find_symbol('main')
# Question 1
# flag = claripy.BVS('flag', 3*8)
# or
# flag = claripy.BVS('flag', 4*8)
# Question 2
# flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(3)]
# flag = claripy.Concat(*flag_chars + [claripy.BVV(b'\n')])
state = p.factory.blank_state(
addr=main.rebased_addr,
# stdin = flag, # uncomment this line when trying Question 1~3
)
sm = p.factory.simgr(state)
sm.explore(
find = lambda s: b'yes' in s.posix.dumps(1),
avoid = lambda s: b'no' in s.posix.dumps(1)
)
if sm.found:
res = sm.found[0]
print('found', res.posix.dumps(0))
else:
print('not found')
It works when I don't explicitly provide 'stdin' for bland_state
. But it shows 'not found' when 'stdin' provided.
Question 1: Syntax from an example, but what's wrong with my code? I tried both 3 and 4 bytes(1 for the '\n'), neither of them work.
Question 2: Syntax from another example, why it works in the example but not my code?