From ad7b7de10ce49221091f3a34a42bc1f1635e30aa Mon Sep 17 00:00:00 2001 From: mingkuang Date: Sun, 16 Jun 2024 10:34:41 +0800 Subject: [PATCH] =?UTF-8?q?Opt,=20NtOpenKeyEx=20REG=5FOPTION=5FOPEN=5FLINK?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=E4=B8=8B=E5=87=8F=E5=B0=91Nt=20API=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E6=AC=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Thunks/CfgMgr32.hpp | 2 + src/Thunks/ntdll.hpp | 86 ++++++++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/src/Thunks/CfgMgr32.hpp b/src/Thunks/CfgMgr32.hpp index 93db5c9..6b5ebc4 100644 --- a/src/Thunks/CfgMgr32.hpp +++ b/src/Thunks/CfgMgr32.hpp @@ -224,6 +224,8 @@ namespace YY::Thunks return _pfnCM_Get_DevNode_PropertyW(dnDevInst, PropertyKey, PropertyType, PropertyBuffer, PropertyBufferSize, ulFlags); } + __WarningMessage__("Opt,Vista系统的setuapi.dll存在CM_Get_DevNode_Property_ExW,但是没有导出。"); + if (!PropertyKey) return CR_INVALID_DEVINST; diff --git a/src/Thunks/ntdll.hpp b/src/Thunks/ntdll.hpp index 4324e96..df68bc9 100644 --- a/src/Thunks/ntdll.hpp +++ b/src/Thunks/ntdll.hpp @@ -20,14 +20,16 @@ return _pfnNtCancelIoFileEx(handle, io, io_status); } - // 最坏打算,清除所有的调用 - if (const auto _pfnNtCancelIoFile = try_get_NtCancelIoFile()) +#ifndef __USING_NTDLL_LIB + const auto NtCancelIoFile = try_get_NtCancelIoFile(); + if(!NtCancelIoFile) { - return _pfnNtCancelIoFile(handle, io_status); + // 正常来说不应该走到这里 + return STATUS_NOT_SUPPORTED; } - - // 正常来说不应该走到这里 - return STATUS_NOT_SUPPORTED; +#endif + // 最坏打算,清除所有的调用 + return NtCancelIoFile(handle, io_status); } #endif @@ -41,69 +43,83 @@ NTSTATUS, NTAPI, NtOpenKeyEx, - __out PHANDLE KeyHandle, - __in ACCESS_MASK DesiredAccess, - __in POBJECT_ATTRIBUTES ObjectAttributes, - __in ULONG OpenOptions + __out PHANDLE _phKeyHandle, + __in ACCESS_MASK _fDesiredAccess, + __in POBJECT_ATTRIBUTES _pObjectAttributes, + __in ULONG _fOpenOptions ) { if (const auto _pfnNtOpenKeyEx = try_get_NtOpenKeyEx()) { - return _pfnNtOpenKeyEx(KeyHandle, DesiredAccess, ObjectAttributes, OpenOptions); + return _pfnNtOpenKeyEx(_phKeyHandle, _fDesiredAccess, _pObjectAttributes, _fOpenOptions); } - const auto _pfnNtOpenKey = try_get_NtOpenKey(); - if (!_pfnNtOpenKey) +#ifndef __USING_NTDLL_LIB + const auto NtOpenKey = try_get_NtOpenKey(); + if (!NtOpenKey) { // 正常来说不应该走到这里,XP存在此函数 return STATUS_NOT_SUPPORTED; } +#endif - if (OpenOptions == 0) - { - return _pfnNtOpenKey(KeyHandle, DesiredAccess, ObjectAttributes); - } + if (_fOpenOptions & (~(REG_OPTION_OPEN_LINK | REG_OPTION_BACKUP_RESTORE))) + return STATUS_INVALID_PARAMETER_4; - if (OpenOptions & (~(REG_OPTION_OPEN_LINK | REG_OPTION_BACKUP_RESTORE))) + OBJECT_ATTRIBUTES _ObjectAttributes; + if (_fOpenOptions & REG_OPTION_OPEN_LINK) { - return STATUS_INVALID_PARAMETER_4; + __try + { + // 避免 ObjectAttributes 指针非法 + // 我们抓异常为了模拟原版函数行为,内存无效时可以返回错误代码。 + _ObjectAttributes = *_pObjectAttributes; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return GetExceptionCode(); + } + + _ObjectAttributes.Attributes |= OBJ_OPENLINK; + _pObjectAttributes = &_ObjectAttributes; } - const auto _pfnNtCreateKey = try_get_NtCreateKey(); - const auto _pfnNtDeleteKey = try_get_NtDeleteKey(); - const auto _pfnNtClose = try_get_NtClose(); - if (_pfnNtCreateKey == nullptr || _pfnNtDeleteKey == nullptr || _pfnNtClose == nullptr) - { + if ((_fOpenOptions & REG_OPTION_BACKUP_RESTORE) == 0) + return NtOpenKey(_phKeyHandle, _fDesiredAccess, _pObjectAttributes); + +#ifndef __USING_NTDLL_LIB + const auto NtCreateKey = try_get_NtCreateKey(); + const auto NtDeleteKey = try_get_NtDeleteKey(); + const auto NtClose = try_get_NtClose(); + if (NtCreateKey == nullptr || NtDeleteKey == nullptr || NtClose == nullptr) return STATUS_NOT_SUPPORTED; - } +#endif - // 先测试一下 Key在不在 + // 先测试一下 Key在不在,如果确定不在就没有必要继续了。 HANDLE _hKey = NULL; - LONG _Status = _pfnNtOpenKey(&_hKey, DesiredAccess, ObjectAttributes); + LONG _Status = NtOpenKey(&_hKey, STANDARD_RIGHTS_READ, _pObjectAttributes); if (_Status < 0 && _Status != STATUS_ACCESS_DENIED) - { return _Status; - } do { ULONG Disposition; - _Status = _pfnNtCreateKey(KeyHandle, DesiredAccess, ObjectAttributes, 0, nullptr, OpenOptions, &Disposition); + _Status = NtCreateKey(_phKeyHandle, _fDesiredAccess, _pObjectAttributes, 0, nullptr, REG_OPTION_BACKUP_RESTORE, &Disposition); if (_Status < 0) break; if (Disposition == REG_CREATED_NEW_KEY) { - // 新建的话就重新删除 - _pfnNtDeleteKey(*KeyHandle); - _pfnNtClose(*KeyHandle); - *KeyHandle = NULL; + // 新建的话就重新删除,毕竟NtOpenKeyEx是没有创建功能的。 + NtDeleteKey(*_phKeyHandle); + NtClose(*_phKeyHandle); + *_phKeyHandle = NULL; _Status = STATUS_OBJECT_NAME_NOT_FOUND; } } while (false); if(_hKey) - _pfnNtClose(_hKey); + NtClose(_hKey); return _Status; }