Skip to content

Commit 82ebb39

Browse files
committed
Implemented a blocklist for loading DLLs.
Can be used to block buggy vfw/acm codecs and unwanted third party hooks.
1 parent d0125a0 commit 82ebb39

File tree

1 file changed

+134
-1
lines changed

1 file changed

+134
-1
lines changed

src/mpc-hc/mplayerc.cpp

Lines changed: 134 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "FGFilterLAV.h"
4949
#include "CMPCThemeMsgBox.h"
5050
#include "version.h"
51+
#include "psapi.h"
5152

5253
HICON LoadIcon(CString fn, bool bSmallIcon, DpiHelper* pDpiHelper/* = nullptr*/)
5354
{
@@ -1448,6 +1449,130 @@ NTSTATUS WINAPI Mine_NtQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFO
14481449
return nRet;
14491450
}
14501451

1452+
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
1453+
1454+
typedef enum _SECTION_INHERIT { ViewShare = 1, ViewUnmap = 2 } SECTION_INHERIT;
1455+
1456+
typedef enum _SECTION_INFORMATION_CLASS {
1457+
SectionBasicInformation = 0,
1458+
SectionImageInformation
1459+
} SECTION_INFORMATION_CLASS;
1460+
1461+
typedef struct _SECTION_BASIC_INFORMATION {
1462+
PVOID BaseAddress;
1463+
ULONG Attributes;
1464+
LARGE_INTEGER Size;
1465+
} SECTION_BASIC_INFORMATION;
1466+
1467+
typedef NTSTATUS(STDMETHODCALLTYPE* pfn_NtMapViewOfSection)(HANDLE, HANDLE, PVOID, ULONG_PTR, SIZE_T, PLARGE_INTEGER, PSIZE_T, SECTION_INHERIT, ULONG, ULONG);
1468+
typedef NTSTATUS(STDMETHODCALLTYPE* pfn_NtUnmapViewOfSection)(HANDLE, PVOID);
1469+
typedef NTSTATUS(STDMETHODCALLTYPE* pfn_NtQuerySection)(HANDLE, SECTION_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T);
1470+
1471+
static pfn_NtMapViewOfSection Real_NtMapViewOfSection = nullptr;
1472+
static pfn_NtUnmapViewOfSection Real_NtUnmapViewOfSection = nullptr;
1473+
static pfn_NtQuerySection Real_NtQuerySection = nullptr;
1474+
1475+
typedef struct {
1476+
// DLL name, lower case, with backslash as prefix
1477+
const wchar_t* name;
1478+
size_t name_len;
1479+
} blocked_module_t;
1480+
1481+
// list of modules that can cause crashes or other unwanted behavior
1482+
static blocked_module_t moduleblocklist[] = {
1483+
#if WIN64
1484+
// Logitech codec
1485+
{_T("\\lvcod64.dll"), 12},
1486+
// ProxyCodec64
1487+
{_T("\\pxc0.dll"), 9},
1488+
#else
1489+
{_T("\\mlc.dll"), 8},
1490+
#endif
1491+
// Lame
1492+
{_T("\\lameacm.acm"), 12},
1493+
// ffdshow vfw
1494+
{_T("\\ff_vfw.dll"), 11},
1495+
#if WIN64
1496+
// Trusteer Rapport
1497+
{_T("\\rooksbas_x64.dll"), 17},
1498+
{_T("\\rooksdol_x64.dll"), 17},
1499+
{_T("\\rapportgh_x64.dll"), 18},
1500+
#endif
1501+
// ASUS GamerOSD
1502+
{_T("\\atkdx11disp.dll"), 16},
1503+
// ASUS GPU TWEAK II OSD
1504+
{_T("\\gtii-osd64.dll"), 15},
1505+
{_T("\\gtii-osd64-vk.dll"), 18},
1506+
// Nahimic Audio
1507+
{L"\\nahimicmsidevprops.dll", 23},
1508+
{L"\\nahimicmsiosd.dll", 18},
1509+
// LoiLoGameRecorder
1510+
{_T("\\loilocap.dll"), 13},
1511+
// Other
1512+
{_T("\\tortoiseoverlays.dll"), 21},
1513+
};
1514+
1515+
bool IsBlockedModule(wchar_t* modulename)
1516+
{
1517+
size_t mod_name_len = wcslen(modulename);
1518+
1519+
//TRACE(L"Checking module blocklist: %s\n", modulename);
1520+
1521+
for (size_t i = 0; i < _countof(moduleblocklist); i++) {
1522+
blocked_module_t* b = &moduleblocklist[i];
1523+
if (mod_name_len > b->name_len) {
1524+
wchar_t* dll_ptr = modulename + mod_name_len - b->name_len;
1525+
if (_wcsicmp(dll_ptr, b->name) == 0) {
1526+
TRACE(L"Blocked module load: %s\n", modulename);
1527+
return true;
1528+
}
1529+
}
1530+
}
1531+
1532+
return false;
1533+
}
1534+
1535+
NTSTATUS STDMETHODCALLTYPE Mine_NtMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID* BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize,
1536+
PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType, ULONG Win32Protect)
1537+
{
1538+
1539+
SECTION_BASIC_INFORMATION section_information;
1540+
wchar_t fileName[MAX_PATH];
1541+
SIZE_T wrote = 0;
1542+
NTSTATUS ret;
1543+
1544+
ret = Real_NtMapViewOfSection(SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect);
1545+
1546+
// Verify map and process
1547+
if (ret < 0 || ProcessHandle != GetCurrentProcess())
1548+
return ret;
1549+
1550+
// Fetch section information
1551+
if (Real_NtQuerySection(SectionHandle, SectionBasicInformation,
1552+
&section_information, sizeof(section_information),
1553+
&wrote) < 0)
1554+
return ret;
1555+
1556+
// Verify fetch was successful
1557+
if (wrote != sizeof(section_information))
1558+
return ret;
1559+
1560+
// We're not interested in non-image maps
1561+
if (!(section_information.Attributes & SEC_IMAGE))
1562+
return ret;
1563+
1564+
// Get the actual filename if possible
1565+
if (GetMappedFileNameW(ProcessHandle, *BaseAddress, fileName, _countof(fileName)) == 0)
1566+
return ret;
1567+
1568+
if (IsBlockedModule(fileName)) {
1569+
Real_NtUnmapViewOfSection(ProcessHandle, BaseAddress);
1570+
ret = STATUS_UNSUCCESSFUL;
1571+
}
1572+
1573+
return ret;
1574+
}
1575+
14511576
static LONG Mine_ChangeDisplaySettingsEx(LONG ret, DWORD dwFlags, LPVOID lParam)
14521577
{
14531578
if (dwFlags & CDS_VIDEOPARAMETERS) {
@@ -1668,13 +1793,21 @@ BOOL CMPlayerCApp::InitInstance()
16681793
AfxMessageBox(IDS_HOOKS_FAILED);
16691794
}
16701795

1796+
if (m_hNTDLL) {
1797+
Real_NtMapViewOfSection = (pfn_NtMapViewOfSection)GetProcAddress(m_hNTDLL, "NtMapViewOfSection");
1798+
Real_NtUnmapViewOfSection = (pfn_NtUnmapViewOfSection)GetProcAddress(m_hNTDLL, "NtUnmapViewOfSection");
1799+
Real_NtQuerySection = (pfn_NtQuerySection)GetProcAddress(m_hNTDLL, "NtQuerySection");
1800+
if (Real_NtMapViewOfSection && Real_NtUnmapViewOfSection && Real_NtQuerySection) {
1801+
VERIFY(Mhook_SetHookEx(&Real_NtMapViewOfSection, Mine_NtMapViewOfSection));
1802+
}
1803+
}
1804+
16711805
// If those hooks fail it's annoying but try to run anyway without reporting any error in release mode
16721806
VERIFY(Mhook_SetHookEx(&Real_ChangeDisplaySettingsExA, Mine_ChangeDisplaySettingsExA));
16731807
VERIFY(Mhook_SetHookEx(&Real_ChangeDisplaySettingsExW, Mine_ChangeDisplaySettingsExW));
16741808
VERIFY(Mhook_SetHookEx(&Real_CreateFileA, Mine_CreateFileA)); // The internal splitter uses the right share mode anyway so this is no big deal
16751809
VERIFY(Mhook_SetHookEx(&Real_LockWindowUpdate, Mine_LockWindowUpdate));
16761810
VERIFY(Mhook_SetHookEx(&Real_mixerSetControlDetails, Mine_mixerSetControlDetails));
1677-
16781811
MH_EnableHook(MH_ALL_HOOKS);
16791812

16801813
CFilterMapper2::Init();

0 commit comments

Comments
 (0)