-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 67a5dc7
Showing
8 changed files
with
217 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build |
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 |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "(Windows) Launch", | ||
"type": "cppvsdbg", | ||
"request": "launch", | ||
"program": "build/squeeze-injector.exe", | ||
"args": [], | ||
"stopAtEntry": false, | ||
"cwd": "${workspaceFolder}", | ||
"environment": [], | ||
"externalConsole": false | ||
} | ||
] | ||
} |
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 |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools" | ||
} |
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 |
---|---|---|
@@ -0,0 +1,9 @@ | ||
cmake_minimum_required(VERSION 3.10) | ||
|
||
project(squeeze) | ||
|
||
set(CMAKE_CXX_STANDARD 17) | ||
set(CMAKE_CXX_STANDARD_REQUIRED True) | ||
|
||
add_library(squeeze SHARED src/squeeze.cc) | ||
add_executable(squeeze-injector WIN32 src/injector.cc) |
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 |
---|---|---|
@@ -0,0 +1,12 @@ | ||
@echo off | ||
|
||
mkdir build | ||
cd build | ||
|
||
if not defined DevEnvDir ( | ||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 | ||
) | ||
cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug | ||
cmake --build . | ||
|
||
cd .. |
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 |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include <Windows.h> | ||
#include "shared.h" | ||
|
||
static bool gShouldExit = 0; | ||
|
||
// TODO: Add explorer.exe restart detection | ||
|
||
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) | ||
{ | ||
// Find shell window | ||
HWND hWnd = FindWindow(TEXT("Shell_TrayWnd"), nullptr); | ||
int t = 0; | ||
while (hWnd == nullptr) { | ||
Sleep(500); | ||
hWnd = FindWindow(TEXT("Shell_TrayWnd"), nullptr); | ||
t++; | ||
if (t > 30 && hWnd == nullptr) { | ||
MessageBox(0, TEXT("Could not find Shell_TrayWnd (is eplorer.exe running?)"), TEXT("Squeeze: Injection error"), MB_ICONERROR); | ||
return -1; | ||
} | ||
} | ||
|
||
// Get thread and process id for shell window | ||
DWORD processId; | ||
DWORD threadId = GetWindowThreadProcessId(hWnd, &processId); | ||
|
||
HANDLE hProcess = OpenProcess(0xFFF, FALSE, processId); | ||
if (hProcess == NULL) { | ||
MessageBox(0, TEXT("Unable to obtain the explorer handle"), TEXT("Squeeze: Injection error"), MB_ICONERROR); | ||
return -1; | ||
} | ||
|
||
// Allocate memory in explorer.exe and write squeeze DLL path to it | ||
LPCSTR dllPath = "D:\\Dev\\squeeze\\build\\squeeze.dll"; | ||
SIZE_T dllPathSize = strlen(dllPath) + 1; | ||
SIZE_T dllPathNumBytesWritten; | ||
LPVOID lpRemoteBuf = VirtualAllocEx(hProcess, NULL, dllPathSize, MEM_COMMIT, PAGE_READWRITE); | ||
if (WriteProcessMemory(hProcess, lpRemoteBuf, dllPath, dllPathSize, &dllPathNumBytesWritten)) { | ||
if (dllPathNumBytesWritten != dllPathSize) { | ||
VirtualFreeEx(hProcess, lpRemoteBuf, dllPathSize, MEM_COMMIT); | ||
MessageBox(0, TEXT("Written memory length does not match DLL path length."), TEXT("Squeeze: Injection error"), MB_ICONERROR); | ||
CloseHandle(hProcess); | ||
return -1; | ||
} | ||
} else { | ||
MessageBox(0, TEXT("Failed to write DLL path to explorer memory"), TEXT("Squeeze: Injection error"), MB_ICONERROR); | ||
CloseHandle(hProcess); | ||
return -1; | ||
} | ||
VirtualFreeEx(hProcess, lpRemoteBuf, dllPathSize, MEM_COMMIT); | ||
|
||
// Inject squeeze DLL | ||
DWORD dwNewThreadId; | ||
LPVOID lpLoadDll = LoadLibraryA; | ||
HANDLE hNewRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadDll, lpRemoteBuf, 0, &dwNewThreadId); | ||
if (hNewRemoteThread == NULL) { | ||
MessageBox(0, TEXT("Failed to start remote thread (LoadLibraryA)."), TEXT("Squeeze: Injection error"), MB_ICONERROR); | ||
CloseHandle(hProcess); | ||
return -1; | ||
} | ||
WaitForSingleObject(hNewRemoteThread, INFINITE); | ||
CloseHandle(hNewRemoteThread); | ||
CloseHandle(hProcess); | ||
|
||
// Send injector PID to the DLL so it knows when to exit | ||
SendMessage(hWnd, WM_SQUEEZE, SQUEEZE_INJECTOR_PID, GetCurrentProcessId()); | ||
|
||
Sleep(INFINITE); | ||
} |
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 |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#define WM_SQUEEZE 0x0409 | ||
#define SQUEEZE_INJECTOR_PID 0x90 |
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 |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#include <Windows.h> | ||
#include "shared.h" | ||
|
||
const int DESIRED_WIDTH = 2560; | ||
|
||
static DWORD gInjectorPid = 0; | ||
static HMODULE gModule = 0; | ||
static HANDLE gThreadHandle = 0; | ||
static HWND gTaskbarHWnd = 0; | ||
|
||
static WNDPROC gOriginalWndProc = 0; | ||
|
||
void UpdateTaskbar() | ||
{ | ||
HWND desktopHWnd = GetDesktopWindow(); | ||
RECT desktopRect; | ||
GetWindowRect(desktopHWnd, &desktopRect); | ||
|
||
RECT taskbarRect; | ||
GetWindowRect(gTaskbarHWnd, &taskbarRect); | ||
|
||
int desiredLeft = (desktopRect.right / 2) - (DESIRED_WIDTH / 2); | ||
int desiredRight = (desktopRect.right / 2) + (DESIRED_WIDTH / 2); | ||
|
||
if (taskbarRect.left != desiredLeft || taskbarRect.right != desiredRight) { | ||
// Resize taskbar and make sure everything is updated | ||
SetWindowPos(gTaskbarHWnd, NULL, desiredLeft, taskbarRect.top, DESIRED_WIDTH, taskbarRect.bottom - taskbarRect.top, SWP_NOSENDCHANGING); | ||
ShowWindow(gTaskbarHWnd, SW_SHOW); | ||
UpdateWindow(gTaskbarHWnd); | ||
RedrawWindow(desktopHWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); | ||
SystemParametersInfo(SPI_SETWORKAREA, 0, NULL, SPIF_SENDCHANGE); | ||
} | ||
} | ||
|
||
void SqueezeExit() | ||
{ | ||
if (gOriginalWndProc != NULL) | ||
SetWindowLongPtr(gTaskbarHWnd, GWLP_WNDPROC, (LONG_PTR)gOriginalWndProc); | ||
|
||
CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)FreeLibraryAndExitThread, gModule, 0, nullptr)); | ||
} | ||
|
||
bool InjectorStillRunning() | ||
{ | ||
if (gInjectorPid == 0) | ||
return true; // Injector has not notified us so we assume we should keep running | ||
|
||
HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, gInjectorPid); | ||
DWORD lpExitCode; | ||
GetExitCodeProcess(handle, &lpExitCode); | ||
if (lpExitCode != STILL_ACTIVE) | ||
return false; | ||
|
||
return true; | ||
} | ||
|
||
LRESULT CALLBACK WndProcTaskBar(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | ||
{ | ||
if (!InjectorStillRunning()) { | ||
SqueezeExit(); | ||
return CallWindowProcA(gOriginalWndProc, hwnd, uMsg, wParam, lParam); | ||
} | ||
|
||
switch (uMsg) { | ||
case WM_WINDOWPOSCHANGING: | ||
UpdateTaskbar(); | ||
return 0; | ||
case WM_SQUEEZE: | ||
if (wParam == SQUEEZE_INJECTOR_PID) { | ||
gInjectorPid = (DWORD)lParam; | ||
} | ||
default: | ||
break; | ||
} | ||
return CallWindowProcA(gOriginalWndProc, hwnd, uMsg, wParam, lParam); | ||
} | ||
|
||
void SqueezeInit() | ||
{ | ||
gTaskbarHWnd = FindWindow(TEXT("Shell_TrayWnd"), nullptr); | ||
if (IsWindow(gTaskbarHWnd)) { | ||
gOriginalWndProc = (WNDPROC)SetWindowLongPtr(gTaskbarHWnd, GWLP_WNDPROC, (LONG_PTR)&WndProcTaskBar); | ||
} | ||
} | ||
|
||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) | ||
{ | ||
switch (ul_reason_for_call) | ||
{ | ||
case DLL_PROCESS_ATTACH: | ||
gModule = hModule; | ||
SqueezeInit(); // CreateThread? | ||
break; | ||
case DLL_PROCESS_DETACH: | ||
break; | ||
case DLL_THREAD_ATTACH: | ||
break; | ||
case DLL_THREAD_DETACH: | ||
break; | ||
} | ||
return TRUE; | ||
} |