mirror of
https://github.com/Chuyu-Team/YY-Thunks.git
synced 2026-10-28 13:57:16 +08:00
改进try_get_function性能,同时增强YY-Thunks兼容性。
This commit is contained in:
@@ -331,7 +331,7 @@ YY-Thunks(鸭船),存在的目的就是抹平不同系统的差异,编
|
||||
* 添加 CreateSymbolicLinkW(A)
|
||||
* 添加 ReOpenFile
|
||||
|
||||
### 1.0.2.3 - 扩充实现(2020-02-26 22:00)
|
||||
### 1.0.2.4 - 扩充实现(2020-03-03 19:00)
|
||||
* 添加 CompareStringEx
|
||||
* 添加 CompareStringOrdinal
|
||||
* 添加 SetFilePointerEx(Windows 2000模式)
|
||||
@@ -344,3 +344,4 @@ YY-Thunks(鸭船),存在的目的就是抹平不同系统的差异,编
|
||||
* 添加 QueryDepthSList(Windows 2000模式)
|
||||
* 添加 InterlockedPushEntrySList(Windows 2000模式)
|
||||
* 添加 InterlockedPopEntrySList(Windows 2000模式)
|
||||
* 优化实现,改进YY-Thunks性能与体积
|
||||
|
||||
+1
-1
@@ -22,7 +22,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" "%~dp0YY_Thunks.cpp"
|
||||
|
||||
::进行函数名称进行修正 __imp__%s_%u -> __imp__%s@%u
|
||||
LibMaker.exe FixObj "%~dp0..\\objs\\%Platform%\\%1" /WeakExternFix:__security_cookie=%PointType%
|
||||
LibMaker.exe FixObj "%~dp0..\\objs\\%Platform%\\%1" /WeakExternFix:__security_cookie=%PointType% /WeakExternFix:__YY_Thunks_Process_Terminating=4
|
||||
|
||||
LibMaker.exe AppendWeak /MACHINE:%Platform% /DEF:"%~dp0def\\%Platform%\\PSAPI2Kernel32.def" /OUT:"%~dp0..\\objs\\%Platform%\\%1"
|
||||
|
||||
|
||||
+13
-14
@@ -3,18 +3,18 @@
|
||||
|
||||
|
||||
|
||||
#define _YY_APPLY_TO_LATE_BOUND_MODULES(_APPLY) \
|
||||
_APPLY(ntdll, "ntdll" ) \
|
||||
_APPLY(kernel32, "kernel32" ) \
|
||||
_APPLY(psapi, "psapi" ) \
|
||||
_APPLY(version, "version" ) \
|
||||
_APPLY(advapi32, "advapi32" ) \
|
||||
_APPLY(user32, "user32" ) \
|
||||
_APPLY(ws2_32, "ws2_32" ) \
|
||||
_APPLY(shell32, "shell32" ) \
|
||||
_APPLY(shlwapi, "shlwapi" ) \
|
||||
_APPLY(api_ms_win_core_winrt_l1_1_0, "api-ms-win-core-winrt-l1-1-0" ) \
|
||||
_APPLY(api_ms_win_core_winrt_string_l1_1_0, "api-ms-win-core-winrt-string-l1-1-0" )
|
||||
#define _YY_APPLY_TO_LATE_BOUND_MODULES(_APPLY) \
|
||||
_APPLY(ntdll, "ntdll" , USING_UNSAFE_LOAD ) \
|
||||
_APPLY(kernel32, "kernel32" , USING_UNSAFE_LOAD ) \
|
||||
_APPLY(psapi, "psapi" , 0 ) \
|
||||
_APPLY(version, "version" , 0 ) \
|
||||
_APPLY(advapi32, "advapi32" , 0 ) \
|
||||
_APPLY(user32, "user32" , 0 ) \
|
||||
_APPLY(ws2_32, "ws2_32" , 0 ) \
|
||||
_APPLY(shell32, "shell32" , 0 ) \
|
||||
_APPLY(shlwapi, "shlwapi" , 0 ) \
|
||||
_APPLY(api_ms_win_core_winrt_l1_1_0, "api-ms-win-core-winrt-l1-1-0" , 0 ) \
|
||||
_APPLY(api_ms_win_core_winrt_string_l1_1_0, "api-ms-win-core-winrt-string-l1-1-0", 0 )
|
||||
|
||||
|
||||
//全局可能使用到的函数
|
||||
@@ -90,8 +90,7 @@
|
||||
return reinterpret_cast<decltype(_FUNCTION)*>(try_get_function( \
|
||||
&_CRT_CONCATENATE( pFun_ ,_FUNCTION), \
|
||||
_CRT_STRINGIZE(_FUNCTION), \
|
||||
_CRT_CONCATENATE(try_get_module_, _MODULE)(), \
|
||||
_CRT_CONCATENATE(module_name_, _MODULE))); \
|
||||
&_CRT_CONCATENATE(try_get_module_, _MODULE))); \
|
||||
}
|
||||
#include "YY_Thunks_List.hpp"
|
||||
|
||||
|
||||
+70
-44
@@ -49,12 +49,35 @@ else
|
||||
*/
|
||||
EXTERN_C const DWORD __YY_Thunks_Installed = YY_Thunks_Support_Version;
|
||||
|
||||
/*
|
||||
导出一个外部弱符号,指示当前是否处于强行卸载模式。
|
||||
|
||||
EXTERN_C BOOL __YY_Thunks_Process_Terminating;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
swtich(dwReason)
|
||||
{
|
||||
case DLL_PROCESS_DETACH:
|
||||
//我们可以通过 lpReserved != NULL 判断,当前是否处于强行卸载模式。
|
||||
__YY_Thunks_Process_Terminating = lpReserved != NULL;
|
||||
|
||||
……
|
||||
break;
|
||||
……
|
||||
*/
|
||||
#if (YY_Thunks_Support_Version < NTDDI_WINXP)
|
||||
//Windows 2000不支持RtlDllShutdownInProgress,因此依然引入__YY_Thunks_Process_Terminating
|
||||
EXTERN_C extern BOOL __YY_Thunks_Process_Terminating;
|
||||
#endif
|
||||
|
||||
#if (YY_Thunks_Support_Version < NTDDI_WIN6)
|
||||
static HANDLE _GlobalKeyedEventHandle;
|
||||
#endif
|
||||
|
||||
static uintptr_t __security_cookie_yy_thunks;
|
||||
|
||||
#define _APPLY(_SYMBOL, _NAME) \
|
||||
#define _APPLY(_SYMBOL, _NAME, ...) \
|
||||
constexpr const wchar_t* _CRT_CONCATENATE(module_name_, _SYMBOL) = _CRT_WIDE(_NAME);
|
||||
_YY_APPLY_TO_LATE_BOUND_MODULES(_APPLY)
|
||||
#undef _APPLY
|
||||
@@ -110,8 +133,8 @@ static PVOID __fastcall __CRT_DecodePointer(
|
||||
{
|
||||
return reinterpret_cast<PVOID>(
|
||||
__crt_rotate_pointer_value(
|
||||
reinterpret_cast<uintptr_t>(Ptr) ^ __security_cookie,
|
||||
__security_cookie % __crt_maximum_pointer_shift
|
||||
reinterpret_cast<uintptr_t>(Ptr) ^ __security_cookie_yy_thunks,
|
||||
__security_cookie_yy_thunks % __crt_maximum_pointer_shift
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -121,8 +144,8 @@ static PVOID __fastcall __CRT_EncodePointer(PVOID const Ptr)
|
||||
return reinterpret_cast<PVOID>(
|
||||
__crt_rotate_pointer_value(
|
||||
reinterpret_cast<uintptr_t>(Ptr),
|
||||
__crt_maximum_pointer_shift - (__security_cookie % __crt_maximum_pointer_shift)
|
||||
) ^ __security_cookie
|
||||
__crt_maximum_pointer_shift - (__security_cookie_yy_thunks % __crt_maximum_pointer_shift)
|
||||
) ^ __security_cookie_yy_thunks
|
||||
);
|
||||
}
|
||||
|
||||
@@ -237,6 +260,9 @@ static HMODULE __fastcall try_load_library_from_system_directory(wchar_t const*
|
||||
}
|
||||
|
||||
|
||||
#define USING_UNSAFE_LOAD 0x00000001
|
||||
|
||||
template<int Flags>
|
||||
static HMODULE __fastcall try_get_module(volatile HMODULE* pModule, const wchar_t* module_name) noexcept
|
||||
{
|
||||
// First check to see if we've cached the module handle:
|
||||
@@ -253,7 +279,7 @@ static HMODULE __fastcall try_get_module(volatile HMODULE* pModule, const wchar_
|
||||
// If we haven't yet cached the module handle, try to load the library. If
|
||||
// this fails, cache the sentinel handle value INVALID_HANDLE_VALUE so that
|
||||
// we don't attempt to load the module again:
|
||||
HMODULE const new_handle = try_load_library_from_system_directory(module_name);
|
||||
HMODULE const new_handle = (Flags & USING_UNSAFE_LOAD) ? LoadLibraryW(module_name) : try_load_library_from_system_directory(module_name);
|
||||
if (!new_handle)
|
||||
{
|
||||
if (HMODULE const cached_handle = __crt_interlocked_exchange_pointer(pModule, INVALID_HANDLE_VALUE))
|
||||
@@ -277,23 +303,23 @@ static HMODULE __fastcall try_get_module(volatile HMODULE* pModule, const wchar_
|
||||
return new_handle;
|
||||
}
|
||||
|
||||
#define _APPLY(_MODULE, _NAME) \
|
||||
static volatile HMODULE* __fastcall _CRT_CONCATENATE(try_get_module_, _MODULE)() noexcept \
|
||||
#define _APPLY(_MODULE, _NAME, _FLAGS) \
|
||||
static volatile HMODULE __fastcall _CRT_CONCATENATE(try_get_module_, _MODULE)() noexcept \
|
||||
{ \
|
||||
__declspec(allocate(".YYThu$AAA")) static volatile HMODULE hModule; \
|
||||
return &hModule; \
|
||||
return try_get_module<_FLAGS>(&hModule, _CRT_CONCATENATE(module_name_, _MODULE)); \
|
||||
}
|
||||
_YY_APPLY_TO_LATE_BOUND_MODULES(_APPLY)
|
||||
#undef _APPLY
|
||||
|
||||
typedef volatile HMODULE (__fastcall* try_get_module_fun)();
|
||||
|
||||
static __forceinline void* __fastcall try_get_proc_address_from_first_available_module(
|
||||
volatile HMODULE* pModule,
|
||||
const wchar_t* module_name,
|
||||
try_get_module_fun get_module,
|
||||
char const* const name
|
||||
) noexcept
|
||||
{
|
||||
HMODULE const module_handle = try_get_module(pModule, module_name);
|
||||
HMODULE const module_handle = get_module();
|
||||
if (!module_handle)
|
||||
{
|
||||
return nullptr;
|
||||
@@ -308,18 +334,13 @@ static __forceinline void* __cdecl invalid_function_sentinel() noexcept
|
||||
return reinterpret_cast<void*>(static_cast<uintptr_t>(-1));
|
||||
}
|
||||
|
||||
static int __cdecl _YY_initialize_winapi_thunks();
|
||||
|
||||
static void* __fastcall try_get_function(
|
||||
void** ppFunAddress,
|
||||
char const* const name,
|
||||
volatile HMODULE* pModule,
|
||||
const wchar_t* module_name
|
||||
try_get_module_fun get_module
|
||||
) noexcept
|
||||
{
|
||||
//尝试初始化YY-Thunks,避免还未初始化问题。
|
||||
_YY_initialize_winapi_thunks();
|
||||
|
||||
// First check to see if we've cached the function pointer:
|
||||
{
|
||||
void* const cached_fp = __crt_fast_decode_pointer(
|
||||
@@ -339,7 +360,7 @@ static void* __fastcall try_get_function(
|
||||
// If we haven't yet cached the function pointer, try to import it from any
|
||||
// of the modules in which it might be defined. If this fails, cache the
|
||||
// sentinel pointer so that we don't attempt to load this function again:
|
||||
void* const new_fp = try_get_proc_address_from_first_available_module(pModule, module_name, name);
|
||||
void* const new_fp = try_get_proc_address_from_first_available_module(get_module, name);
|
||||
if (!new_fp)
|
||||
{
|
||||
void* const cached_fp = __crt_fast_decode_pointer(
|
||||
@@ -382,8 +403,7 @@ static void* __fastcall try_get_function(
|
||||
return reinterpret_cast<_CRT_CONCATENATE(_FUNCTION, _pft)>(try_get_function( \
|
||||
&_CRT_CONCATENATE( pFun_ ,_FUNCTION), \
|
||||
_CRT_STRINGIZE(_FUNCTION), \
|
||||
_CRT_CONCATENATE(try_get_module_, _MODULE)(), \
|
||||
_CRT_CONCATENATE(module_name_, _MODULE))); \
|
||||
&_CRT_CONCATENATE(try_get_module_, _MODULE))); \
|
||||
}
|
||||
_YY_APPLY_TO_LATE_BOUND_FUNCTIONS(_APPLY)
|
||||
#undef _APPLY
|
||||
@@ -392,8 +412,20 @@ static void* __fastcall try_get_function(
|
||||
static void __cdecl __YY_uninitialize_winapi_thunks()
|
||||
{
|
||||
//当DLL被强行卸载时,我们什么都不做。
|
||||
if (pRtlDllShutdownInProgress && pRtlDllShutdownInProgress())
|
||||
return;
|
||||
if (pRtlDllShutdownInProgress)
|
||||
{
|
||||
if(pRtlDllShutdownInProgress())
|
||||
return;
|
||||
}
|
||||
__if_exists(__YY_Thunks_Process_Terminating)
|
||||
{
|
||||
else
|
||||
{
|
||||
if (__YY_Thunks_Process_Terminating)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto pModule = (HMODULE*)__YY_THUNKS_MODULE_START;
|
||||
auto pModuleEnd = (HMODULE*)__YY_THUNKS_FUN_START;
|
||||
|
||||
@@ -468,33 +500,27 @@ InitOnceExecuteOnceDownlevel(
|
||||
|
||||
static int __cdecl _YY_initialize_winapi_thunks()
|
||||
{
|
||||
//为了防止多线程同时初始化,我们还是加个锁
|
||||
static INIT_ONCE InitOnce;
|
||||
|
||||
InitOnceExecuteOnceDownlevel(&InitOnce, [](PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) -> BOOL
|
||||
{
|
||||
if (auto hNtdll = GetModuleHandleW(L"ntdll"))
|
||||
{
|
||||
if (auto hNtdll = try_get_module_ntdll())
|
||||
{
|
||||
#if defined(_X86_) || defined(_M_IX86)
|
||||
pRtlWow64EnableFsRedirectionEx = (decltype(RtlWow64EnableFsRedirectionEx)*)GetProcAddress(hNtdll, "RtlWow64EnableFsRedirectionEx");
|
||||
pRtlWow64EnableFsRedirectionEx = (decltype(RtlWow64EnableFsRedirectionEx)*)GetProcAddress(hNtdll, "RtlWow64EnableFsRedirectionEx");
|
||||
#endif
|
||||
pRtlDllShutdownInProgress = (decltype(RtlDllShutdownInProgress)*)GetProcAddress(hNtdll,"RtlDllShutdownInProgress");
|
||||
}
|
||||
pRtlDllShutdownInProgress = (decltype(RtlDllShutdownInProgress)*)GetProcAddress(hNtdll, "RtlDllShutdownInProgress");
|
||||
}
|
||||
|
||||
if (auto hKernel32 = GetModuleHandleW(L"kernel32"))
|
||||
{
|
||||
bSupportSafe = GetProcAddress(hKernel32, "AddDllDirectory") != nullptr;
|
||||
}
|
||||
if (auto hKernel32 =try_get_module_kernel32())
|
||||
{
|
||||
bSupportSafe = GetProcAddress(hKernel32, "AddDllDirectory") != nullptr;
|
||||
}
|
||||
|
||||
void* const encoded_nullptr = __crt_fast_encode_pointer((void*)nullptr);
|
||||
__security_cookie_yy_thunks = __security_cookie;
|
||||
|
||||
for (auto p = __YY_THUNKS_FUN_START; p != __YY_THUNKS_FUN_END; ++p)
|
||||
{
|
||||
*p = encoded_nullptr;
|
||||
}
|
||||
void* const encoded_nullptr = __crt_fast_encode_pointer((void*)nullptr);
|
||||
|
||||
return TRUE;
|
||||
}, nullptr, nullptr);
|
||||
for (auto p = __YY_THUNKS_FUN_START; p != __YY_THUNKS_FUN_END; ++p)
|
||||
{
|
||||
*p = encoded_nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user