Skip to content

Commit

Permalink
Opt, 优化try_get_DrawThemeTextEx、try_get_CM_Get_DevNode_Property_ExW、tr…
Browse files Browse the repository at this point in the history
…y_get_CM_Set_DevNode_Property_ExW地址获取
  • Loading branch information
mingkuang-Chuyu committed Jun 17, 2024
1 parent 9255040 commit 0be59db
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 58 deletions.
6 changes: 4 additions & 2 deletions ThunksList.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,10 @@
## CfgMgr32.dll
| 函数 | Fallback
| ---- | -----------
| CM_Get_DevNode_PropertyW | 不存在时,调用CM_Get_DevNode_Registry_PropertyW。
| CM_Set_DevNode_PropertyW | 不存在时,调用CM_Set_DevNode_Registry_PropertyW。
| CM_Get_DevNode_Property_ExW | 不存在时,调用CM_Get_DevNode_Registry_PropertyW。
| CM_Set_DevNode_Property_ExW | 不存在时,调用CM_Set_DevNode_Registry_PropertyW。
| CM_Get_DevNode_PropertyW | 不存在时,调用CM_Get_DevNode_Property_ExW。
| CM_Set_DevNode_PropertyW | 不存在时,调用CM_Set_DevNode_Property_ExW。

## Crypt32.dll
| 函数 | Fallback
Expand Down
154 changes: 130 additions & 24 deletions src/Thunks/CfgMgr32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
#include <SetupAPI.h>
#endif

#if (YY_Thunks_Support_Version < NTDDI_WIN7) && !defined(__Comment_Lib_cfgmgr32)
#if (YY_Thunks_Support_Version < NTDDI_WIN7) && !defined(__Comment_Lib_setupapi)
#define __Comment_Lib_setupapi
#pragma comment(lib, "SetupAPI.Lib")
#endif

#if (YY_Thunks_Support_Version < NTDDI_WIN7) && __YY_Thunks_libs && !defined(__Comment_Lib_cfgmgr32)
#define __Comment_Lib_cfgmgr32
#pragma comment(lib, "Cfgmgr32.lib")
#pragma comment(lib, "cfgmgr32.Lib")
#endif

#ifdef YY_Thunks_Implemented
Expand Down Expand Up @@ -194,6 +199,51 @@ namespace YY::Thunks::Fallback
return &_Item;
}

void* __fastcall try_get_CM_Get_DevNode_Property_ExW(const ProcInfo& _ProcInfo)
{
auto _pProc = try_get_proc_address_from_dll(_ProcInfo);
if (_pProc)
return _pProc;

static constexpr const ProcOffsetInfo kProcInfo[] =
{
#if defined(_X86_)
{ 0x4549BDB0ul, 0x7427B681ul - 0x74270000ul }, // 6.0.6000.16386 (Windows Vista RTM)
{ 0x4791A754ul, 0x738DB93Dul - 0x738D0000ul }, // 6.0.6002.18000 (Windows Vista SP1)
{ 0x49E037E9ul, 0x744DED36ul - 0x744D0000ul }, // 6.0.6002.18005 (Windows Vista SP2)
#elif defined(_AMD64_)
{ 0x4549D318ul, 0x000007FF7C006400ull - 0x7FF7C000000ull }, // 6.0.6000.16386 (Windows Vista RTM)
{ 0x4791ADA3ul, 0x000007FF7BC06E00ull - 0x7FF7BC00000ull }, // 6.0.6002.18000 (Windows Vista SP1)
{ 0x49E041EDul, 0x000007FF7C007090ull - 0x7FF7C000000ull }, // 6.0.6002.18005 (Windows Vista SP2)
#endif
};

__WarningMessage__("try_get_CM_Get_DevNode_Property_ExW 可能遗漏Vista/2008某些补丁中的setupapi.dll,如果你知道详细可以提交PR。");
return try_get_proc_address_from_offset(try_get_module_setupapi(), kProcInfo);
}

