Provide symbol server auth to windows debugger

We have a tool that runs cdb and processes dmp files. The symbol server needs authentication for cdb to be able to download files from it. Our setup does not allow symbol access without auth.

I get the below log from the cdb for downloading ntdll. ntdll is just an example, and this dll could be any private dll.

The logs show its trying to auth using some credential provider, but there is no info about how to resolve the error.
Can anyone share documentation related to credential provider, how to give cdb the credentials in non-interactive mode?

 
SYMSRV:  BYINDEX: 0x9
         c:sym1*https://repos.net/factory/symbols/microsoftsymbols/
         ntdll.pdb
         03818EC49CBD48F2B0B378C3558734891
SYMSRV:  UNC: c:sym1ntdll.pdb3818EC49CBD48F2B0B378C3558734891ntdll.pdb - path not found
SYMSRV:  UNC: c:sym1ntdll.pdb3818EC49CBD48F2B0B378C3558734891ntdll.pd_ - path not found
SYMSRV:  UNC: c:sym1ntdll.pdb3818EC49CBD48F2B0B378C3558734891file.ptr - path not found
SYMSRV:  HTTPGET: /factory/symbols/microsoftsymbols//ntdll.pdb/03818EC49CBD48F2B0B378C3558734891/ntdll.pdb
SYMSRV:  HttpQueryInfo: 80190191 - HTTP_STATUS_DENIED
SYMSRV:  Credential Provider: Getting credentials for: protocol=https, host=repos.net, path=factory/symbols/microsoftsymbols/, interactive=0, isRetry=0
SYMSRV:  Credential Provider: Getting credentials from provider: C:Program Files (x86)Windows Kits10Debuggersx64credentialprovidersgcmwdbgcredentialprovider_gcmw.dll...
SYMSRV:  Credential Provider: DebuggerCredentialManager.exe is not found.
SYMSRV:  Credential Provider: DbgCredentialProvider_gcmw: Failed to build execution command.
HttpQueryInfo: Requesting Authentication for Web Site.
SYMSRV:  RESULT: 0x80190191

Update 10/31/2024:

Modified the powershell script and its reading the credential from Credential manager successfully but the debugger is receiving only the last 13 chars. Verified the powershell script is returning the expected info. We use the debugger version 10.22621.755.

    SYMSRV:  BYINDEX: 0x7
         c:sym1*https://repos.net/factory/symbols/microsoftsymbols/
         ntdll.pdb
         03818EC49CBD48F2B0B378C3558734891
SYMSRV:  UNC: c:sym1ntdll.pdb3818EC49CBD48F2B0B378C3558734891ntdll.pdb - path not found
SYMSRV:  UNC: c:sym1ntdll.pdb3818EC49CBD48F2B0B378C3558734891ntdll.pd_ - path not found
SYMSRV:  UNC: c:sym1ntdll.pdb3818EC49CBD48F2B0B378C3558734891file.ptr - path not found
SYMSRV:  HTTPGET: /factory/symbols/microsoftsymbols//ntdll.pdb/03818EC49CBD48F2B0B378C3558734891/ntdll.pdb
SYMSRV:  HttpQueryInfo: 80190191 - HTTP_STATUS_DENIED
SYMSRV:  Credential Provider: Getting credentials for: protocol=https, host=repos.net, path=factory/symbols/microsoftsymbols/, interactive=0, isRetry=0
SYMSRV:  Credential Provider: Getting credentials from provider: C:Program Files (x86)Windows Kits10Debuggersx64credentialprovidersmycredentialprovidermycredentialprovider.bat...
SYMSRV:  Credential Provider: Stream response:'WdG90amuHYswd'
SYMSRV:  Credential Provider: Stream response:''
SYMSRV:  Credential Provider: Failed to get user credentials from stream for 'C:Program Files (x86)Windows Kits10Debuggersx64credentialprovidersmycredentialprovidermycredentialprovider.bat'.
HttpQueryInfo: Requesting Authentication for Web Site.
SYMSRV:  RESULT: 0x80190191

credProviderLog.txt contains the Found PAT log:

