Changeset 85905 in vbox for trunk/src/VBox/Runtime/r0drv/nt/dbgkrnlinfo-r0drv-nt.cpp
- Timestamp:
- Aug 27, 2020 1:42:38 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/nt/dbgkrnlinfo-r0drv-nt.cpp
r82968 r85905 365 365 366 366 /** 367 * Searches the given module information from the kernel for the NT kernel module, the 368 * HAL module, and optionally one more module. 369 * 370 * If the NT kernel or HAL modules have already been found, they'll be skipped. 371 * 372 * @returns IPRT status code. 373 * @retval VERR_LDR_GENERAL_FAILURE if we failed to parse the NT kernel or HAL. 374 * @retval VERR_BAD_EXE_FORMAT if we failed to parse @a pModInfo. 375 * @retval VERR_MODULE_NOT_FOUND if @a pModInfo wasn't found. 376 * 377 * @param pInfo Pointer to the module information. 378 * @param cModules Number of valid module entries in the module information pointer. 379 * @param pModInfo Custom module to search for. Optional. 380 */ 381 static int rtR0DbgKrnlNtSearchForModuleWorker(PRTL_PROCESS_MODULES pInfo, uint32_t cModules, PRTDBGNTKRNLMODINFO pModInfo) 382 { 383 AssertPtrReturn(pInfo, VERR_INVALID_PARAMETER); 384 AssertReturn(cModules >= 2, VERR_INVALID_PARAMETER); 385 386 /* 387 * Search the info. The information is ordered with the kernel bits first, 388 * we expect aleast two modules to be returned to us (kernel + hal)! 389 */ 390 int rc = VINF_SUCCESS; 391 #if ARCH_BITS == 32 392 uintptr_t const uMinKernelAddr = _2G; /** @todo resolve MmSystemRangeStart */ 393 #else 394 uintptr_t const uMinKernelAddr = (uintptr_t)MM_SYSTEM_RANGE_START; 395 #endif 396 397 for (uint32_t iModule = 0; iModule < cModules; iModule++) 398 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: [%u]= %p LB %#x %s\n", iModule, pInfo->Modules[iModule].ImageBase, 399 pInfo->Modules[iModule].ImageSize, pInfo->Modules[iModule].FullPathName)); 400 401 /* 402 * First time around we serch for the NT kernel and HAL. We'll look for NT 403 * kerneland HAL in the first 16 entries, and if not found, use the first 404 * and second entry respectively. 405 */ 406 if ( !g_NtOsKrnlInfo.pbImageBase 407 && !g_HalInfo.pbImageBase) 408 { 409 /* Find them. */ 410 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Looking for kernel and hal...\n")); 411 uint32_t const cMaxModules = RT_MIN(cModules, 16); 412 uint32_t idxNtOsKrnl = UINT32_MAX; 413 uint32_t idxHal = UINT32_MAX; 414 for (uint32_t iModule = 0; iModule < cMaxModules; iModule++) 415 { 416 RTL_PROCESS_MODULE_INFORMATION const * const pModule = &pInfo->Modules[iModule]; 417 if ( (uintptr_t)pModule->ImageBase >= uMinKernelAddr 418 && (uintptr_t)pModule->ImageSize >= _4K) 419 { 420 const char *pszName = (const char *)&pModule->FullPathName[pModule->OffsetToFileName]; 421 if ( idxNtOsKrnl == UINT32_MAX 422 && RTStrICmpAscii(pszName, g_NtOsKrnlInfo.szName) == 0) 423 { 424 idxNtOsKrnl = iModule; 425 if (idxHal != UINT32_MAX) 426 break; 427 } 428 else if ( idxHal == UINT32_MAX 429 && RTStrICmpAscii(pszName, g_HalInfo.szName) == 0) 430 { 431 idxHal = iModule; 432 if (idxHal != UINT32_MAX) 433 break; 434 } 435 } 436 } 437 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: idxNtOsKrnl=%#x idxHal=%#x\n", idxNtOsKrnl, idxHal)); 438 if (idxNtOsKrnl == UINT32_MAX) 439 { 440 idxNtOsKrnl = 0; 441 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: 'ntoskrnl.exe' not found, picking '%s' instead\n", 442 pInfo->Modules[idxNtOsKrnl].FullPathName)); 443 } 444 if (idxHal == UINT32_MAX) 445 { 446 idxHal = 1; 447 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: 'hal.dll' not found, picking '%s' instead\n", 448 pInfo->Modules[idxHal].FullPathName)); 449 } 450 451 /* Parse them. */ 452 //RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Parsing NT kernel...\n")); 453 __try 454 { 455 g_NtOsKrnlInfo.fOkay = rtR0DbgKrnlNtParseModule(&g_NtOsKrnlInfo, 456 (uint8_t const *)pInfo->Modules[idxNtOsKrnl].ImageBase, 457 pInfo->Modules[idxNtOsKrnl].ImageSize); 458 } 459 __except(EXCEPTION_EXECUTE_HANDLER) 460 { 461 g_NtOsKrnlInfo.fOkay = false; 462 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: Exception in rtR0DbgKrnlNtParseModule parsing ntoskrnl.exe...\n")); 463 } 464 465 //RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Parsing HAL...\n")); 466 __try 467 { 468 g_HalInfo.fOkay = rtR0DbgKrnlNtParseModule(&g_HalInfo, (uint8_t const *)pInfo->Modules[idxHal].ImageBase, 469 pInfo->Modules[idxHal].ImageSize); 470 } 471 __except(EXCEPTION_EXECUTE_HANDLER) 472 { 473 g_HalInfo.fOkay = false; 474 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: Exception in rtR0DbgKrnlNtParseModule parsing hal.dll...\n")); 475 } 476 if (!g_NtOsKrnlInfo.fOkay || !g_HalInfo.fOkay) 477 rc = VERR_LDR_GENERAL_FAILURE; 478 479 /* 480 * Resolve symbols we may need in the NT kernel (provided it parsed successfully) 481 */ 482 if (g_NtOsKrnlInfo.fOkay) 483 { 484 if (!g_pfnMmGetSystemRoutineAddress) 485 { 486 //RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Looking up 'MmGetSystemRoutineAddress'...\n")); 487 rtR0DbgKrnlInfoLookupSymbol(&g_NtOsKrnlInfo, "MmGetSystemRoutineAddress", 0, 488 (void **)&g_pfnMmGetSystemRoutineAddress); 489 } 490 } 491 } 492 493 /* 494 * If we're still good, search for the given module (optional). 495 */ 496 if (RT_SUCCESS(rc) && pModInfo) 497 { 498 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Locating module '%s'...\n", pModInfo->szName)); 499 rc = VERR_MODULE_NOT_FOUND; 500 for (uint32_t iModule = 0; iModule < cModules; iModule++) 501 { 502 RTL_PROCESS_MODULE_INFORMATION const * const pModule = &pInfo->Modules[iModule]; 503 if ( (uintptr_t)pModule->ImageBase >= uMinKernelAddr 504 && (uintptr_t)pModule->ImageSize >= _4K) 505 { 506 const char *pszName = (const char *)&pModule->FullPathName[pModule->OffsetToFileName]; 507 if ( pModInfo->pbImageBase == NULL 508 && RTStrICmpAscii(pszName, pModInfo->szName) == 0) 509 { 510 /* 511 * Found the module, try parse it. 512 */ 513 __try 514 { 515 pModInfo->fOkay = rtR0DbgKrnlNtParseModule(pModInfo, (uint8_t const *)pModule->ImageBase, 516 pModule->ImageSize); 517 rc = VINF_SUCCESS; 518 } 519 __except(EXCEPTION_EXECUTE_HANDLER) 520 { 521 pModInfo->fOkay = false; 522 rc = VERR_BAD_EXE_FORMAT; 523 } 524 break; 525 } 526 } 527 } 528 } 529 530 return rc; 531 } 532 533 534 /** 535 * Queries the given maximum amount of modules and returns a pointer to the 536 * allocation holding the modules. 537 * 538 * @returns IPRT status code. 539 * @param ppInfo Where to store the pointer to the module information structure on success. 540 * Free with RTMemFree() when done. 541 * @param cModulesMax Maximum number of modules to return. 542 * @param pcModules Where to store the amount of modules returned upon success, 543 * can be lower than the requested maximum. 544 */ 545 static int rtR0DbgKrnlNtQueryModules(PRTL_PROCESS_MODULES *ppInfo, uint32_t cModulesMax, uint32_t *pcModules) 546 { 547 *ppInfo = NULL; 548 *pcModules = 0; 549 550 ULONG cbInfo = RT_UOFFSETOF_DYN(RTL_PROCESS_MODULES, Modules[cModulesMax]); 551 PRTL_PROCESS_MODULES pInfo = (PRTL_PROCESS_MODULES)RTMemAllocZ(cbInfo); 552 if (!pInfo) 553 { 554 cModulesMax = cModulesMax / 4; 555 cbInfo = RT_UOFFSETOF_DYN(RTL_PROCESS_MODULES, Modules[cModulesMax]); 556 pInfo = (PRTL_PROCESS_MODULES)RTMemAllocZ(cbInfo); 557 if (!pInfo) 558 { 559 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtQueryModules: Out of memory!\n")); 560 return VERR_NO_MEMORY; 561 } 562 } 563 564 int rc; 565 ULONG cbActual = 0; 566 NTSTATUS rcNt = ZwQuerySystemInformation(SystemModuleInformation, pInfo, cbInfo, &cbActual); 567 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtQueryModules: ZwQuerySystemInformation returned %#x and NumberOfModules=%#x\n", 568 rcNt, pInfo->NumberOfModules)); 569 if ( NT_SUCCESS(rcNt) 570 || rcNt == STATUS_INFO_LENGTH_MISMATCH) 571 { 572 *ppInfo = pInfo; 573 *pcModules = RT_MIN(cModulesMax, pInfo->NumberOfModules); 574 rc = VINF_SUCCESS; 575 } 576 else 577 { 578 RTMemFree(pInfo); 579 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtQueryModules: ZwQuerySystemInformation failed: %#x\n", rcNt)); 580 rc = RTErrConvertFromNtStatus(rcNt); 581 } 582 583 return rc; 584 } 585 586 587 /** 367 588 * Searches the module information from the kernel for the NT kernel module, the 368 589 * HAL module, and optionally one more module. … … 398 619 * the syscall ourselves, if we cared. 399 620 */ 400 uint32_t cModules = pModInfo ? 110 /*32KB*/ : 27 /*8KB*/; 401 ULONG cbInfo = RT_UOFFSETOF_DYN(RTL_PROCESS_MODULES, Modules[cModules]); 402 PRTL_PROCESS_MODULES pInfo = (PRTL_PROCESS_MODULES)RTMemAllocZ(cbInfo); 403 if (!pInfo) 404 { 405 cModules = cModules / 4; 406 cbInfo = RT_UOFFSETOF_DYN(RTL_PROCESS_MODULES, Modules[cModules]); 407 pInfo = (PRTL_PROCESS_MODULES)RTMemAllocZ(cbInfo); 408 if (!pInfo) 409 { 410 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: Out of memory!\n")); 411 return VERR_NO_MEMORY; 412 } 413 } 414 415 int rc; 416 ULONG cbActual = 0; 417 NTSTATUS rcNt = ZwQuerySystemInformation(SystemModuleInformation, pInfo, cbInfo, &cbActual); 418 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: ZwQuerySystemInformation returned %#x and NumberOfModules=%#x\n", 419 rcNt, pInfo->NumberOfModules)); 420 if ( NT_SUCCESS(rcNt) 421 || rcNt == STATUS_INFO_LENGTH_MISMATCH) 422 rc = VINF_SUCCESS; 423 else 424 { 425 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: ZwQuerySystemInformation failed: %#x\n", rcNt)); 426 rc = RTErrConvertFromNtStatus(rcNt); 427 } 621 uint32_t cModules = 0; 622 PRTL_PROCESS_MODULES pInfo = NULL; 623 int rc = rtR0DbgKrnlNtQueryModules(&pInfo, pModInfo ? 110 /*32KB*/ : 27 /*8KB*/, &cModules); 428 624 if (RT_SUCCESS(rc)) 429 625 { 430 /* 431 * Search the info. The information is ordered with the kernel bits first, 432 * we expect aleast two modules to be returned to us (kernel + hal)! 433 */ 434 #if ARCH_BITS == 32 435 uintptr_t const uMinKernelAddr = _2G; /** @todo resolve MmSystemRangeStart */ 436 #else 437 uintptr_t const uMinKernelAddr = (uintptr_t)MM_SYSTEM_RANGE_START; 438 #endif 439 if (pInfo->NumberOfModules < cModules) 440 cModules = pInfo->NumberOfModules; 441 if (cModules < 2) 442 { 626 if (cModules >= 2) 627 { 628 rc = rtR0DbgKrnlNtSearchForModuleWorker(pInfo, cModules, pModInfo); 629 if ( rc == VERR_MODULE_NOT_FOUND 630 && pInfo->NumberOfModules > cModules 631 && pModInfo) 632 { 633 /* Module not found in the first round, reallocate array to maximum size and rerun. */ 634 cModules = pInfo->NumberOfModules; 635 636 RTMemFree(pInfo); 637 pInfo = NULL; 638 639 rc = rtR0DbgKrnlNtQueryModules(&pInfo, cModules, &cModules); 640 if (RT_SUCCESS(rc)) 641 { 642 rc = rtR0DbgKrnlNtSearchForModuleWorker(pInfo, cModules, pModInfo); 643 RTMemFree(pInfo); 644 } 645 } 646 } 647 else 648 { 649 RTMemFree(pInfo); 443 650 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: Error! Only %u module(s) returned!\n", cModules)); 444 651 rc = VERR_BUFFER_UNDERFLOW; 445 652 } 446 for (uint32_t iModule = 0; iModule < cModules; iModule++)447 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: [%u]= %p LB %#x %s\n", iModule, pInfo->Modules[iModule].ImageBase,448 pInfo->Modules[iModule].ImageSize, pInfo->Modules[iModule].FullPathName));449 450 /*451 * First time around we serch for the NT kernel and HAL. We'll look for NT452 * kerneland HAL in the first 16 entries, and if not found, use the first453 * and second entry respectively.454 */455 if ( RT_SUCCESS(rc)456 && !g_NtOsKrnlInfo.pbImageBase457 && !g_HalInfo.pbImageBase)458 {459 /* Find them. */460 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Looking for kernel and hal...\n"));461 uint32_t const cMaxModules = RT_MIN(cModules, 16);462 uint32_t idxNtOsKrnl = UINT32_MAX;463 uint32_t idxHal = UINT32_MAX;464 for (uint32_t iModule = 0; iModule < cMaxModules; iModule++)465 {466 RTL_PROCESS_MODULE_INFORMATION const * const pModule = &pInfo->Modules[iModule];467 if ( (uintptr_t)pModule->ImageBase >= uMinKernelAddr468 && (uintptr_t)pModule->ImageSize >= _4K)469 {470 const char *pszName = (const char *)&pModule->FullPathName[pModule->OffsetToFileName];471 if ( idxNtOsKrnl == UINT32_MAX472 && RTStrICmpAscii(pszName, g_NtOsKrnlInfo.szName) == 0)473 {474 idxNtOsKrnl = iModule;475 if (idxHal != UINT32_MAX)476 break;477 }478 else if ( idxHal == UINT32_MAX479 && RTStrICmpAscii(pszName, g_HalInfo.szName) == 0)480 {481 idxHal = iModule;482 if (idxHal != UINT32_MAX)483 break;484 }485 }486 }487 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: idxNtOsKrnl=%#x idxHal=%#x\n", idxNtOsKrnl, idxHal));488 if (idxNtOsKrnl == UINT32_MAX)489 {490 idxNtOsKrnl = 0;491 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: 'ntoskrnl.exe' not found, picking '%s' instead\n",492 pInfo->Modules[idxNtOsKrnl].FullPathName));493 }494 if (idxHal == UINT32_MAX)495 {496 idxHal = 1;497 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: 'hal.dll' not found, picking '%s' instead\n",498 pInfo->Modules[idxHal].FullPathName));499 }500 501 /* Parse them. */502 //RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Parsing NT kernel...\n"));503 __try504 {505 g_NtOsKrnlInfo.fOkay = rtR0DbgKrnlNtParseModule(&g_NtOsKrnlInfo,506 (uint8_t const *)pInfo->Modules[idxNtOsKrnl].ImageBase,507 pInfo->Modules[idxNtOsKrnl].ImageSize);508 }509 __except(EXCEPTION_EXECUTE_HANDLER)510 {511 g_NtOsKrnlInfo.fOkay = false;512 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: Exception in rtR0DbgKrnlNtParseModule parsing ntoskrnl.exe...\n"));513 }514 515 //RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Parsing HAL...\n"));516 __try517 {518 g_HalInfo.fOkay = rtR0DbgKrnlNtParseModule(&g_HalInfo, (uint8_t const *)pInfo->Modules[idxHal].ImageBase,519 pInfo->Modules[idxHal].ImageSize);520 }521 __except(EXCEPTION_EXECUTE_HANDLER)522 {523 g_HalInfo.fOkay = false;524 RTR0DBG_NT_ERROR_LOG(("rtR0DbgKrnlNtInit: Exception in rtR0DbgKrnlNtParseModule parsing hal.dll...\n"));525 }526 if (!g_NtOsKrnlInfo.fOkay || !g_HalInfo.fOkay)527 rc = VERR_LDR_GENERAL_FAILURE;528 529 /*530 * Resolve symbols we may need in the NT kernel (provided it parsed successfully)531 */532 if (g_NtOsKrnlInfo.fOkay)533 {534 if (!g_pfnMmGetSystemRoutineAddress)535 {536 //RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Looking up 'MmGetSystemRoutineAddress'...\n"));537 rtR0DbgKrnlInfoLookupSymbol(&g_NtOsKrnlInfo, "MmGetSystemRoutineAddress", 0,538 (void **)&g_pfnMmGetSystemRoutineAddress);539 }540 }541 }542 543 /*544 * If we're still good, search for the given module (optional).545 */546 if (RT_SUCCESS(rc) && pModInfo)547 {548 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: Locating module '%s'...\n", pModInfo->szName));549 rc = VERR_MODULE_NOT_FOUND;550 for (uint32_t iModule = 0; iModule < cModules; iModule++)551 {552 RTL_PROCESS_MODULE_INFORMATION const * const pModule = &pInfo->Modules[iModule];553 if ( (uintptr_t)pModule->ImageBase >= uMinKernelAddr554 && (uintptr_t)pModule->ImageSize >= _4K)555 {556 const char *pszName = (const char *)&pModule->FullPathName[pModule->OffsetToFileName];557 if ( pModInfo->pbImageBase == NULL558 && RTStrICmpAscii(pszName, pModInfo->szName) == 0)559 {560 /*561 * Found the module, try parse it.562 */563 __try564 {565 pModInfo->fOkay = rtR0DbgKrnlNtParseModule(pModInfo, (uint8_t const *)pModule->ImageBase,566 pModule->ImageSize);567 rc = VINF_SUCCESS;568 }569 __except(EXCEPTION_EXECUTE_HANDLER)570 {571 pModInfo->fOkay = false;572 rc = VERR_BAD_EXE_FORMAT;573 }574 break;575 }576 }577 }578 }579 653 } 580 654 581 655 RTR0DBG_NT_DEBUG_LOG(("rtR0DbgKrnlNtInit: returns %d\n", rc)); 582 RTMemFree(pInfo);583 656 return rc; 584 657 }
Note:
See TracChangeset
for help on using the changeset viewer.