互斥体
互斥体(mutant)和事件(event)和信号量(semaphore)一样,都可以用来进行线程的同步控制,这几个对象都是内核对象,所以意味着,通过这些对象可以进行跨进程的线程同步控制
极端情况 :
*如果B进程的Y线程还没有来得及调用修改SignalState的函数(如果SetEvent),那么等待对象将被遗弃,这也就意味着等待对象的链表上的线程将永远等待下去*
1.互斥体遇到这种情况,系统会将SignalState进行重置
2.互斥体可以重入
WaitForSingleObject(A)
...
WaitForSingleObject(A,B,C)
...
互斥体结构
_KMUTANT
nt!_KMUTANT
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListEntry : _LIST_ENTRY
+0x018 OwnerThread : Ptr32 _KTHREAD
+0x01c Abandoned : UChar
+0x01d ApcDisable : UChar
3环程序创建的 ; NtCreateMutant ApcDisable = 0
0环程序创建的 ; NtCreateMutex ApcDisable = 1
_DISPATCHER_HEADER
ntdll!_DISPATCHER_HEADER
+0x000 Type : UChar
+0x001 Absolute : UChar
+0x002 Size : UChar
+0x003 Inserted : UChar
+0x004 SignalState : Int4B
+0x008 WaitListHead : _LIST_ENTRY
创建互斥体
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTE SlpMutexAttributes,
BOOL bInitialOwner,
LPCTSTR lpName
)
MUTANT.header.Type = 2
MUTANT.header.SignalState = bInitialOwner ? 0 : 1
MUTANT.OwnerThread = 当前线程 or NULL
MUTANT.Abandoned = 0
MUTANT.ApcDisable = 0
bInitialOwner == TRUE 将当前互斥体挂入到当前线程的互斥体链表(_KTHREAD+0x10 MutantListHead)
释放互斥体
BOOL WINAPI ReleaseMutext(HANDLE hMUTEX);
ReleaseMutext -> NtReleaseMutext -> KeReleaseMutant
MmUnloadSysteImage -> KeReleaseMutant(x,y,Abandon,Z)
if (Abandon == false)
{
MUTANT.Header.SignalState++;
}
else
{
MUTANT.Header.SignalState = 1;
MUTANT.OwnerThread = NULL;
}
if (UTANT.Header.SignalState == 1)
{
MUTANT.OwnerThread = NULL;
从当前线程互斥体链表中将当前互斥体移除
}
MUTANT.Header.SignalState++