在Usermode中使用ntCreatemutant

Using NtCreateMutant in usermode

本文关键字:ntCreatemutant Usermode      更新时间:2023-10-16

我尝试在我的过程中创建一个突变体,该突变体使用此代码不止一次创建过程时关闭该过程:

HANDLE m;
OBJECT_ATTRIBUTES attr;
attr.Length = sizeof(OBJECT_ATTRIBUTES);
UNICODE_STRING str;
RtlInitUnicodeString(&str, L"123");
attr.ObjectName = &str;
long stats;
if (!(stats = NtCreateMutant(&m, MUTANT_ALL_ACCESS, &attr, false))) {
    if (0xC0000035 == stats) {
        return false;
    }
    return true;
}

所有功能都有正确的地址

当我删除代码attr.ObjectName = &str;时,突变的手柄不是null,但是第二个过程不会退出,因为NTSTATUS为0

当我保留代码时,ntstatus返回status_object_path_syntax_bad,我不知道该与ntcreatemutant有什么关系

我想知道是否可以使用usermode中的ntcreatemutex进行此操作,并解决这些问题,或者我是否应该停止尝试并只使用creatsemutex(我不想出于其他原因使用它尝试使用ntcreatemutex)

我知道迟到了1年,但是考虑到堆栈上有多少个问题,总比没有好。

我很惊讶为什么@Raymond Chen发表了这一评论,因为您可以使用无证件的API。它们到处都是窗户,在过去的十年中几乎没有改变。

实际上,它们也可以在每个Windows内核驱动程序中使用,因此它们不是"无证件"。和"不支持"。

首先,这不是您初始化object_attributes的方式;如果您想这样做:

OBJECT_ATTRIBUTES ObjectAttributes; = { sizeof(ObjectAttributes) };

推荐和官方方法是使用initializeObjectattributes宏。

第二,Mutex名称不能为" 123"。在NT名称空间内。这就是为什么您获得status_object_path_syntax_bad。

第三,您的代码只是丑陋的,用法不好。您想创建的内容(从听起来)是"过程障碍"。

我会给您一个工作的完整示例代码:

BOOL CreateProcessBarrier()
{
    NTSTATUS Result;
    UNICODE_STRING MutantName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE MutantHandle;
    WCHAR MutantNameNT[] = L"\??\40691290-71d5-45bc-b86a-e714496f4bf2";
    WCHAR MutantNameWin[] = L"40691290-71d5-45bc-b86a-e714496f4bf2";
    RtlInitUnicodeString(&MutantName, MutantNameNT);
    InitializeObjectAttributes(&ObjectAttributes, &MutantName, 0, NULL, NULL);
    // ALL OK
    if (0 <= (Result = ZwCreateMutant(&MutantHandle, MUTANT_ALL_ACCESS, &ObjectAttributes, TRUE)))
    {
        // Banana
        return TRUE;
    }
    // Already exists
    else if (Result == STATUS_OBJECT_NAME_COLLISION || Result == STATUS_OBJECT_NAME_EXISTS)
    {
        // Que paso ?
        return FALSE;
    }
    // Mutex creation failed, fallback to winapi
    else
    {
        // Papaya
        CreateMutexW(NULL, TRUE, MutantNameWin);
        if (GetLastError() == ERROR_ALREADY_EXISTS)
        {
            return FALSE;
        }
    }
    return TRUE;
}

上面的功能支持降级到普通Winapi,以防万一失败。

用法很简单,如:

进程A:

CreateProcessBarrier();

过程B,C,D等:

if(!CreateProcessBarrier()) ... do whatever.

享受。