KeCapturePersistentThreadState() и crash dump'ы

Дата публикации 24 ноя 2008

KeCapturePersistentThreadState() и crash dump'ы — Архив WASM.RU

Я тут обнаружил очень занятную недокументированную функцию, экспортируемую ядром, на которую нет ссылок внутри ядра, но которая делает весьма занятную вещь. А именно, записывает в переданный кусок памяти полноценный minidump на данный момент времени. Весьма полезно с учетом того, что там (в дампе) есть оффсеты неэкспортируемых структур типа PsLoadedModuleList, которые могут пригодиться. Спасибо [b]Freeman[/b] за помощь)

Прототип:

Код (Text):
  1.  
  2. ULONG
  3. NTAPI
  4. KeCapturePersistentThreadState(
  5.     PCONTEXT Context,
  6.     PKTHREAD Thread,
  7.     ULONG BugCheckCode,
  8.     ULONG BugCheckParameter1,
  9.     ULONG BugCheckParameter2,
  10.     ULONG BugCheckParameter3,
  11.     ULONG BugCheckParameter4,
  12.     PVOID VirtualAddress
  13.     );

Входные параметры:

  • Context - текущий контекст (можно от балды, нужно лишь заполнить EIP & ESP)
  • Thread - текущий поток. можно указать NULL, тогда она сама возьмет текущий
  • BugCheckCode, ParametersX - багчек код и аргументы, которые она запишет в дамп.
  • VirtualAddress - адрес выделенных 16 страниц памяти (64кб), куда она положит аккуратно готовенький крешдамп.

Пример:

Заголовок дампа:

Код (Text):
  1.  
  2. typedef struct _DUMP_HEADER {
  3. /* 00 */    ULONG Signature;
  4. /* 04 */    ULONG ValidDump;
  5. /* 08 */    ULONG MajorVersion;
  6. /* 0c */    ULONG MinorVersion;
  7. /* 10 */    ULONG DirectoryTableBase;
  8. /* 14 */    PULONG PfnDataBase;
  9. /* 18 */    PLIST_ENTRY PsLoadedModuleList;
  10. /* 1c */    PLIST_ENTRY PsActiveProcessHead;
  11. /* 20 */    ULONG MachineImageType;
  12. /* 24 */    ULONG NumberProcessors;
  13. /* 28 */    ULONG BugCheckCode;
  14. /* 2c */    ULONG BugCheckParameter1;
  15. /* 30 */    ULONG BugCheckParameter2;
  16. /* 34 */    ULONG BugCheckParameter3;
  17. /* 38 */    ULONG BugCheckParameter4;
  18. /* 3c */    CHAR  VersionUser[32];
  19. /* 5c */    UCHAR  PaeEnabled;
  20.             UCHAR  NotUsed[3];
  21. /* 60 */    PVOID KdDebuggerDataBlock;
  22. } DUMP_HEADER, *PDUMP_HEADER;

Использование функции:

Код (Text):
  1.  
  2.     PVOID Dump;
  3.     PMDL Mdl;
  4.     PHYSICAL_ADDRESS LowPhysAddr = {0}, HighPhysAddr = {-1}, SkipBytes = {PAGE_SIZE};
  5.  
  6.     Mdl = MmAllocatePagesForMdl( LowPhysAddr, HighPhysAddr, SkipBytes, 0x10000 );
  7.  
  8.     if( Mdl )
  9.     {
  10.         KdPrint(("Mdl created at %08x\n", Mdl));
  11.  
  12.         Dump = MmMapLockedPagesSpecifyCache( Mdl,
  13.             KernelMode,
  14.             MmCached,
  15.             NULL,
  16.             FALSE,
  17.             NormalPagePriority );
  18.  
  19.         if( Dump )
  20.         {
  21.             KdPrint(("Mapped at %08x\n", Dump));
  22.  
  23.             CONTEXT ctx = {0};
  24.  
  25.             __asm {
  26.                 call _1
  27. _1:             pop [ctx.Eip]
  28.                 mov [ctx.Esp], esp
  29.             }
  30.  
  31.             ULONG Result = KeCapturePersistentThreadState(
  32.                 &ctx,
  33.                 KeGetCurrentThread(),
  34.                 MANUALLY_INITIATED_CRASH,
  35.                 0,
  36.                 0,
  37.                 0,
  38.                 0,
  39.                 Dump );
  40.  
  41.             KdPrint(("KeCapturePersistentThreadState = %08x\n", Result));
  42.            
  43.             PDUMP_HEADER DumpHdr = (PDUMP_HEADER) Dump;
  44.             KdPrint(("MmPfnDatabase = %08x\n", DumpHdr->PfnDataBase));
  45.             KdPrint(("PsLoadedModuleList = %08x\n", DumpHdr->PsLoadedModuleList));
  46.             KdPrint(("PsActiveProcessHead = %08x\n", DumpHdr->PsActiveProcessHead));
  47.  
  48.             HANDLE hFile;
  49.             IO_STATUS_BLOCK IoStatus;
  50.             OBJECT_ATTRIBUTES oa;
  51.             UNICODE_STRING FileName;
  52.             NTSTATUS Status;
  53.  
  54.             RtlInitUnicodeString( &FileName, L"\\??\\C:\\dumpfile.dmp" );
  55.             InitializeObjectAttributes( &oa, &FileName, OBJ_KERNEL_HANDLE, 0, 0 );
  56.  
  57.             Status = ZwCreateFile( &hFile,
  58.                 GENERIC_WRITE | SYNCHRONIZE,
  59.                 &oa,
  60.                 &IoStatus,
  61.                 NULL,
  62.                 FILE_ATTRIBUTE_NORMAL,
  63.                 0,
  64.                 FILE_OVERWRITE_IF,
  65.                 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_WRITE_THROUGH,
  66.                 NULL,
  67.                 0 );
  68.  
  69.             if( NT_SUCCESS(Status) )
  70.             {
  71.                 KdPrint(("File handle = %08x\n", hFile));
  72.  
  73.                 Status = ZwWriteFile( hFile,
  74.                     NULL,
  75.                     NULL,
  76.                     NULL,
  77.                     &IoStatus,
  78.                     Dump,
  79.                     0x10000,
  80.                     NULL,
  81.                     NULL );
  82.  
  83.                 if( NT_SUCCESS(Status) )
  84.                 {
  85.                     KdPrint(("%08x bytes written ok\n", IoStatus.Information));
  86.                 }
  87.                 else
  88.                 {
  89.                     KdPrint(("ZwWriteFile(): Status = %08x\n", Status));
  90.                 }
  91.  
  92.                 ZwClose( hFile );
  93.             }
  94.             else
  95.             {
  96.                 KdPrint(("ZwCreateFile(): Status = %08x\n", Status));
  97.             }
  98.  
  99.             MmUnmapLockedPages( Dump, Mdl );
  100.         }
  101.  
  102.         MmFreePagesFromMdl( Mdl );
  103.         ExFreePool( Mdl );
  104.     }
  105.  

Кодес получает дамп, показывает адерса MmPfnDatabase, PsActiveProcessHead, PsLoadedModuleList и сбрасывает дамп на диск. Дамп можно спокойно запихать в WinDbg и изучать

Вообщем, весьма занятная штуковина... © Great


0 1.748
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532