Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetLastError ERROR_ALREADY_EXISTS #150

Closed
wants to merge 1 commit into from

Conversation

HIllya51
Copy link
Contributor

DLL链接到yythunks,load&free&再次load时,如果在DLL中也有检测GetLastError ERROR_ALREADY_EXISTS的逻辑,会被这个所干扰导致失败。

@mingkuang-Chuyu
Copy link
Collaborator

我不是特别明白。是否可以写一下示例?
因为load如果成功会返回一个非null值,此时似乎不需要检测LastError

@HIllya51
Copy link
Contributor Author

HIllya51 commented Mar 11, 2025

理论上是这样没错,但我实测中这个地方就是会谜之影响到我后面的getlasterror判断结果
https://github.com/HIllya51/LunaTranslator/blob/main/src/cpp/LunaHook/LunaHook/main.cc#L198
我也是偶然才发现这个问题,本地开发时图省事会链接到1.1.6版本,release时用的是个旧版就没问题了。
然后我调试的时候发现每次detach dll之后除非关闭游戏,不然第二次就无法重新注入了。
最后定位到这里有问题。但是我也是明白理论上getlasterror只会获取到我自己的这个 WinMutex里createmutex的error的,所以就很奇怪了,我也是测试是viewMutex是确实正确close了的。
然后我试着把yythunks这里添加上setlasterror(0)后,就可以正确第二次注入了,所以就很迷。

@HIllya51
Copy link
Contributor Author

我晚点看能不能搞个小的复现出来

@mingkuang-Chuyu
Copy link
Collaborator

mingkuang-Chuyu commented Mar 11, 2025

话说你的WinMutex实现的也太复杂了吧……看的晕乎乎的。

不过感觉就是触发了你的代码是存在问题的。
viewMutex 先调用了CreateMutexW,然后调用了CloseHandle,然后再是GetLastError。

正确的做法应该是 CreateMutexW后立即GetLastError。YY-Thunks会再CloseHandle会调用GetYY_ThunksSharedData。只能说恰好覆盖了你之前CreateMutexW的错误代码。

但是根源是你现在的代码没有再CreateMutexW后立即调用GetLastError。

@HIllya51
Copy link
Contributor Author

HIllya51 commented Mar 11, 2025

话说你的WinMutex实现的也太复杂了吧……看的晕乎乎的。

啊这,不是才十几行么,您是不是看错了 https://github.com/HIllya51/LunaTranslator/blob/main/src/cpp/LunaHook/include/types.h#L3-L20 AutoHandle<>只是个简单的用raii自动closehandle的东西不用细究

不过感觉就是触发了你的代码是存在问题的。 viewMutex 先调用了CreateMutexW,然后调用了CloseHandle,然后再是GetLastError。

肯定不是啊,这个mutex的CloseHandle要等viewMutex析构了(dll detach时)才会执行的,就是CreateMutexW后立即就会GetLastError的

@HIllya51 HIllya51 marked this pull request as draft March 11, 2025 10:58
@mingkuang-Chuyu
Copy link
Collaborator

mingkuang-Chuyu commented Mar 11, 2025 via email

@mingkuang-Chuyu
Copy link
Collaborator

mingkuang-Chuyu commented Mar 11, 2025 via email

@mingkuang-Chuyu mingkuang-Chuyu added 方案:无效问题 This doesn't seem right and removed 进度:等待审核 labels Mar 11, 2025
@mingkuang-Chuyu
Copy link
Collaborator

如果有疑问可以继续回复,如果没有其他问题,那么将关闭这个PR。

故意把这个调用拆成2部分应该就能解决。或者让WinMutex默认不要构造出一个Mutex内核对象。

auto MutexTmp = WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(GetCurrentProcessId()), &allAccess);
if (GetLastError() == ERROR_ALREADY_EXISTS)
    return FALSE;

viewMutex = std::move(MutexTmp );

@HIllya51
Copy link
Contributor Author

HIllya51 commented Mar 11, 2025

这个AutoHandle并不是我写的,是从textractor继承下来的,真的好迷,测试发现不知道为什么他会初始化为一个不是null的东西导致居然真的会closehandle一下

不过,即使我真的调用了CloseHandle进入到yythunks的某个内部函数,它也不应该修改lasterror的值吧,文档里也没有提到CloseHandle会修改lasterror。是否应该将yythunks函数改成在进入时先getlasterror然后退出时setlasterror更好一点?

@mingkuang-Chuyu
Copy link
Collaborator

文档明确规定了 CloseHandle 失败时通过 GetLastError获取错误代码。我不知道你说的文档没有提到会修改……

如果该函数成功,则返回值为非零值。
如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。

@HIllya51
Copy link
Contributor Author

文档明确规定了 CloseHandle 失败时通过 GetLastError获取错误代码。我不知道你说的文档没有提到会修改……

如果该函数成功,则返回值为非零值。
如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。

不好意思,我眼瞎了...

@HIllya51
Copy link
Contributor Author

您觉得改成我刚才改的这样好不好?我现在完全没搞明白为什么会进入到GetYY_ThunksSharedData这个函数中,迷。
viewMutex这个代码确实一团糟,但这是一个有很多年历史运行正常的继承来的代码了,它在不链接yythunks或链接1.1.5时一切都是正常的,只有链接了1.1.6之后才会getlasterror错误,所以我觉得这个不太能算是我的一个错误(虽然之后我也打算改一下这个谜之closehandle问题)。

@HIllya51
Copy link
Contributor Author

HIllya51 commented Mar 11, 2025

而且我试了一下,closehandle一个错误值并不会导致ERROR_ALREADY_EXISTS,它的错误值是ERROR_INVALID_HANDLE

@mingkuang-Chuyu
Copy link
Collaborator

您觉得改成我刚才改的这样好不好?我现在完全没搞明白为什么会进入到GetYY_ThunksSharedData这个函数中,迷。 viewMutex这个代码确实一团糟,但这是一个有很多年历史运行正常的继承来的代码了,它在不链接yythunks或链接1.1.5时一切都是正常的,只有链接了1.1.6之后才会getlasterror错误,所以我觉得这个不太能算是我的一个错误(虽然之后我也打算改一下这个谜之closehandle问题)。

本末倒置了。
首先根本原因在于没有及时使用GetLastError保存错误代码。只能说YY-Thunks的新的行为让你暴露了这个问题,这并不是说没问题。

对于CloseHandle微软只承诺,失败时可以通过GetLastError获取错误代码,其他没有做承诺,你只是恰好遇到了成功时没有修改LastError。

@mingkuang-Chuyu
Copy link
Collaborator

另外你提交的代码也不好,目前也没有良好的保存LastError。后续链路那么长(MapViewOfFile等)……这些都是LastError修改潜在点。你的修改只是恰好规避了你目前环境的问题。

@mingkuang-Chuyu
Copy link
Collaborator

mingkuang-Chuyu commented Mar 11, 2025

而且我试了一下,closehandle一个错误值并不会导致ERROR_ALREADY_EXISTS,它的错误值是ERROR_INVALID_HANDLE

你关闭的又不是一个错误的值。你目前的代码关闭的是一个合法的句柄。

@mingkuang-Chuyu
Copy link
Collaborator

be74d0e

Opt, 保证GetYY_ThunksSharedData不修改LastError,缓解不及时调用GetLastError的代码逻辑异常。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
方案:无效问题 This doesn't seem right
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants