-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
VirtualProtect.py
54 lines (44 loc) · 2.16 KB
/
VirtualProtect.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
import angr
import logging
from .VirtualAlloc import convert_prot, deconvert_prot
l = logging.getLogger(name=__name__)
class VirtualProtect(angr.SimProcedure):
def run(self, lpAddress, dwSize, flNewProtect, lpfOldProtect):
l.debug("VirtualProtect(%s, %s, %s, %s)", lpAddress, dwSize, flNewProtect, lpfOldProtect)
addrs = self.state.solver.eval_upto(lpAddress, 2)
if len(addrs) != 1:
raise angr.errors.SimValueError("VirtualProtect can't handle symbolic lpAddress")
addr = addrs[0]
size = self.state.solver.max_int(dwSize)
if dwSize.symbolic and size > self.state.libc.max_variable_size:
l.warning('symbolic VirtuaProtect dwSize %s has maximum %#x, greater than state.libc.max_variable_size %#x',
dwSize, size, self.state.libc.max_variable_size)
size = self.state.libc.max_variable_size
prots = self.state.solver.eval_upto(flNewProtect, 2)
if len(prots) != 1:
raise angr.errors.SimValueError("VirtualProtect can't handle symbolic flNewProtect")
prot = prots[0]
try:
if not self.state.solver.is_false(self.state.memory.permissions(lpfOldProtect) & 2 == 0):
l.debug("...failed, bad lpfOldProtect (write-perm)")
return 0
except angr.errors.SimMemoryError:
l.debug("...failed, bad lpfOldProtect (write-miss)")
return 0
page_start = addr & ~0xfff
page_end = (addr + size - 1) & ~0xfff
first_prot = None
try:
for page in range(page_start, page_end + 0x1000, 0x1000):
old_prot = self.state.memory.permissions(page)
if first_prot is None:
first_prot = self.state.solver.eval(old_prot)
except angr.errors.SimMemoryError:
l.debug("...failed, bad address")
return 0
angr_prot = convert_prot(prot)
# we're good! make the changes.
for page in range(page_start, page_end + 0x1000, 0x1000):
self.state.memory.permissions(page, angr_prot)
self.state.mem[lpfOldProtect].dword = deconvert_prot(first_prot)
return 1