Last active
June 8, 2023 12:19
-
-
Save mr-tz/f17d9948036dd9313b99dde608c16e43 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright (C) 2023 Mandiant, Inc. All Rights Reserved. | |
| import sys | |
| import struct | |
| import logging | |
| import argparse | |
| import pefile | |
| logger = logging.getLogger(__name__) | |
| MIN_STR_LEN = 4 | |
| def main(): | |
| parser = argparse.ArgumentParser(description="Get Go strings") | |
| parser.add_argument("path", help="file or path to analyze") | |
| # TODO -n no effect yet | |
| parser.add_argument( | |
| "-n", | |
| "--minimum-length", | |
| dest="min_length", | |
| type=int, | |
| default=MIN_STR_LEN, | |
| help="minimum string length", | |
| ) | |
| logging_group = parser.add_argument_group("logging arguments") | |
| logging_group.add_argument("-d", "--debug", action="store_true", help="enable debugging output on STDERR") | |
| logging_group.add_argument( | |
| "-q", | |
| "--quiet", | |
| action="store_true", | |
| help="disable all status output except fatal errors", | |
| ) | |
| args = parser.parse_args() | |
| try: | |
| pe = pefile.PE(args.path) | |
| except pefile.PEFormatError as err: | |
| logger.debug(f"NOT valid PE header: {err}") | |
| return False | |
| if pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"]: | |
| """ | |
| .data:0000000000770F20 3D 68 60 00 00 00+off_770F20 dq offset aString | |
| .data:0000000000770F28 15 db 15h | |
| .data:0000000000770F29 00 db 0 | |
| """ | |
| alignment = 0x10 | |
| fmt = "<QQ" | |
| elif pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_I386"]: | |
| """ | |
| .data:102A78D0 E3 9A 17 10 dd offset aString | |
| .data:102A78D4 12 db 12h | |
| """ | |
| alignment = 0x8 | |
| fmt = "<II" | |
| else: | |
| raise ValueError("unhandled architecture") | |
| for section in pe.sections: | |
| try: | |
| section_name = section.Name.partition(b"\x00")[0].decode("utf-8") | |
| except UnicodeDecodeError: | |
| continue | |
| if section_name in (".data",): # TODO also ".rdata"? | |
| section_va = section.VirtualAddress | |
| section_size = section.SizeOfRawData | |
| section_data = section.get_data(section_va, section_size) | |
| for i in range(0, len(section_data), alignment): | |
| curr = section_data[i : i + alignment] | |
| s_off, s_size = struct.unpack(fmt, curr) | |
| if s_off and s_size: | |
| s_rva = s_off - pe.OPTIONAL_HEADER.ImageBase | |
| if pe.get_section_by_rva(s_rva): | |
| if 1 <= s_size < 128: | |
| addr = pe.OPTIONAL_HEADER.ImageBase + section_va + i | |
| try: | |
| string = pe.get_string_at_rva(s_rva, s_size).decode("utf-8") | |
| except UnicodeDecodeError: | |
| continue | |
| print(f"{section_name} 0x{addr:08x} 0x{s_off:08x} 0x{s_size:02x} {string}") | |
| if __name__ == "__main__": | |
| sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment