Skip to content

Commit

Permalink
Fea #90,补充一些Chrome 125 Windows 7缺少的接口
Browse files Browse the repository at this point in the history
  • Loading branch information
mingkuang-Chuyu committed Jun 7, 2024
1 parent ea07bce commit 5e2649f
Show file tree
Hide file tree
Showing 9 changed files with 1,083 additions and 539 deletions.
17 changes: 17 additions & 0 deletions src/Shared/km.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@

#define NtGetCurrentProcess() (HANDLE)-1

#define NtGetCurrentThread() (HANDLE)-2

// begin_access
#define DUPLICATE_CLOSE_SOURCE 0x00000001
#define DUPLICATE_SAME_ACCESS 0x00000002
Expand Down Expand Up @@ -1580,6 +1582,21 @@ NtQueryDirectoryFile (

};

typedef struct _OBJECT_BASIC_INFORMATION
{
ULONG Attributes;
ACCESS_MASK GrantedAccess;
ULONG HandleCount;
ULONG PointerCount;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG Reserved[3];
ULONG NameInfoSize;
ULONG TypeInfoSize;
ULONG SecurityDescriptorSize;
LARGE_INTEGER CreationTime;
} OBJECT_BASIC_INFORMATION, * POBJECT_BASIC_INFORMATION;

typedef struct _OBJECT_NAME_INFORMATION
{
UNICODE_STRING Name;
Expand Down
2 changes: 2 additions & 0 deletions src/Thunks/YY_Thunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
_APPLY(dwmapi, "dwmapi" , 0 ) \
_APPLY(d3d9, "d3d9" , 0 ) \
_APPLY(d3d11, "d3d11" , 0 ) \
_APPLY(d3d12, "d3d12" , 0 ) \
_APPLY(dbghelp, "dbghelp" , USING_UNSAFE_LOAD ) \
_APPLY(dxgi, "dxgi" , 0 ) \
_APPLY(dwrite, "dwrite" , 0 ) \
Expand Down Expand Up @@ -38,6 +39,7 @@
_APPLY(wevtapi, "wevtapi" , 0 ) \
_APPLY(winhttp, "winhttp" , 0 ) \
_APPLY(zipfldr, "zipfldr" , LOAD_AS_DATA_FILE ) \
_APPLY(api_ms_win_core_handle_l1_1_0, "api-ms-win-core-handle-l1-1-0" , 0 ) \
_APPLY(api_ms_win_core_realtime_l1_1_1, "api-ms-win-core-realtime-l1-1-1" , 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 ) \
Expand Down
275 changes: 275 additions & 0 deletions src/Thunks/api-ms-win-core-handle.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@

#if defined(YY_Thunks_Implemented)
namespace YY::Thunks
{
namespace
{
#if (YY_Thunks_Support_Version < NTDDI_WIN10)
static SRWLOCK g_CompareObjectHandles;
#endif
}
}
#endif

namespace YY::Thunks
{

#if (YY_Thunks_Support_Version < NTDDI_WIN10)

// 最低受支持的客户端 Windows 2000 专业版 [桌面应用 |UWP 应用]
// 最低受支持的服务器 Windows 2000 Server[桌面应用 | UWP 应用]
// 虽然2000就支持,但是为了实现CompareObjectHandles,目前需要处理一下关闭。
__DEFINE_THUNK(
kernel32,
4,
BOOL,
WINAPI,
CloseHandle,
_In_ _Post_ptr_invalid_ HANDLE _hObject
)
{
const auto _pfnCloseHandle = try_get_CloseHandle();
const auto _pfnCompareObjectHandles = try_get_CompareObjectHandles();

if (_pfnCompareObjectHandles == nullptr && _hObject && _hObject != INVALID_HANDLE_VALUE)
{
::AcquireSRWLockShared(&g_CompareObjectHandles);
}
// 空指针故意崩溃
auto _bRet = _pfnCloseHandle(_hObject);

if (_pfnCompareObjectHandles == nullptr && _hObject && _hObject != INVALID_HANDLE_VALUE)
{
auto _lStatus = GetLastError();
::ReleaseSRWLockShared(&g_CompareObjectHandles);
SetLastError(_lStatus);
}

return _bRet;
}
#endif


#if (YY_Thunks_Support_Version < NTDDI_WIN10)

// 最低受支持的客户端 Windows 2000 专业版 [桌面应用 |UWP 应用]
// 最低受支持的服务器 Windows 2000 Server[桌面应用 | UWP 应用]
// 虽然2000就支持,但是为了实现CompareObjectHandles,目前需要处理一下关闭。
__DEFINE_THUNK(
kernel32,
28,
BOOL,
WINAPI,
DuplicateHandle,
_In_ HANDLE _hSourceProcessHandle,
_In_ HANDLE _hSourceHandle,
_In_ HANDLE _hTargetProcessHandle,
_Outptr_ LPHANDLE _phTargetHandle,
_In_ DWORD _fDesiredAccess,
_In_ BOOL _bInheritHandle,
_In_ DWORD _uOptions
)
{
const auto _pfnDuplicateHandle = try_get_DuplicateHandle();
const auto _pfnCompareObjectHandles = try_get_CompareObjectHandles();

bool _bNeedLock = false;
if (_pfnCompareObjectHandles)
{
// 无须加锁
}
if (_hTargetProcessHandle == NtGetCurrentProcess() || GetProcessId(_hTargetProcessHandle) == GetCurrentProcessId())
{
_bNeedLock = true;
}
else if ((DUPLICATE_CLOSE_SOURCE & _uOptions)
&& (_hSourceProcessHandle == NtGetCurrentProcess() || GetProcessId(_hSourceProcessHandle) == GetCurrentProcessId()))
{
_bNeedLock = true;
}

if (_bNeedLock)
{
::AcquireSRWLockShared(&g_CompareObjectHandles);
}

// 空指针故意崩溃
auto _bRet = _pfnDuplicateHandle(_hSourceProcessHandle, _hSourceHandle, _hTargetProcessHandle, _phTargetHandle, _fDesiredAccess, _bInheritHandle, _uOptions);

if (_bNeedLock)
{
auto _lStatus = GetLastError();
::ReleaseSRWLockShared(&g_CompareObjectHandles);
SetLastError(_lStatus);
}
return _bRet;
}
#endif

#if (YY_Thunks_Support_Version < NTDDI_WIN10)

// 最低受支持的客户端 Windows 10 [桌面应用 |UWP 应用]
// 最低受支持的服务器 Windows Server 2016[桌面应用 | UWP 应用]
__DEFINE_THUNK(
api_ms_win_core_handle_l1_1_0,
8,
BOOL,
WINAPI,
CompareObjectHandles,
_In_ HANDLE _hFirstObjectHandle,
_In_ HANDLE _hSecondObjectHandle
)
{
if (const auto _pfnCompareObjectHandles = try_get_CompareObjectHandles())
{
return _pfnCompareObjectHandles(_hFirstObjectHandle, _hSecondObjectHandle);
}

if (_hFirstObjectHandle == _hSecondObjectHandle)
{
if (NtGetCurrentProcess() == _hFirstObjectHandle
|| NtGetCurrentThread() == _hFirstObjectHandle)
{
return TRUE;
}

const auto _pfnNtQueryObject = try_get_NtQueryObject();
if (!_pfnNtQueryObject)
return FALSE;

// 用来检测句柄是否合法
OBJECT_BASIC_INFORMATION _FirstObjectBaseInfo = {};
LONG _Status = _pfnNtQueryObject(_hFirstObjectHandle, ObjectBasicInformation, &_FirstObjectBaseInfo, sizeof(_FirstObjectBaseInfo), nullptr);
if (_Status < 0)
{
return FALSE;
}
return TRUE;
}

const auto _pfnNtQueryObject = try_get_NtQueryObject();
if (!_pfnNtQueryObject)
return FALSE;

OBJECT_BASIC_INFORMATION _FirstObjectBaseInfo = {};
OBJECT_BASIC_INFORMATION _SecondObjectBaseInfo = {};
LONG _Status = _pfnNtQueryObject(_hFirstObjectHandle, ObjectBasicInformation, &_FirstObjectBaseInfo, sizeof(_FirstObjectBaseInfo), nullptr);

// 实际测试,ObjectBasicInformation 只出现无效句柄错误
if (_Status < 0)
{
return FALSE;
}

if (_FirstObjectBaseInfo.HandleCount == 1)
{
// 引用计数为 1,这肯定不可能与另外一个句柄是同一个内核对象
return FALSE;
}

_Status = _pfnNtQueryObject(_hSecondObjectHandle, ObjectBasicInformation, &_SecondObjectBaseInfo, sizeof(_SecondObjectBaseInfo), nullptr);
if (_Status < 0)
{
return FALSE;
}

if (_SecondObjectBaseInfo.HandleCount == 1)
{
// 引用计数为 1,这肯定不可能与另外一个句柄是同一个内核对象
return FALSE;
}

if (_FirstObjectBaseInfo.NameInfoSize != _SecondObjectBaseInfo.NameInfoSize
|| _FirstObjectBaseInfo.TypeInfoSize != _SecondObjectBaseInfo.TypeInfoSize
|| _FirstObjectBaseInfo.SecurityDescriptorSize != _SecondObjectBaseInfo.SecurityDescriptorSize
|| _FirstObjectBaseInfo.CreationTime.QuadPart != _SecondObjectBaseInfo.CreationTime.QuadPart)
{
return FALSE;
}

const auto _pfnDuplicateHandle = try_get_DuplicateHandle();
const auto _pfnCloseHandle = try_get_CloseHandle();

if (_pfnDuplicateHandle == nullptr || _pfnCloseHandle == nullptr)
return FALSE;

HANDLE _hFirstTmp = NULL;
BOOL _bHandleIsSame = FALSE;

::AcquireSRWLockExclusive(&g_CompareObjectHandles);

for (;;)
{
if (!_pfnDuplicateHandle(NtGetCurrentProcess(), _hFirstObjectHandle, NtGetCurrentProcess(), &_hFirstTmp, 0, FALSE, 0))
{
break;
}

_Status = _pfnNtQueryObject(_hFirstObjectHandle, ObjectBasicInformation, &_FirstObjectBaseInfo, sizeof(_FirstObjectBaseInfo), nullptr);

// 实际测试,ObjectBasicInformation 只出现无效句柄错误
if (_Status < 0)
{
break;
}

if (_FirstObjectBaseInfo.HandleCount == 1)
{
// 引用计数为 1,这肯定不可能与另外一个句柄是同一个内核对象
break;
}

_Status = _pfnNtQueryObject(_hSecondObjectHandle, ObjectBasicInformation, &_SecondObjectBaseInfo, sizeof(_SecondObjectBaseInfo), nullptr);
if (_Status < 0)
{
break;
}

if (_SecondObjectBaseInfo.HandleCount != _FirstObjectBaseInfo.HandleCount)
{
// 引用计数为 1,这肯定不可能与另外一个句柄是同一个内核对象
break;
}

_pfnCloseHandle(_hFirstTmp);
_hFirstTmp = NULL;

_Status = _pfnNtQueryObject(_hFirstObjectHandle, ObjectBasicInformation, &_FirstObjectBaseInfo, sizeof(_FirstObjectBaseInfo), nullptr);

// 实际测试,ObjectBasicInformation 只出现无效句柄错误
if (_Status < 0)
{
break;
}

if (_FirstObjectBaseInfo.HandleCount == 1)
{
// 引用计数为 1,这肯定不可能与另外一个句柄是同一个内核对象
break;
}

_Status = _pfnNtQueryObject(_hSecondObjectHandle, ObjectBasicInformation, &_SecondObjectBaseInfo, sizeof(_SecondObjectBaseInfo), nullptr);
if (_Status < 0)
{
break;
}

if (_SecondObjectBaseInfo.HandleCount != _FirstObjectBaseInfo.HandleCount)
{
// 引用计数为 1,这肯定不可能与另外一个句柄是同一个内核对象
break;
}

_bHandleIsSame = TRUE;
break;
}

::ReleaseSRWLockExclusive(&g_CompareObjectHandles);

if(_hFirstTmp)
_pfnCloseHandle(_hFirstTmp);

return _bHandleIsSame;
}
#endif
}
Loading

0 comments on commit 5e2649f

Please sign in to comment.