Files
ExploerPatcher/ExplorerPatcher/StartMenu.c
T
2021-10-21 09:01:59 +03:00

409 lines
12 KiB
C

#include "StartMenu.h"
void OpenStartOnMonitor(HMONITOR monitor)
{
HRESULT hr = S_OK;
IUnknown* pImmersiveShell = NULL;
hr = CoCreateInstance(
&CLSID_ImmersiveShell,
NULL,
CLSCTX_NO_CODE_DOWNLOAD | CLSCTX_LOCAL_SERVER,
&IID_IServiceProvider,
&pImmersiveShell
);
if (SUCCEEDED(hr))
{
IImmersiveMonitorService* pMonitorService = NULL;
IUnknown_QueryService(
pImmersiveShell,
&SID_IImmersiveMonitorService,
&IID_IImmersiveMonitorService,
&pMonitorService
);
if (pMonitorService)
{
IUnknown* pMonitor = NULL;
pMonitorService->lpVtbl->GetFromHandle(
pMonitorService,
monitor,
&pMonitor
);
IImmersiveLauncher10RS* pLauncher = NULL;
IUnknown_QueryService(
pImmersiveShell,
&SID_ImmersiveLauncher,
&IID_IImmersiveLauncher10RS,
&pLauncher
);
if (pLauncher)
{
BOOL bIsVisible = FALSE;
pLauncher->lpVtbl->IsVisible(pLauncher, &bIsVisible);
if (SUCCEEDED(hr))
{
if (!bIsVisible)
{
if (pMonitor)
{
pLauncher->lpVtbl->ConnectToMonitor(pLauncher, pMonitor);
}
pLauncher->lpVtbl->ShowStartView(pLauncher, 11, 0);
}
else
{
pLauncher->lpVtbl->Dismiss(pLauncher);
}
}
pLauncher->lpVtbl->Release(pLauncher);
}
if (pMonitor)
{
pMonitor->lpVtbl->Release(pMonitor);
}
pMonitorService->lpVtbl->Release(pMonitorService);
}
pImmersiveShell->lpVtbl->Release(pImmersiveShell);
}
}
LRESULT CALLBACK OpenStartOnCurentMonitorThreadHook(
int code,
WPARAM wParam,
LPARAM lParam
)
{
if (code == HC_ACTION && wParam)
{
MSG* msg = (MSG*)lParam;
if (GetSystemMetrics(SM_CMONITORS) >= 2 && msg->message == WM_SYSCOMMAND && (msg->wParam & 0xFFF0) == SC_TASKLIST)
{
if (bMonitorOverride)
{
goto finish;
}
/*DWORD dwStatus = 0;
DWORD dwSize = sizeof(DWORD);
HMODULE hModule = GetModuleHandle(TEXT("Shlwapi.dll"));
FARPROC SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hModule, "SHRegGetValueFromHKCUHKLM");
if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc(
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"),
TEXT("MonitorOverride"),
SRRF_RT_REG_DWORD,
NULL,
&dwStatus,
(LPDWORD)(&dwSize)
) != ERROR_SUCCESS || dwStatus == 1)
{
goto finish;
}*/
DWORD pts = GetMessagePos();
POINT pt;
pt.x = GET_X_LPARAM(pts);
pt.y = GET_Y_LPARAM(pts);
HMONITOR monitor = MonitorFromPoint(
pt,
MONITOR_DEFAULTTONULL
);
OpenStartOnMonitor(monitor);
msg->message = WM_NULL;
}
}
finish:
return CallNextHookEx(NULL, code, wParam, lParam);
}
DWORD OpenStartOnCurentMonitorThread(OpenStartOnCurentMonitorThreadParams* unused)
{
HANDLE hEvent = CreateEventW(0, 0, 0, L"ShellDesktopSwitchEvent");
if (!hEvent)
{
printf("Failed to start \"Open Start on current monitor\" thread.\n");
return 0;
}
WaitForSingleObject(
hEvent,
INFINITE
);
printf("Started \"Open Start on current monitor\" thread.\n");
HWND g_ProgWin = NULL;
while (!g_ProgWin)
{
g_ProgWin = FindWindowEx(
NULL,
NULL,
L"Progman",
NULL
);
if (!g_ProgWin)
{
Sleep(100);
}
}
printf("Progman: %d\n", g_ProgWin);
DWORD progThread = GetWindowThreadProcessId(
g_ProgWin,
NULL
);
HHOOK g_ProgHook = SetWindowsHookEx(
WH_GETMESSAGE,
OpenStartOnCurentMonitorThreadHook,
NULL,
progThread
);
printf("Progman hook: %d\n", g_ProgHook);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
printf("Ended \"Open Start on current monitor\" thread.\n");
}
DWORD OpenStartAtLogonThread(OpenStartAtLogonThreadParams* unused)
{
HANDLE hEvent = CreateEvent(0, 0, 0, L"ShellDesktopSwitchEvent");
if (!hEvent)
{
printf("Failed to start \"Open Start at Logon\" thread.\n");
return 0;
}
WaitForSingleObject(
hEvent,
INFINITE
);
printf("Started \"Open Start at Logon\" thread.\n");
if (!bOpenAtLogon)
{
return 0;
}
/*DWORD dwStatus = 0;
DWORD dwSize = sizeof(DWORD);
HMODULE hModule = GetModuleHandle(TEXT("Shlwapi"));
FARPROC SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hModule, "SHRegGetValueFromHKCUHKLM");
if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc(
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"),
TEXT("OpenAtLogon"),
SRRF_RT_REG_DWORD,
NULL,
&dwStatus,
(LPDWORD)(&dwSize)
) != ERROR_SUCCESS || dwStatus == 0)
{
return 0;
}*/
POINT pt;
pt.x = 0;
pt.y = 0;
HMONITOR monitor = MonitorFromPoint(
pt,
MONITOR_DEFAULTTOPRIMARY
);
OpenStartOnMonitor(monitor);
printf("Ended \"Open Start at Logon\" thread.\n");
}
DWORD WINAPI HookStartMenu(HookStartMenuParams* params)
{
printf("Started \"Hook Start Menu\" thread.\n");
TCHAR wszKnownPath[MAX_PATH];
GetWindowsDirectoryW(wszKnownPath, MAX_PATH);
wcscat_s(wszKnownPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\StartMenuExperienceHost.exe");
while (TRUE)
{
unsigned int retry = 0;
HANDLE hProcess, hSnapshot;
PROCESSENTRY32 pe32;
while (TRUE)
{
hProcess = NULL;
hSnapshot = NULL;
ZeroMemory(&pe32, sizeof(PROCESSENTRY32));
pe32.dwSize = sizeof(PROCESSENTRY32);
hSnapshot = CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS,
0
);
if (Process32First(hSnapshot, &pe32) == TRUE)
{
do
{
if (!wcscmp(pe32.szExeFile, TEXT("StartMenuExperienceHost.exe")))
{
hProcess = OpenProcess(
PROCESS_QUERY_LIMITED_INFORMATION |
PROCESS_VM_OPERATION |
PROCESS_VM_READ |
PROCESS_VM_WRITE |
PROCESS_CREATE_THREAD |
SYNCHRONIZE,
FALSE,
pe32.th32ProcessID
);
if (!hProcess)
{
printf("Unable to open handle to StartMenuExperienceHost.exe.\n");
Sleep(params->dwTimeout);
continue;
}
TCHAR wszProcessPath[MAX_PATH];
DWORD dwLength = MAX_PATH;
QueryFullProcessImageNameW(
hProcess,
0,
wszProcessPath,
&dwLength
);
if (!_wcsicmp(wszProcessPath, wszKnownPath))
{
break;
}
else
{
CloseHandle(hProcess);
hProcess = NULL;
}
}
} while (Process32Next(hSnapshot, &pe32) == TRUE);
}
CloseHandle(hSnapshot);
if (hProcess)
{
break;
}
else
{
retry++;
if (retry > 5) return 0;
Sleep(params->dwTimeout);
}
}
LPVOID lpRemotePath = VirtualAllocEx(
hProcess,
NULL,
MAX_PATH,
MEM_COMMIT,
PAGE_READWRITE
);
if (!lpRemotePath)
{
printf("Unable to allocate path memory.\n");
Sleep(1000);
continue;
}
if (!WriteProcessMemory(
hProcess,
lpRemotePath,
(void*)params->wszModulePath,
MAX_PATH,
NULL
))
{
printf("Unable to write path.\n");
Sleep(params->dwTimeout);
continue;
}
HANDLE hThread = CreateRemoteThread(
hProcess,
NULL,
0,
LoadLibraryW,
lpRemotePath,
0,
NULL
);
if (!hThread)
{
printf("Unable to inject DLL.\n");
Sleep(params->dwTimeout);
continue;
}
if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0)
{
printf("Unable to determine LoadLibrary outcome.\n");
Sleep(params->dwTimeout);
continue;
}
CloseHandle(hThread);
DWORD cbNeeded = 0;
EnumProcessModules(
hProcess,
NULL,
0,
&cbNeeded
);
if (!cbNeeded)
{
printf("Unable to determine number of modules in process.\n");
Sleep(params->dwTimeout);
continue;
}
HMODULE* hMods = malloc(cbNeeded);
if (!hMods)
{
printf("Out of memory.\n");
Sleep(params->dwTimeout);
continue;
}
if (!EnumProcessModulesEx(
hProcess,
hMods,
cbNeeded,
&cbNeeded,
LIST_MODULES_ALL
))
{
printf("Unable to enumerate modules of process.\n");
Sleep(params->dwTimeout);
continue;
}
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); ++i)
{
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameExW(hProcess, hMods[i], szModName,
sizeof(szModName) / sizeof(TCHAR)))
{
if (!wcscmp(szModName, params->wszModulePath))
{
printf("Found module in process memory space.\n");
HANDLE hTh = CreateRemoteThread(
hProcess,
NULL,
0,
(uintptr_t)(hMods[i]) + ((uintptr_t)params->proc - (uintptr_t)params->hModule),
0,
0,
NULL
);
if (hTh)
{
printf("Waiting for remote initialization.\n");
WaitForSingleObject(hTh, INFINITE);
DWORD dwExitCode = 0;
GetExitCodeThread(hTh, &dwExitCode);
printf("Initialization exited with code 0x%x.\n", dwExitCode);
CloseHandle(hTh);
printf("HOOKED START MENU\n");
}
break;
}
}
}
free(hMods);
WaitForSingleObject(
hProcess,
INFINITE
);
CloseHandle(hProcess);
}
}