Entering Credential Provider
interactive=0
symbolsRequest=1
isRetry=0
parentHwnd=0x10010
protocol=https
host=repos.net
path=factory/symbols/microsoftsymbols/
Installing module
Found path line: host=repos.net
Found symbol path: symbol:repos.net
Found PAT!

3

The documentation will be published in the near future. I’ve copied that documentation and pasted it below.

Note that the specific location of DbgCredentialProvider.config.xml depends on which version of the Windows Kit you have installed. Based on your debugger logs, you don’t have the latest Kit, but I don’t think that affects the instructions below.

The Windows debugger infrastructure has been updated to assist symbols or sources files download when the server returns
an error HTTP_STATUS_DENIED 401 (access denied). In such case the request has to be resent with updated authentication headers
containing proper credentials for the user.

The bridge between the debugger and the credential providers is DbgCredentialProvider.dll. It will look for credential providers using the following algorithm:

    1) It opens a file DbgCredentialProvider.config.xml which should be located next to DbgCredentialProvider.dll. The search behavior that is used to locate
       DbgCredentialProvider.config.xml file may change in the future.

            The DbgCredentialProvider.config.xml file contains a folders list:

                 <?xml version="1.0" encoding="utf-8"?>
                 <!--
                 The config file is located next to DbgCredentialProvider.dll.
                 -->
                 <Settings>
                     <Folders>
                         <!--
                             This is a list of the folders which should be provided as an absolute file path or
                             relative to the location of this config file.
                         -->
                         <Folder>CredentialProviders</Folder>
                     </Folders>
                 </Settings>

                 You can list more than one folder under <Folders></Folders> elements. The folders can be relative or absolute path. If it is relative path, it is relative to the location
                 of the DbgCredentialProvider.config.xml file. The folders will be searched for providers in the order listed in the XML file.

                 In the current example the Folders collection has just one folder "CredentialProviders" and it is a relative path.

    2) Then all files with extension '*.xml' in CredentialProviders folder will be enumerated. The order in which the XML files are enumerated is unspecified. Those XML files describe which
       debugger credential providers are available for the debugger. You may find DbgCredentialProvider_gcmw.xml file (or other XML files) in CredentialProvider folder which contain data like this:

                 <?xml version="1.0" encoding="utf-8"?>
                 <CredentialProviders>
                     <!--
                           This is a list of the provider modules which should be provided as an absolute file path or
                           relative to the location of this config file.
                           The provider is a DLL, EXE or CMD file.
                     -->
                   <CredentialProvider ApiVersion="2.0.0">GCMWDbgCredentialProvider_gcmw.dll</CredentialProvider>

                 </CredentialProviders>

       The XML file may list more than one credential provider. In this example we have just one provider DbgCredentialProvider_gcmw.dll and it is located
       in GCMW folder relative to the DbgCredentialProvider_gcmw.xml file location. The providers may be relative or absolute paths similar to the ones described
       in the section for DbgCredentialProvider.config.xml file.

The debugger credential providers can be DLL, EXE or CMD script files. The debugger will ask every provider for credentials and it will use the credentials from the first provider
which returns success.

