This class attempts to help the process of identifying strings that might be plain Unicode or Pascal. A list of strings will be wrapped on it with the hope the overlappings will help make the decision about their type.
| 742 | |
| 743 | |
| 744 | class UnicodeStringWrapperPostProcessor: |
| 745 | """This class attempts to help the process of identifying strings |
| 746 | that might be plain Unicode or Pascal. A list of strings will be |
| 747 | wrapped on it with the hope the overlappings will help make the |
| 748 | decision about their type.""" |
| 749 | |
| 750 | def __init__(self, pe, rva_ptr): |
| 751 | self.pe = pe |
| 752 | self.rva_ptr = rva_ptr |
| 753 | self.string = None |
| 754 | |
| 755 | def get_rva(self): |
| 756 | """Get the RVA of the string.""" |
| 757 | return self.rva_ptr |
| 758 | |
| 759 | def __str__(self): |
| 760 | """Return the escaped UTF-8 representation of the string.""" |
| 761 | return self.decode("utf-8", "backslashreplace_") |
| 762 | |
| 763 | def decode(self, *args): |
| 764 | if not self.string: |
| 765 | return "" |
| 766 | return self.string.decode(*args) |
| 767 | |
| 768 | def invalidate(self): |
| 769 | """Make this instance None, to express it's no known string type.""" |
| 770 | self = None |
| 771 | |
| 772 | def render_pascal_16(self): |
| 773 | try: |
| 774 | self.string = self.pe.get_string_u_at_rva( |
| 775 | self.rva_ptr + 2, max_length=self.get_pascal_16_length() |
| 776 | ) |
| 777 | except PEFormatError: |
| 778 | self.pe.get_warnings().append( |
| 779 | "Failed rendering pascal string, " |
| 780 | "attempting to read from RVA 0x{0:x}".format(self.rva_ptr + 2) |
| 781 | ) |
| 782 | |
| 783 | def get_pascal_16_length(self): |
| 784 | return self.__get_word_value_at_rva(self.rva_ptr) |
| 785 | |
| 786 | def __get_word_value_at_rva(self, rva): |
| 787 | try: |
| 788 | data = self.pe.get_data(rva, 2) |
| 789 | except PEFormatError: |
| 790 | return False |
| 791 | |
| 792 | if len(data) < 2: |
| 793 | return False |
| 794 | |
| 795 | return struct.unpack("<H", data)[0] |
| 796 | |
| 797 | def ask_unicode_16(self, next_rva_ptr): |
| 798 | """The next RVA is taken to be the one immediately following this one. |
| 799 | |
| 800 | Such RVA could indicate the natural end of the string and will be checked |
| 801 | to see if there's a Unicode NULL character there. |
no outgoing calls
no test coverage detected