From 2e8a7039471c78f4dc6767dd4e09aa7440e893ad Mon Sep 17 00:00:00 2001 From: lazymio Date: Mon, 9 May 2022 00:12:52 +0200 Subject: [PATCH 1/5] Support memory slicing --- qiling/os/memory.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/qiling/os/memory.py b/qiling/os/memory.py index 5357623ef..fe9470b01 100644 --- a/qiling/os/memory.py +++ b/qiling/os/memory.py @@ -3,6 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # +from ctypes import Union import os, re from typing import Any, Callable, List, MutableSequence, Optional, Sequence, Tuple @@ -63,6 +64,29 @@ def __read_string(self, addr: int) -> str: def __write_string(self, addr: int, s: str, encoding: str): self.write(addr, bytes(s, encoding) + b'\x00') + def __getitem__(self, key: Union[slice, int]) -> bytearray: + if isinstance(key, slice): + start = key.start + stop = key.stop + step = key.step + + if step and step != 1: + # step != 1 means we have to do copy, don't allow it. + raise IndexError("Only support slicing continous memory") + + return self.ql.mem.read(start, stop - start) + elif isinstance(key, int): + return self.ql.mem.read(key, 1) + else: + raise KeyError("Wrong type of key") + + def __setitem__(self, key: Union[slice, int], value: Union[bytes, bytearray]): + if isinstance(key, int): + self.ql.mem.write(key, value) + else: + # Slicing doesn't make sense in writing. + raise KeyError("Wrong type of key") + # TODO: this is an obsolete utility method that should not be used anymore # and here for backward compatibility. use QlOsUtils.read_cstring instead def string(self, addr: int, value=None, encoding='utf-8') -> Optional[str]: From 11224c3cbfd1c82ecf756955c7660d872a357c3e Mon Sep 17 00:00:00 2001 From: lazymio Date: Mon, 9 May 2022 00:19:46 +0200 Subject: [PATCH 2/5] Fix typo --- qiling/os/memory.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qiling/os/memory.py b/qiling/os/memory.py index fe9470b01..35742ed84 100644 --- a/qiling/os/memory.py +++ b/qiling/os/memory.py @@ -3,9 +3,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -from ctypes import Union import os, re -from typing import Any, Callable, List, MutableSequence, Optional, Sequence, Tuple +from typing import Any, Callable, List, MutableSequence, Optional, Sequence, Tuple, Union from unicorn import UC_PROT_NONE, UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC, UC_PROT_ALL From 9f78b696fc304200fc4c481fa97a20aeaccb800d Mon Sep 17 00:00:00 2001 From: lazymio Date: Mon, 9 May 2022 00:29:17 +0200 Subject: [PATCH 3/5] Check None correctly --- qiling/os/memory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiling/os/memory.py b/qiling/os/memory.py index 35742ed84..eca30ec0d 100644 --- a/qiling/os/memory.py +++ b/qiling/os/memory.py @@ -69,7 +69,7 @@ def __getitem__(self, key: Union[slice, int]) -> bytearray: stop = key.stop step = key.step - if step and step != 1: + if step is not None and step != 1: # step != 1 means we have to do copy, don't allow it. raise IndexError("Only support slicing continous memory") From 41d6d30b9afab54d4701dd0d6d11baff311c2afc Mon Sep 17 00:00:00 2001 From: lazymio Date: Mon, 9 May 2022 14:23:57 +0200 Subject: [PATCH 4/5] mimic bytearray --- qiling/os/memory.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/qiling/os/memory.py b/qiling/os/memory.py index eca30ec0d..d6ea555f6 100644 --- a/qiling/os/memory.py +++ b/qiling/os/memory.py @@ -73,17 +73,31 @@ def __getitem__(self, key: Union[slice, int]) -> bytearray: # step != 1 means we have to do copy, don't allow it. raise IndexError("Only support slicing continous memory") - return self.ql.mem.read(start, stop - start) + return self.ql.mem.read(start, max(0, stop - start)) elif isinstance(key, int): - return self.ql.mem.read(key, 1) + return self.ql.mem.read(key, 1)[0] else: raise KeyError("Wrong type of key") - def __setitem__(self, key: Union[slice, int], value: Union[bytes, bytearray]): + def __setitem__(self, key: Union[slice, int], value: bytes): if isinstance(key, int): - self.ql.mem.write(key, value) + self.ql.mem.write(key, bytes([value])) + elif isinstance(key, slice): + start = key.start + stop = key.stop + step = key.step + + if step is not None and step != 1: + raise IndexError("Only support slicing continous memory") + + if start is None: + raise IndexError("The start of memory is not supplied") + + if len(value) > stop - start: + raise IndexError("Bytes to write are more than sliced memory") + + self.ql.mem.write(start, value) else: - # Slicing doesn't make sense in writing. raise KeyError("Wrong type of key") # TODO: this is an obsolete utility method that should not be used anymore From 295ea603f9cfe55b1436ce6acf631463ae0c1221 Mon Sep 17 00:00:00 2001 From: lazymio Date: Tue, 10 May 2022 20:41:35 +0200 Subject: [PATCH 5/5] Enforce ql.mem[addr:] to be more intuitive --- qiling/os/memory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiling/os/memory.py b/qiling/os/memory.py index d6ea555f6..9526f90ab 100644 --- a/qiling/os/memory.py +++ b/qiling/os/memory.py @@ -93,7 +93,7 @@ def __setitem__(self, key: Union[slice, int], value: bytes): if start is None: raise IndexError("The start of memory is not supplied") - if len(value) > stop - start: + if stop is not None and len(value) > stop - start: raise IndexError("Bytes to write are more than sliced memory") self.ql.mem.write(start, value)