【问题标题】:WINAPI - Close mutex without being the ownerWINAPI - 关闭互斥锁而不是所有者
【发布时间】:2018-04-16 12:32:56
【问题描述】:

我正在尝试关闭另一个应用程序中的互斥锁。

我正在使用 WinAPI(“windows.h”)。

这是我关闭此互斥锁的代码:

DWORD pid = 0;
hMyWnd = FindWindow(NULL, "TheFamousWindowName");

GetWindowThreadProcessId(hMyWnd, &pid);

HANDLE hProc = OpenProcess(PROCESS_DUP_HANDLE, 0, pid);

HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, false, "TheEvilMutex"); // hMutex isn't null
WaitForSingleObject(hMutex, 10000); // Wait 10 seconds, nothing happens

if (!DuplicateHandle(hProc, hMutex, NULL, 0, 0, false, DUPLICATE_CLOSE_SOURCE)) {
    // Arrive always here because of error 288
    // And the mutex is still there, not closed
}

ReleaseMutex(hMutex);
CloseHandle(hMutex);

问题是当我打电话时

DuplicateHandle(hProc, hMutex, NULL, 0, 0, false, DUPLICATE_CLOSE_SOURCE)

我收到了错误 288

GetLastError()

标记为“尝试释放不属于调用者的互斥锁”并且互斥锁未关闭

现在,我知道我不是所有者,但我看不到关闭此互斥锁的解决方案。

我见过一些程序这样做,例如 Process Explorer 或 Process Hacker。我在 GitHub 上查看了最后的代码,但没有找到任何关于它如何在不成为所有者的情况下关闭互斥锁的信息。

我也检查了这个帖子 how does procexp close a mutex held by another process? 但我无法让它工作。

感谢您阅读我。 希望有人可以帮助我。

编辑
感谢@RbMm,替换了

DuplicateHandle(hProc, hMutex, NULL, 0, 0, false, DUPLICATE_CLOSE_SOURCE)

DuplicateHandle((HANDLE)-1, hMutex, NULL, 0, 0, false, DUPLICATE_CLOSE_SOURCE)

解决了错误 288,但互斥锁并未因此关闭。

【问题讨论】:

  • 您只能释放一个已等待(ed) 的互斥锁:"...或通过在调用其中一个等待函数时指定其句柄。..." i> msdn.microsoft.com/en-us/library/windows/desktop/…
  • C != C++。仅使用您正在使用的语言进行标记,除非两者确实相关。
  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须在问题本身中包含所需的行为和重现它所需的最短代码。请阅读如何创建minimal reproducible example
  • @tambre 谢谢,我已尝试根据您的建议改进我的问题。
  • 这闻起来像an XY problem。为什么,为什么,你想通过摆弄它的互斥锁来破坏另一个应用程序?你真正想做什么?

标签: c++ c winapi mutex ownership


【解决方案1】:

调用中的DuplicateHandle(hProc, hMutex, NULL, 0, 0, false, DUPLICATE_CLOSE_SOURCE) hMutex 必须是在hProc 的上下文中有效的句柄。但hMutex 是当前进程中的句柄,而不是hProc 中的句柄。因此,在这行代码中,您尝试在hProc 的上下文中关闭任意句柄,但不是您的hMutex。这样做的结果将是任意的。可能是你关闭了一些句柄。可能这个句柄根本不存在,或者句柄被保护不被关闭。

而且互斥体还在,没有关闭

当然它没有关闭,也不能关闭。要关闭它,您需要调用

DuplicateHandle(NtCurrentProcess(), hMutex, NULL, 0, 0, false, DUPLICATE_CLOSE_SOURCE);

因为错误 288

我绝对确定DuplicateHandle 永远不会返回此错误。 ERROR_NOT_OWNER你来自ReleaseMutex(hMutex);


对于 另一个 进程中的关闭互斥锁 - 需要在目标进程中使用此互斥锁的句柄值,而不是在自身进程中。此代码已完成工作:

void CloseRemote(ULONG dwProcessId, PCWSTR Name)
{
    // create any file
    HANDLE hFile = OpenMutex(MAXIMUM_ALLOWED, FALSE, Name);

    if (hFile != INVALID_HANDLE_VALUE)
    {
        if (HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId))
        {

            NTSTATUS status;
            ULONG cb = 0x80000;

            union {
                PSYSTEM_HANDLE_INFORMATION_EX pshi;
                PVOID pv;
            };

            do 
            {
                status = STATUS_INSUFFICIENT_RESOURCES;

                if (pv = LocalAlloc(0, cb))
                {
                    if (0 <= (status = ZwQuerySystemInformation(SystemExtendedHandleInformation, pv, cb, &cb)))
                    {
                        if (ULONG_PTR NumberOfHandles = pshi->NumberOfHandles)
                        {
                            ULONG_PTR UniqueProcessId = GetCurrentProcessId();
                            PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles = pshi->Handles;
                            do 
                            {
                                // search for created file
                                if (Handles->UniqueProcessId == UniqueProcessId && Handles->HandleValue == (ULONG_PTR)hFile)
                                {
                                    // we got it !
                                    PVOID Object = Handles->Object;

                                    NumberOfHandles = pshi->NumberOfHandles, Handles = pshi->Handles;
                                    do 
                                    {
                                        if (Object == Handles->Object && Handles->UniqueProcessId == dwProcessId)
                                        {
                                            DuplicateHandle(hProcess, (HANDLE)Handles->HandleValue, 0, 0, 0, 0, DUPLICATE_CLOSE_SOURCE);
                                        }

                                    } while (Handles++, --NumberOfHandles);

                                    break;
                                }
                            } while (Handles++, --NumberOfHandles);
                        }
                    }
                    LocalFree(pv);
                }

            } while (status == STATUS_INFO_LENGTH_MISMATCH);

            CloseHandle(hProcess);
        }

        CloseHandle(hFile);
    }
}

【讨论】:

  • @PandoresStrongest - PSYSTEM_HANDLE_INFORMATION_EX 未记录在案且不存在于任何 Windows 标头中。但你可以找到它的定义。 STATUS_INSUFFICIENT_RESOURCES 在 wdk 的 ntstatus.h 中声明。
  • @PandoresStrongest - ntdll.lib 文件存在。您可以在 inet 中找到的所有定义。例如processhacker.sourceforge.netresource
  • @PandoresStrongest - 你在做什么?!?你需要链接ntdll.lib
  • @PandoresStrongest - 你的零知识问题。例如,首先尝试了解如何从 kernel32.dll 调用 api。你怎么称呼DuplicateHandle - 真的怎么样?!?
  • @PandoresStrongest - 不。回复我(真的是为你自己) - 你怎么称呼DuplicateHandleOpenMutexWOpenProcess - 直到你不明白这一点,你才能继续前进
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
  • 2018-05-23
  • 2012-06-05
  • 2018-11-12
  • 1970-01-01
相关资源
最近更新 更多