[PowerShell Script] Downloading PDB for Specific Modules
A few weeks ago, during a laboratory with a customer, I found myself struggling to download the public symbol from a specific driver. Since driver is Kernel Mode if you get a User Mode dump from the application using the driver, you won’t be able to actually see and download the driver. If you have a Kernel dump, you can get the module and download the symbols, but it’s more work.
There are other approaches and tools, but during this lab a colleague from PFE recommended symchk.exe, which is part of Debugging Tools for Windows. It turned out to be the best approach for my needs; however, chances are I’ll forget the syntax and my customer, too. To avoid this problem, I decided to create a small script that acts as a wrapper for symchk. To use it you have to pass 4 required parameters:
<Folder that Has the Modules> - Folder that has the modules (dlls/exes)
<Module Name or Mask> - You can use something like *.dll or the module name, like tcpip.dll.
<Folder To Save the Symbols>- Name for the folder that is going to store the symbols.
<Folder Where Debugging Tools For Windows is Installed>- Directory where Debugging tools for Windows was installed.
Usage:
Let’s suppose my dlls are in c:\test\dlls, my debugger is in c:\debuggers, and I want to save the public symbols for all dlls ( *.dll) in c:\test\symbols.
Here is the command line:
.\GetPDBForModules "c:\test\dlls" " *.dll" "c:\test\symbols" "c:\debuggers"
Before - just our binaries:
Execution:
After execution - binaries, symbols and manifest file:
Source code for GetPDBForModules.PS1:
########################################################################################################
# Script: GetPDBforModules.ps1
#
# Parameters: <dirModules> - Folder that has the modules (dlls)
# <moduleName> - You can use something like *.dll or the module name.
# <outputDirName> - Name for the folder that is going to store the symbols.
# <dirForDbgTools> - Directory where Debugging tools for Windows was installed.
#
# Purpose: Access the Microsoft public symbols and download the symbols for each module.
#
# Requirement: Debugging Tools For Windows.
#
# Usage: .\GetPDBforModules "c:\modules" "ntdll.dll" "c:\symbols" "c:\debuggers"
# .\GetPDBforModules "c:\modules" "*.dll" "c:\symbols" "c:\debuggers"
#
# Changes History:
#
# Roberto Alexis Farah
# All my functions are provided "AS IS" with no warranties, and confer no rights.
########################################################################################################
param(
[string] $dirModules = $(throw "Error! You must provide the path which has the modules like: c:\modules"),
[string] $moduleName = $(throw "Error! You must provide the file name like: ntdll.dll or *.dll or *.exe"),
[string] $outputDirName = $(throw "Error! You must provide the path which is going to store the symbols, like: c:\symbols"),
[string] $dirForDbgTools = $(throw "Error! You must provide the path for Debugging Toos For Windows.")
)
set-psdebug -strict
$ErrorActionPreference = "stop"
trap {"Error message: $_"}
$tempFile = "Manifest.txt" # We use $outputDirName plus .txt to create the manifest text file.
$dirForDbgTools += "\symchk" # Add symchk.exe to path.
# In case we are adding one more \, let's remove the extra \.
$dirForDbgTools = $dirForDbgTools.Replace("\\", "\")
# Windows Shell to call the console application.
$instance = new-object -comobject WScript.Shell
write-Host "`nExtracting manifest file from module(s)...`n" -foreground Green -background Black
$temp = "$dirModules\$moduleName".Replace("\\", "\")
# Creates directory. If it already exists it's ok.
$hideOutput = md "$outputDirName"
# It should be something like: symchk /om C:\SymListManifest /if c:\WINDOWS\system32\*.dll
$argument = "$dirForDbgTools /om $outputDirName$tempFile /if $temp"
write-Host $argument -foreground Red -background Black
$output = $instance.Run($argument, 3)
# The Run() method from WshShell doesn't wait for the callee to finish the execution, so let's wait for 10 seconds.
# On next version let's monitor if the console window had disappeared, so we don't have to use the forced delay.
start-Sleep 10
write-Host "`nDone!" -foreground Green -background Black
write-Host "`nDownloading symbols to $outputDirName folder..." -foreground Green -background Black
$argument = "$dirForDbgTools /im $outputDirName$tempFile /s SRV*$outputDirName*https://msdl.microsoft.com/download/symbols"
write-Host $argument -foreground Red -background Black
$output = $instance.Run($argument, 3)
write-Host "`nDone! " -foreground Green -background Black -nonewline
write-Host $outputDirName -foreground Red -background Black -nonewline
write-Host " has all requested PDB files.`n" -foreground Green -background Black
Comments
Anonymous
August 08, 2008
PingBack from http://blog.a-foton.ru/2008/08/powershell-script-downloading-pdb-for-specific-modules/Anonymous
August 08, 2008
PingBack from http://blog.a-foton.ru/2008/08/powershell-script-downloading-pdb-for-specific-modules/