Skip to content

Commit

Permalink
feat: Allow to read string without their size if they are null-termin…
Browse files Browse the repository at this point in the history
…ated
  • Loading branch information
A. Challande committed Nov 17, 2022
1 parent 3194242 commit b6232d0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 7 deletions.
27 changes: 20 additions & 7 deletions bindings/python/quokka/executable.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,25 +75,38 @@ def read(self, offset: int, size: int) -> bytes:
except IndexError as exc:
raise ValueError(f"Content not found at offset {offset}") from exc

def read_string(self, offset: int, size: int) -> str:
def read_string(self, offset: int, size: Optional[int] = None) -> str:
"""Read a string in the file.
If the size is not given, Quokka will try to read the string until the
first null byte. That works only for null-terminated strings.
If the string is null terminated, remove the trailing 0.
Arguments:
offset: String file offset
size: String size
offset: String file offset
size: String size if known.
Returns:
The decoded string
Raises:
ValueError: If the string is not found nor decoded.
"""
try:
string = self.read(offset, size).decode("utf-8")
except UnicodeDecodeError as exc:
raise ValueError("Unable to read or decode the string.") from exc

if size is not None:
try:
string = self.read(offset, size).decode("utf-8")
except UnicodeDecodeError as exc:
raise ValueError("Unable to read or decode the string.") from exc

else:
try:
null_byte = self.content.index(b"\x00", offset)
except ValueError as exc:
raise ValueError("String is not null-terminated and size was not given") from exc

string = self.content[offset: null_byte].decode("utf-8")

# FIX: When returning a single character string, it does not end with a '\0'
if len(string) > 1 and string.endswith("\x00"):
Expand Down
25 changes: 25 additions & 0 deletions tests/python/tests/test_executable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 2022 Quarkslab
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import quokka


def test_read_string_unknown_size(prog: quokka.Program):
data_address: int = 0x3088
assert prog.executable.read_string(data_address) == "F00d1e"


def test_read_string(prog: quokka.Program):
data = prog.data_holder[20]
assert prog.executable.read_string(0x3088, data.size) == "F00d1e"

0 comments on commit b6232d0

Please sign in to comment.