Здрасте. Это макро захватывает мьютекс при работе с ап. В XP это ExAcquireFastMutex(AddressCreationLock). Если счётчик захватов не равен одному, то вызывающий поток ждёт сигнализацию мьютекса, которая произойдёт при освобождении ресурса. Сервис NtAreMappedFilesTheSame в начале захватывает этот мьютекс: Код (Text): $ NtAreMappedFilesTheSame: $+2 push ebp $+3 mov ebp,esp $+5 push ecx $+6 push esi $+7 push edi $+8 mov eax,dword ptr fs:[124] ; KPRCB.CurrentThread $+E mov eax,dword ptr ds:[eax+44] ; KTHREAD.ApcState.Process $+11 lea edi,dword ptr ds:[eax+F0] ; EPROCESS.AddressCreationLock $+17 mov ecx,edi $+19 call ExAcquireFastMutex Если остановить поток вызвавший NtAreMappedFilesTheSame, то мьютекс останется захваченным и другой поток вызвавший этот сервис должен ждать освобождение мьютекса, тоесть это деадлок при рк атаке. Реально такого не происходит, кажется что на мьютексе не происходит ожидания: Код (Text): LOCK_RESOURCE macro Call $ + 5 Call $ + 5 Call NtAreMappedFilesTheSame endm .data WaitThreadId HANDLE ? LockThreadId HANDLE ? LockThreadHandle HANDLE ? WaitThreadHandle HANDLE ? SynchLock BOOLEAN FALSE RaiseLock BOOLEAN FALSE TryLocks ULONG ? .code LockRoutine proc UserData:PVOID @@: cmp RaiseLock,FALSE je @b LOCK_RESOURCE mov RaiseLock,FALSE jmp @b ret LockRoutine endp WaitRoutine proc UserData:PVOID @@: cmp SynchLock,FALSE je @b LOCK_RESOURCE mov SynchLock,FALSE jmp @b ret WaitRoutine endp Entry proc invoke CreateThread, NULL, 0, addr WaitRoutine, 123, 0, addr WaitThreadId mov WaitThreadHandle,eax %APIERR invoke CreateThread, NULL, 0, addr LockRoutine, 123, 0, addr LockThreadId mov LockThreadHandle,eax %APIERR Freeze: mov RaiseLock,TRUE invoke ZwSuspendThread, LockThreadHandle, NULL %NTERR inc TryLocks mov SynchLock,TRUE invoke Sleep, 50 ; ms cmp SynchLock,FALSE jne Raised UnFreeze: invoke ZwResumeThread, LockThreadHandle, NULL %NTERR invoke ZwYieldExecution jmp Freeze Raised: Int 3 ret Entry endp Как это возможно ?
А затем освобождает его: Код (Text): PAGE:004D91DA xor esi, esi PAGE:004D91DC jmp loc_510D94 ... PAGE:00510D94 loc_510D94: ; CODE XREF: NtAreMappedFilesTheSame(x,x)-37B12j PAGE:00510D94 ; NtAreMappedFilesTheSame(x,x)-37AFEj ... PAGE:00510D94 mov ecx, edi PAGE:00510D96 call ds:__imp_@ExReleaseFastMutex@4 ; ExReleaseFastMutex(x) PAGE:00510D9C pop edi PAGE:00510D9D mov eax, esi PAGE:00510D9F pop esi PAGE:00510DA0 leave PAGE:00510DA1 retn 8 PAGE:00510DA1 _NtAreMappedFilesTheSame@8 endp Видимо нужно очень постараться, чтобы остановить выполнение потока внутри NtAreMappedFilesTheSame
Если под не подразумевается изменение контекста потока и других хитрых действий, которых нет в приведённом выше сэмпле, то мне не ясно почему должен быть лок. NtAreMappedFilesTheSame в начале своего выполнения захватывает мъютекс, а в конце его освобождает. Соответственно, как минимум, неправильно называть макрос LOCK_RESOURCE, а хотя бы LOCK_AND_UNLOCK_RESOURCE. Т.е. по приведённому выше сэмплу: останавливает поток LockThread уже после выхода потока LockThread из выполнения NtAreMappedFilesTheSame, т.е. когда мъютекс уже освобождён, а, следовательно, после Код (Text): mov SynchLock,TRUE поток WaitThread успешно выполнит NtAreMappedFilesTheSame без дэдлока.
Доставка kernel APC PspSuspendThread или как-то так, которая ждет на спецсобытии из KPROCESS. PsResumeThread() соотв. сигналит событие. Все просто
Код (Text): VOID KiSuspendThread ( IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ) /*++ Routine Description: This function is the kernel routine for the builtin suspend APC of a thread. It is executed as the result of queuing the builtin suspend APC and suspends thread execution by waiting nonalerable on the thread's builtin suspend semaphore. When the thread is resumed, execution of thread is continued by simply returning. Arguments: NormalContext - Not used. SystemArgument1 - Not used. SystemArgument2 - Not used. Return Value: None. --*/ { PKTHREAD Thread; UNREFERENCED_PARAMETER(NormalContext); UNREFERENCED_PARAMETER(SystemArgument1); UNREFERENCED_PARAMETER(SystemArgument2); // // Get the address of the current thread object and Wait nonalertable on // the thread's builtin suspend semaphore. // Thread = KeGetCurrentThread(); KeWaitForSingleObject(&Thread->SuspendSemaphore, Suspended, KernelMode, FALSE, NULL); return; }
Great n0name Не понятно смысловая нагрузка, имея ядро, делать попытку остановить тред, притом что нужно, всего лишь сделать запрос с не валидным указателем и перехватить исключения , захватив тем самым обработчик для текущего треда ... Раскажите почему? ((
n0name Да, спасибо за пруфкод) IceCrashLdr Ой, не виноватая я, он сам пришел... я просто написал как останавливалиется тред, остальной топик читал, но не вникал и уж тем более отвечать не собираюсь