void* __fastcall try_get_CM_Set_DevNode_Property_ExW(const ProcInfo& _ProcInfo)
{
auto _pProc = try_get_proc_address_from_dll(_ProcInfo);
if (_pProc)
return _pProc;

static constexpr const ProcOffsetInfo kProcInfo[] =
{
#if defined(_X86_)
{ 0x4549BDB0ul, 0x7433C705ul - 0x74270000ul }, // 6.0.6000.16386 (Windows Vista RTM)
{ 0x4791A754ul, 0x7399D7ADul - 0x738D0000ul }, // 6.0.6002.18000 (Windows Vista SP1)
{ 0x49E037E9ul, 0x7459DC1Dul - 0x744D0000ul }, // 6.0.6002.18005 (Windows Vista SP2)
#elif defined(_AMD64_)
{ 0x4549D318ul, 0x000007FF7C0FDD70ull - 0x7FF7C000000ull }, // 6.0.6000.16386 (Windows Vista RTM)
{ 0x4791ADA3ul, 0x000007FF7BCE1E08ull - 0x7FF7BC00000ull }, // 6.0.6002.18000 (Windows Vista SP1)
{ 0x49E041EDul, 0x000007FF7C0E2550ull - 0x7FF7C000000ull }, // 6.0.6002.18005 (Windows Vista SP2)
#endif
};

__WarningMessage__("try_get_CM_Set_DevNode_Property_ExW 可能遗漏Vista/2008某些补丁中的setupapi.dll,如果你知道详细可以提交PR。");
return try_get_proc_address_from_offset(try_get_module_setupapi(), kProcInfo);
}
#endif
}
}
Expand All @@ -203,29 +253,28 @@ namespace YY::Thunks
{
#if (YY_Thunks_Support_Version < NTDDI_WIN7)

// 最低受支持的客户端 在 Microsoft Windows Vista 和更高版本的 Windows 中可用。
// 实际Windows Vista RTM根本就没有这个接口
// Windows 7 RTM 导出
// Windows Vista有这个函数但是没有导出
__DEFINE_THUNK(
cfgmgr32,
24,
28,
CONFIGRET,
WINAPI,
CM_Get_DevNode_PropertyW,
CM_Get_DevNode_Property_ExW,
_In_ DEVINST dnDevInst,
_In_ CONST DEVPROPKEY* PropertyKey,
_Out_ DEVPROPTYPE* PropertyType,
_Out_writes_bytes_opt_(*PropertyBufferSize) PBYTE PropertyBuffer,
_Inout_ PULONG PropertyBufferSize,
_In_ ULONG ulFlags
_In_ ULONG ulFlags,
_In_opt_ HMACHINE hMachine
)
{
if (const auto _pfnCM_Get_DevNode_PropertyW = try_get_CM_Get_DevNode_PropertyW())
if (const auto _pfnCM_Get_DevNode_Property_ExW = try_get_CM_Get_DevNode_Property_ExW())
{
return _pfnCM_Get_DevNode_PropertyW(dnDevInst, PropertyKey, PropertyType, PropertyBuffer, PropertyBufferSize, ulFlags);
return _pfnCM_Get_DevNode_Property_ExW(dnDevInst, PropertyKey, PropertyType, PropertyBuffer, PropertyBufferSize, ulFlags, hMachine);
}

__WarningMessage__("Opt,Vista系统的setuapi.dll存在CM_Get_DevNode_Property_ExW,但是没有导出。");

if (!PropertyKey)
return CR_INVALID_DEVINST;

Expand All @@ -243,18 +292,18 @@ namespace YY::Thunks

if (!Fallback::DevNodeTempPropertyBufffer::HasTransform(_pProperty->PropertyType))
{
return CM_Get_DevNode_Registry_PropertyW(dnDevInst, _pProperty->CM_DeviceRegistryProperty, nullptr, PropertyBuffer, PropertyBufferSize, ulFlags);
return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, _pProperty->CM_DeviceRegistryProperty, nullptr, PropertyBuffer, PropertyBufferSize, ulFlags, hMachine);
}

Fallback::DevNodeTempPropertyBufffer TempBuffer = {};
ULONG _cbTempBuffer = sizeof(TempBuffer);
auto _Error = CM_Get_DevNode_Registry_PropertyW(dnDevInst, _pProperty->CM_DeviceRegistryProperty, nullptr, &TempBuffer, &_cbTempBuffer, ulFlags);
auto _Error = CM_Get_DevNode_Registry_Property_ExW(dnDevInst, _pProperty->CM_DeviceRegistryProperty, nullptr, &TempBuffer, &_cbTempBuffer, ulFlags, hMachine);
if (CR_SUCCESS != _Error)
{
return _Error;
}

if(!TempBuffer.TryTransformGetBuffer(_pProperty->PropertyType, PropertyBuffer, PropertyBufferSize))
if (!TempBuffer.TryTransformGetBuffer(_pProperty->PropertyType, PropertyBuffer, PropertyBufferSize))
return CR_BUFFER_SMALL;

return CR_SUCCESS;
Expand All @@ -264,26 +313,27 @@ namespace YY::Thunks

#if (YY_Thunks_Support_Version < NTDDI_WIN7)

// 最低受支持的客户端 在 Microsoft Windows Vista 和更高版本的 Windows 中可用。
// 实际Windows Vista RTM根本就没有这个接口
// Windows 7 RTM 导出
// Windows Vista有这个函数但是没有导出
__DEFINE_THUNK(
cfgmgr32,
24,
28,
CONFIGRET,
WINAPI,
CM_Set_DevNode_PropertyW,
CM_Set_DevNode_Property_ExW,
_In_ DEVINST dnDevInst,
_In_ CONST DEVPROPKEY *PropertyKey,
_In_ CONST DEVPROPKEY* PropertyKey,
_In_ DEVPROPTYPE PropertyType,
_In_reads_bytes_opt_(PropertyBufferSize) PBYTE PropertyBuffer,
_In_ ULONG PropertyBufferSize,
_In_ ULONG ulFlags
_In_ ULONG ulFlags,
_In_opt_ HMACHINE hMachine
)
{
if (const auto _pfnCM_Set_DevNode_PropertyW = try_get_CM_Set_DevNode_PropertyW())
if (const auto _pfnCM_Set_DevNode_Property_ExW = try_get_CM_Set_DevNode_Property_ExW())
{
return _pfnCM_Set_DevNode_PropertyW(dnDevInst, PropertyKey, PropertyType, PropertyBuffer, PropertyBufferSize, ulFlags);
}
return _pfnCM_Set_DevNode_Property_ExW(dnDevInst, PropertyKey, PropertyType, PropertyBuffer, PropertyBufferSize, ulFlags, hMachine);
}

if (!PropertyKey)
return CR_INVALID_DEVINST;
Expand All @@ -305,7 +355,63 @@ namespace YY::Thunks
if (!TempBuffer.TryTransformSetBuffer(PropertyType, &PropertyBuffer, &PropertyBufferSize))
return CR_BUFFER_SMALL;

return CM_Set_DevNode_Registry_PropertyW(dnDevInst, _pProperty->CM_DeviceRegistryProperty, PropertyBuffer, PropertyBufferSize, ulFlags);
return CM_Set_DevNode_Registry_Property_ExW(dnDevInst, _pProperty->CM_DeviceRegistryProperty, PropertyBuffer, PropertyBufferSize, ulFlags, hMachine);
}
#endif


