Skip to content

Instantly share code, notes, and snippets.

@mr-tz
Last active June 8, 2023 12:19
Show Gist options
  • Select an option

  • Save mr-tz/f17d9948036dd9313b99dde608c16e43 to your computer and use it in GitHub Desktop.

Select an option

Save mr-tz/f17d9948036dd9313b99dde608c16e43 to your computer and use it in GitHub Desktop.
# 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