Просветите в SoftIce Всем привет Ответь пожалуйста на пару вопросов: Во-первых Почему при активном айсе у меня незапускаются пдф файлы(акробат начинает инит и потом пропадает).Как это лечится.Ведь вся инфа по айсу(для начинающих)находится в пдф. Ну и во-вторых(чисто из интереса).Может кто знает как айс делает свои хуки(bpx)на такое большое количество системных функций(сервисов) или подскажите где про это можно почитать.Очень интересно узнать. Спасибо
Если я правильно помню то по пути \Program Files\Adobe\Acrobat 5.0\Reader\plug_ins\InterTrust лежит плагин, который нужно удалить для решения проблемы
подскажите где про это можно почитать Нигде. Можно дизассемблировать ntice.sys и посмотреть самому. А как он это делает... Одни догадки
Или взять уже готовый дизассемблированный Зачем тебе дрова сорокалетней давности? Они ж уже испортились
Еще один до боли нужный вопрос.Как в айсе можно исправить page fault что бы система (возврате из айса) не глючила или не приходилось перезагружатся. P.S.пдф пока что по поиску пролистал там по этому вопросу (именно решение) ничего помойму нету.
vaskovich Это совсем нето.при faults on и page fault появлялся айс и при выходе из него все было нормально(правда система чуть подтормаживала),а при faults off ->BSOD->Reset. Суть вопроса: можно ли при page fault в айсе назначить как то обработчик (наподобие SEH)или может вызвать какуюто системную функцию по обработке page fault. Ведь сама система вызывает функции обработки для данной ошибки(помойму неэкспортируемую).А как мне быть если у меня такая ошибка в дровах.
Мда... Глубоко тебя понесло, Шарапов... Причем, судя по посту, то и сам не слишком в таких вещах разбираешься... Page Fault обрабаывается вектором в IDT - номер вектора - 14 (в 10-системе счисления). На языке Windows это пишется так: IDTEntry _KiTrap0E, D_INT032 ; E: Page Fault Код выглядит так: Код (Text): ;++ ; ; Routine Description: ; ; Handle page fault. ; ; The page fault occurs if paging is enabled and any one of the ; conditions is true: ; ; 1. page not present ; 2. the faulting procedure does not have sufficient privilege to ; access the indicated page. ; ; For case 1, the referenced page will be loaded to memory and ; execution continues. ; For case 2, registered exception handler will be invoked with ; appropriate error code (in most cases STATUS_ACCESS_VIOLATION) ; ; N.B. It is assumed that no page fault is allowed during task ; switches. ; ; N.B. INTERRUPTS MUST REMAIN OFF UNTIL AFTER CR2 IS CAPTURED. ; ; Arguments: ; ; Error code left on stack. ; CR2 contains faulting address. ; Interrupts are turned off at entry by use of an interrupt gate. ; ; Return value: ; ; None ; ;-- ASSUME DS:NOTHING, SS:NOTHING, ES:NOTHING ENTER_DR_ASSIST kite_a, kite_t, NoAbiosAssist align dword public _KiTrap0E _KiTrap0E proc ENTER_TRAP kite_a, kite_t if FAST_V86_TRAP or FAST_BOP cmp byte ptr PCR[PcVdmAlert], 0 jne Kt0eVdmAlert endif VERIFY_BASE_TRAP_FRAME mov edi,cr2 ; ; Now that everything is in a sane state check for rest of the Pentium ; Processor bug work around for illegal operands ; cmp _KiI386PentiumLockErrataPresent, 0 jne PentiumTest ; Check for special problems NoPentiumFix: ; No. Skip it sti test [ebp]+TsEFlags, EFLAGS_INTERRUPT_MASK ; faulted with jz Kt0e12b ; interrupts disabled? Kt0e01: ; ; call _MmAccessFault to page in the not present page. If the cause ; of the fault is 2, _MmAccessFault will return approriate error code ; sub esp, 16 mov eax,[ebp]+TsSegCs and eax,MODE_MASK ; (eax) = arg3: PreviousMode mov [esp+12], ebp ; pass in the trap frame base mov [esp+8], eax mov [esp+4], edi mov eax, [ebp]+TsErrCode ; (eax)= error code and eax, ERR_0E_STORE ; (eax)= 0 if fault caused by read ; = 2 if fault caused by write shr eax, 1 ; (eax) = 0 if read fault, 1 if write fault mov [esp+0], eax ; arg3: load/store indicator call _MmAccessFault@16 if DEVL cmp _PsWatchEnabled,0 jz short xxktskip mov ebx, [ebp]+TsEip stdCall _PsWatchWorkingSet,<eax, ebx, edi> xxktskip: endif or eax, eax ; sucessful? jge Kt0e10 ; yes, go exit mov ecx,PCR[PcGdt] ; Form Ldt Base movzx ebx,byte ptr [ecx + KGDT_LDT].KgdtBaseHi shl ebx,8 or bl,byte ptr [ecx + KGDT_LDT].KgdtBaseMid shl ebx,16 or bx,word ptr [ecx + KGDT_LDT].KgdtBaseLow or ebx,ebx ; check for zero jz short Kt0e05 ; no ldt cmp edi,ebx jb short Kt0e05 ; address not in LDT ; Form Ldt limit movzx edx,byte ptr [ecx + KGDT_LDT].KgdtLimitHi and edx,000000FFh shl edx,16 or dx,word ptr [ecx + KGDT_LDT].KgdtLimitLow add ebx,edx cmp edi,ebx jae short Kt0e05 ; too high to be an ldt address sldt cx ; Verify this process has an LDT test ecx, 0ffffh ; Check CX jz short Kt0e05 ; If ZY, no LDT mov eax, [ebp]+TsErrCode ; (eax)= error code and eax, ERR_0E_STORE ; (eax)= 0 if fault caused by read ; = 2 if fault caused by write shr eax, 1 ; (eax) = 0 if read fault, 1 if write fault ; call page fault handler stdCall _MmAccessFault, <eax, edi, 0, ebp> or eax, eax ; successful? jge Kt0e10 ; if z, yes, go exit mov ebx,[ebp]+TsSegCs ; restore previous mode and ebx,MODE_MASK mov [esp + 8],ebx ; ; Check to determine if the fault occured in the interlocked pop entry slist ; code. There is a case where a fault may occur in this code when the right ; set of circumstances occurs. The fault can be ignored by simply skipping ; the faulting instruction. ; Kt0e05: mov ecx, offset FLAT:ExpInterlockedPopEntrySListFault ; get pop code address cmp [ebp].TsEip, ecx ; check if fault at pop code address je Kt0e10a ; if eq, skip faulting instruction ; ; Did the fault occur in KiSystemService while copying arguments from ; user stack to kernel stack? ; mov ecx, offset FLAT:KiSystemServiceCopyArguments cmp [ebp].TsEip, ecx jne short @f mov ecx, [ebp].TsEbp ; (eax)->TrapFrame of SysService test [ecx].TsSegCs, MODE_MASK jz short @f ; caller of SysService is k mode, we ; will let it bugchecked. mov [ebp].TsEip, offset FLAT:kss60 mov eax, STATUS_ACCESS_VIOLATION mov [ebp].TsEax, eax jmp _KiExceptionExit @@: mov ecx, [ebp]+TsErrCode ; (ecx) = error code and ecx, ERR_0E_STORE ; (ecx) = 0 if fault caused by read ; 2 if fault caused by write shr ecx,1 ; (ecx) = load/store indicator ; ; Did the fault occur in a VDM? ; test dword ptr [ebp]+TsEFlags,EFLAGS_V86_MASK jnz Kt0e7 ; ; Did the fault occur in a VDM while running in protected mode? ; mov esi,PCR[PcPrcbData+PbCurrentThread] mov esi,[esi]+ThApcState+AsProcess test byte ptr [esi]+PrVdmFlag,0fh ; is this a vdm process? jz short Kt0e9 ; z -> not vdm test dword ptr [ebp]+TsSegCs, MODE_MASK jz short kt0e8 cmp word ptr [ebp]+TsSegCs, KGDT_R3_CODE OR RPL_MASK jz kt0e9 ; z -> not vdm Kt0e7: mov esi, eax stdCall _VdmDispatchPageFault, <ebp,ecx,edi> test al,0fh ; returns TRUE, if success jnz Kt0e11 ; Exit,No need to call the debugger mov eax, esi jmp short Kt0e9 Kt0e8: ; ; Did the fault occur in our kernel VDM support code? ; At this point, we know: ; . Current process is VDM process ; . this is a unresolvable pagefault ; . the fault occurred in kernel mode. ; ; ; First make sure this is not pagefault at irql > 1 ; which should be bugchecked. ; cmp eax, STATUS_IN_PAGE_ERROR or 10000000h je Kt0e12 cmp word ptr [ebp]+TsSegCs, KGDT_R0_CODE ; Did fault occur in kernel? jnz short Kt0e9 ; if nz, no, not ours cmp PCR[PcExceptionList], EXCEPTION_CHAIN_END jnz short Kt0e9 ; there is at least a handler to ; handle this exception mov ebp, PCR[PcInitialStack] xor ecx, ecx ; set to fault-at-read sub ebp, KTRAP_FRAME_LENGTH mov esp, ebp ; clear stack (ebp)=(esp)->User trap frame mov esi, [ebp]+TsEip ; (esi)-> faulting instruction jmp Kt0e9b ; go dispatching the exception to user Kt0e9: ; Set up exception record and arguments and call _KiDispatchException mov esi, [ebp]+TsEip ; (esi)-> faulting instruction cmp eax, STATUS_ACCESS_VIOLATION ; dispatch access violation or je short Kt0e9b ; or in_page_error? cmp eax, STATUS_GUARD_PAGE_VIOLATION je short Kt0e9b cmp eax, STATUS_STACK_OVERFLOW je short Kt0e9b ; ; test to see if davec's reserved status code bit is set. If so, then bugchecka ; cmp eax, STATUS_IN_PAGE_ERROR or 10000000h je Kt0e12 ; bugchecka ; ; (ecx) = ExceptionInfo 1 ; (edi) = ExceptionInfo 2 ; (eax) = ExceptionInfo 3 ; (esi) -> Exception Addr ; mov edx, ecx mov ebx, esi mov esi, edi mov ecx, 3 mov edi, eax mov eax, STATUS_IN_PAGE_ERROR call CommonDispatchException ; Won't return Kt0e9b: mov ebx, esi mov edx, ecx mov esi, edi jmp CommonDispatchException2Args ; Won't return .FPO ( 0, 0, 0, 0, 0, FPO_TRAPFRAME ) ; ; The fault occured in the interlocked pop slist function and the faulting ; instruction should be skipped. ; Kt0e10a:mov ecx, offset FLAT:ExpInterlockedPopEntrySListResume ; get resume address mov [ebp].TsEip, ecx ; set continuation address Kt0e10: if DEVL mov esp,ebp ; (esp) -> trap frame test _KdpOweBreakpoint, 1 ; do we have any owed breakpoints? jz _KiExceptionExit ; No, all done stdCall _KdSetOwedBreakpoints ; notify the debugger endif Kt0e11: mov esp,ebp ; (esp) -> trap frame jmp _KiExceptionExit ; join common code Kt0e12: stdCall _KeGetCurrentIrql ; (eax) = OldIrql Kt0e12a: lock inc ds:_KiHardwareTrigger ; trip hardware analyzer ; ; bugcheck a, addr, irql, load/store, pc ; mov ecx, [ebp]+TsErrCode ; (ecx)= error code and ecx, ERR_0E_STORE ; (ecx)= 0 if fault caused by read shr ecx, 1 ; (ecx) = 0 if read fault, 1 if write fault mov esi, [ebp]+TsEip ; [esi] = faulting instruction stdCall _KeBugCheckEx,<IRQL_NOT_LESS_OR_EQUAL,edi,eax,ecx,esi> Kt0e12b: ; In V86 mode with iopl allowed it is OK to handle ; a page fault with interrupts disabled test dword ptr [ebp]+TsEFlags, EFLAGS_V86_MASK jz short Kt0e12c cmp _KeI386VdmIoplAllowed, 0 jnz Kt0e01 Kt0e12c: cmp _KiFreezeFlag,0 ; during boot we can take jnz Kt0e01 ; 'transistion failts' on the ; debugger before it's been locked cmp _KiBugCheckData, 0 ; If crashed, handle trap in jnz Kt0e01 ; normal manner mov eax, 0ffh ; OldIrql = -1 jmp short Kt0e12a if FAST_BOP or FAST_V86_TRAP Kt0eVdmAlert: ; If a page fault occured while we are in VDM alert mode (processing ; v86 trap without building trap frame), we will restore all the ; registers and return to its recovery routine which is stored in ; the TsSegGs of original trap frame. ; mov eax, PCR[PcVdmAlert] mov byte ptr PCR[PcVdmAlert], 0 IF FAST_V86_TRAP cmp al, 0Dh jne short @f mov eax, offset FLAT:V86TrapDRecovery jmp short KtvaExit @@: cmp al, 10h jne short @f mov eax, offset FLAT:V86Trap10Recovery jmp short KtvaExit @@: ENDIF ; FAST_V86_TRAP IF FAST_BOP cmp al, 6 jne short @f mov eax, offset FLAT:V86Trap6Recovery jmp short KtvaExit @@: ENDIF ; FAST_BOP mov eax, [ebp].TsEip KtvaExit: mov [ebp].TsEip, eax mov esp,ebp ; (esp) -> trap frame jmp _KiExceptionExit ; join common code if DBG @@: int 3 endif ENDIF ; FAST_BOP OR FAST_V86_TRAP _KiTrap0E endp Теперь посмотрим, что говорит нам айс. Код (Text): :idt Int Type Sel:Offset Attributes Symbol/Owner ... 000E IntG32 0008:80468E78 DPL=0 P ntoskrnl!Kei386EoiHelper+28D2 Ага, айс нам нагло врет, что хендлер расположен по 0008:80468E78... Проверим. Запускаем стороннюю утилиту-драйвер по дампу IDT. Смотрим: Код (Text): INT 0000000E Location: 00000008:804688F4 DPL: 00000000 Type: 32bit Interrupt Gate Хм-хм, ну... Кто-то паскудно определяет адреса, но для нас важно, что хендлер действительно НЕ перехвачен. Кстати, поставлена была опция faults off. Включаем faults on и повторяем idt еще раз. Ага! idt изменилась! Код (Text): INT 0000000E Location: 00000008:B99A5F22 DPL: 00000000 Type: 32bit Interrupt Gate Если отдать айсу команду mod, то можно видеть, что по тому адресу сидит драйвер айса, т.е. прерывание действительно перехвачено (кстати, вовсе не самым грамотным способом - кто ж так явно прерывания-то хватает!). Далее надо узнать базу ntice - Код (Text): :mod ntice hMod Base PEHeader Module Name File Name B98D3000 B98D30F0 NTice \SystemRoot\System32\Drivers\NTice.SYS Теперь вычитаем базу из полученного адреса и идем в гости дизассемблером. А можно и прямо в айсе. Словом, пилите Шура, пилите. А то у мя времени сейчас мало в этом разбираться...
VOOrDOOluck, в общем, если опустить все что написал выше volodya, то любой необработанный сбой страницы приводит в kernel-mode к вызову KeBugCheck, которая и выполняет все посмертные действия. Теоретически там конечно можно что-нибудь запатчить, чтобы система не ребутилась, но это чревато потерей данных - форматнутые винты и прочее. Поэтому обычно сбоев пытаются просто не допускать.
Еще один до боли нужный вопрос.Как в айсе можно исправить page fault что бы система (возврате из айса) не глючила или не приходилось перезагружатся. Если pagefault "настоящий", т.е. не возникающий при выгрузке страницы системой, а именно из-за програмной ошибки, то можно рискнуть самому "исправить" ситуацию. Например, у жены 1эс валилась как-то - я поставил айс и научил жену исправлять eip на следующую команду Такое прокатит не всегда. В том случае был нулевой указатель, переданный в какую-то там интерфейсную функцию, которая посуществу нах никому не была нужна. В драйверах сложнее. Вообще-то можно вернуться из подпрограммы драйвера / вообще из драйвера, не выполняя инвалидные команды, манипулируя eip ориентируясь на то, что сидит в стеке или добиться того, чтобы система сама срубила драйвер как задачу (иногда же у нее это получается). Возможно, этого можно достичь "заменой" PageFault на GPF или UD. Это все были общее рассуждения, ни на что не претендую. Но теоретически задача должна иметь несложное решение. Вот откуда это следует. Допустим, Вы написали сами ось и к ней есть аналог Айса. Вы вываливаетесь в айс по pagefault, но Вы прекрасно знаете, что это был всего лишь call в какой-то там драйвер и знаете, как корректно исправить глюк "на лету".
> Хамите, сэ-э-эр? volodya, да нет, просто в данном случае ты очень подробно начал копать. В прочем, как и обычно. Думаю достаточно было сказать про манипулирование EIP и стеком, чтобы осветить суть вопроса.
VOOrDOOluck Это просто : в ini-файле есть строчки типа: EXP=\SystemRoot\system32\kernel32.dll Можно и самому такие команды выдать. Тогда все экспортируемые функции можно указывать в командах BPX/B