If the provider is implemented in a DLL it must export GetUserCredentials method as listed in this file.
If the provider is implemented in EXE or a CMD script it should be able to process the following command line parameters (case insensitive), which cannot be combined with each other.
    - Get
    - Erase
    - Store

    Get Command
    It is used to retrieve a credential. The remaining data will be passed to the provider via the standard input stream:

        protocol=https or http. For security reasons we recommend you send credentials only over https.
        host=XXX ex. host=contoso.symbols.com
        path=YYY ex. path=apis/symbol/symsrv
        resourceKind=symbols or sources. Ex resourceKind=symbols
        isretry=true or false 
        issilent=true or false
        parenthwnd=ZZZ ex. parenthwnd=593598
        <Followed by an empty line to indicate the end of the input data>

        The full URI/URL is built by concatenating <protocol>://<host>/<path> from above i.e. it is
                https://contoso.symbols.com/apis/symbol/symsrv

        The return data to the debugger is via the standard output stream as follows:

        username=xxx
        credentialkind=Basic
        password=yyy --> This can be a password or a PAT token

        Or 

        username=xxx
        credentialkind=Bearer
        header=Bearer <TOKEN_GOES_HERE> ---> Usually OAuth2 tokens begin with "ey" and it is a very long string

        Error may be returned via 

        error=zzzzz

        For example for the symbol server https://contoso.symbols.com/apis/symbol/symsrv the request would look like this:

        protocol=https
        host=contoso.symbols.com
        path=apis/symbol/symsrv
        resourceKind=symbols
        isretry=false 
        issilent=false
        parenthwnd=593598
        Followed by an empty line to indicate the end of the input data.

    Please note that the parameters above (or in the resulting output stream below) are not case sensitive.

    The debugger asks for the credential using isRetry=false. Some providers may be getting the token from their local cache. Once the debugger resends the HTTP request
    with this token the server may return 401 response again. This may be due to the token has expired. Then the debugger will ask the credential provider for a new token
    and this time the isRetry=true. In such case the provider should not use its cache but retrieve a brand new token.

    Some providers may display an authentication UI. If so it should use the 'parenthwnd' parameter so this UI would appear as a modal dialog to the main debugger window.
    Otherwise the authentication UI may be hidden behind the main debugger window and the user may be given the impression that the debugger is "frozen".

    A debugger client application similar to windbg may use may use DBG_CREDENTIAL_PROVIDER_PARENT_HWND environment variable or imagehlp/dbghelp SymSetParentWindow method to setup the parent HWND.
    You can also use IDebugAdvanced2::Request message DEBUG_REQUEST_SET_PARENT_HWND with value of HWND cast to UINT32.

    In some non-interactive environments there may be no user to interact with a UI. In such a case the parameter issilent would be true.
    The provider should not be displaying any authentication or other UI when this parameter is true.

    How to setup the silent (non interactive) environment is described below:
           a) SYMOPT_NO_PROMPTS described in this document https://learn.microsoft.com/windows-hardware/drivers/debugger/symbol-options.
           b) SSRVOPT_UNATTENDED described in this document https://learn.microsoft.com/previous-versions/ff797954(v=vs.85)
           c) IDebugSymbols::SetSymbolOptions described in this document https://learn.microsoft.com/windows-hardware/drivers/ddi/dbgeng/nf-dbgeng-idebugsymbols3-setsymboloptions
           d) From the Windows debugger you can execute the following bang command "!sym quiet" (or "!sym prompts off")

    Store Command
        The credential provider may choose to use this command to store the credentials into its cache. The input parameters are same as for Get command.
        There is no output return value needed (Error still might be returned)

    Erase Command
        The credential provider may choose to use this command to erase the credentials from its cache. The input parameters are same as for Get command.
        There is no output return value needed (Error still might be returned)

    Here is an example of a CMD file which returns an HTTP authentication header:

         OAuth2CredentialProvider.xml file located in CredentialProviders folder:

             <?xml version="1.0" encoding="utf-8"?>
             <CredentialProviders>
                 <CredentialProvider ApiVersion="2.0.0" >OAuth2CredentialProviderOAuth2CredentialProvider.cmd</CredentialProvider>
             </CredentialProviders> 

         OAuth2CredentialProvider.cmd file located in OAuth2CredentialProvider folder:

             @echo off
             echo [email protected]
             echo header=Bearer <TOKEN_GOES_HERE>

   Here is a PS script example of returning a PAT token:

         File PatCredentialProvider.xml content:

             <?xml version="1.0" encoding="utf-8"?>
             <CredentialProviders>
                 <CredentialProvider ApiVersion="2.0.0">PATCredentialProviderPATCredentialProvider.bat</CredentialProvider>
             </CredentialProviders>

         File PATCredentialProvider.bat located in PATCredentialProvider folder:

             @echo off
             <PATH_TO_POWERSHELL>PowerShell.exe -NoProfile -executionpolicy Unrestricted -WindowStyle Hidden -File "%~dp0PATCredentialProvider.ps1"

         File PATCredentialProvider.ps1 located in PATCredentialProvider folder:

             <#
            .SYNOPSIS
               Given input, parses to find out which symbol server we want credentails for, and searches the Microsoft Credential Manager for those credentials.
               If found, prints the credentials to standard output. If not, prints error.

            .INPUT
               Delivered through standard input:
               protocol=http or https
               host=xxx ex. host=contoso.symbols.com
               path=yyy ex. path=apis/symbol/symsrv
               resourceKind=symbols
               isretry=false 
               issilent=false
               parenthwnd=593598
               <empty line to mark the end of the input parameters>

            .OUTPUT

               Delivered through standard output:

               username=aaa
               password=bbb - where the password can be a password or PAT. When PAT is returned the username will be any name (not necessarily the name of the currently logged in user)<!--[SuppressMessage("Microsoft.Security", "CS001:SecretInline", Justification="It's an example")]-->
               <empty line to mark the end of the output parameters>

            #>

            $logDirectory = (Get-Item Env:LoggingDirectory).Value
            $logFile = Join-Path $logDirectory "credProviderLog.txt"

            try
            {
               "Entering Credential Provider" | Out-File $logFile -Append

               $lines = While($line=Read-Host) {$line}
               $lines | Out-File $logFile -Append
               if (!(Get-Module "CredentialManager"))
               {
                   "Installing module" | Out-File $logFile -Append

                   Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force

                   Install-Module CredentialManager -force -Scope CurrentUser
               }

               $pathLine = $lines | Where-Object {$_.StartsWith("path=")} | Select-Object -First 1
               "Found path line: $pathLine" | Out-File $logFile -Append

               [regex]$regex="path=(?<ServerName>.*)"
               $pathLine -Match $regex

               $symbolPath = "symbol:$($Matches.ServerName)"

               "Found symbol path: $symbolPath" | Out-File $logFile -Append

               $PAT = Get-StoredCredential -Target $symbolPath -AsCredentialObject

               if ($PAT)
               {
                   "Found PAT!" | Out-File $logFile -Append
                   Write-Host "username=placeholder"
                   Write-Host "password=$($PAT.Password)"; # For OAuth 2 tokens You can change to output header=Bearer TOKEN
                   Write-Host
               }
               else
               {
                   "Could not locate PAT for Symbol Server: $symbolPath" | Out-File $logFile -Append
                   Write-Host "error=Could not locate PAT for Symbol Server: $symbolPath"
               }
            }
            catch [System.SystemException]
            {
               "ERROR" | Out-File $logFile -Append
            
               $_ | Out-File $logFile -Append
            }

