Last active
October 14, 2018 19:49
-
-
Save strictlymike/325371108b1e59bbed4f5616b177c802 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
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