как использовать SymGetSourceFile api для получения исходного файла при посмертной отладке

Я хочу использовать SymGetSourceFile для получения исходного файла с исходного сервера, используя информацию из файла дампа. Но первый параметр - это дескриптор для обработки, но на постмортеме у нас нет процесса, поэтому он предназначен для использования только для инструментов отладки в реальном времени? Как я могу использовать его из инструмента посмертной отладки?

      BOOL IMAGEAPI SymGetSourceFile(
  HANDLE  hProcess,
  ULONG64 Base,
  PCSTR   Params,
  PCSTR   FileSpec,
  PSTR    FilePath,
  DWORD   Size
);

https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-symgetsourcefile

1 ответ

это был комментарий, но он вырос, поэтому добавляю в качестве ответа

GetSourceFileINformation iirc проверяет исходные серверы, которые начинаются с srv или%srcsrv%,
это возвращает токен для использования с findourcefileandtoken

если у вас есть известное смещение (0x1070 == main() в случае ниже),
используйте GetLineByOffset, это дает дополнительное преимущество перезагрузки всех модулей

Надеюсь, у вас есть личный PDB для файла дампа, который вы открываете.

это синтаксис engext

          Hr = m_Client->OpenDumpFile("criloc.dmp");
    Hr = m_Control->WaitForEvent(0,INFINITE);
    unsigned char Buff[BUFFERSIZE] = {0};
    ULONG Buffused = 0;
    DEBUG_READ_USER_MINIDUMP_STREAM MiniStream ={ModuleListStream,0,0,Buff,BUFFERSIZE,Buffused};    
    Hr = m_Advanced2->Request(DEBUG_REQUEST_READ_USER_MINIDUMP_STREAM,&MiniStream,sizeof(  
    DEBUG_READ_USER_MINIDUMP_STREAM),NULL,NULL,NULL);
    MINIDUMP_MODULE_LIST *modlist = (MINIDUMP_MODULE_LIST *)&Buff;
    Hr = m_Symbols->GetLineByOffset(modlist->Modules[0].BaseOfImage+0x1070,&Line,  
    FileBuffer,0x300,&Filesize,&Displacement);
    Out("getlinebyoff returned %x\nsourcefile is at %s line number is %d\n",Hr,FileBuffer,Line);

это часть src, адаптируйте его под свои нужды.

результат команды расширения вставлен ниже

      0:000> .load .\mydt.dll
0:000> !mydt    
Loading Dump File [C:\Users\xxxx\Desktop\srcfile\criloc.dmp]
User Mini Dump File with Full Memory: Only application data is available

OpenDumpFile Returned 0    
WaitForEvent Returned 0    
Request Returned 0    
Ministream Buffer Used 28c

06 00 00 00 00 00 8d 00 00 00 00 00 00 e0 04 00
f0 9a 05 00 2d 2e a8 5f ba 14 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
43 00 00 00 4a 38 00 00 00 00 00 00 00 00 00 00
40 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00

No of Modules =6
Module[0]
Base = 8d0000
Size = 4e000

getlinebyoff returned 0

sourcefile is at c:\users\xxx\desktop\misc\criloc\criloc.cpp line number is 21 <<<<<<<<<

||1:1:010> lm
start    end        module name
008d0000 0091e000   CRILOC     (private pdb symbols)  C:\Users\xxxx\Desktop\misc\CRILOC\CRILOC.pdb
||1:1:010>

и фактическое содержимое исходного файла по пути

      :\>grep -i -n main CRILOC.CPP
20:int main(void)  << the curly braces is on line 21

ОБНОВИТЬ:

да, если файл src не проиндексирован по источнику (cvs, perforce,...) GetSourceFileInformation () не будет возвращать токен, который
он проверяет на наличие токена с помощью параметра Какой параметр
и возвращенная информация может использоваться в FindSourceFileAndToken();

если ваш источник не проиндексирован, и у вас есть только исходный путь,
используйте FindSourceFileandToken() с флагом DEBUG_FIND_SOURCE_FULL_PATH

имейте в виду, что вам нужно либо использовать SetSourcePath (), либо выполнить команду .srcpath, либо использовать переменную среды _NT_SOURCE_PATH, либо использовать переключатель командной строки -srcpath перед вызовом FindSourceFileAndToken()