#if (YY_Thunks_Support_Version < NTDDI_WIN7)

// 最低受支持的客户端 在 Microsoft Windows Vista 和更高版本的 Windows 中可用。
// 实际Windows Vista RTM根本就没有这个接口
__DEFINE_THUNK(
cfgmgr32,
24,
CONFIGRET,
WINAPI,
CM_Get_DevNode_PropertyW,
_In_ DEVINST dnDevInst,
_In_ CONST DEVPROPKEY* PropertyKey,
_Out_ DEVPROPTYPE* PropertyType,
_Out_writes_bytes_opt_(*PropertyBufferSize) PBYTE PropertyBuffer,
_Inout_ PULONG PropertyBufferSize,
_In_ ULONG ulFlags
)
{
if (const auto _pfnCM_Get_DevNode_PropertyW = try_get_CM_Get_DevNode_PropertyW())
{
return _pfnCM_Get_DevNode_PropertyW(dnDevInst, PropertyKey, PropertyType, PropertyBuffer, PropertyBufferSize, ulFlags);
}

return ::CM_Get_DevNode_Property_ExW(dnDevInst, PropertyKey, PropertyType, PropertyBuffer, PropertyBufferSize, ulFlags, nullptr);
}
#endif


#if (YY_Thunks_Support_Version < NTDDI_WIN7)

