Skip to content

Commit

Permalink
Opt, NtOpenKeyEx REG_OPTION_OPEN_LINK场景下减少Nt API调用次数
Browse files Browse the repository at this point in the history
  • Loading branch information
mingkuang-Chuyu committed Jun 16, 2024
1 parent 85149a6 commit ad7b7de
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 35 deletions.
2 changes: 2 additions & 0 deletions src/Thunks/CfgMgr32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
86 changes: 51 additions & 35 deletions src/Thunks/ntdll.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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;
}
Expand Down

0 comments on commit ad7b7de

Please sign in to comment.