From a2498ca55846956bf85d84280d4cf435f5ce4e48 Mon Sep 17 00:00:00 2001 From: mingkuang Date: Fri, 12 May 2023 01:13:57 +0800 Subject: [PATCH] =?UTF-8?q?Fea,=20=E5=85=BC=E5=AE=B9=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=87=AA=E5=B7=B1=E7=BC=96=E8=AF=91=E7=9A=84CRT=20DLL=EF=BC=8C?= =?UTF-8?q?=E5=A6=82msvcr14x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Build.cmd | 2 +- src/Thunks/YY_Thunks.h | 32 +++++++++++++++++-- .../YY-Thunks.UnitTest.vcxproj | 10 ++++-- .../YY-Thunks.UnitTest.vcxproj.filters | 3 ++ src/YY-Thunks.UnitTest/pch.cpp | 4 +-- src/YY-Thunks.UnitTest/weak.c | 4 +++ 6 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 src/YY-Thunks.UnitTest/weak.c diff --git a/src/Build.cmd b/src/Build.cmd index ae3e46f..0a9056e 100644 --- a/src/Build.cmd +++ b/src/Build.cmd @@ -27,7 +27,7 @@ goto:eof cl /O1 /Os /Oi /GS- /arch:IA32 /Z7 /MT /Fo"objs\\%Platform%\\%1" /Zl /c /D "NDEBUG" /D "YY_Thunks_Support_Version=%2" "%~dp0Thunks\YY_Thunks.cpp" ::½øÐк¯ÊýÃû³ƽøÐÐÐÞÕý __imp__%s_%u -> __imp__%s@%u -LibMaker.exe FixObj "%~dp0..\\objs\\%Platform%\\%1" /WeakExternFix:__security_cookie=%PointType% /WeakExternFix:__YY_Thunks_Process_Terminating=4 +LibMaker.exe FixObj "%~dp0..\\objs\\%Platform%\\%1" /WeakExternFix:__security_cookie=%PointType% /WeakExternFix:__YY_Thunks_Process_Terminating=4 /WeakExternFix:__acrt_atexit_table=%PointType% LibMaker.exe AppendWeak /MACHINE:%Platform% /DEF:"%~dp0def\\%Platform%\\PSAPI2Kernel32.def" /OUT:"%~dp0..\\objs\\%Platform%\\%1" diff --git a/src/Thunks/YY_Thunks.h b/src/Thunks/YY_Thunks.h index 2b187dc..8d724a5 100644 --- a/src/Thunks/YY_Thunks.h +++ b/src/Thunks/YY_Thunks.h @@ -396,8 +396,16 @@ static void* __fastcall try_get_function( #undef _APPLY +static bool g_bUninitialize/* = false*/; + static void __cdecl __YY_uninitialize_winapi_thunks() { + // 值反初始化一次 + if (g_bUninitialize) + return; + + g_bUninitialize = true; + //当DLL被强行卸载时,我们什么都不做。 if (auto pRtlDllShutdownInProgress = (decltype(RtlDllShutdownInProgress)*)GetProcAddress(try_get_module_ntdll(), "RtlDllShutdownInProgress")) { @@ -466,19 +474,37 @@ static int __cdecl _YY_initialize_winapi_thunks() return 0; } +// 外部weak符号,用于判断当前是否静态 +EXTERN_C extern void* __acrt_atexit_table; + static int __cdecl __YY_initialize_winapi_thunks() { _YY_initialize_winapi_thunks(); - //只在节点位置插入 atexit 流程,避免CRT还没完全初始化好出现问题。 - atexit(__YY_uninitialize_winapi_thunks); + // 如果 == null,那么有2种情况: + // 1. 非UCRT,比如2008,VC6,这时,调用 atexit是安全的,因为atexit在 XIA初始化完成了。 + // 2. UCRT 并且处于MD状态。这时 atexit初始化 会提与 XIA,这时也是没有问题的。 + // 如果 != null: + // 那么说明UCRT处于静态状态(CRT DLL其实也是静态的一种) + // 这时,XTY是可以正确执行的,这时就不用调用atexit了 + // 由于XTY晚于onexit,所以它是可靠的。 + if (__acrt_atexit_table == nullptr) + { + atexit(__YY_uninitialize_winapi_thunks); + } return 0; } typedef int(__cdecl* _PIFV)(void); +typedef void(__cdecl* _PVFV)(void); -#pragma section(".CRT$XID", long, read) // CRT C Initializers +// CRT C Initializers +#pragma section(".CRT$XID", long, read) +// CRT C Terminators(仅稍微之后于XTZ),这是故意的。 +// YY-Thunks属于API底层理应尽可能的滞后,且反初始化工作不依赖与CRT +#pragma section(".CRT$XTY", long, read) __declspec(allocate(".CRT$XID")) static _PIFV ___Initialization = __YY_initialize_winapi_thunks; +__declspec(allocate(".CRT$XTY")) static _PVFV ___Uninitialization = __YY_uninitialize_winapi_thunks; diff --git a/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj b/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj index 92232ec..bf3d61e 100644 --- a/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj +++ b/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj @@ -116,7 +116,7 @@ true pch.h Use - MultiThreadedDebug + MultiThreadedDebugDLL false @@ -132,7 +132,7 @@ true pch.h Use - MultiThreadedDebug + MultiThreadedDebugDLL false @@ -176,6 +176,12 @@ + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing diff --git a/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj.filters b/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj.filters index 085a225..493974a 100644 --- a/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj.filters +++ b/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj.filters @@ -66,6 +66,9 @@ 源文件\UnitTest + + 源文件 + diff --git a/src/YY-Thunks.UnitTest/pch.cpp b/src/YY-Thunks.UnitTest/pch.cpp index 8799ee5..781d282 100644 --- a/src/YY-Thunks.UnitTest/pch.cpp +++ b/src/YY-Thunks.UnitTest/pch.cpp @@ -2,6 +2,4 @@ #include "pch.h" -// 当使用预编译的头时,需要使用此源文件,编译才能成功。 - -EXTERN_C BOOL __YY_Thunks_Process_Terminating = 0; \ No newline at end of file +// 当使用预编译的头时,需要使用此源文件,编译才能成功。 \ No newline at end of file diff --git a/src/YY-Thunks.UnitTest/weak.c b/src/YY-Thunks.UnitTest/weak.c new file mode 100644 index 0000000..d5e8855 --- /dev/null +++ b/src/YY-Thunks.UnitTest/weak.c @@ -0,0 +1,4 @@ + +const int __YY_Thunks_Process_Terminating; + +const void* __acrt_atexit_table;