[*] 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(WinTrust);
ADD_LOAD_LIB(IPHelper);
ADD_LOAD_LIB(COM);
#define ADD_GET_PROC(name, proc) \
if (h ## name) \
@ -157,7 +158,14 @@ namespace Aurora
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, SHGetFolderPathA)
ADD_GET_PROC(Shell, CommandLineToArgvW)
ADD_GET_PROC(Shell, ShellExecuteW)
if (pNtCreateKeyedEvent &&

View File

@ -51,6 +51,7 @@ namespace Aurora
static const wchar_t *kDbgHelperDllName { L"dbghelp.dll" };
static const wchar_t *kWinTrustDllName { L"WINTRUST.dll" };
static const wchar_t *kIPHelperDllName { L"IPHLPAPI.dll" };
static const wchar_t *kCOMDllName { L"ole32.dll" };
struct WIN32_MEMORY_RANGE_ENTRY2
{
@ -411,13 +412,6 @@ namespace Aurora
HANDLE hThread
);
inline HRESULT(__stdcall *pSHGetKnownFolderPath)(
const GUID & rfid,
DWORD dwFlags,
HANDLE hToken,
PWSTR * ppszPath
);
// dbghelp
inline DWORD(__stdcall *pUnDecorateSymbolName)(
@ -510,7 +504,7 @@ namespace Aurora
ULONG Family,
ULONG Flags,
PVOID Reserved,
IP_ADAPTER_ADDRESSES *AdapterAddresses,
IP_ADAPTER_ADDRESSES * AdapterAddresses,
PULONG SizePointer
);
@ -519,6 +513,50 @@ namespace Aurora
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 gUseNativeWaitCondvar {};
inline bool gUseNativeWaitSemapahore {};

View File

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

View File

@ -140,32 +140,55 @@ namespace Aurora::IO::FS
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)
{
PWSTR directory;
if (!pSHGetKnownFolderPath)
{
if (auto opt = GUIDTOCISL(rfid))
{
AuString temp(MAX_PATH, '\x00');
if (SHGetFolderPathA(0, *opt, 0, 0, temp.data()) == S_OK)
{
return temp;
}
}
return "";
return GetSpecialDirOldOS(rfid);
}
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",
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);
CoTaskMemFree(directory);
if (pCoTaskMemFree)
{
pCoTaskMemFree(directory);
}
return ret;
}

View File

@ -8,17 +8,14 @@
#include <Source/RuntimeInternal.hpp>
#include "AuProcesses.hpp"
#include "AuOpen.Win32.hpp"
#include <shellapi.h>
#include <tlhelp32.h>
#include <Source/IO/FS/FS.hpp>
#include "Objbase.h"
#include "shellapi.h"
#define COINIT_APARTMENTTHREADED 0x2
#define COINIT_DISABLE_OLE1DDE 0x4
namespace Aurora::Processes
{
static AuList<AuString> gOpenItems;
static AuList<AuPair<AuString, bool>> gOpenItems;
static AuThreadPrimitives::ConditionMutex gCondMutex;
static AuThreadPrimitives::ConditionVariable gCondVariable(AuUnsafeRaiiToShared(gCondMutex.AsPointer()));
static AuThreads::ThreadUnique_t gOpenerThread;
@ -31,17 +28,61 @@ namespace Aurora::Processes
{
try
{
for (const auto &open : gOpenItems)
for (const auto &[uri, type] : gOpenItems)
{
if (open.empty()) continue; // [*1]
bool bDirExists {};
bool bFileExists {};
ShellExecuteW(nullptr,
AuIOFS::DirExists(open) ? L"explore" : L"open",
Locale::ConvertFromUTF8(open).c_str(),
if (uri.empty())
{
continue;
}
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();
gCondVariable->WaitForSignal();
}
@ -55,9 +96,17 @@ namespace Aurora::Processes
static void OpenerThread()
{
(void)CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (pCoInitializeEx)
{
(void)pCoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
}
RunTasks();
CoUninitialize();
if (pCoUninitialize)
{
pCoUninitialize();
}
}
void InitWin32Opener()
@ -81,21 +130,14 @@ namespace Aurora::Processes
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);
AuTryInsert(gOpenItems, uri);
AuTryInsert(gOpenItems, AuMakePair(uri, true));
gCondVariable->Signal();
}
AUKN_SYM void OpenFile(const AuString &file)
{
auto path = AuIOFS::NormalizePathRet(file);
bool bFileExists {};
if (path.empty())
{
@ -103,25 +145,9 @@ namespace Aurora::Processes
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);
AuTryInsert(gOpenItems, AuMove(path));
AuTryInsert(gOpenItems, AuMove(AuMakePair(AuMove(path), false)));
gCondVariable->Signal();
}
}