If you are writing a custom provider located in a CMD or EXE file, you can test it simply by launching it from a console window using the commands.
For example:

DebuggerCredentialManager.exe get

    This would start the application, and print something like this and then will wait for user input (an empty line indicates end of the user input).

[Information] [DebuggerCredentialProvider.102949]Microsoft Debugger Credential Manager version 2024.0409.02656.285 (Windows, .NET 6.0.29) 'get'

Please note that the providers may chose to print some diagnostic information on the output stream, but the debugger would ignore it, nor it will
display those to the user. So the examples of extra information printed here are for illustration purposes only. Other providers may print
other diagnostic information or not print anything.

Here is the information you enter (it can be any text case) in the console window (input stream):

protocol=https
host=contoso.symbols.com
path=apis/symbol/symsrv
resourceKind=symbols
isretry=false 
issilent=false
parenthwnd=593598
Then press ENTER key twice to indicate end of user input.

The provider responds via the standard output stream.
The debugger will ignore any lines not matching the pattern `key=value` where key is
one of the following: protocol, host, path, username, credentialkind,or header.
Case is ignored in the key. The debugger treats a blank line as the end of input.

[Verbose] [DebuggerCredentialProvider.103258]AzureCredentialProvider - Attempting to acquire bearer token using provider 'Msal Cache'
[Verbose] [DebuggerCredentialProvider.103300]Token expiration data - current UTC time:9/18/2024 5:33:00 PM, ExpiresOn: 9/18/2024 6:43:25 PM
[Information] [DebuggerCredentialProvider.103300]AzureCredentialProvider - Acquired bearer token using 'Msal Cache'
protocol=https
host=contoso.symbols.com
path=apis/symbol/symsrv
[email protected]
credentialkind=Bearer
header=Bearer eyJ0eXAi....
<empty line>

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật