Доброго времени суток! помогите порешать проблему. Делаю эмулятор flash-накопителя на базе vusb-based эмуля. Максимальный объем данных для чтения 65536 байт - сделан буфер UCHAR ucDataPBP[65536]={0}; адрес которого передается в подпрограмму чтения (обертка Код (C): MMC_ReadBlock(&ucDataPBP[0], uiFileOffset, min(ucRead,65536));. Адаптировал команды scsi, но есть одно НО - с ZwReadFile(). в обработчике команд все хорошо и для SCSI_OP_READ_10 вычисляю длину блока данных для чтения и смещение в файле откуда считываем эти данные, устанавливаю флаг для чтения данных: Код (C): case SCSIOP_READ: //SCSI_OP_READ_10: {//55 53 42 43 40 0B E7 6C 00 08 00 00 80 00 0A 28 00 00 00 00 10 00 00 01 00 00 00 00 00 00 00 ResetSenseData(0); offset = reverse(*(uint32_t *) &cbw.Cdb.CDB10.LogicalBlockByte0); //ULONG - номер блока len = reverse(*(uint32_t *) &usb_read_capacity[4]); //ULONG - длина блока uiFileOffset = offset * len; //LONGLONG - смещение от начала файла ucInfo = ucRead = (wreverse(*(uint16_t *) &cbw.Cdb.CDB10.TransferBlocksMsb)) * (reverse(*(uint32_t *) &usb_read_capacity[4])); DbgPrint(" Cmd : SCSIOP_READ_10 : %02x %I64x %08x\n", cbw.Cdb.AsByte[0], uiFileOffset, ucInfo); Lun = 0; // MMC_ReadBlock(&ucDataPBP[0], uiFileOffset, min(ucRead,65536)); csw.dCSWDataResidue = cbw.dCBWDataTransferLength - ucInfo; eInfo = rxData; } break; по выходу из обработчика команд после проверки флага идет чтение данных из файла: Код (C): NTSTATUS ReadFile(UCHAR Index, UCHAR *ucData, LONGLONG ucPosition, unsigned long ucLen) { OBJECT_ATTRIBUTES oa; IO_STATUS_BLOCK iosb; HANDLE hFile; NTSTATUS ntStatus; UNICODE_STRING g_usFileName; LARGE_INTEGER byteOffset; PUCHAR intData; KIRQL irql=PASSIVE_LEVEL, currentirql; PCWSTR FilePath[2] = {L"\\??\\C:\\PUBLIC.bin", L"\\??\\C:\\HIDDEN.bin"}; // if ( (currentirql= KeGetCurrentIrql()) != PASSIVE_LEVEL ) // return STATUS_UNSUCCESSFUL; RtlInitUnicodeString(&g_usFileName, FilePath[0/*Index*/]); DbgPrint("Opening file for reading %wZ\n", &g_usFileName); InitializeObjectAttributes(&oa, &g_usFileName, OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL); if (currentirql = KeGetCurrentIrql() > PASSIVE_LEVEL) KeLowerIrql ( irql ); #if 1 ntStatus = ZwOpenFile(&hFile, FILE_READ_DATA + SYNCHRONIZE, &oa, &iosb, \ FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT); #else ntStatus = ZwCreateFile(&hFile, GENERIC_READ + SYNCHRONIZE, &oa, &iosb, 0, 0, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); #endif if (ntStatus == STATUS_SUCCESS) { DbgPrint("File openeded\n"); byteOffset.QuadPart = ucPosition; ntStatus = ZwReadFile(hFile, 0, NULL, NULL, &iosb, ucData, ucLen, &byteOffset, NULL); if (ntStatus == STATUS_SUCCESS) DbgPrint("File content read.\n"); else DbgPrint("Can't read from the file. Status: %08X\n", ntStatus); ZwClose(hFile); } else DbgPrint("Can't open file. Status: %08X\n", ntStatus); KeRaiseIrql(currentirql, &irql); return ntStatus; } пробую три варианта : 1. Если раскомментить Код (C): if ( (currentirql= KeGetCurrentIrql()) != PASSIVE_LEVEL ) return STATUS_UNSUCCESSFUL; всегда выходит, т.к. нет PASSIVE_LEVEL 2. Если закоментить п.1 и закомментить код: Код (C): if (currentirql = KeGetCurrentIrql() > PASSIVE_LEVEL) KeLowerIrql ( irql ); ...... KeRaiseIrql(currentirql, &irql); то BSOD 0xD1 при чтении с IRQL=DISPATCH_LEVEL 3. Если оставлять и не комментить п.2 , то драйвер открывает файл и не возвращается из ZwReadFile(). Вопрос - что я делаю не правильно? ЗЫ: этот код работает на win xp x32 без проблем
Чтобы из кода с высоким IRQL вызвать код для низких IRQL, используй, например, тредпул: твой основной поток с высоким IRQL ставит задачу другому потоку, который крутится в ожидании задач и работает на PASSIVE_LEVEL, и ждёт, пока тот её выполнит. Понижать IRQL нельзя.
вроде "запилил" через ExInitializeWorkItem / ExQueueWorkItem / KeWaitForSingleObject Спасибо за совет
Радость была, но вылезло это: Код (Text): kb will then show the corrected stack. Arguments: Arg1: 00000008, EXCEPTION_DOUBLE_FAULT Arg2: 801e0000 Arg3: 00000000 Arg4: 00000000 при чем не сразу - SCSI_OP_READ_10 читает первый, затем второй, затем снова первый файл и все крошится =( Код (Text): PCWSTR FilePath[2] = {L"\\??\\C:\\PUBLIC.bin", L"\\??\\C:\\HIDDEN.bin"}; проверка длин буферов, передаваемые параметры - все вроде в норме. пока не знаю куда дальше "копать".
Проверь все места, которые могут выдавать эксепшны. Где-то вылетает один эксепшн и на попытке его обработать вылетает второй - вот и дабл-фолт. Кроме того, а что в стактрейсе? Почему его не приводишь? Ведь это ценнейшая информация, которая сразу тыкает носом в файл с сурсами на конкретную строчку.
ну я туплю, но не понимаю: Код (Text): DEFAULT_BUCKET_ID: WIN7_DRIVER_FAULT PROCESS_NAME: System CURRENT_IRQL: 2 TRAP_FRAME: 807cb1b8 -- (.trap 0xffffffff807cb1b8) ErrCode = 00000000 eax=807ca000 ebx=807cb37c ecx=807caf3c edx=00000001 esi=807cb46c edi=0000000e eip=8327da8b esp=807cb22c ebp=807cb34c iopl=0 nv up ei ng nz na pe nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010286 nt!_chkstk+0x27: 8327da8b 8500 test dword ptr [eax],eax ds:0023:807ca000=???????? Resetting default scope LAST_CONTROL_TRANSFER: from 832440bf to 832e3358 STACK_TEXT: 807cb198 832440bf 0000000a 807ca000 00000002 nt!KeBugCheck2+0x11 807cb198 8327da8b 0000000a 807ca000 00000002 nt!KiTrap0E+0x1b3 807cb34c 832419e6 807cb368 00000000 807cb3bc nt!_chkstk+0x27 807cb3b4 83242288 807cb68c 832c945c badb0d00 nt!CommonDispatchException+0x4a 807cb3b4 832c945d 807cb68c 832c945c badb0d00 nt!KiTrap03+0xb8 807cb68c 8321258c 00000065 00000003 b51f12e2 nt!vDbgPrintExWithPrefixInternal+0x2b2 807cb6ac b51f0db9 b51f12e2 0000001f 807cb6d0 nt!DbgPrint+0x1d 807cb6bc b51f03e1 85246d40 0000001f 00000000 mBVUSBBUS!usbFunctionWriteOut+0x1b [c:\xxx\vid_xxxx-pid_xxxx\bus\massstorage.c @ 2266] 807cb6d0 b51f07df 86b67338 807cb700 86b67248 mBVUSBBUS!EmulateKeyMS+0x19 [c:\xxx\vid_xxxx-pid_xxxx\bus\usbkeyemu.c @ 105] 807cb710 8323a169 86b67300 86c8e5f0 85246cdc mBVUSBBUS!Bus_HandleUSBIoCtl+0x3df [c:\xxx\vid_xxxx-pid_xxxx\bus\usbkeyemu.c @ 732] 807cb728 b4e02050 85246d5f 86aa6f20 86aa6e0a nt!IofCallDriver+0x63 807cb748 b4e03d71 85246b98 86c8e5f0 f881db38 USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+0xcc 807cb784 b4e050fc 85246b98 86c8e5f0 85246b98 USBSTOR!USBSTOR_CbwTransfer+0xb7 807cb7b8 832165ae 85246b98 00c8e5f0 86b76628 USBSTOR!USBSTOR_StartIo+0x208 807cb7dc b4e0293e 85246b98 86c8e5f0 86aa6f0c nt!IoStartPacket+0x85 807cb800 8323a169 86b76570 86c8e5f0 84bc2258 USBSTOR!USBSTOR_Scsi+0x2e0 807cb818 87380308 807cb878 84b96cc0 84b184a8 nt!IofCallDriver+0x63 807cb844 87d27cdd 94717fd0 85218010 84bc2258 Wdf01000!imp_WdfRequestSend+0x33c 807cb878 87d29c09 86aa6ee0 00000000 84b96fe4 cdrom!ScratchBuffer_SendSrb+0xef 807cb89c 87d2a3cb 84b96c01 00000001 87d2a133 cdrom!ScratchBuffer_PerformNextReadWrite+0xc6 807cb8c8 87381008 7ade7fe8 7b43dda0 84bde544 cdrom!ScratchBuffer_ReadWriteCompletionRoutine+0x298 807cb8f0 8737ced1 86c8e5f0 84bc2258 84bc5210 Wdf01000!FxRequestBase::CompleteSubmitted+0xf1 807cb91c 8737d0ae 84bc2258 90bfff60 807cb954 Wdf01000!FxIoTarget::RequestCompletionRoutine+0x140 807cb92c 83287182 00000000 86c8e5f0 85218010 Wdf01000!FxIoTarget::_RequestCompletionRoutine+0x33 807cb954 8327c063 00000000 86c8e5f0 90bfff60 nt!IopUnloadSafeCompletion+0x4a 807cb99c b51f0430 85246c50 849be0e0 849be020 nt!IopfCompleteRequest+0x128 807cb9cc 8323a169 86b67300 86c8e5f0 85246cdc mBVUSBBUS!Bus_HandleUSBIoCtl+0x30 [c:\xxx\vid_xxxx-pid_xxxx\bus\usbkeyemu.c @ 175] 807cb9e4 b4e02050 85246d40 b4e09000 86aa6ee0 nt!IofCallDriver+0x63 807cba04 b4e045c9 85246b98 86c8e5f0 f7849712 USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+0xcc 807cba38 b4e034f0 f7849712 86c8e5f0 86c8e663 USBSTOR!USBSTOR_CswTransfer+0x7b 807cba5c 8327c063 85246b98 86c8e5f0 00000000 USBSTOR!USBSTOR_DataCompletion+0x1c6 807cbaa4 b51f0430 85246c50 00000001 80000003 nt!IopfCompleteRequest+0x128 807cbad4 8323a169 86b67300 86c8e5f0 85246cdc mBVUSBBUS!Bus_HandleUSBIoCtl+0x30 [c:\xxx\vid_xxxx-pid_xxxx\bus\usbkeyemu.c @ 175] 807cbaec b4e02050 86c8e5f0 86aa6ee0 85a24a30 nt!IofCallDriver+0x63 807cbb0c b4e036c8 85246b98 86c8e5f0 f7849712 USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+0xcc 807cbb50 b4e03b0b 85246b98 86c8e5f0 86c8e663 USBSTOR!USBSTOR_DataTransfer+0x104 807cbb74 8327c063 86b76570 86aa6ee0 00000000 USBSTOR!USBSTOR_CbwCompletion+0x173 807cbbb8 b51f0430 85246c50 00000003 00000000 nt!IopfCompleteRequest+0x128 807cbbe8 8323a169 86b67300 86c8e5f0 85246cdc mBVUSBBUS!Bus_HandleUSBIoCtl+0x30 [c:\xxx\vid_xxxx-pid_xxxx\bus\usbkeyemu.c @ 175] 807cbc00 b4e02050 85246d5f 86aa6f20 86aa6e0a nt!IofCallDriver+0x63 807cbc20 b4e03d71 85246b98 86c8e5f0 f881db38 USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+0xcc 807cbc5c b4e050fc 85246b98 86c8e5f0 85246b98 USBSTOR!USBSTOR_CbwTransfer+0xb7 807cbc90 832165ae 85246b98 00c8e5f0 86b76628 USBSTOR!USBSTOR_StartIo+0x208 807cbcb4 b4e0293e 85246b98 86c8e5f0 86aa6f0c nt!IoStartPacket+0x85 807cbcd8 8323a169 86b76570 86c8e5f0 84bc2258 USBSTOR!USBSTOR_Scsi+0x2e0 807cbcf0 87380308 807cbd50 84b96cc0 84b18480 nt!IofCallDriver+0x63 807cbd1c 87d27cdd 94717fd0 85218010 84bc2258 Wdf01000!imp_WdfRequestSend+0x33c 807cbd50 87d29c09 86aa6ee0 00000000 84b96fe4 cdrom!ScratchBuffer_SendSrb+0xef 807cbd74 87d2a3cb 84b96c01 00000001 87d2a133 cdrom!ScratchBuffer_PerformNextReadWrite+0xc6 807cbda0 87381008 7ade7fe8 7b43dda0 84bde544 cdrom!ScratchBuffer_ReadWriteCompletionRoutine+0x298 807cbdc8 8737ced1 86c8e5f0 84bc2258 84bc5210 Wdf01000!FxRequestBase::CompleteSubmitted+0xf1 807cbdf4 8737d0ae 84bc2258 85d094b8 807cbe2c Wdf01000!FxIoTarget::RequestCompletionRoutine+0x140 807cbe04 83287182 00000000 86c8e5f0 85218010 Wdf01000!FxIoTarget::_RequestCompletionRoutine+0x33 807cbe2c 8327c063 00000000 86c8e5f0 85d094b8 nt!IopUnloadSafeCompletion+0x4a 807cbe74 b51f0430 85246c50 849be0e0 849be020 nt!IopfCompleteRequest+0x128 807cbea4 8323a169 86b67300 86c8e5f0 85246cdc mBVUSBBUS!Bus_HandleUSBIoCtl+0x30 [c:\xxx\vid_xxxx-pid_xxxx\bus\usbkeyemu.c @ 175] 807cbebc b4e02050 85246d40 b4e09000 86aa6ee0 nt!IofCallDriver+0x63 807cbedc b4e045c9 85246b98 86c8e5f0 f7849712 USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+0xcc 807cbf10 b4e034f0 f7849712 86c8e5f0 86c8e663 USBSTOR!USBSTOR_CswTransfer+0x7b 807cbf34 8327c063 85246b98 86c8e5f0 00000000 USBSTOR!USBSTOR_DataCompletion+0x1c6 807cbf7c b51f0430 85246c50 00000001 80000003 nt!IopfCompleteRequest+0x128 807cbfac 8323a169 86b67300 86c8e5f0 85246cdc mBVUSBBUS!Bus_HandleUSBIoCtl+0x30 [c:\xxx\vid_xxxx-pid_xxxx\bus\usbkeyemu.c @ 175] 807cbfc4 b4e02050 86c8e5f0 86aa6ee0 85a24a30 nt!IofCallDriver+0x63 807cbfe4 b4e036c8 85246b98 86c8e5f0 f7849712 USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+0xcc 807cc028 b4e03b0b 85246b98 86c8e5f0 86c8e663 USBSTOR!USBSTOR_DataTransfer+0x104 807cc04c 8327c063 86b76570 86aa6ee0 00000000 USBSTOR!USBSTOR_CbwCompletion+0x173 807cc090 b51f0430 85246c50 00000003 00000000 nt!IopfCompleteRequest+0x128 807cc0c0 8323a169 86b67300 86c8e5f0 85246cdc mBVUSBBUS!Bus_HandleUSBIoCtl+0x30 [c:\xxx\vid_xxxx-pid_xxxx\bus\usbkeyemu.c @ 175] 807cc0d8 b4e02050 85246d5f 86aa6f20 86aa6e0a nt!IofCallDriver+0x63 807cc0f8 b4e03d71 85246b98 86c8e5f0 f881db38 USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+0xcc 807cc134 b4e050fc 85246b98 86c8e5f0 85246b98 USBSTOR!USBSTOR_CbwTransfer+0xb7 807cc168 832165ae 85246b98 00c8e5f0 86b76628 USBSTOR!USBSTOR_StartIo+0x208 807cc18c b4e0293e 85246b98 86c8e5f0 86aa6f0c nt!IoStartPacket+0x85 807cc1b0 8323a169 86b76570 86c8e5f0 84bc2258 USBSTOR!USBSTOR_Scsi+0x2e0 807cc1c8 87380308 807cc228 84b96cc0 84b18458 nt!IofCallDriver+0x63 STACK_COMMAND: .tss 0x28 ; kb FOLLOWUP_IP: mBVUSBBUS!usbFunctionWriteOut+1b [c:\xxx\vid_xxxx-pid_xxxx\bus\massstorage.c @ 2266] b51f0db9 8b450c mov eax,dword ptr [ebp+0Ch] FAULTING_SOURCE_LINE: c:\xxx\vid_xxxx-pid_xxxx\bus\massstorage.c FAULTING_SOURCE_FILE: c:\xxx\vid_xxxx-pid_xxxx\bus\massstorage.c FAULTING_SOURCE_LINE_NUMBER: 2266 FAULTING_SOURCE_CODE: 2262: csw.dCSWDataResidue = cbw.dCBWDataTransferLength - ucLen; 2263: 2264: eRxStage = rxsCBW;////// 2265: eTxStage = txsCSW; > 2266: } 2267: 2268: unsigned long MSD_TxData(unsigned char* ucData, unsigned long ucLen) 2269: { 2270: int i; 2271: if (MSD_GetStage() == rxData)
А чего тупить? Тебе же прямо на конкретную строчку показывает трейс: файл massstorage.c, строчка 2266. В функции usbFunctionWriteOut ты вызвал DbgPrint, который вызвал повреждение стека, на что указывает багчек в функции _chkstk: был повреждён Security Cookie, о чём мы узнали в обработчике первого эксепшна. Это и сгенерило нам второй эксепшн - дабл-фолт. А значит это только одно: ты или передал неправильную строку форматирования в DbgPrint, или перепутал значения, которые туда подставляшь, и вместо числа воткнул, например, огромный массив. Стек не выдержал и лопнул. --- Сообщение объединено, 20 июл 2019 --- Хм, стоп. Только сейчас увидел, что в конце твоего трейса ещё и кусок сурсов. Однако, он не совпадает с тем, что мы видим в трейсе. Отключены ли оптимизации? Вся ли отладочная информация включена? Уверен ли, что не менял сурсы после сборки конкретно этого билда? Посмотри, есть ли в окрестностях этой функции твои DbgPrint'ы?
HoShiMin, > Это и сгенерило нам второй эксепшн - дабл-фолт. При даблфаулт процессор ресетит мгновенно, без каких либо крэш дампов. Эта ошибка - #PF при обработке дебагпринта, он не может ровно напечатать строку. Пусть тренируется на кроликах" отладке юзер апп. --- Сообщение объединено, 21 июл 2019 --- FoxB, > Если оставлять и не комментить п.2 , то драйвер открывает файл и не возвращается из ZwReadFile(). Чувак закрой это всё, какие тебе драйвера, ты даже не понимаешь фундаментальные основы. Зет функции могут вызываться только на пассив и в т-фрейме. Это просто ппц - пилить драйвер методом убирания комментов с irql, жесть.
Да ладно тебе, все ведь когда-то были новичками. А написать эмулятор накопителя - вообще не тривиальная задача. Но надо же как-то учиться!
Indy_, я не хочу вступать в дискуссии - изниняй. Я Zw чтением были эксперименты и про пассив я тоже в курсе. Если есть что сказать - буду благодарен, а "говно на вентилятор" мы все умеем кидать. HoShiMin, буду проверять - отпишу...
Ну почему сразу говно на вентилятор? Инди прав - ошибки у тебя детские: в трейс не посмотрел, IRQL понижаешь, что-то комментируешь и раскомменчиваешь, не понимая до конца, что и зачем. А в курсе, откуда взялось ограничение на IRQL у разных функций и почему, всё-таки, его нельзя понижать?
т.е он сразу роился с золотой ложкой во рту и знаниями в голове? понимаю, что у меня ложка была алюминиевая, как и у всех в 60-х...
Думаю, его посыл был - прежде чем писать такой рокетсаенс, как эмулирование девайсов, было бы неплохо ознакомиться с азами. Потому что, уверен, выложи ты исходники в паблик, получил бы изрядную долю критики именно по основам, даже не углубляясь в детали SCSI. Вот тебе яркий пример: в твоих исходниках ты складываешь флаги плюсами: > OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE > FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE Делать так категорически нельзя, т.к., складывая числа, ты получаешь совсем не то же самое, что битовый OR. Правильно делать так: Flag1 | Flag2 | Flag3. --- Сообщение объединено, 21 июл 2019 --- Или вот: Ты делаешь DbgPrint("... %wZ", UNICODE_STRING). Сам говорил, что твоя функция работает на DISPATCH_LEVEL, а выводить юникодные строки в DbgPrint можно только на PASSIVE_LEVEL, о чём жирным текстом написано в документации по DbgPrint: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-dbgprint Не удивлюсь, если твой пример падает именно из-за этого.
HoShiMin, это было изначально, сейчас у меня чтение на Код (Text): WorkerRoute: IRQL = 0 WorkerRoute: Thread Priority = 13 In the WorkerRoute. Parameter = 0x85c7b0b0 Function WorkerRoute parameter's 1 = 0x0, 2 = 0x99b8c000, 3= 0x8800, 4= 0x800, 5 = 0x0 Opening file for reading \??\C:\Public.bin File openeded File content read. где LUN 1 = 0x0 Буфер для чтения 2 = 0x99b8c000 Смещение в файле 3= 0x8800 Длина 4= 0x800 Флаг чтение/запись 5 = 0x0 --- Сообщение объединено, 21 июл 2019 --- посмотрел код после компиляции - что "+" что "|" = генерится WDK одинаково... и еще - код работал на хп сп3 х32 и не падал, попросили переделать под в7 х32. вот и начал "разбираться".
Да, тебе повезло, потому что у этих флагов значения удачно подобраны так, что складывание их плюсами даст тот же результат, что и OR: 0001 + 0010 = 0011 0001 | 0010 = 0011 Если нарвёшься на складывание "комплексных" флагов, где в одном флаге взведены несколько бит, и складываешь его с флагом, где тоже взведён один из взведённых ранее битов, всё сломается. 0001 + 0011 = 0100 0001 | 0011 = 0011 Есть разница? Поэтому переделывай на OR.
Просто посмотри в отладчике, где конкретно и что идёт не так. Ты подключаешь отладчик к виртуалке или анализируешь крашдамп? Если крашдамп, то настрой полноценную отладку в VMware и скачай UWP'шную версию WinDbg в Microsoft Store (называется WinDbg Preview) - не в пример удобнее, чем тыкаться в классическом WinDbg. Если знаешь, в какой функции у тебя крашится, поставь туда брейкпоинт интринсиком __debugbreak(): Код (C): void func() { ... __debugbreak(); // Здесь исполнение остановится и управление получит WinDbg ... } Как только сработает брейкпоинт, в WinDbg откроются сурсы и ты сможешь нормально посмотреть, в какой переменной что лежит. Дальше просто шагай построчно, пока не найдёшь ошибку. Т.к. дефолтная отладка по виртуальному COM-порту ужасно медленная и пожирает 100% процессора, очень советую поставить VirtualKd. Он умеет VMware из коробки. Не придётся ждать по полчаса, пока сработает шаг в отладчике - по скорости будет практически как отладка юзермодных приложений. А ещё, для скорости выстави виртуалке не все физические ядра, а половину - отзывчивее будет и хост, и сама виртуалка.
HoShiMin, > скачай UWP'шную версию WinDbg в Microsoft Store Это довольно сложно сделать. Я хотел посмотреть как работает TTD, но так и не смог скачать. Какие то извраты, регистрация и есчо как то через ось нужно заходить - я покопался и забил.