Skip to content

Instantly share code, notes, and snippets.

@strictlymike
Last active October 14, 2018 19:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save strictlymike/325371108b1e59bbed4f5616b177c802 to your computer and use it in GitHub Desktop.
Save strictlymike/325371108b1e59bbed4f5616b177c802 to your computer and use it in GitHub Desktop.
import sys
import pefile
import struct
import httplib
import os.path
import argparse
# from urllib.parse import urlparse # Python 3
import urlparse
# PDB downloading adapted from:
# https://gist.github.com/steeve85/2665503
# @steeve85's gist comments:
# pdb_downloader.py
# v0.1
# Steeve Barbeau
# @steevebarbeau
# steeve-barbeau.blogspot.com
uri = "/download/symbols/%s.pdb/%s/%s.pdb"
def download_pdb(dll_name, guid):
final_uri = uri % (dll_name, guid, dll_name)
conn = httplib.HTTPConnection("msdl.microsoft.com")
headers = {
'User-Agent': 'Microsoft-Symbol-Server/6.12.0002.633',
# 'Accept-Encoding': 'gzip',
# 'Connection': 'Keep-Alive',
# 'Cache-Control': 'no-cache',
}
conn.request("GET", final_uri, "", headers)
response = conn.getresponse()
if response.status == 302:
redir_url = response.getheader('Location')
redir_parsed = urlparse.urlparse(redir_url)
server = redir_parsed.netloc
redir_uri = '%s?%s' % (redir_parsed.path, redir_parsed.query)
if redir_parsed.scheme == 'https':
conn = httplib.HTTPSConnection(server)
else:
conn = httplib.HTTPConnection(server)
conn.request("GET", redir_uri, "", headers)
response = conn.getresponse()
if response.status == 200:
pdb_buffer = response.read()
pdb_filename = os.path.basename(uri % (dll_name, guid, dll_name))
pdb_file = open(pdb_filename, 'wb')
pdb_file.write(pdb_buffer)
pdb_file.close()
return True
return False
def get_guid(dll_path):
# ugly code, isn't it ?
try:
dll = pefile.PE(dll_path)
rva = dll.DIRECTORY_ENTRY_DEBUG[0].struct.AddressOfRawData
tmp = ''
tmp += '%0.*X' % (8, dll.get_dword_at_rva(rva+4))
tmp += '%0.*X' % (4, dll.get_word_at_rva(rva+4+4))
tmp += '%0.*X' % (4, dll.get_word_at_rva(rva+4+4+2))
x = dll.get_word_at_rva(rva+4+4+2+2)
tmp += '%0.*X' % (4, struct.unpack('<H',struct.pack('>H',x))[0])
x = dll.get_word_at_rva(rva+4+4+2+2+2)
tmp += '%0.*X' % (4, struct.unpack('<H',struct.pack('>H',x))[0])
x = dll.get_word_at_rva(rva+4+4+2+2+2+2)
tmp += '%0.*X' % (4, struct.unpack('<H',struct.pack('>H',x))[0])
x = dll.get_word_at_rva(rva+4+4+2+2+2+2+2)
tmp += '%0.*X' % (4, struct.unpack('<H',struct.pack('>H',x))[0])
tmp += '%0.*X' % (1, dll.get_word_at_rva(rva+4+4+2+2+2+2+2+2))
except AttributeError, e:
print 'Error appends during %s parsing' % dll_path
print e
return None
return tmp.upper()
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--filepath', help='Path to file')
args = parser.parse_args()
if not args.filepath:
print('Usage: getpdb.py --filepath <path_to_exe_or_dll>')
else:
guid = get_guid(args.filepath)
filename = os.path.splitext(os.path.basename(args.filepath))[0]
if guid:
download_pdb(filename, guid)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment