Get an Unicode string located at the given address.
(self, rva, max_length=2**16, encoding=None)
| 5986 | return s |
| 5987 | |
| 5988 | def get_string_u_at_rva(self, rva, max_length=2**16, encoding=None): |
| 5989 | """Get an Unicode string located at the given address.""" |
| 5990 | |
| 5991 | if max_length == 0: |
| 5992 | return b"" |
| 5993 | |
| 5994 | # If the RVA is invalid let the exception reach the callers. All |
| 5995 | # call-sites of get_string_u_at_rva() will handle it. |
| 5996 | data = self.get_data(rva, 2) |
| 5997 | # max_length is the maximum count of 16bit characters needs to be |
| 5998 | # doubled to get size in bytes |
| 5999 | max_length <<= 1 |
| 6000 | |
| 6001 | requested = min(max_length, 256) |
| 6002 | data = self.get_data(rva, requested) |
| 6003 | # try to find null-termination |
| 6004 | null_index = -1 |
| 6005 | while True: |
| 6006 | null_index = data.find(b"\x00\x00", null_index + 1) |
| 6007 | if null_index == -1: |
| 6008 | data_length = len(data) |
| 6009 | if data_length < requested or data_length == max_length: |
| 6010 | null_index = len(data) >> 1 |
| 6011 | break |
| 6012 | |
| 6013 | # Request remaining part of data limited by max_length |
| 6014 | data += self.get_data(rva + data_length, max_length - data_length) |
| 6015 | null_index = requested - 1 |
| 6016 | requested = max_length |
| 6017 | |
| 6018 | elif null_index % 2 == 0: |
| 6019 | null_index >>= 1 |
| 6020 | break |
| 6021 | |
| 6022 | # convert selected part of the string to unicode |
| 6023 | uchrs = struct.unpack("<{:d}H".format(null_index), data[: null_index * 2]) |
| 6024 | s = "".join(map(chr, uchrs)) |
| 6025 | |
| 6026 | if encoding: |
| 6027 | return b(s.encode(encoding, "backslashreplace_")) |
| 6028 | |
| 6029 | return b(s.encode("utf-8", "backslashreplace_")) |
| 6030 | |
| 6031 | def get_section_by_offset(self, offset): |
| 6032 | """Get the section containing the given file offset.""" |
no test coverage detected