// 最低受支持的客户端 在 Microsoft Windows Vista 和更高版本的 Windows 中可用。
// 实际Windows Vista RTM根本就没有这个接口
__DEFINE_THUNK(
cfgmgr32,
24,
CONFIGRET,
WINAPI,
CM_Set_DevNode_PropertyW,
_In_ DEVINST dnDevInst,
_In_ CONST DEVPROPKEY *PropertyKey,
_In_ DEVPROPTYPE PropertyType,
_In_reads_bytes_opt_(PropertyBufferSize) PBYTE PropertyBuffer,
_In_ ULONG PropertyBufferSize,
_In_ ULONG ulFlags
)
{
if (const auto _pfnCM_Set_DevNode_PropertyW = try_get_CM_Set_DevNode_PropertyW())
{
return _pfnCM_Set_DevNode_PropertyW(dnDevInst, PropertyKey, PropertyType, PropertyBuffer, PropertyBufferSize, ulFlags);
}

return ::CM_Set_DevNode_Property_ExW(dnDevInst, PropertyKey, PropertyType, PropertyBuffer, PropertyBufferSize, ulFlags, nullptr);
}
#endif
}
21 changes: 14 additions & 7 deletions src/Thunks/YY_Thunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1117,15 +1117,10 @@ static HMODULE __fastcall try_get_module(volatile HMODULE* pModule, const wchar_
return new_handle;
}

static __forceinline void* __fastcall try_get_proc_address_from_first_available_module(
const ProcInfo& _ProcInfo
static __forceinline void* __fastcall try_get_proc_address_from_dll(
const ProcInfo& _ProcInfo
) noexcept
{
if (_ProcInfo.pfnCustomGetProcAddress)
{
return _ProcInfo.pfnCustomGetProcAddress(_ProcInfo);
}

HMODULE const module_handle = _ProcInfo.pfnGetModule();
if (!module_handle)
{
Expand Down Expand Up @@ -1155,3 +1150,15 @@ static __forceinline void* __fastcall try_get_proc_address_from_first_available_
return reinterpret_cast<void*>(GetProcAddress(module_handle, _ProcInfo.szProcName));
#endif // defined(__USING_NTDLL_LIB)
}

static __forceinline void* __fastcall try_get_proc_address_from_first_available_module(
const ProcInfo& _ProcInfo
) noexcept
{
if (_ProcInfo.pfnCustomGetProcAddress)
{
return _ProcInfo.pfnCustomGetProcAddress(_ProcInfo);
}

return try_get_proc_address_from_dll(_ProcInfo);
}
51 changes: 51 additions & 0 deletions src/Thunks/YY_Thunks.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,16 @@ static PVOID __fastcall YY_ImageDirectoryEntryToData(
return PBYTE(pBaseAddress) + _DataDirectory.VirtualAddress;
}

static DWORD __fastcall GetDllTimeDateStamp(_In_ HMODULE _hModule)
{
if (!_hModule)
return 0;

auto _pDosHeader = (PIMAGE_DOS_HEADER)_hModule;
auto _pNtHerder = reinterpret_cast<PIMAGE_NT_HEADERS>(PBYTE(_hModule) + _pDosHeader->e_lfanew);
return _pNtHerder->FileHeader.TimeDateStamp;
}

enum : int
{
__crt_maximum_pointer_shift = sizeof(uintptr_t) * 8
Expand Down Expand Up @@ -329,6 +339,47 @@ static __forceinline void* __fastcall try_get_proc_address_from_first_available_
const ProcInfo& _ProcInfo
) noexcept;

static __forceinline void* __fastcall try_get_proc_address_from_dll(
const ProcInfo& _ProcInfo
) noexcept;

struct ProcOffsetInfo
{
DWORD uTimeDateStamp;
DWORD uProcOffset;
};

template<size_t kLength>
static __forceinline void* __fastcall try_get_proc_address_from_offset(
HMODULE _hModule,
const ProcOffsetInfo (&_ProcOffsetInfos)[kLength]
) noexcept
{
if (_hModule)
{
__try
{
const auto _uTimeDateStamp = GetDllTimeDateStamp(_hModule);
if (_uTimeDateStamp)
{
for (auto& _ProcOffsetInfo : _ProcOffsetInfos)
{
if (_ProcOffsetInfo.uTimeDateStamp == _uTimeDateStamp)
{
return PBYTE(_hModule) + _ProcOffsetInfo.uProcOffset;
}
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
// 避免遇到畸形DLL而触发异常。
}
}

return nullptr;
}

static __forceinline void* __cdecl invalid_function_sentinel() noexcept
{
return reinterpret_cast<void*>(static_cast<uintptr_t>(-1));
Expand Down
5 changes: 5 additions & 0 deletions src/Thunks/api-ms-win-core-handle.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@

#if (YY_Thunks_Support_Version < NTDDI_WIN10) && !defined(__Comment_Lib_advapi32)
#define __Comment_Lib_advapi32
#pragma comment(lib, "Advapi32.lib")
#endif

#if defined(YY_Thunks_Implemented)
namespace YY::Thunks
{
Expand Down
Loading

0 comments on commit 0be59db

Please sign in to comment.