Привет Всем! Помогите разобраться с проблемой плз... Я пытаюсь написать драйвер для перехвата пакетов в сети. Делаю по описанию в книгах, ddk и еще исходники смотрю winpcap, passthru и прочее. Состряпал пример и пытаюсь его поглядеть в VMWare. После старта через некоторое время появляется BSOD или все виснет намертво. Несколько часов сижу и не могу воткнуть, где я напортачил. ОС - WinXP SP1. Поглядите плз: Код (Text): #include <ntddk.h> #define NDIS50 1 #include <ndis.h> #include <stdio.h> #define PACKET_POOL_TAG 'pPR2' struct UserStruct { ULONG ulData; } g_UserStruct; // Описатель открытого сетевого адаптера NDIS_HANDLE g_AdapterHandle; NDIS_HANDLE g_NdisProtocolHandle; PNDIS_EVENT g_pCloseWaitEvent; VOID OnOpenAdapterDone(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus) { NDIS_REQUEST ndisRequest; NDIS_STATUS ndisStatus; ULONG uiMode = NDIS_PACKET_TYPE_PROMISCUOUS; DbgPrint("In OnOpenAdapterDone"); if( NT_SUCCESS(OpenErrorStatus) ) { ndisRequest.RequestType = NdisRequestSetInformation; ndisRequest.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER; ndisRequest.DATA.SET_INFORMATION.InformationBuffer = &uiMode; ndisRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof(ULONG); NdisRequest(&ndisStatus, g_AdapterHandle, &ndisRequest); } // if( NT_SUCCESS(OpenErrorStatus) ) return; } VOID OnCloseAdapterDone(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status) { DbgPrint("In OnCloseAdapterDone"); NdisSetEvent(g_pCloseWaitEvent); return; } VOID OnSendDone(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status) { DbgPrint("In OnSendDone"); return; } VOID OnTransferDataDone(IN NDIS_HANDLE pBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status, IN UINT uiBytesTransfered) { DbgPrint("In OnTransferDataDone"); return; } VOID OnResetDone(IN NDIS_HANDLE pBindingContext, IN NDIS_STATUS Status) { DbgPrint("In OnResetDone"); return; } VOID OnRequestDone(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST pNdisRequest, IN NDIS_STATUS Status) { DbgPrint("In OnRequestDone"); return; } NDIS_STATUS OnReceiveStub(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID pvHeaderBuffer, IN UINT uiHeaderBufferSize, IN PVOID pvLookAheadBuffer, IN UINT uiLookAheadBufferSize, UINT uiPacketSize) { char _t[255]={0}; UINT uiFrameType = 0; memcpy(&uiFrameType, ( ((char*)pvHeaderBuffer) + 12 ), 2); _snprintf(_t, 253, "Type %u, PacketSize %u", uiFrameType, uiPacketSize); DbgPrint(_t); return NDIS_STATUS_NOT_ACCEPTED; } VOID OnReceiveDoneStub(IN NDIS_HANDLE ProtocolBindingContext) { DbgPrint("In OnReceiveDoneStub"); return; } VOID OnStatus(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN PVOID pvStatusBuffer, IN UINT uiStatusBufferSize) { DbgPrint("In OnStatus"); return; } VOID OnStatusDone(IN NDIS_HANDLE ProtocolBindingContext) { DbgPrint("In OnStatusDone"); return; } VOID OnBindAdapter(OUT PNDIS_STATUS pStatus, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID pvSS1, IN PVOID pvSS2) { DbgPrint("In OnBindAdapter"); return; } VOID OnUnbindAdapter(OUT PNDIS_STATUS pStatus, IN NDIS_HANDLE BindContext, IN PNDIS_HANDLE UnbindContext) { DbgPrint("In OnUnbindAdapter"); return; } VOID OnProtocolUnload(VOID) { DbgPrint("In OnProtocolUnload"); return; } INT OnReceivePacket(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket) { DbgPrint("In OnReceivePacket"); return 0; } NDIS_STATUS OnPNPEvent(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent) { DbgPrint("In OnPNPEvent"); return NDIS_STATUS_SUCCESS; } VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject) { NDIS_STATUS ndisStatus; NdisResetEvent(g_pCloseWaitEvent); NdisCloseAdapter(&ndisStatus, g_AdapterHandle); if( ndisStatus == NDIS_STATUS_PENDING ) { NdisWaitEvent(g_pCloseWaitEvent, 0); } NdisDeregisterProtocol(&ndisStatus, g_NdisProtocolHandle); if( !NT_SUCCESS(ndisStatus) ) { DbgPrint("In DriverUnload: NdisDeregisterProtocol failed"); } ExFreePoolWithTag(g_pCloseWaitEvent, PACKET_POOL_TAG); DbgPrint("In DriverUnload: NdisDeregisterProtocol success"); return; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING ustrRegistryPath) { UINT uiMediumIndex = 0; NDIS_STATUS ndisStatus, ndisErrorStatus; NDIS_MEDIUM ndisMediumArray = NdisMedium802_3; UNICODE_STRING ustrAdapterName; NDIS_PROTOCOL_CHARACTERISTICS ndisProtocolCharacteristics; NDIS_STRING ndisProtoName = NDIS_STRING_CONST("PACKET_MODULE"); ULONG OsMajorVersion; ULONG OsMinorVersion; DbgPrint("In DriverEntry: Loading..."); RtlInitUnicodeString(&ustrAdapterName, L"\\Device\\{79D2A5DE-2BA5-44A1-ADAF-69B90724722D}"); g_pCloseWaitEvent = (PNDIS_EVENT)ExAllocatePoolWithTag(NonPagedPool, sizeof(NDIS_EVENT), PACKET_POOL_TAG); NdisInitializeEvent(g_pCloseWaitEvent); pDriverObject->DriverUnload = DriverUnload; PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL); DbgPrint("In DriverEntry: OsMajorVersion = %lu, OsMinorVersion = %lu", OsMajorVersion, OsMinorVersion); RtlZeroMemory(&ndisProtocolCharacteristics, sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); ndisProtocolCharacteristics.MajorNdisVersion = 5; ndisProtocolCharacteristics.MinorNdisVersion = 0; ndisProtocolCharacteristics.Reserved = 0; ndisProtocolCharacteristics.OpenAdapterCompleteHandler = OnOpenAdapterDone; ndisProtocolCharacteristics.CloseAdapterCompleteHandler = OnCloseAdapterDone; ndisProtocolCharacteristics.SendCompleteHandler = OnSendDone; ndisProtocolCharacteristics.TransferDataCompleteHandler = OnTransferDataDone; ndisProtocolCharacteristics.ResetCompleteHandler = OnResetDone; ndisProtocolCharacteristics.RequestCompleteHandler = OnRequestDone; ndisProtocolCharacteristics.ReceiveHandler = OnReceiveStub; ndisProtocolCharacteristics.ReceiveCompleteHandler = OnReceiveDoneStub; ndisProtocolCharacteristics.StatusHandler = OnStatus; ndisProtocolCharacteristics.StatusCompleteHandler = OnStatusDone; ndisProtocolCharacteristics.Name = ndisProtoName; ndisProtocolCharacteristics.BindAdapterHandler = OnBindAdapter; ndisProtocolCharacteristics.UnbindAdapterHandler = OnUnbindAdapter; ndisProtocolCharacteristics.UnloadHandler = OnProtocolUnload; ndisProtocolCharacteristics.ReceivePacketHandler = OnReceivePacket; ndisProtocolCharacteristics.PnPEventHandler = OnPNPEvent; DbgPrint("In DriverEntry: Register NDIS Protocol"); NdisRegisterProtocol(&ndisStatus, &g_NdisProtocolHandle, &ndisProtocolCharacteristics, sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); if( ndisStatus != NDIS_STATUS_SUCCESS ) { return ndisStatus; } DbgPrint("In DriverEntry: NdisRegisterProtocol success"); NdisOpenAdapter(&ndisStatus, &ndisErrorStatus, &g_AdapterHandle, &uiMediumIndex, &ndisMediumArray, 1, g_NdisProtocolHandle, &g_UserStruct, &ustrAdapterName, 0, NULL); if( ndisStatus != NDIS_STATUS_PENDING ) { if( !NT_SUCCESS(ndisStatus) ) { if( ndisStatus == NDIS_STATUS_ADAPTER_NOT_FOUND ) { DbgPrint("In DriverEntry: Adapter not found"); } NdisDeregisterProtocol(&ndisStatus, g_NdisProtocolHandle); if( !NT_SUCCESS(ndisStatus) ) { DbgPrint("In DriverEntry: NdisDeregisterProtocol failed"); } return STATUS_UNSUCCESSFUL; } // if( !NT_SUCCESS(ndisStatus) ) else { OnOpenAdapterDone(&g_UserStruct, ndisStatus, NDIS_STATUS_SUCCESS); if(NT_SUCCESS(ndisStatus)){ DbgPrint(("In DriverEntry: NdisOpenAdapter returned STATUS_SUCCESS\n")); } } DbgPrint("In DriverEntry: NdisOpenAdapter success"); } // if( ndisStatus != NDIS_STATUS_PENDING ) return STATUS_SUCCESS; }
steelfactor Не подскажите, чем анализ проделать? Тут статья на сайте была с исходниками, но там bcdesc.h нехватает. Чем еще это сделать можно?
prus Берешь файл крешдампадампа . Открываешь с помощью Windbg . И делаешь анализ (проще говоря прикрепляешь то, что выдал виндбг) и постишь сюда.
Debugging tools http://www.microsoft.com/whdc/devtools/debugging/default.mspx содержат отличный бесплатный отладчик WinDbg. С его помощью сможешь открыть crashdump (скорее всего он у тебя находится в %SystemRoot%\Minidump, но можешь это посмотреть в System Properties->Advanced->Startup And Recovery Settings...->Dump file). Более подробно об анализе аварийных дампов можно поискать у Руссиновича. (опередил )
Вот это оно? Код (Text): *** ERROR: Symbol file could not be found. Defaulted to export symbols for ntoskrnl.exe - Loading Kernel Symbols ................................................................................................ Loading User Symbols Loading unloaded module list .. ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* Use !analyze -v to get detailed debugging information. BugCheck D1, {3f595555, 2, 0, bae813da} ***** Kernel symbols are WRONG. Please fix symbols to do analysis. *** ERROR: Symbol file could not be found. Defaulted to export symbols for NDIS.sys - ************************************************************************* *** *** *** *** *** Your debugger is not using the correct symbols *** *** *** *** In order for this command to work properly, your symbol path *** *** must point to .pdb files that have full type information. *** *** *** *** Certain .pdb files (such as the public OS symbols) do not *** *** contain the required information. Contact the group that *** *** provided you with these symbols if you need this command to *** *** work. *** *** *** *** Type referenced: nt!_KPRCB *** *** *** ************************************************************************* ************************************************************************* *** *** *** *** *** Your debugger is not using the correct symbols *** *** *** *** In order for this command to work properly, your symbol path *** *** must point to .pdb files that have full type information. *** *** *** *** Certain .pdb files (such as the public OS symbols) do not *** *** contain the required information. Contact the group that *** *** provided you with these symbols if you need this command to *** *** work. *** *** *** *** Type referenced: nt!_KPRCB *** *** *** ************************************************************************* ********************************************************************* * Symbols can not be loaded because symbol path is not initialized. * * * * The Symbol Path can be set by: * * using the _NT_SYMBOL_PATH environment variable. * * using the -y <symbol_path> argument when starting the debugger. * * using .sympath and .sympath+ * ********************************************************************* ********************************************************************* * Symbols can not be loaded because symbol path is not initialized. * * * * The Symbol Path can be set by: * * using the _NT_SYMBOL_PATH environment variable. * * using the -y <symbol_path> argument when starting the debugger. * * using .sympath and .sympath+ * ********************************************************************* Probably caused by : NDIS.sys ( NDIS!NdisCompletePnPEvent+71c ) Followup: MachineOwner ---------
Код (Text): MODULE_NAME: NDIS FAULTING_MODULE: 804d4000 nt DEBUG_FLR_IMAGE_TIMESTAMP: 3d6de4c3 READ_ADDRESS: unable to get nt!MmSpecialPoolStart unable to get nt!MmSpecialPoolEnd unable to get nt!MmPoolCodeStart unable to get nt!MmPoolCodeEnd 3f595555 CURRENT_IRQL: 2 FAULTING_IP: NDIS!NdisCompletePnPEvent+71c bae813da 833800 cmp dword ptr [eax],0 DEFAULT_BUCKET_ID: WRONG_SYMBOLS BUGCHECK_STR: 0xD1 LAST_CONTROL_TRANSFER: from 804dce53 to 805266db STACK_TEXT: WARNING: Stack unwind information not available. Following frames may be wrong. f6702ccc 804dce53 0000000a 3f595555 00000002 nt!KeBugCheckEx+0x19 f6702cf8 80593875 f6810000 f680d000 8054aed0 nt!Kei386EoiHelper+0x251c f6702d10 8058f5a7 00000000 00000023 00000023 nt!PsSetThreadWin32Thread+0x92 f6702d58 bae7df29 8168abc0 81687130 81522f08 nt!NtQueryInformationToken+0xd9 f6702d74 bae815ec 8168abc0 81522f08 8151a870 NDIS!NdisRequest+0x73 f6702d98 bae70623 8151a858 00000000 81572020 NDIS!NdisCompletePnPEvent+0x92e f6702dac 8057c73a 8151a860 00000000 00000000 NDIS!NdisFreeToBlockPool+0xb2d f6702ddc 805124c1 bae70600 8151a860 00000000 nt!CcUnpinDataForThread+0x66d 00000000 00000000 00000000 00000000 00000000 nt!KeProfileInterruptWithSource+0x28e STACK_COMMAND: .bugcheck ; kb FOLLOWUP_IP: NDIS!NdisCompletePnPEvent+71c bae813da 833800 cmp dword ptr [eax],0 SYMBOL_NAME: NDIS!NdisCompletePnPEvent+71c FOLLOWUP_NAME: MachineOwner IMAGE_NAME: NDIS.sys BUCKET_ID: WRONG_SYMBOLS Followup: MachineOwner ---------
Как я понял, при оповещении о завершении подключения твой драйвер получает конфликт прерываний, что и дает BSOD - BugCheck D1 означает IRQ_NOT_LESS_OR_EQUAL (?) . Все на это указывает. P.S. Символы нормальные загрузи
Конфликт прерываний?! Чето ты помоему не в теме вообще.. Этот бсод происходит при ошибке страницы при высоком IRQL, прерывания тут не очень причем как-то. Разве что таймеровские. А символы да, не помешает.
Great Э, ну да, сорри, непростительно, не о том думал, когда писал... пойду просплюсь 0x000000d1 означает, что драйвер пытается получить доступ к странице не на том IRQL
Вот с символами анализ получился такой: Код (Text): DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1) An attempt was made to access a pageable (or completely invalid) address at an interrupt request level (IRQL) that is too high. This is usually caused by drivers using improper addresses. If kernel debugger is available get stack backtrace. Arguments: Arg1: 3f595555, memory referenced Arg2: 00000002, IRQL Arg3: 00000000, value 0 = read operation, 1 = write operation Arg4: bae813da, address which referenced memory Debugging Details: ------------------ READ_ADDRESS: 3f595555 CURRENT_IRQL: 2 FAULTING_IP: NDIS!ndisMQueueRequest+11 bae813da 833800 cmp dword ptr [eax],0 DEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO BUGCHECK_STR: 0xD1 PROCESS_NAME: System TRAP_FRAME: f6702ce8 -- (.trap 0xfffffffff6702ce8) ErrCode = 00000000 eax=3f595555 ebx=804ee071 ecx=81687130 edx=81522f08 esi=81687130 edi=8168abc0 eip=bae813da esp=f6702d5c ebp=f6702d74 iopl=0 ov up ei ng nz ac pe cy cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010a97 NDIS!ndisMQueueRequest+0x11: bae813da 833800 cmp dword ptr [eax],0 ds:0023:3f595555=???????? Resetting default scope LAST_CONTROL_TRANSFER: from 804dce53 to 805266db STACK_TEXT: f6702ccc 804dce53 0000000a 3f595555 00000002 nt!KeBugCheckEx+0x19 f6702ccc bae813da 0000000a 3f595555 00000002 nt!KiTrap0E+0x2ad f6702d58 bae7df29 8168abc0 81687130 81522f08 NDIS!ndisMQueueRequest+0x11 f6702d74 bae815ec 8168abc0 81522f08 8151a870 NDIS!ndisMRequest+0x93 f6702d98 bae70623 8151a858 00000000 81572020 NDIS!ndisMRundownRequests+0x30 f6702dac 8057c73a 8151a860 00000000 00000000 NDIS!ndisWorkerThread+0x73 f6702ddc 805124c1 bae70600 8151a860 00000000 nt!PspSystemThreadStartup+0x34 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 STACK_COMMAND: kb FOLLOWUP_IP: NDIS!ndisMQueueRequest+11 bae813da 833800 cmp dword ptr [eax],0 SYMBOL_STACK_INDEX: 2 SYMBOL_NAME: NDIS!ndisMQueueRequest+11 FOLLOWUP_NAME: MachineOwner MODULE_NAME: NDIS IMAGE_NAME: NDIS.sys DEBUG_FLR_IMAGE_TIMESTAMP: 3d6de4c3 FAILURE_BUCKET_ID: 0xD1_VRF_NDIS!ndisMQueueRequest+11 BUCKET_ID: 0xD1_VRF_NDIS!ndisMQueueRequest+11 Followup: MachineOwner Используйте тег [ code ] для заключения большого текста в фиксированную область окна
.sympath srv*d:\symbols*http://msdl.microsoft.com/download/symbols d:\symbols - локальный каталог, куда сохранять оные.
С BSOD вроде бы разобрался... Но почему-то не вижу пакетов теперь. Протокол зарегистрировался нормально, адаптер открывается тоже без ошибок, перевод сетевой карточки в неразборчивый режим тоже, как я понимаю, без ошибок. Но вот пакетов не вижу. Кто-нить сталкивался с такой проблемой?
Ты чем отлаживаешь свой драйвер? Если тупо DbgPrint'ами, то тебе хоть рабочий исходник дай, толку не будет. Научись отлаживать ринг0 код. Потом уже пробуй что-то писать.
я вот тоже не знаю. WIN32 человек же явно учится, и вместо бессмысленного тролинга лучше бы совет дали, что и как и чем
Вы издеваетесь чтоли? Поднимать темы 3х летней давности, когда в топике выделена тема Драйверы режима ядра и там можно найти практически все ответы на подобные вопросы. Еще раз увижу - в бан отправлю.