为啥“CreateEvent”创建的 HANDLE 在另一个进程中无效?

Posted

技术标签:

【中文标题】为啥“CreateEvent”创建的 HANDLE 在另一个进程中无效?【英文标题】:Why HANDLE created by 'CreateEvent' isn't valid in another process?为什么“CreateEvent”创建的 HANDLE 在另一个进程中无效? 【发布时间】:2014-12-30 21:16:51 【问题描述】:

我正在编写一个 ant-cheat Win32 加载程序,我需要在其中创建一个事件,等待它由我存储它的另一个进程发出信号 - 但它因 ERROR_INVALID_HANDLE 而失败。我正在创建一个未命名的事件,并将它的 HANDLE 值传递给另一个进程,该进程应该在特定条件下将其设置为信号状态。任何想法为什么会这样 - 'CreateEvent' 创建的 HANDLE 不是对所有进程都有效。说明这一点的伪代码:

进程1,线程1:

extern LPVOID pExternalMemory;

extern HANDLE hExternalProcess; //Process2 Handle

extern HANDLE hExternalThread; //In suspended state (Thread1)

extern HANDLE hEventDuplicate;

HANDLE hEvent = CreateEvent(nullptr, true, false, nullptr);

DuplicateHandle(GetCurrentProcess(), hEvent, hExternalProcess, &hEventDuplicate, STANDARD_RIGHTS_ALL, false, 0); //Wrong, check EDIT1

WriteProcessMemory(hProcess, pExternalMemory, &hEventDuplicate, sizeof(HANDLE), nullptr);

ResumeThread(hExternalThread);

WaitForSingleObject(hEvent, INFINITE);

进程2,线程1:

EIP->

if(SomeCondition) SetEvent((HANDLE)ExternalMemory); //fails with 'ERROR_INVALID_HANDLE'

//Other code

编辑:我使用“DuplicateHandle”来解决问题,但现在对第二个进程的“SetEvent”调用失败并出现“ERROR_ACCESS_DENIED”。

EDIT1:解决了问题 - 它是与“DuplicateHandle”函数调用有关,应该是

DuplicateHandle(GetCurrentProcess(), hEvent, hExternalProcess, &hEventDuplicate, 0, false, DUPLICATE_SAME_ACCESS)

出于某种奇怪的原因 - 任何人都可以解释这是为什么?

【问题讨论】:

为什么不呢?因为他们不是。不过有一些方法可以绕过它,DuplicateHandle 就是其中之一。 是的,我明白了。但我记得在某处我读到的事件用于进程同步。 事件可以在进程之间共享。但是每个进程都需要自己的事件句柄。句柄特定于进程。 DuplicateHandle 的电话在哪里?你用了什么参数? STANDARD_RIGHTS_ALL only 包括standard access rights,这是所有类型的安全对象所共有的。它不包括特定于对象的访问权限。 SetEvent 的文档指定您需要特定于对象的访问权限EVENT_MODIFY_STATE。因此,如果您说STANDARD_RIGHTS_ALL|EVENT_MODIFY_STATE,它可能会起作用,但使用DUPLICATE_SAME_ACCESS 在概念上更简单。 【参考方案1】:

句柄有点像指针,因为它们通常是特定于进程的。它需要特殊的操作(例如使用 DuplicateHandle)来共享它们。

根据情况,命名对象然后让其他进程以这种方式访问​​它可能更容易。见CreateEvent的第四个参数。

【讨论】:

以上是关于为啥“CreateEvent”创建的 HANDLE 在另一个进程中无效?的主要内容,如果未能解决你的问题,请参考以下文章

事件对象Event的使用

Windows API——CREATEEVENT——创建事件

原生js之document.createEvent建立自定义事件

为啥 TForm.Handle 是一个吸气剂而不是一个字段?

VK_NULL_HANDLE 始终为 0;为啥不是 nullptr?

CreateEvent和SetEvent及WaitForSingleObject的使用方法