-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from Aetopia/main
Remove thread detection loop + use file enumeration to find Discord's executable.
- Loading branch information
Showing
2 changed files
with
117 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,132 @@ | ||
#include <windows.h> | ||
#include <pathcch.h> | ||
#include <Windows.h> | ||
#include <shlwapi.h> | ||
#include <tlhelp32.h> | ||
#include <winternl.h> | ||
#include <wtsapi32.h> | ||
#include <shlwapi.h> | ||
#define printf __builtin_printf | ||
|
||
INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) | ||
static LPWSTR szFileName = NULL; | ||
|
||
void WinEventProc(HWINEVENTHOOK hWinEventHook, | ||
DWORD event, | ||
HWND hwnd, | ||
LONG idObject, | ||
LONG idChild, | ||
DWORD idEventThread, | ||
DWORD dwmsEventTime) | ||
{ | ||
INT iNumArgs = 0; | ||
WCHAR **pszArgvW = CommandLineToArgvW(GetCommandLineW(), &iNumArgs), | ||
*szFileName = 0; | ||
WCHAR lpExeName[MAX_PATH] = {}; | ||
DWORD dwProcessId = 0; | ||
DWORD dwThreadId = GetWindowThreadProcessId(hwnd, &dwProcessId); | ||
WCHAR ptszClassName[256] = {}; | ||
HANDLE hThreadSnapshot = NULL; | ||
THREADENTRY32 te = {.dwSize = sizeof(THREADENTRY32)}; | ||
MODULEENTRY32W me = {.dwSize = sizeof(MODULEENTRY32W)}; | ||
HANDLE hThreadSnapshot = 0, hModuleSnapshot = 0, hThread = 0; | ||
DWORD64 dw64StartAddress = 0; | ||
PWTS_PROCESS_INFOW pProcessInfo = 0; | ||
DWORD dwCount = 0; | ||
BOOL bSuspended = FALSE; | ||
|
||
PathCchRemoveFileSpec(pszArgvW[0], wcslen(pszArgvW[0]) + 1); | ||
SetCurrentDirectoryW(pszArgvW[0]); | ||
LocalFree(pszArgvW); | ||
RealGetWindowClassW(hwnd, ptszClassName, 256); | ||
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId); | ||
QueryFullProcessImageNameW(hProcess, 0, lpExeName, &((DWORD){MAX_PATH})); | ||
PathStripPathW(_wcslwr(lpExeName)); | ||
CloseHandle(hProcess); | ||
|
||
if ((szFileName = PathFileExistsW(L"discord.exe") | ||
? L"discord.exe" | ||
: PathFileExistsW(L"discordcanary.exe") | ||
? L"discordcanary.exe" | ||
: PathFileExistsW(L"discordptb.exe") | ||
? L"discordptb.exe" | ||
: 0)) | ||
if (!wcscmp(lpExeName, szFileName) && !wcscmp(ptszClassName, L"raw_input")) | ||
{ | ||
ShellExecuteW(NULL, NULL, szFileName, NULL, NULL, SW_SHOWNORMAL); | ||
while (!bSuspended && !SleepEx(1, TRUE)) | ||
if (Thread32First((hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0)), &te)) | ||
{ | ||
WTSEnumerateProcessesW(WTS_CURRENT_SERVER, 0, 1, &pProcessInfo, &dwCount); | ||
for (DWORD dwIndex = 0; dwIndex < dwCount; dwIndex++) | ||
do | ||
{ | ||
if (wcscmp(szFileName, _wcslwr(pProcessInfo[dwIndex].pProcessName))) | ||
if (te.th32OwnerProcessID != dwProcessId) | ||
continue; | ||
if (Thread32First((hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0)), &te)) | ||
{ | ||
DWORD64 ThreadInformation = 0; | ||
MODULEENTRY32W me = {.dwSize = sizeof(MODULEENTRY32W)}; | ||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID), | ||
hModuleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE32 | TH32CS_SNAPMODULE, dwProcessId); | ||
NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &ThreadInformation, sizeof(DWORD64), NULL); | ||
if (Module32FirstW((hModuleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE32 | TH32CS_SNAPMODULE, dwProcessId)), &me)) | ||
do | ||
{ | ||
if (te.th32OwnerProcessID != pProcessInfo[dwIndex].ProcessId) | ||
continue; | ||
hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID); | ||
NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &dw64StartAddress, sizeof(DWORD64), NULL); | ||
if (Module32FirstW((hModuleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE32 | TH32CS_SNAPMODULE, pProcessInfo[dwIndex].ProcessId)), &me)) | ||
do | ||
{ | ||
if (dw64StartAddress >= (DWORD64)me.modBaseAddr && | ||
dw64StartAddress <= ((DWORD64)me.modBaseAddr + me.modBaseSize) && | ||
!wcscmp(me.szModule, L"discord_utils.node")) | ||
bSuspended = SuspendThread(hThread); | ||
} while (Module32NextW(hModuleSnapshot, &me)); | ||
CloseHandle(hModuleSnapshot); | ||
CloseHandle(hThread); | ||
} while (Thread32Next(hThreadSnapshot, &te)); | ||
} | ||
CloseHandle(hThreadSnapshot); | ||
} | ||
WTSFreeMemory(pProcessInfo); | ||
if (ThreadInformation >= (DWORD64)me.modBaseAddr && | ||
ThreadInformation <= ((DWORD64)me.modBaseAddr + me.modBaseSize) && | ||
!wcscmp(me.szModule, L"discord_utils.node")) | ||
SuspendThread(hThread); | ||
} while (Module32NextW(hModuleSnapshot, &me)); | ||
CloseHandle(hModuleSnapshot); | ||
CloseHandle(hThread); | ||
} while (Thread32Next(hThreadSnapshot, &te)); | ||
} | ||
CloseHandle(hThreadSnapshot); | ||
PostQuitMessage(0); | ||
} | ||
} | ||
|
||
BOOL EnumWindowsProc(HWND hWnd, LPARAM lParam) | ||
{ | ||
DWORD dwProcessId = 0; | ||
WCHAR lpExeName[MAX_PATH] = {}; | ||
GetWindowThreadProcessId(hWnd, &dwProcessId); | ||
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId); | ||
QueryFullProcessImageNameW(hProcess, 0, lpExeName, &((DWORD){MAX_PATH})); | ||
PathStripPathW(_wcslwr(lpExeName)); | ||
CloseHandle(hProcess); | ||
if (!wcscmp(lpExeName, szFileName)) | ||
EndTask(hWnd, FALSE, TRUE); | ||
return TRUE; | ||
} | ||
|
||
INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) | ||
{ | ||
CONST LPWSTR lpProcesses[] = {L"discord.exe", L"discordptb.exe", L"discordptb.exe"}; | ||
WCHAR lpPathName[MAX_PATH] = {}; | ||
HANDLE hProcess = GetCurrentProcess(); | ||
WIN32_FIND_DATAW FindFileData = {}; | ||
PWTS_PROCESS_INFOW pProcessInfo = NULL; | ||
DWORD Count = 0; | ||
|
||
QueryFullProcessImageNameW(hProcess, 0, lpPathName, &((DWORD){MAX_PATH})); | ||
for (DWORD dwIndex = MAX_PATH; dwIndex < -1; dwIndex -= 1) | ||
{ | ||
if (lpPathName[dwIndex] == '\\') | ||
{ | ||
lpPathName[dwIndex] = '\0'; | ||
SetCurrentDirectoryW(lpPathName); | ||
lpPathName[dwIndex] = '\\'; | ||
lpPathName[dwIndex + 1] = '*'; | ||
lpPathName[dwIndex + 2] = '\0'; | ||
break; | ||
} | ||
} | ||
|
||
HANDLE hFindFile = FindFirstFileExW(lpPathName, | ||
FindExInfoBasic, | ||
&FindFileData, | ||
FindExSearchLimitToDirectories, | ||
NULL, | ||
FIND_FIRST_EX_LARGE_FETCH); | ||
if (hFindFile) | ||
{ | ||
do | ||
if (PathIsDirectoryW(FindFileData.cFileName) && | ||
wcscmp(FindFileData.cFileName, L".") && | ||
wcscmp(FindFileData.cFileName, L"..")) | ||
if (SetCurrentDirectoryW(FindFileData.cFileName)) | ||
for (INT iIndex = 0; iIndex < 3; iIndex++) | ||
if (PathFileExistsW(lpProcesses[iIndex])) | ||
{ | ||
szFileName = lpProcesses[iIndex]; | ||
EnumWindows(EnumWindowsProc, 0); | ||
ShellExecuteW(NULL, NULL, szFileName, NULL, NULL, SW_SHOWNORMAL); | ||
SetWinEventHook(EVENT_OBJECT_CREATE, | ||
EVENT_OBJECT_CREATE, | ||
NULL, | ||
WinEventProc, | ||
0, | ||
0, | ||
WINEVENT_OUTOFCONTEXT); | ||
while (GetMessageW(&((MSG){}), NULL, 0, 0)) | ||
; | ||
break; | ||
} | ||
while (FindNextFileW(hFindFile, &FindFileData)); | ||
FindClose(hFindFile); | ||
} | ||
|
||
return 0; | ||
} |