Skip to content

Commit b7de2df

Browse files
committed
test(mem): remove assert_mem_equal, add option to use R2Qiling
assert_mem_equal is only needed for R2Qiling
1 parent 280dd8d commit b7de2df

File tree

2 files changed

+113
-125
lines changed

2 files changed

+113
-125
lines changed

qiling/extensions/r2/r2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ def enable_trace(self, mode='full'):
452452
elif mode == 'history':
453453
trace.enable_history_trace(self.ql)
454454

455-
def deflat(self, target: int | R2Data):
455+
def deflat(self, target: Union[int, R2Data]):
456456
'''Create deflator with self r2 instance, will patch ql code'''
457457
addr = target if isinstance(target, int) else target.start_ea
458458
deflator = R2Deflator(self)

tests/test_mem.py

Lines changed: 112 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,112 @@
1-
#!/usr/bin/env python3
2-
3-
import sys
4-
import unittest
5-
sys.path.append("..")
6-
7-
from qiling import Qiling
8-
from qiling.const import QL_VERBOSE
9-
from qiling.exception import QlMemoryMappedError
10-
from qiling.os.posix.syscall.mman import ql_syscall_mmap2
11-
from qiling.os.posix.syscall.unistd import ql_syscall_brk
12-
from unicorn.x86_const import UC_X86_REG_EAX, UC_X86_REG_ESI
13-
from unicorn import UC_PROT_ALL, UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC, UC_PROT_NONE, UcError
14-
from test_shellcode import MIPS32EL_LIN, X8664_LIN, X86_LIN
15-
16-
17-
class MemTest(unittest.TestCase):
18-
def assert_mem_equal(self, ql: "Qiling"):
19-
map_info = ql.mem.map_info
20-
mem_regions = list(ql.uc.mem_regions())
21-
self.assertEqual(len(map_info), len(mem_regions))
22-
for i, mem_region in enumerate(mem_regions):
23-
s, e, p, _, _, data = map_info[i]
24-
self.assertEqual((s, e - 1, p), mem_region)
25-
uc_mem = ql.mem.read(
26-
mem_region[0], mem_region[1] - mem_region[0] + 1)
27-
self.assertEqual(data, uc_mem)
28-
29-
def test_map_correct(self):
30-
ql = Qiling(code=X8664_LIN, archtype="x86_64", ostype="linux")
31-
ql.mem.map(0x40000, 0x1000 * 16, UC_PROT_ALL) # [0x40000, 0x50000]
32-
ql.mem.map(0x60000, 0x1000 * 16, UC_PROT_ALL) # [0x60000, 0x70000]
33-
ql.mem.map(0x20000, 0x1000 * 16, UC_PROT_ALL) # [0x20000, 0x30000]
34-
self.assertRaises(QlMemoryMappedError, ql.mem.map,
35-
0x10000, 0x2000 * 16, UC_PROT_ALL)
36-
self.assertRaises(QlMemoryMappedError, ql.mem.map,
37-
0x25000, 0x1000 * 16, UC_PROT_ALL)
38-
self.assertRaises(QlMemoryMappedError, ql.mem.map,
39-
0x35000, 0x1000 * 16, UC_PROT_ALL)
40-
self.assertRaises(QlMemoryMappedError, ql.mem.map,
41-
0x45000, 0x1000 * 16, UC_PROT_ALL)
42-
self.assertRaises(QlMemoryMappedError, ql.mem.map,
43-
0x55000, 0x2000 * 16, UC_PROT_ALL)
44-
ql.mem.map(0x50000, 0x5000, UC_PROT_ALL)
45-
ql.mem.map(0x35000, 0x5000, UC_PROT_ALL)
46-
self.assertEqual(len(ql.mem.map_info), 5 + 2) # GDT, shellcode_stack
47-
self.assert_mem_equal(ql)
48-
49-
def test_mem_protect(self):
50-
ql = Qiling(code=X86_LIN, archtype="x86", ostype="linux")
51-
code = bytes([0x01, 0x70, 0x04])
52-
r_eax = 0x2000
53-
r_esi = 0xdeadbeef
54-
ql.arch.regs.write(UC_X86_REG_EAX, r_eax)
55-
ql.arch.regs.write(UC_X86_REG_ESI, r_esi)
56-
ql.mem.map(0x1000, 0x1000, UC_PROT_READ | UC_PROT_EXEC)
57-
ql.mem.map(0x2000, 0x1000, UC_PROT_READ)
58-
ql.mem.protect(0x2000, 0x1000, UC_PROT_READ | UC_PROT_WRITE)
59-
ql.mem.write(0x1000, code)
60-
ql.emu_start(0x1000, 0x1000 + len(code) - 1, 0, 1)
61-
buf = ql.mem.read(0x2000 + 4, 4)
62-
self.assertEqual(int.from_bytes(buf, "little"), 0xdeadbeef)
63-
self.assert_mem_equal(ql)
64-
65-
def test_splitting_mem_unmap(self):
66-
ql = Qiling(code=X86_LIN, archtype="x86", ostype="linux")
67-
ql.mem.map(0x20000, 0x1000, UC_PROT_NONE)
68-
ql.mem.map(0x21000, 0x2000, UC_PROT_NONE)
69-
try:
70-
ql.mem.unmap(0x21000, 0x1000)
71-
except UcError as e:
72-
print(e)
73-
for s, e, p in ql.uc.mem_regions():
74-
print(hex(s), hex(e), p)
75-
for line in ql.mem.get_formatted_mapinfo():
76-
print(line)
77-
self.assert_mem_equal(ql)
78-
79-
def test_mem_protect_map_ptr(self):
80-
ql = Qiling(code=X8664_LIN, archtype="x86_64", ostype="linux")
81-
val = 0x114514
82-
data1 = bytearray(0x4000)
83-
data2 = bytearray(0x2000)
84-
ql.mem.map(0x4000, 0x4000, UC_PROT_ALL, "data1", data1)
85-
ql.mem.unmap(0x6000, 0x2000)
86-
ql.mem.change_mapinfo(0x4000, 0x4000 + 0x2000, UC_PROT_ALL, "data1")
87-
self.assert_mem_equal(ql)
88-
89-
# ql.mem.map will call map_ptr and add_mapinfo
90-
ql.mem.map_ptr(0x6000, 0x2000, UC_PROT_ALL, data2)
91-
ql.mem.add_mapinfo(0x6000, 0x6000 + 0x2000,
92-
UC_PROT_ALL, "data2", False, data2)
93-
94-
ql.mem.write(0x6004, val.to_bytes(8, "little"))
95-
ql.mem.protect(0x6000, 0x1000, UC_PROT_READ)
96-
buf = ql.mem.read(0x6004, 8)
97-
self.assertEqual(int.from_bytes(buf, 'little'), val)
98-
self.assert_mem_equal(ql)
99-
100-
def test_map_at_the_end(self):
101-
ql = Qiling(code=X8664_LIN, archtype="x86_64", ostype="linux")
102-
mem = bytearray(0x1000)
103-
mem[:0x100] = [0xff] * 0x100
104-
mem = bytes(mem)
105-
ql.mem.map(0xfffffffffffff000, 0x1000, UC_PROT_ALL)
106-
ql.mem.write(0xfffffffffffff000, mem)
107-
self.assertRaises(UcError, ql.mem.write, 0xffffffffffffff00, mem)
108-
self.assertRaises(UcError, ql.mem.write, 0, mem)
109-
self.assert_mem_equal(ql)
110-
111-
def test_mmap2(self):
112-
ql = Qiling(code=X86_LIN, archtype="x86", ostype="linux", verbose=QL_VERBOSE.DEBUG)
113-
ql.loader.mmap_address = int(ql.profile.get('OS32', 'mmap_address'), 0)
114-
ql_syscall_mmap2(ql, 0, 8192, 3, 2050, 4294967295, 0)
115-
del ql
116-
117-
ql = Qiling(code=MIPS32EL_LIN, archtype="mips", ostype="linux", verbose=QL_VERBOSE.DEBUG)
118-
ql.loader.mmap_address = int(ql.profile.get('OS32', 'mmap_address'), 0)
119-
ql_syscall_mmap2(ql, 0, 8192, 3, 2050, 4294967295, 0)
120-
del ql
121-
122-
123-
if __name__ == "__main__":
124-
unittest.main()
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
import unittest
5+
sys.path.append("..")
6+
7+
from qiling import Qiling
8+
from qiling.const import QL_VERBOSE
9+
from qiling.exception import QlMemoryMappedError
10+
from qiling.os.posix.syscall.mman import ql_syscall_mmap2
11+
from qiling.os.posix.syscall.unistd import ql_syscall_brk
12+
from unicorn.x86_const import UC_X86_REG_EAX, UC_X86_REG_ESI
13+
from unicorn import UC_PROT_ALL, UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC, UC_PROT_NONE, UcError
14+
from test_shellcode import MIPS32EL_LIN, X8664_LIN, X86_LIN
15+
16+
17+
test_r2 = False
18+
if test_r2: # use R2Qiling as Qiling instead
19+
from qiling.extensions.r2 import R2Qiling as Qiling
20+
21+
class MemTest(unittest.TestCase):
22+
def test_map_correct(self):
23+
ql = Qiling(code=X8664_LIN, archtype="x86_64", ostype="linux")
24+
ql.mem.map(0x40000, 0x1000 * 16, UC_PROT_ALL) # [0x40000, 0x50000]
25+
ql.mem.map(0x60000, 0x1000 * 16, UC_PROT_ALL) # [0x60000, 0x70000]
26+
ql.mem.map(0x20000, 0x1000 * 16, UC_PROT_ALL) # [0x20000, 0x30000]
27+
self.assertRaises(QlMemoryMappedError, ql.mem.map,
28+
0x10000, 0x2000 * 16, UC_PROT_ALL)
29+
self.assertRaises(QlMemoryMappedError, ql.mem.map,
30+
0x25000, 0x1000 * 16, UC_PROT_ALL)
31+
self.assertRaises(QlMemoryMappedError, ql.mem.map,
32+
0x35000, 0x1000 * 16, UC_PROT_ALL)
33+
self.assertRaises(QlMemoryMappedError, ql.mem.map,
34+
0x45000, 0x1000 * 16, UC_PROT_ALL)
35+
self.assertRaises(QlMemoryMappedError, ql.mem.map,
36+
0x55000, 0x2000 * 16, UC_PROT_ALL)
37+
ql.mem.map(0x50000, 0x5000, UC_PROT_ALL)
38+
ql.mem.map(0x35000, 0x5000, UC_PROT_ALL)
39+
self.assertEqual(len(ql.mem.map_info), 5 + 2) # GDT, shellcode_stack
40+
41+
def test_mem_protect(self):
42+
ql = Qiling(code=X86_LIN, archtype="x86", ostype="linux")
43+
code = bytes([0x01, 0x70, 0x04])
44+
r_eax = 0x2000
45+
r_esi = 0xdeadbeef
46+
ql.arch.regs.write(UC_X86_REG_EAX, r_eax)
47+
ql.arch.regs.write(UC_X86_REG_ESI, r_esi)
48+
ql.mem.map(0x1000, 0x1000, UC_PROT_READ | UC_PROT_EXEC)
49+
ql.mem.map(0x2000, 0x1000, UC_PROT_READ)
50+
ql.mem.protect(0x2000, 0x1000, UC_PROT_READ | UC_PROT_WRITE)
51+
ql.mem.write(0x1000, code)
52+
ql.emu_start(0x1000, 0x1000 + len(code) - 1, 0, 1)
53+
buf = ql.mem.read(0x2000 + 4, 4)
54+
self.assertEqual(int.from_bytes(buf, "little"), 0xdeadbeef)
55+
56+
def test_splitting_mem_unmap(self):
57+
ql = Qiling(code=X86_LIN, archtype="x86", ostype="linux")
58+
ql.mem.map(0x20000, 0x1000, UC_PROT_NONE)
59+
ql.mem.map(0x21000, 0x2000, UC_PROT_NONE)
60+
try:
61+
ql.mem.unmap(0x21000, 0x1000)
62+
except UcError as e:
63+
print(e)
64+
for s, e, p in ql.uc.mem_regions():
65+
print(hex(s), hex(e), p)
66+
for line in ql.mem.get_formatted_mapinfo():
67+
print(line)
68+
69+
@unittest.skipUnless(test_r2, "Requires R2Qiling refactoring ql.mem")
70+
def test_mem_protect_map_ptr(self):
71+
ql = Qiling(code=X8664_LIN, archtype="x86_64", ostype="linux")
72+
val = 0x114514
73+
data1 = bytearray(0x4000)
74+
data2 = bytearray(0x2000)
75+
ql.mem.map(0x4000, 0x4000, UC_PROT_ALL, "data1", data1)
76+
ql.mem.unmap(0x6000, 0x2000)
77+
ql.mem.change_mapinfo(0x4000, 0x4000 + 0x2000, UC_PROT_ALL, "data1")
78+
79+
# ql.mem.map will call map_ptr and add_mapinfo
80+
ql.mem.map_ptr(0x6000, 0x2000, UC_PROT_ALL, data2)
81+
ql.mem.add_mapinfo(0x6000, 0x6000 + 0x2000,
82+
UC_PROT_ALL, "data2", False, data2)
83+
84+
ql.mem.write(0x6004, val.to_bytes(8, "little"))
85+
ql.mem.protect(0x6000, 0x1000, UC_PROT_READ)
86+
buf = ql.mem.read(0x6004, 8)
87+
self.assertEqual(int.from_bytes(buf, 'little'), val)
88+
89+
def test_map_at_the_end(self):
90+
ql = Qiling(code=X8664_LIN, archtype="x86_64", ostype="linux")
91+
mem = bytearray(0x1000)
92+
mem[:0x100] = [0xff] * 0x100
93+
mem = bytes(mem)
94+
ql.mem.map(0xfffffffffffff000, 0x1000, UC_PROT_ALL)
95+
ql.mem.write(0xfffffffffffff000, mem)
96+
self.assertRaises(UcError, ql.mem.write, 0xffffffffffffff00, mem)
97+
self.assertRaises(UcError, ql.mem.write, 0, mem)
98+
99+
def test_mmap2(self):
100+
ql = Qiling(code=X86_LIN, archtype="x86", ostype="linux", verbose=QL_VERBOSE.DEBUG)
101+
ql.loader.mmap_address = int(ql.profile.get('OS32', 'mmap_address'), 0)
102+
ql_syscall_mmap2(ql, 0, 8192, 3, 2050, 4294967295, 0)
103+
del ql
104+
105+
ql = Qiling(code=MIPS32EL_LIN, archtype="mips", ostype="linux", verbose=QL_VERBOSE.DEBUG)
106+
ql.loader.mmap_address = int(ql.profile.get('OS32', 'mmap_address'), 0)
107+
ql_syscall_mmap2(ql, 0, 8192, 3, 2050, 4294967295, 0)
108+
del ql
109+
110+
111+
if __name__ == "__main__":
112+
unittest.main()

0 commit comments

Comments
 (0)