-
Notifications
You must be signed in to change notification settings - Fork 748
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor!: ql own mem as bytearray, ref passed to uc and r2
BREAKING CHANGE: MapInfoEntry now has 6 elements instead of 5 BREAKING CHANGE: mem is managed in Python instead of uc BREAKING CHANGE: r2 map io from ql.mem, no full binary, now missing symbols BREAKING CHANGE: del_mapinfo and change_mapinfo recreate and remap mem Add unit tests for ql mem operations Also fix potential bug in syscall_munmap
- Loading branch information
Showing
6 changed files
with
157 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import sys, unittest | ||
sys.path.append("..") | ||
|
||
from unicorn import UC_PROT_ALL, UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC, UC_PROT_NONE, UcError | ||
from unicorn.x86_const import UC_X86_REG_EAX, UC_X86_REG_ESI | ||
|
||
from qiling import Qiling | ||
from qiling.exception import QlMemoryMappedError | ||
from test_shellcode import X8664_LIN, X86_LIN | ||
|
||
|
||
class MemTest(unittest.TestCase): | ||
def test_map_correct(self): | ||
ql = Qiling(code=X8664_LIN, archtype="x86_64", ostype="linux") | ||
ql.mem.map(0x40000, 0x1000 * 16, UC_PROT_ALL) # [0x40000, 0x50000] | ||
ql.mem.map(0x60000, 0x1000 * 16, UC_PROT_ALL) # [0x60000, 0x70000] | ||
ql.mem.map(0x20000, 0x1000 * 16, UC_PROT_ALL) # [0x20000, 0x30000] | ||
self.assertRaises(QlMemoryMappedError, ql.mem.map, 0x10000, 0x2000 * 16, UC_PROT_ALL) | ||
self.assertRaises(QlMemoryMappedError, ql.mem.map, 0x25000, 0x1000 * 16, UC_PROT_ALL) | ||
self.assertRaises(QlMemoryMappedError, ql.mem.map, 0x35000, 0x1000 * 16, UC_PROT_ALL) | ||
self.assertRaises(QlMemoryMappedError, ql.mem.map, 0x45000, 0x1000 * 16, UC_PROT_ALL) | ||
self.assertRaises(QlMemoryMappedError, ql.mem.map, 0x55000, 0x2000 * 16, UC_PROT_ALL) | ||
ql.mem.map(0x50000, 0x5000, UC_PROT_ALL) | ||
ql.mem.map(0x35000, 0x5000, UC_PROT_ALL) | ||
|
||
def test_mem_protect(self): | ||
ql = Qiling(code=X86_LIN, archtype="x86", ostype="linux") | ||
code = bytes([0x01, 0x70, 0x04]) | ||
r_eax = 0x2000 | ||
r_esi = 0xdeadbeef | ||
ql.arch.regs.write(UC_X86_REG_EAX, r_eax) | ||
ql.arch.regs.write(UC_X86_REG_ESI, r_esi) | ||
ql.mem.map(0x1000, 0x1000, UC_PROT_READ | UC_PROT_EXEC) | ||
ql.mem.map(0x2000, 0x1000, UC_PROT_READ) | ||
ql.mem.protect(0x2000, 0x1000, UC_PROT_READ | UC_PROT_WRITE) | ||
ql.mem.write(0x1000, code) | ||
ql.emu_start(0x1000, 0x1000 + len(code) - 1, 0, 1) | ||
buf = ql.mem.read(0x2000 + 4, 4) | ||
self.assertEqual(int.from_bytes(buf, "little"), 0xdeadbeef) | ||
|
||
def test_splitting_mem_unmap(self): | ||
ql = Qiling(code=X86_LIN, archtype="x86", ostype="linux") | ||
ql.mem.map(0x20000, 0x1000, UC_PROT_NONE) | ||
ql.mem.map(0x21000, 0x2000, UC_PROT_NONE) | ||
try: | ||
ql.mem.unmap(0x21000, 0x1000) | ||
except UcError as e: | ||
print(e) | ||
for s, e, p in ql.uc.mem_regions(): | ||
print(hex(s), hex(e), p) | ||
for line in ql.mem.get_formatted_mapinfo(): | ||
print(line) | ||
|
||
def test_mem_protect_map_ptr(self): | ||
ql = Qiling(code=X8664_LIN, archtype="x86_64", ostype="linux") | ||
val = 0x114514 | ||
data1 = bytearray(0x4000) | ||
data2 = bytearray(0x2000) | ||
ql.mem.map_ptr(0x4000, 0x4000, UC_PROT_ALL, data1) | ||
ql.mem.add_mapinfo(0x4000, 0x4000 + 0x4000, UC_PROT_ALL, "data1", False, data1) | ||
ql.mem.unmap(0x6000, 0x2000) | ||
ql.mem.map(0x6000, 0x2000, UC_PROT_ALL, data2) | ||
ql.mem.add_mapinfo(0x6000, 0x6000 + 0x2000, UC_PROT_ALL, "data2", False, data2) | ||
|
||
ql.mem.write(0x6004, val.to_bytes(8, "little")) | ||
ql.mem.protect(0x6000, 0x1000, UC_PROT_READ) | ||
buf = ql.mem.read(0x6004, 8) | ||
self.assertEqual(int.from_bytes(buf, 'little'), val) | ||
|
||
def test_map_at_the_end(self): | ||
ql = Qiling(code=X8664_LIN, archtype="x86_64", ostype="linux") | ||
mem = bytearray(0x1000) | ||
mem[:0x100] = [0xff] * 0x100 | ||
mem = bytes(mem) | ||
ql.mem.map(0xfffffffffffff000, 0x1000, UC_PROT_ALL) | ||
ql.mem.write(0xfffffffffffff000, mem) | ||
self.assertRaises(UcError, ql.mem.write, 0xffffffffffffff00, mem) | ||
self.assertRaises(UcError, ql.mem.write, 0, mem) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |