Vsem dobrogo!!! U menya kak vsegda problemnii-vopros. Ya, pitalsya rasobrat'sya v ddk\filespy, vrode ponyatno, no ya popitlsya zapustit' driver i vot tut poyavilis' problemi. Na danii moment ya ne mogu ponyat' sleduyushee, ya pitayus' priattachit' disk "C:" i vot chto proishodit: 1) visivaetsya FatsIODeviceControl(tut vse ponyatno) 2) SpyCommonDeviceIoControl(tut toje ponyatno) 3) SpyStartLoggingDevice 4) SpyIsAttachedToDeviceByUserDeviceName, tut idet inicialisacya peremenih i popitka podklyuchenya, voobshem vse tut idet normal'no do vot etogo uchastka: Код (Text): // get a pointer to the volumes file object // status = ObReferenceObjectByHandle( fileHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, &volumeFileObject, NULL); posle vipolnenya ObReferenceObjectByHandle, pochemuto idet vozvrat v funkcyu SpyCommonDeviceIoControl, a samoe interesnoe chto imenno v etot uchastok koda Код (Text): if (NT_SUCCESS( IoStatus->Status )) { deviceName[InputBufferLength / sizeof(WCHAR)] = UNICODE_NULL; IoStatus->Status = SpyStartLoggingDevice( deviceName ); } break; i uje na sledyushem vitke pri vipolnenii ObReferenceObjectByHandle, driver vilitaet v BSOD. Pochemu emenno syuda idet vozvrat???
Исходник спая не подвергался улучшению с твоей стороны? И как понимать "idet vozvrat v funkcyu"? Судя по коду, если ObReferenceObjectByHandle обламывается, то управление возвращается в SpyStartLoggingDevice и оттуда сразу в SpyCommonDeviceIoControl. Так что никаких чудес. А что за BSOD? Код и параметры? Код (Text): SpyIsAttachedToDeviceByUserDeviceName ( . . . ) { . . . // // get a pointer to the volumes file object // status = ObReferenceObjectByHandle( . . . ); if(!NT_SUCCESS( status )) { ZwClose( fileHandle ); return status; } . . . } SpyStartLoggingDevice ( . . . ) { . . . status = SpyIsAttachedToDeviceByUserDeviceName( . . . ); if (!NT_SUCCESS( status )) { // // There was an error, so return the error code. // return status; } . . . } SpyCommonDeviceIoControl ( . . . . ) { . . . . if (NT_SUCCESS( IoStatus->Status )) { deviceName[InputBufferLength / sizeof(WCHAR)] = UNICODE_NULL; IoStatus->Status = SpyStartLoggingDevice( deviceName ); } break; . . . . }
Four-F, da bili koekakie izmenenya v kode i okasalos' eto exception, iz-za nego voznikala eta situacya, a prichina sboya ObReferenceObjectByHandle bila v etoi peremennoi *IoFileObjectType, obyasnite zachem ona nujna??? nigde bolee ona nevstrechaetsya krome kak ntddk i to prosto obyavlena. voobshem zameniv ee na "null", oshibka v etom uchastke koda ischezla. No po zaversheniyu SpyFatsIODeviceControl BSOD vse je poyavlyaetsy c oshibkoi "DRIVER_IRQL_NOT_LESS_OR_EQUAL", chto eto znachit? Код (Text): The computer has rebooted from a bugcheck. The bugcheck was: 0x000000d1 (0x7c4e6582, 0x0000006c, 0x00000000, 0x7c4e6582). Microsoft Windows 2000 [v15.2195]. A dump was saved in: C:\WINNT\MEMORY.DMP. Four-F, eshe y menya pros'ba, nadeyus' ne slishkom naglaya, mne nujnii otkompilirovannie failii filespy.sys filespy.exe dliya analiza, ochen' nujnii.
Код (Text): ********************************************************************** ********* * * * Bugcheck Analysis * * * ********************************************************************** ********* 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: 7c4e6582, memory referenced Arg2: 0000006c, IRQL Arg3: 00000000, value 0 = read operation, 1 = write operation Arg4: 7c4e6582, address which referenced memory Debugging Details: ------------------ OVERLAPPED_MODULE: vpc_s3_fba67000 READ_ADDRESS: 7c4e6582 CURRENT_IRQL: 6c FAULTING_IP: kernel32!ReadFile+0 7c4e6582 ?? ??? DEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO BUGCHECK_STR: 0xD1 LAST_CONTROL_TRANSFER: from 7c4e6582 to 80468b6f STACK_TEXT: fad6ad64 7c4e6582 00009481 fc658300 74c08500 nt!KiTrap0E+0x27c 0012ff3c 00402637 00000003 00406184 00000080 kernel32!ReadFile WARNING: Stack unwind information not available. Following frames may be wrong. 0012ffc0 7c4e87f5 e7ffffff 00000000 7ffdf000 Load+0x2637 0012fff0 00000000 00403f68 00000000 000000c8 kernel32!BaseProcessStart+0x3d FAILED_INSTRUCTION_ADDRESS: kernel32!ReadFile+0 7c4e6582 ?? ??? FOLLOWUP_IP: nt!KiTrap0E+27c 80468b6f f7457000000200 test dword ptr [ebp+0x70],0x20000 SYMBOL_STACK_INDEX: 0 FOLLOWUP_NAME: MachineOwner SYMBOL_NAME: nt!KiTrap0E+27c MODULE_NAME: nt IMAGE_NAME: ntoskrnl.exe DEBUG_FLR_IMAGE_TIMESTAMP: 3ee6c002 STACK_COMMAND: kb FAILURE_BUCKET_ID: 0xD1_CODE_AV_BAD_IP_nt!KiTrap0E+27c BUCKET_ID: 0xD1_CODE_AV_BAD_IP_nt!KiTrap0E+27c Followup: MachineOwner --------- nichego ne ponimayu, nujna pomosh
IoFileObjectType - это указатель на переменную, в которой хранится указатель на структуру OBJECT_TYPE, описывающую объект "тип" для объектов "файл" Если у тебя есть указатель на объект, то проверить, действительно ли это файл, событие, мьютекс... можно имея указатели на соответствующие объекты "тип": IoFileObjectType, ExMutantObjectType, ExEventPairObjectType ... ObReferenceObjectByHandle как раз это и делает. Объяснять всё это долго. Кое-что есть у Шрайбера, кое-что у Соломона, кое-что у меня проскакивало, кое-что тут: http://gl00my.chat.ru/nt/ob.txt Я как-то баловался написанием расширения для Kernel Debugger. Слей obx отсюда http://www.wasm.ru/toollist.php?list=21 В заголовке каждого объекта есть указатель на OBJECT_TYPE для соответствующего типа. Вот пример испльзования: Код (Text): 038c: Object: 8135d488 GrantedAccess: 0012019f Object: 8135d488 Type: ([b]818a5b40[/b]) File ObjectHeader: 8135d470 HandleCount: 1 PointerCount: 1 Directory Object: 00000000 Name: \Dbg1100 {NamedPipe} kd> !load obx.dll kd> !obx.help dob [options] <address> - Dump the object body. Print <!dob -h> for extra help doh [options] <address> - Dump the object header. Print <!doh -h> for extra help dot [options] <address> - Dump the object type. Print <!dot -h> for extra help help - Display this help ver[sion] - Version of extension dll kd> kd> !dot poi(IoFileObjectType) OBJECT_TYPE { at [b]0x818A5B40[/b] +0x00 ERESOURCE Mutex +0x00 LIST_ENTRY SystemResourcesList +0x00 PLIST_ENTRY Flink 0x8053DE40 +0x04 PLIST_ENTRY Blink 0x818A5C40 +0x08 POWNER_ENTRY OwnerTable NULL +0x0C SHORT ActiveCount 0 +0x0E USHORT Flag 0 +0x10 PKSEMAPHORE SharedWaiters NULL +0x14 PKEVENT ExclusiveWaiters NULL +0x18 OWNER_ENTRY OwnerThreads[0] +0x18 ERESOURCE_THREAD OwnerThread 0 union { +0x1C LONG OwnerCount 0 +0x1C ULONG TableSize 0 } +0x20 OWNER_ENTRY OwnerThreads[1] +0x20 ERESOURCE_THREAD OwnerThread 0 union { +0x24 LONG OwnerCount 0 +0x24 ULONG TableSize 0 } +0x28 ULONG ContentionCount 0 +0x2C USHORT NumberOfSharedWaiters 0 +0x2E USHORT NumberOfExclusiveWaiters 0 union { +0x30 PVOID Address NULL +0x30 ULONG_PTR CreatorBackTraceIndex 0 } +0x34 KSPIN_LOCK SpinLock 0 +0x38 LIST_ENTRY TypeList +0x38 PLIST_ENTRY Flink 0x818A5B78 +0x3C PLIST_ENTRY Blink 0x818A5B78 +0x40 UNICODE_STRING Name +0x40 USHORT Length 0x8 +0x42 USHORT MaximumLength 0xA +0x44 PWSTR Buffer 0xE1477D88 "File" +0x48 PVOID DefaultObject 0x0000005C +0x4C ULONG Index 26 +0x50 ULONG TotalNumberOfObjects 2799 +0x54 ULONG TotalNumberOfHandles 692 +0x58 ULONG HighWaterNumberOfObjects 3082 +0x5C ULONG HighWaterNumberOfHandles 723 +0x60 OBJECT_TYPE_INITIALIZER TypeInfo +0x60 USHORT Length 0x4C +0x62 BOOLEAN UseDefaultObject FALSE +0x63 UCHAR Reserved 0 +0x64 ULONG InvalidAttributes 0x00000130 +0x68 GENERIC_MAPPING GenericMapping +0x68 ACCESS_MASK GenericRead 0x00120089 +0x6C ACCESS_MASK GenericWrite 0x00120116 +0x70 ACCESS_MASK GenericExecute 0x001200a0 +0x74 ACCESS_MASK GenericAll 0x001f01ff +0x78 ULONG ValidAccessMask 0x001F01FF +0x7C BOOLEAN SecurityRequired FALSE +0x7D BOOLEAN MaintainHandleCount TRUE +0x7E BOOLEAN MaintainTypeList FALSE +0x7F --- +0x80 POOL_TYPE PoolType 0 (NonPagedPool) +0x84 ULONG DefaultPagedPoolCharge 0x400 +0x88 ULONG DefaultNonPagedPoolCharge 0xE8 +0x8C PVOID DumpProcedure NULL +0x90 PVOID OpenProcedure NULL +0x94 PVOID CloseProcedure 0x8056D03B nt!IopCloseFile +0x98 PVOID DeleteProcedure 0x804FA4C3 nt!IopDeleteFile +0x9C PVOID ParseProcedure 0x8056CF08 nt!IopParseFile +0xA0 PVOID SecurityProcedure 0x8058A6DC nt!IopGetSetSecurityObject +0xA4 PVOID QueryNameProcedure 0x8058CF93 nt!IopQueryName +0xA8 PVOID OkayToCloseProcedure NULL +0xAC ULONG Key 'eliF' } DRIVER_IRQL_NOT_LESS_OR_EQUAL довольно часто вылазит и означает просто кто-то находясь на повышенном IRQL сделал что-то, что на этом IRQL делать нельзя. В твоём случае произошло обращение к отсутствующей памяти, а подкачать её нельзя, т.к. очень высок IRQL, либо её там вообще нет. filespy ушел мылом.
Four-F, nashel structuru _OBJECT_TYPE Код (Text): struct _OBJECT_TYPE { _ERESOURCE Mutex; _LIST_ENTRY TypeList; _UNICODE_STRING Name; void* DefaultObject; DWORD Index; DWORD TotalNumberOfObjects; DWORD TotalNumberOfHandles; DWORD HighWaterNumberOfObjects; DWORD HighWaterNumberOfHandles; _OBJECT_TYPE_INITIALIZER TypeInfo; DWORD Key; [b]_ERESOURCE ObjectLocks[4];[/b] }; ona nemno otlichaetsya ot tvoei, pochemu?
Об этом лучше спросить Свена Я брал её из официальных символов. Точно не помню, но кажется я проверял, что она одинакова для w2k, XP и 2003 Server. Определение Свена возможно соответствует NT4, возможно получено путём медитации. В любом случае, подобные структуры не документированы, так что от версии к версии запросто могут меняться.
Four-F, vopros prosvuchit bit' mojet ochen' glupim, no... kak v masm importiruetsya peremennie, k primeru taje IoFileObjectType???
Код (Text): mov ecx, ExEventObjectType mov ecx, [ecx] mov ecx, [ecx] ; PTR OBJECT_TYPE invoke ObReferenceObjectByHandle, edx, EVENT_MODIFY_STATE, ecx, \ UserMode, addr g_pkEventObject, NULL IoFileObjectType и прочие XxxObjectType так же.
Four-F, Da eshe, MSDN nashel o IoFileObjectType, chto esli ObReferenceObjectByHandle visivaetsya KernelMode, to parametr POBJECT_TYPE doljen bit' Null. Pochemu je v filespy eto nesobludaetsya?
Ну я ведь нигде дополнительно не объявляю, что буду импортировать функцию ObReferenceObjectByHandle. Механизм экспортирования переменных и адресов функций ни чем не отличается, так что достаточно просто использовать переменную, а линкер сам разберется. Пример кода взят из KmdKit\examples\basic\Synchronization\SharedEvent - ProcessMon Потому что ObReferenceObjectByHandle, как и многие другие функции, на самом деле работает не так как написано в MSDN/DDK. Например, там пишут: "ObjectType can be either *IoFileObjectType or *ExEventObjectType." - это не верно. Это просто чтоб не использовали другие переменные XxxObjectType. А например, ObReferenceObjectByPointer вообще работает ну совсем не так как в доке написано (см. Часть 14 : Базовая техника. Синхронизация). Для того чтоб понять, почему спай делает именно так, надо лезть в исходный код ObReferenceObjectByHandle. Щас некогда, может завтра посмотрю.
Собственно в исходный код ObReferenceObjectByHandle лезть не надо, и так всё ясно, достаточно подняться не пару строчек выше. Код (Text): InitializeObjectAttributes( &objectAttributes, &volumeNameUnicodeString, OBJ_CASE_INSENSITIVE | [b]OBJ_KERNEL_HANDLE[/b], NULL, NULL); ZwCreateFile( . . . ); ObReferenceObjectByHandle( fileHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, &volumeFileObject, NULL ); LuckyDevil, я уже много раз мусолил эту тему в статьях, но изволь. Сначала разберемся с KernelMode. Не знаю, что неписано в MSDN, но в DDK говорят: "This parameter can also be NULL if AccessMode is KernelMode." Т.е. может быть, но не должен. Если определить NULL, то ObReferenceObjectByHandle просто не будет проверять, а действительно ли хендл объекта соответствует объекту "файл" (в данном случае). Когда мы референсим хендл пришедший из юзер-моды, или хендл открытый пусть даже в ядре, но в контексте пользовательского процесса, то обязаны определить параметр ObjectType. Если этого не сделать, то ещё до того как мы успеем сделать референс другой поток пользовательского процесса может закрыть этот хендл и создать другой объект. Хендл нового объекта численно может совпасть с первоначальным значением и мы получим ссылку на объект совсем другого типа, но будем считать, что это файл. Также значение UserMode заставляет функцию проверить права доступа к объекту. Теперь обрати внимание на OBJ_KERNEL_HANDLE. Это означает, что хендл создаваемого объекта попадет не в таблицу хендлов текущего процесса, а в таблицу хендлов процесса System. К таким объектам режим ядра может обращаться из контекста любого процесса, а режим пользователя не может вообще. Т.е. спай создает файл в режиме ядра и помещает его в таблицу хендлов системного процесса. Поэтому и определяет KernelMode, т.к. точно знает, что хендл валиден. Вместо *IoFileObjectType он мог бы определить NULL. При этом ничего не изменилось бы, т.к. есть гарантия, что хендл соответствует и будет соответствовать именно обекту "файл". Случайно закрыть его может только ядро, а это исключено. Определяя *IoFileObjectType спай просто ещё больше ужесточает условия проверки и теоретически это абсолютно правильно. Надеюсь, понятно. Вот ключевой кусок из кода ObReferenceObjectByHandle: Код (Text): if ((ObjectHeader->Type == ObjectType) || (ObjectType == NULL)) { // Работаем с объектом } else { Status = STATUS_OBJECT_TYPE_MISMATCH; } Как видно, если явно не определить тип объекта, то ObReferenceObjectByHandle не проверяет совпадение типов и начинает работать с объектом. Если же тип объекта задан явно, например *IoFileObjectType, а хендл в действительности соответствует, скажем, объекту "событие", то функция вернет STATUS_OBJECT_TYPE_MISMATCH. Вот, на вскидку, имена переменных (многие экспортируются), в которых хранятся указатели на OBJECT_TYPE для соответствующих типов объектов. Все их можно передавать в функции ObReferenceObjectXxx для проверки типа объекта, а не только IoFileObjectType и ExEventObjectType, как пишут в DDK. ExEventPairObjectType PsProcessType PsThreadType PsJobType LpcPortObjectType LpcWaitablePortObjectType IoAdapterObjectType IoCompletionObjectType IoControllerObjectType IoDeviceObjectType IoDriverObjectType IoFileObjectType CmpKeyObjectType ExCallbackObjectType ExCallbackObjectType ExEventObjectType ExEventPairObjectType ExMutantObjectType ... продолжение следует ))
takoe Код (Text): typedef enum _EVENT_TYPE { NotificationEvent, SynchronizationEvent } EVENT_TYPE, *PEVENT_TYPE; ili ya oshibayus'?