diff --git a/gef.py b/gef.py index af6ee583e..2a6312ae8 100644 --- a/gef.py +++ b/gef.py @@ -10737,8 +10737,24 @@ def read_cstring(self, try: res_bytes = self.read(address, length) except gdb.error: - err(f"Can't read memory at '{address}'") - return "" + current_address = address + res_bytes = b"" + while len(res_bytes) < length: + try: + # Calculate how many bytes there are until next page + next_page = current_address + DEFAULT_PAGE_SIZE + page_mask = ~(DEFAULT_PAGE_SIZE - 1) + size = (next_page & page_mask) - current_address + + # Read until the end of the current page + res_bytes += self.read(current_address, size) + + current_address += size + except gdb.error: + if not res_bytes: + err(f"Can't read memory at '{address:#x}'") + return "" + break try: with warnings.catch_warnings(): # ignore DeprecationWarnings (see #735) diff --git a/tests/api/gef_memory.py b/tests/api/gef_memory.py index 8a448a5af..6b0b6760d 100644 --- a/tests/api/gef_memory.py +++ b/tests/api/gef_memory.py @@ -178,3 +178,17 @@ def test_func_parse_maps_realpath(self): "/usr" not in section.realpath): assert pathlib.Path(section.realpath).is_file() break + + def test_func_read_cstring_oob(self): + gef, gdb = self._gef, self._gdb + + gdb.execute("b main") + gdb.execute("start") + + section = gef.memory.maps[0] + oob_val = gef.memory.read_cstring(section.page_start, section.page_end - + section.page_start + 0x100) + val = gef.memory.read_cstring(section.page_start, section.page_end - + section.page_start) + + assert val == oob_val