[*] Further drop required symbols from OLE (COM) and SHELL32 (NT Shell)
[*] Optimize NT file and URI opener
This commit is contained in:
parent
c5a2d1e582
commit
9be76adb23
@ -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 &&
|
||||
|
@ -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 {};
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user