[*] Further drop required symbols from OLE (COM) and SHELL32 (NT Shell)

[*] Optimize NT file and URI opener
This commit is contained in:
Reece Wilson 2023-09-17 21:33:14 +01:00
parent c5a2d1e582
commit 9be76adb23
5 changed files with 170 additions and 70 deletions

View File

@ -36,6 +36,7 @@ namespace Aurora
ADD_LOAD_LIB(DbgHelper); ADD_LOAD_LIB(DbgHelper);
ADD_LOAD_LIB(WinTrust); ADD_LOAD_LIB(WinTrust);
ADD_LOAD_LIB(IPHelper); ADD_LOAD_LIB(IPHelper);
ADD_LOAD_LIB(COM);
#define ADD_GET_PROC(name, proc) \ #define ADD_GET_PROC(name, proc) \
if (h ## name) \ if (h ## name) \
@ -156,8 +157,15 @@ namespace Aurora
ADD_GET_PROC(BCrypt, BCryptGenRandom) ADD_GET_PROC(BCrypt, BCryptGenRandom)
ADD_GET_PROC(Theme, SetWindowTheme) ADD_GET_PROC(Theme, SetWindowTheme)
ADD_GET_PROC(COM, CoInitializeEx)
ADD_GET_PROC(COM, CoUninitialize)
ADD_GET_PROC(COM, CoTaskMemFree)
ADD_GET_PROC(Shell, SHGetKnownFolderPath) ADD_GET_PROC(Shell, SHGetKnownFolderPath)
ADD_GET_PROC(Shell, SHGetFolderPathA)
ADD_GET_PROC(Shell, CommandLineToArgvW)
ADD_GET_PROC(Shell, ShellExecuteW)
if (pNtCreateKeyedEvent && if (pNtCreateKeyedEvent &&

View File

@ -51,6 +51,7 @@ namespace Aurora
static const wchar_t *kDbgHelperDllName { L"dbghelp.dll" }; static const wchar_t *kDbgHelperDllName { L"dbghelp.dll" };
static const wchar_t *kWinTrustDllName { L"WINTRUST.dll" }; static const wchar_t *kWinTrustDllName { L"WINTRUST.dll" };
static const wchar_t *kIPHelperDllName { L"IPHLPAPI.dll" }; static const wchar_t *kIPHelperDllName { L"IPHLPAPI.dll" };
static const wchar_t *kCOMDllName { L"ole32.dll" };
struct WIN32_MEMORY_RANGE_ENTRY2 struct WIN32_MEMORY_RANGE_ENTRY2
{ {
@ -411,13 +412,6 @@ namespace Aurora
HANDLE hThread HANDLE hThread
); );
inline HRESULT(__stdcall *pSHGetKnownFolderPath)(
const GUID & rfid,
DWORD dwFlags,
HANDLE hToken,
PWSTR * ppszPath
);
// dbghelp // dbghelp
inline DWORD(__stdcall *pUnDecorateSymbolName)( inline DWORD(__stdcall *pUnDecorateSymbolName)(
@ -507,18 +501,62 @@ namespace Aurora
// IP Helper // IP Helper
inline ULONG(__stdcall *pGetAdaptersAddresses)( inline ULONG(__stdcall *pGetAdaptersAddresses)(
ULONG Family, ULONG Family,
ULONG Flags, ULONG Flags,
PVOID Reserved, PVOID Reserved,
IP_ADAPTER_ADDRESSES *AdapterAddresses, IP_ADAPTER_ADDRESSES * AdapterAddresses,
PULONG SizePointer PULONG SizePointer
); );
inline ULONG(__stdcall *pGetAdaptersInfo)( inline ULONG(__stdcall *pGetAdaptersInfo)(
_IP_ADAPTER_INFO * AdapterInfo, _IP_ADAPTER_INFO * AdapterInfo,
PULONG SizePointer PULONG SizePointer
); );
// COM
inline HRESULT(__stdcall *pCoInitializeEx)(
LPVOID pvReserved,
DWORD dwCoInit
);
inline void(__stdcall *pCoTaskMemFree)(
LPVOID pv
);
inline void(__stdcall *pCoUninitialize)();
// Shell
inline HRESULT(__stdcall *pSHGetKnownFolderPath)(
const GUID &rfid,
DWORD dwFlags,
HANDLE hToken,
PWSTR *ppszPath
);
inline HINSTANCE(__stdcall *pShellExecuteW)(
HWND hwnd,
LPCWSTR lpOperation,
LPCWSTR lpFile,
LPCWSTR lpParameters,
LPCWSTR lpDirectory,
INT nShowCmd
);
inline HRESULT(__stdcall *pSHGetFolderPathA)(
HWND hwnd,
int csidl,
HANDLE hToken,
DWORD dwFlags,
LPSTR pszPath
);
inline LPWSTR *(__stdcall *pCommandLineToArgvW)(
LPCWSTR lpCmdLine,
int * pNumArgs
);
inline bool gUseNativeWaitMutex {}; inline bool gUseNativeWaitMutex {};
inline bool gUseNativeWaitCondvar {}; inline bool gUseNativeWaitCondvar {};
inline bool gUseNativeWaitSemapahore {}; inline bool gUseNativeWaitSemapahore {};

View File

@ -77,8 +77,13 @@ namespace Aurora::CmdLine
#if defined(AURORA_PLATFORM_WIN32) #if defined(AURORA_PLATFORM_WIN32)
if (!pCommandLineToArgvW)
{
return {};
}
int count {}; int count {};
auto temp = CommandLineToArgvW(cmd, &count); auto temp = pCommandLineToArgvW(cmd, &count);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {

View File

@ -140,32 +140,55 @@ namespace Aurora::IO::FS
return {}; return {};
} }
static AuString GetSpecialDirOldOS(REFKNOWNFOLDERID rfid)
{
if (!pSHGetFolderPathA)
{
return "";
}
if (auto opt = GUIDTOCISL(rfid))
{
AuString temp(MAX_PATH, '\x00');
if (pSHGetFolderPathA(0, *opt, 0, 0, temp.data()) == S_OK)
{
return temp;
}
}
else
{
return "";
}
}
static AuString GetSpecialDir(REFKNOWNFOLDERID rfid) static AuString GetSpecialDir(REFKNOWNFOLDERID rfid)
{ {
PWSTR directory; PWSTR directory;
if (!pSHGetKnownFolderPath) if (!pSHGetKnownFolderPath)
{ {
if (auto opt = GUIDTOCISL(rfid)) return GetSpecialDirOldOS(rfid);
{
AuString temp(MAX_PATH, '\x00');
if (SHGetFolderPathA(0, *opt, 0, 0, temp.data()) == S_OK)
{
return temp;
}
}
return "";
} }
if (pSHGetKnownFolderPath(rfid, KF_FLAG_DEFAULT, NULL, &directory) != S_OK) if (pSHGetKnownFolderPath(rfid, KF_FLAG_DEFAULT, NULL, &directory) != S_OK)
{ {
AuString str;
if ((str = GetSpecialDirOldOS(rfid)).size())
{
return str;
}
SysPanic("Couldn't get known special directory path of [MS:{}-{}-{}-{}{}{}{}{}{}{}{}] with a NULL access token", SysPanic("Couldn't get known special directory path of [MS:{}-{}-{}-{}{}{}{}{}{}{}{}] with a NULL access token",
rfid.Data1, rfid.Data2, rfid.Data3, rfid.Data4[0], rfid.Data4[1], rfid.Data4[2], rfid.Data4[3], rfid.Data4[4], rfid.Data4[5], rfid.Data4[6], rfid.Data4[7]); rfid.Data1, rfid.Data2, rfid.Data3, rfid.Data4[0], rfid.Data4[1], rfid.Data4[2], rfid.Data4[3], rfid.Data4[4], rfid.Data4[5], rfid.Data4[6], rfid.Data4[7]);
} }
auto ret = Locale::ConvertFromWChar(directory); auto ret = Locale::ConvertFromWChar(directory);
CoTaskMemFree(directory); if (pCoTaskMemFree)
{
pCoTaskMemFree(directory);
}
return ret; return ret;
} }

View File

@ -8,17 +8,14 @@
#include <Source/RuntimeInternal.hpp> #include <Source/RuntimeInternal.hpp>
#include "AuProcesses.hpp" #include "AuProcesses.hpp"
#include "AuOpen.Win32.hpp" #include "AuOpen.Win32.hpp"
#include <shellapi.h>
#include <tlhelp32.h>
#include <Source/IO/FS/FS.hpp> #include <Source/IO/FS/FS.hpp>
#include "Objbase.h"
#include "shellapi.h" #define COINIT_APARTMENTTHREADED 0x2
#define COINIT_DISABLE_OLE1DDE 0x4
namespace Aurora::Processes namespace Aurora::Processes
{ {
static AuList<AuString> gOpenItems; static AuList<AuPair<AuString, bool>> gOpenItems;
static AuThreadPrimitives::ConditionMutex gCondMutex; static AuThreadPrimitives::ConditionMutex gCondMutex;
static AuThreadPrimitives::ConditionVariable gCondVariable(AuUnsafeRaiiToShared(gCondMutex.AsPointer())); static AuThreadPrimitives::ConditionVariable gCondVariable(AuUnsafeRaiiToShared(gCondMutex.AsPointer()));
static AuThreads::ThreadUnique_t gOpenerThread; static AuThreads::ThreadUnique_t gOpenerThread;
@ -31,17 +28,61 @@ namespace Aurora::Processes
{ {
try try
{ {
for (const auto &open : gOpenItems) for (const auto &[uri, type] : gOpenItems)
{ {
if (open.empty()) continue; // [*1] bool bDirExists {};
bool bFileExists {};
ShellExecuteW(nullptr, if (uri.empty())
AuIOFS::DirExists(open) ? L"explore" : L"open", {
Locale::ConvertFromUTF8(open).c_str(), continue;
nullptr, }
nullptr,
SW_SHOWNORMAL); if (!pShellExecuteW)
{
SysPushErrorUninitialized("Cannot open URIs yet");
continue;
}
bFileExists = AuIOFS::FileExists(uri);
if (!type)
{
bDirExists = AuIOFS::DirExists(uri);
if (!bFileExists &&
!bDirExists)
{
SysPushErrorGeneric("Exploit attempt? Attempted to open non-existent file/directory. (request: {})", uri);
continue;
}
if (bFileExists)
{
if (!AuFS::IsFileBlocked(uri))
{
SysPushErrorGeneric("Exploit attempt? Attempted to open untrusted file/directory. (request: {})", uri);
continue;
}
}
}
else
{
if (bFileExists)
{
SysPushErrorGeneric("Exploit attempt? Attempted to open existing file/directory via URI ({})", uri);
continue;
}
}
pShellExecuteW(nullptr,
bDirExists ? L"explore" : L"open",
Locale::ConvertFromUTF8(uri).c_str(),
nullptr,
nullptr,
SW_SHOWNORMAL);
} }
gOpenItems.clear(); gOpenItems.clear();
gCondVariable->WaitForSignal(); gCondVariable->WaitForSignal();
} }
@ -55,9 +96,17 @@ namespace Aurora::Processes
static void OpenerThread() static void OpenerThread()
{ {
(void)CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (pCoInitializeEx)
{
(void)pCoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
}
RunTasks(); RunTasks();
CoUninitialize();
if (pCoUninitialize)
{
pCoUninitialize();
}
} }
void InitWin32Opener() void InitWin32Opener()
@ -81,21 +130,14 @@ namespace Aurora::Processes
AUKN_SYM void OpenUri(const AuString &uri) AUKN_SYM void OpenUri(const AuString &uri)
{ {
if (AuFS::FileExists(uri))
{
SysPushErrorGeneric("Exploit attempt? Attempted to open existing file/directory via URI ({})", uri);
return;
}
AU_LOCK_GUARD(gCondMutex); AU_LOCK_GUARD(gCondMutex);
AuTryInsert(gOpenItems, uri); AuTryInsert(gOpenItems, AuMakePair(uri, true));
gCondVariable->Signal(); gCondVariable->Signal();
} }
AUKN_SYM void OpenFile(const AuString &file) AUKN_SYM void OpenFile(const AuString &file)
{ {
auto path = AuIOFS::NormalizePathRet(file); auto path = AuIOFS::NormalizePathRet(file);
bool bFileExists {};
if (path.empty()) if (path.empty())
{ {
@ -103,25 +145,9 @@ namespace Aurora::Processes
return; return;
} }
if (!(bFileExists = AuFS::FileExists(path)) &&
!AuFS::DirExists(path))
{
SysPushErrorGeneric("Exploit attempt? Attempted to open non-existent file/directory. (request: {})", file);
return;
}
if (bFileExists)
{
if (!AuFS::IsFileBlocked(path))
{
SysPushErrorGeneric("Exploit attempt? Attempted to open untrusted file/directory. (request: {})", file);
return;
}
}
{ {
AU_LOCK_GUARD(gCondMutex); AU_LOCK_GUARD(gCondMutex);
AuTryInsert(gOpenItems, AuMove(path)); AuTryInsert(gOpenItems, AuMove(AuMakePair(AuMove(path), false)));
gCondVariable->Signal(); gCondVariable->Signal();
} }
} }