-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
fdopen.py
59 lines (47 loc) · 2.21 KB
/
fdopen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import angr
from cle.backends.externs.simdata.io_file import io_file_data_for_arch
######################################
# fdopen
#
# Reference for implementation:
# glibc-2.25/libio/iofdopen.c
######################################
def mode_to_flag(mode):
# TODO improve this: handle mode = strings
if mode[-1] == b'b': # lol who uses windows
mode = mode[:-1]
all_modes = {
b"r" : angr.storage.file.Flags.O_RDONLY,
b"r+" : angr.storage.file.Flags.O_RDWR,
b"w" : angr.storage.file.Flags.O_WRONLY | angr.storage.file.Flags.O_CREAT,
b"w+" : angr.storage.file.Flags.O_RDWR | angr.storage.file.Flags.O_CREAT,
b"a" : angr.storage.file.Flags.O_WRONLY | angr.storage.file.Flags.O_CREAT | angr.storage.file.Flags.O_APPEND,
b"a+" : angr.storage.file.Flags.O_RDWR | angr.storage.file.Flags.O_CREAT | angr.storage.file.Flags.O_APPEND
}
if mode not in all_modes:
raise angr.SimProcedureError('unsupported file open mode %s' % mode)
return all_modes[mode]
class fdopen(angr.SimProcedure):
#pylint:disable=arguments-differ
def run(self, fd_int, m_addr):
#pylint:disable=unused-variable
strlen = angr.SIM_PROCEDURES['libc']['strlen']
m_strlen = self.inline_call(strlen, m_addr)
m_expr = self.state.memory.load(m_addr, m_strlen.max_null_index, endness='Iend_BE')
mode = self.state.solver.eval(m_expr, cast_to=bytes)
# TODO: handle append and other mode subtleties
fd = self.state.solver.eval(fd_int)
if fd not in self.state.posix.fd:
# if file descriptor not found return NULL
return 0
else:
# Allocate a FILE struct in heap
malloc = angr.SIM_PROCEDURES['libc']['malloc']
io_file_data = io_file_data_for_arch(self.state.arch)
file_struct_ptr = self.inline_call(malloc, io_file_data['size']).ret_expr
# Write the fd
fd_bvv = self.state.solver.BVV(fd, 4 * 8) # int
self.state.memory.store(file_struct_ptr + io_file_data['fd'],
fd_bvv,
endness=self.state.arch.memory_endness)
return file_struct_ptr