Cannot successfully end Symbolic execution for statically compiled 64bit ELF
See original GitHub issueHello, I have a 64biy ELF compiled statically with GCC, not stripped. Source can be viewed here, C program below. I’m trying to log all syscalls from symbolic execution.
Using strace
in linux I’m getting following syscalls:
execve("./if_else_static", ["./if_else_static"], ...OMITTED...) = -1 EINVAL (Invalid argument)
brk(NULL) = 0x1c23000
brk(0x1c241c0) = 0x1c241c0
arch_prctl(ARCH_SET_FS, 0x1c23880) = 0
uname({sysname="Linux", nodename="OMITTED", release="5.4.0-72-generic", version="OMITTED", machine="x86_64", domainname="(none)"}) = 0
readlink("/proc/self/exe", "/home/OMITTED/OMITTED/if_else_static", 4096) = 70
brk(0x1c451c0) = 0x1c451c0
brk(0x1c46000) = 0x1c46000
mprotect(0x4dc000, 12288, PROT_READ) = 0
fstat(0, {OMITTED}) = 0
read(0, "4\n", 1024) = 2
fstat(1, {OMITTED}) = 0
write(1, "ne, 52\n", 7) = 7
lseek(0, -1, SEEK_CUR) = -1 ESPIPE (Illegal seek)
exit_group(0) = ?
First issue I ran into was that the readlink
system call was not implemented so program stuck at the infinite loop. I have implemented readlink
syscall (SimProcedure is below), and added it successfully to the framework.
class readlink(SimProcedure):
def run(self, pathname, buf, bufsiz):
elf_path = (os.getcwd() + "/" + self.state.project.filename).encode('utf-8')
buffsize_int = self.state.solver.eval(bufsiz)
elf_path_bvv = claripy.BVV(value=elf_path, size=len(elf_path) * 8)
store_size = min(buffsize_int, len(elf_path))
#addr, data, size=None
self.state.memory.store(addr=buf, data=elf_path_bvv, size=store_size)
l.debug('readlink: {} : {} : {} | {}'.format(pathname, buf, buffsize_int, buffsize_int))
return len(elf_path)
Later on, I’ve tried to run a simulation with following code:
def syscall_action_builder(fd):
# Function logs syscall name, params and return value
def syscall_action_func(state):
simproc = state.inspect.simprocedure
return_value = ret_val_to_str(simproc.ret_expr)
args_string = ','.join([bitvec_to_str(simproc.arg(i)) for i in range(0, simproc.num_args)])
fd.write("{}:{}:{}:{}\n".format(simproc.library_name, simproc.display_name, args_string, return_value))
fd.flush()
return syscall_action_func
if __name__ == '__main__':
RESULTS_DIR = 'results/'
BIN_DIR = 'examples/bin/'
FILE_NAME = 'if_else_static'
trace_fd = open(RESULTS_DIR + FILE_NAME + '_bp.systrace', 'w')
proj = angr.Project(BIN_DIR + FILE_NAME, load_options={'auto_load_libs': True, 'except_missing_libs': True},
use_sim_procedures=False)
start_state = proj.factory.entry_state()
start_state.inspect.b('syscall', when=angr.BP_AFTER, action = syscall_action_builder(trace_fd))
simgr = proj.factory.simgr(start_state)
simgr.explore()
But simulation ends with 14 ‘errored’ states.
First 12 are <State errored with “Page is already mapped”> at the address 0x70018e. Block of the states looks like:
0x70018e: add byte ptr [rax], al
, from address 0x70018e to 0x700228.
Following syscalls are logged:
linux:geteuid::int,1000
linux:getuid::int,1000
linux:getegid::int,1000
linux:getgid::int,1000
linux:arch_prctl:<64,12289>,<64,576460752303357648>:int,22
linux:brk:<64,0>:BVV,64,5124096
linux:brk:<64,5128640>:BVV,64,5128640
linux:arch_prctl:<64,4098>,<64,5126272>:int,0
linux:uname:<64,576460752303357104>:int,0
linux:readlink:<64,5036867>,<64,576460752303353232>,<64,4096>:int,67
linux:readlink:<64,5036867>,<64,576460752303353232>,<64,4096>:int,67
linux:mprotect:<64,5095424>,<64,12288>,<64,1>:int,0
linux:mprotect:<64,5095424>,<64,12288>,<64,1>:int,0
As you can see, execution didn’t reach scanf
function. With objectdump I cannot access these addresses, and I don’t see what’s happening.
The other 2 states have <State errored with "IR decoding error at 0x46cca9>, and that IR is rdsspq %rax
. It seems like VEX doesn’t support this IR.
Do you have any ideas?
Later I tried to start from main function. I’ve set start_state = proj.factory.blank_state(addr=0x401d05)
.
This time I only logged: <SimProcedure fstat (syscall)>
syscall, and it ended with only one ‘errored’ state: <State errored with "Cannot execute following jumpkind Ijk_SigSEGV">
. State got error 0x410f76 on block:
0x410f76: movaps xmmword ptr [rbp - 0x600], xmm1
0x410f7d: mov qword ptr [rbp - 0x598], rax
0x410f84: mov eax, dword ptr [rdi + 0xc0]
0x410f8a: test eax, eax
0x410f8c: jne 0x411610
How can I fix this?
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (10 by maintainers)
Top GitHub Comments
I found a bug in our implementation of brk which allows the execution to continue. Now it produces a large number of active paths. Try out the branch linked above.
I am not sure. I will look into your example. I missed that part of your original post until just now.