If I have an executable file (let's say ntoskrnl.exe) I can obtain it's .pdb file from Microsoft. Is it possible to do the reverse? If I have a .pdb can I obtain the .exe? Or the only method is to hope it is somewhere on my symbols server and look it up by pdb signature and/or timedate stamp?

  • You mean like do it automatically? Jun 22, 2017 at 14:33
  • @PawełŁukasik is there a manual way of doing it?
    – icebp
    Jun 22, 2017 at 14:55
  • Well, in PDB you have some functiona names and other things that could potentially identify the exe/dll/sys but probably you would have to search for those and hope that you will get some hits as for the dll name. Jun 22, 2017 at 16:07
  • binaries are fetched from symsrv using thier timestamp and size which afaik is not present in pdb so you may have to grep the dumpbin output of similar named binaries in your local drives and hope for a match dumpbin /headers c:\Windows\System32\calc.exe | grep -i rsds 4CE7979D cv 21 00053C80 53080 Format: RSDS, {971D2945-E998- 438C-8476-43A9DB39C88E}, 2, calc.pdb dbh srvind .\calc.pdb .\calc.pdb : 971D2945E998438C847643A9DB39C88E2
    – blabb
    Jun 22, 2017 at 20:14
  • @blabb you should write a proper answer, this is good info but a little cramped and difficult to interpret like that.
    – Igor Skochinsky
    Jun 22, 2017 at 20:57

2 Answers 2


the binaries (exe , sys , dll ) are fetched from ms symbol servers by their time_date_stamp and size

the windbg command !chkimg normally fetches the binaries for minidumps and it uses SymFindFileInPath Function

which takes three ids which are different for pdbs and binaries you may take a look at the Remarks Section Of the function for the id definition

there is no reverse match afaik ie given a pdb you cant retrieve the timestamp and size of the binary which you would require for a successfull retrieval

only recourse left is to grep the local drives for similar named binary

using dumpbin and the windbg package tool dbh.exe

note there are two pdb in the cache while i have only one binary matching the second pdb in my system note carefully the age is appended to the guid in the srvind output while the age is printed in a seperate line in dump bin out put

now that you know the file you can fetch a pristine copy if needed from ms symbols server by dumping the time stamp / size and appending them in to a string and calling httpget with useragent as microsoft-symbol-server (or whatever it is now (my memory of the useragent is several years old grab a network packet for a latest user agent string)

C:\>dbh srvind e:\SYMBOLS\cdfs.pdb\6FA7C1B9FB96447B8608B2F31CEADB312\cdfs.pdb

e:\SYMBOLS\cdfs.pdb\6FA7C1B9FB96447B8608B2F31CEADB312\cdfs.pdb : 6FA7C1B9FB96447

C:\>dbh srvind e:\SYMBOLS\cdfs.pdb\D457507255544405BD9A5C4D3EBCCBAE2\cdfs.pdb

e:\SYMBOLS\cdfs.pdb\D457507255544405BD9A5C4D3EBCCBAE2\cdfs.pdb : D45750725554440

C:\>dumpbin /headers "c:\Windows\System32\drivers\cdfs.sys" | grep -i rsds
    4A5BBF12 cv            21 000028C0     1CC0    Format: RSDS, {D4575072-5554-
4405-BD9A-5C4D3EBCCBAE}, 2, cdfs.pdb

here is a dumpbin versus actual dump and !itoldyouso output

C:\>dumpbin /headers "c:\Windows\System32\drivers\cdfs.sys" | grep -i "size of i
           16000 size of image

C:\>dumpbin /headers "c:\Windows\System32\drivers\cdfs.sys" | grep -i date
        4A5BBF12 time date stamp Tue Jul 14 04:41:14 2009

C:\>cdb -z c:\Windows\System32\drivers\cdfs.sys

0:000> !itoldyouso cdfs

    Timestamp: 4A5BBF12
  SizeOfImage: 16000
          pdb: cdfs.pdb
      pdb sig: D4575072-5554-4405-BD9A-5C4D3EBCCBAE
          age: 2

Loaded pdb is e:\symbols\cdfs.pdb\D457507255544405BD9A5C4D3EBCCBAE2\cdfs.pdb

      pdb sig: D4575072-5554-4405-BD9A-5C4D3EBCCBAE
          age: 2

MATCH: cdfs.pdb and cdfs.sys

here is a network packet header with the latest user agent string for a binary fetch

"Host Name":"msdl.microsoft.com",
"User Agent":"Microsoft-Symbol-Server/",
"Response Code":"200",
"Response String":"OK",
"Content Type":"application/octet-stream",
"Content Encoding":"",
"Transfer Encoding":"",
"Content Length":"295985",
"Cache Control":"public",
"Server Time":"6/24/2017 4:37:26 PM",
"Expiration Time":"",
"Last Modified Time":"12/16/2010 8:20:21 AM",
"Client Address":"xxx.xxx.xx.xx:xxxxx",
"Server Address":"",
"Request Time":"00:07:23.331",
"Response Time":"1444 ms",

and the timestamp and size details grabbed from list modules output

0:000> dx -r0 @$lmvmcalc = Debugger.Utility.Control.ExecuteCommand("lmvm calc")
@$lmvmcalc = Debugger.Utility.Control.ExecuteCommand("lmvm calc")                
0:000> dx -r0 @$lmvmcalc[8] ; dx -r0 @$lmvmcalc[6]
@$lmvmcalc[8]    :     ImageSize:        000C0000
@$lmvmcalc[6]    :     Timestamp:        Sat Nov 20 15:10:45 2010 (4CE7979D)

and a fetch without symsrv.dll using wget and comparing with local file

C:\>md testfetchwithwget

C:\>cd testfetchwithwget

C:\testfetchwithwget>ls -l
total 0

wgetting with useragent and debug spew on

C:\testfetchwithwget>wget -d -c -U="Microsoft-Symbol-Server/" "http://msdl.microsoft.com/dow
Setting --continue (continue) to 1
Setting --user-agent (useragent) to =Microsoft-Symbol-Server/
DEBUG output created by Wget 1.12.1-dev Mar 04 2010 (mainline-013c8e2f5997) on Windows-MinGW.

--2017-06-24 22:35:20--  http://msdl.microsoft.com/download/symbols/calc.exe/4CE7979Dc0000/calc.ex_
Resolving msdl.microsoft.com... seconds 0.00,
Caching msdl.microsoft.com =>
Connecting to msdl.microsoft.com||:80... seconds 0.00, connected.
Created socket 204.
Releasing 0x00893e38 (new refcount 1).

---request begin---
GET /download/symbols/calc.exe/4CE7979Dc0000/calc.ex_ HTTP/1.0
User-Agent: =Microsoft-Symbol-Server/
Accept: */*
Host: msdl.microsoft.com
Connection: Keep-Alive

---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.1 200 OK
Cache-Control: public
Content-Length: 295985
Content-Type: application/octet-stream
Last-Modified: Thu, 16 Dec 2010 08:20:21 GMT
Accept-Ranges: bytes
ETag: "7367f914fa9ccb1:0"
Server: Microsoft-IIS/8.5
X-MSEdge-Ref: Ref A: A80831FD9CD34C76B235D9794A671A8B Ref B: BOM02EDGE0109 Ref C: Sat Jun 24 10:05:3
3 2017 PST
X-MSEdge-Ref-OriginShield: Ref A: 5B1085618AB14BDBA7B8195D249E26E2 Ref B: BOM01EDGE0317 Ref C: Sat J
un 24 07:42:52 2017 PST
Date: Sat, 24 Jun 2017 17:05:33 GMT
Connection: keep-alive

---response end---
200 OK
Registered socket 204 for persistent reuse.
Length: 295985 (289K) [application/octet-stream]
Saving to: `calc.ex_'

100%[==========================================================>] 295,985     15.1K/s   in 25s

2017-06-24 22:35:51 (11.3 KB/s) - `calc.ex_' saved [295985/295985]


C:\testfetchwithwget>ls -l
total 292
-rw-rw-rw-  1 HP 0 295985 2010-12-16 13:50 calc.ex_

C:\testfetchwithwget>expand -R calc.ex_ calc.exe
Microsoft (R) File Expansion Utility  Version 6.1.7600.16385
Copyright (c) Microsoft Corporation. All rights reserved.

Adding C:\testfetchwithwget\calc.exe to Extraction Queue

Expanding Files ....

Expanding Files Complete ...
Cannot expand a file onto itself: calc.exe.

C:\testfetchwithwget>ls -l
total 1052
-rw-rw-rw-  1 HP 0 295985 2010-12-16 13:50 calc.ex_
-rwxrwxrwx  1 HP 0 776192 2010-12-15 20:21 calc.exe

C:\testfetchwithwget>ls -l c:\Windows\System32\calc.exe
-rwxrwxrwx  2 HP 0 776192 2010-11-20 04:16 c:\Windows\System32\calc.exe

C:\testfetchwithwget>fc /b  c:\Windows\System32\calc.exe .\calc.exe
Comparing files C:\WINDOWS\SYSTEM32\calc.exe and .\CALC.EXE
FC: no differences encountered

Haven't tried it, but SymFindExecutableImage might work if the image is present on the symbol server. I know that WinDbg/Visual Studio are able in some cases download images referenced in the crash dumps, and they probably use this or similar function.

  • afaik there is no reverse matching from a pdb to binary windbg !chkimg function retrieves the binary based on the crash dump module timestamp and size which aren't available in pdb
    – blabb
    Jun 22, 2017 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.