см. ниже прохождение

исходный файл и содержимое

      :\>ls *.cpp
mydt.cpp

:\>cat mydt.cpp
#include <engextcpp.cpp>
#define BSIZE 0x1000
class EXT_CLASS : public ExtExtension {
public:
    EXT_COMMAND_METHOD(mydt);
};
EXT_DECLARE_GLOBALS();
EXT_COMMAND( mydt, "mydt", "{;e,o,d=0;!mydt;}" ){
    HRESULT Hr = m_Client->OpenDumpFile("criloc.dmp");
    Hr = m_Control->WaitForEvent(0,INFINITE);
    char Buff[BSIZE] = {0};
    ULONG Buffused = 0;
    DEBUG_READ_USER_MINIDUMP_STREAM MiniStream ={ModuleListStream,0,0,
        Buff,BSIZE,Buffused};
    Hr = m_Advanced2->Request(DEBUG_REQUEST_READ_USER_MINIDUMP_STREAM,&MiniStream,
    sizeof(DEBUG_READ_USER_MINIDUMP_STREAM),NULL,NULL,NULL);
    MINIDUMP_MODULE_LIST *modlist = (MINIDUMP_MODULE_LIST *)&Buff;
    //m_Symbols->SetSourcePath("C:\\Users\\xxx\\Desktop\\misc\\CRILOC");
    char srcfilename[BSIZE] ={0};
    ULONG foundsize =0 ;
    Hr = m_Advanced3->FindSourceFileAndToken(0,modlist->Modules[0].BaseOfImage,"criloc.cpp",
    DEBUG_FIND_SOURCE_FULL_PATH,NULL,0,NULL,srcfilename,0x300,&foundsize);
    Out("gsfi returned %x\n" , Hr);
    Out("srcfilename is %s\n",srcfilename);
}

скомпилирован и связан с

      :\>cat bld.bat
@echo off
set "INCLUDE= %INCLUDE%;E:\windjs\windbg_18362\inc"
set "LIB=%LIB%;E:\windjs\windbg_18362\lib\x86"
set "LINKLIBS=user32.lib kernel32.lib dbgeng.lib dbghelp.lib"

cl /LD /nologo /W4 /Od  /Zi /EHsc mydt.cpp /link /nologo /EXPORT:DebugExtensionInitialize /Export:mydt /Export:help /RELEASE %linklibs%
:\>bld.bat
mydt.cpp
E:\windjs\windbg_18362\inc\engextcpp.cpp(1849): warning C4245: 'argument': conversion from 'int' to 'ULONG64', signed/unsigned mismatch
   Creating library mydt.lib and object mydt.exp

:\>file mydt.dll
mydt.dll; PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit

выполнение

      :\>cdb cdb

Microsoft (R) Windows Debugger Version 10.0.18362.1 X86
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ntdll!LdrpDoDebuggerBreak+0x2c:
77d805a6 cc              int     3
0:000> .load .\mydt.dll
0:000> .chain

Extension DLL chain:
    .\mydt.dll: API 1.0.0, built Thu Mar 18 20:40:04 2021
        [path: C:\Users\xxxx\Desktop\srcfile\New folder\mydt.dll]

0:000> !mydt

Loading Dump File [C:\Users\xxxx\Desktop\srcfile\New folder\criloc.dmp]
User Mini Dump File with Full Memory: Only application data is available

gsfi returned 80004002
srcfilename is
||1:1:010> .srcpath "c:\\users\\xxxx\\desktop\\misc\\criloc\\"
Source search path is: c:\\users\\xxxx\\desktop\\misc\\criloc\\

************* Path validation summary **************
Response                         Time (ms)     Location
OK                                             c:\\users\\xxxx\\desktop\\misc\\criloc\\
||1:1:010> !mydt

Loading Dump File [C:\Users\xxxx\Desktop\srcfile\New folder\criloc.dmp]

gsfi returned 0
srcfilename is c:\\users\\xxxx\\desktop\\misc\\criloc\\criloc.cpp
||2:2:021>
Другие вопросы по тегам