Add dll-inject function and overlayelement needed for UWPOverlay

Also made some "slight" overlay adjustments
main
Peter Repukat 3 years ago
parent cb41e5fadd
commit 0e292cb591

@ -96,6 +96,8 @@ int main(int argc, char* argv[])
SetWindowLong(hwnd, GWL_STYLE, style);
// Enable blurbehind (not needed?) anyway gives nice background on win7 and 8
// LOL.. just realizing < Win 10 is not supported by HidHide driver...
// let's see what users think...
DWM_BLURBEHIND bb{};
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = true;

@ -0,0 +1,110 @@
#pragma once
#include <windows.h>
#include <tlhelp32.h>
#include <spdlog/spdlog.h>
namespace DllInjector {
inline bool TakeDebugPrivilege()
{
HANDLE process = GetCurrentProcess(), token;
TOKEN_PRIVILEGES priv;
LUID luid = {NULL};
if (!OpenProcessToken(process, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
CloseHandle(process);
spdlog::error("Failed to open process token");
return false;
}
LookupPrivilegeValue(0, SE_DEBUG_NAME, &luid);
priv.PrivilegeCount = 1;
priv.Privileges[0].Luid = luid;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(token, false, &priv, sizeof(priv), NULL, NULL)) {
spdlog::error("Failed to take debug privilege token");
}
CloseHandle(token);
CloseHandle(process);
return true;
}
inline bool Inject(DWORD pid, const std::wstring& lib_path)
{
HANDLE process = NULL, alloc_address = NULL, remote_thread = NULL;
LPTHREAD_START_ROUTINE thread_routine = NULL;
size_t path_size = (lib_path.length() + 1) * sizeof(wchar_t);
process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid);
if (!process) {
spdlog::error("Failed to open process");
return false;
}
alloc_address = VirtualAllocEx(process, NULL, path_size, MEM_COMMIT, PAGE_READWRITE);
if (!VirtualAllocEx(process, NULL, path_size, MEM_COMMIT, PAGE_READWRITE)) {
spdlog::error("Failed to allocate memory in target process");
CloseHandle(process);
return false;
}
if (!WriteProcessMemory(process, (LPVOID)alloc_address, lib_path.c_str(), path_size, NULL)) {
spdlog::error("Failed to write memory in target process");
VirtualFreeEx(process, alloc_address, path_size, MEM_DECOMMIT);
CloseHandle(process);
return false;
}
thread_routine = reinterpret_cast<PTHREAD_START_ROUTINE>(GetProcAddress(GetModuleHandle(L"Kernel32"), "LoadLibraryW"));
if (!thread_routine) {
spdlog::error("Failed to get address of LoadLibraryW");
VirtualFreeEx(process, alloc_address, path_size, MEM_DECOMMIT);
CloseHandle(process);
return false;
}
remote_thread = CreateRemoteThread(process, NULL, 0, thread_routine, alloc_address, 0, NULL);
if (!remote_thread) {
spdlog::error("Failed to create remote thread");
VirtualFreeEx(process, alloc_address, path_size, MEM_DECOMMIT);
CloseHandle(process);
return false;
}
WaitForSingleObject(remote_thread, INFINITE);
CloseHandle(remote_thread);
VirtualFreeEx(process, alloc_address, path_size, MEM_DECOMMIT);
CloseHandle(process);
spdlog::debug("Successfully injected");
return true;
}
inline bool findModule(DWORD pid, std::wstring& lib_path, HMODULE& hMod)
{
MODULEENTRY32W entry = {sizeof(entry)};
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
if (Module32FirstW(snapshot, &entry) == TRUE) {
while (Module32NextW(snapshot, &entry) == TRUE) {
std::wstring ModuleName(entry.szModule);
std::wstring ExePath(entry.szExePath);
if (ModuleName == lib_path || ExePath == lib_path) {
hMod = (HMODULE)entry.modBaseAddr;
CloseHandle(snapshot);
return true;
}
}
}
CloseHandle(snapshot);
spdlog::error(L"Failed to find module \"{}\"", lib_path);
return false;
}
}; // namespace DllInjector

@ -187,6 +187,7 @@
<ClInclude Include="..\deps\imgui\imgui.h" />
<ClInclude Include="..\deps\subhook\subhook.h" />
<ClInclude Include="AppLauncher.h" />
<ClInclude Include="DllInjector.h" />
<ClInclude Include="HidHide.h" />
<ClInclude Include="imconfig.h" />
<ClInclude Include="InputRedirector.h" />
@ -199,6 +200,7 @@
<ClInclude Include="SteamTarget.h" />
<ClInclude Include="steam_sf_keymap.h" />
<ClInclude Include="TargetWindow.h" />
<ClInclude Include="UWPOverlayEnabler.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\deps\SFML\out\build\x64-Debug\lib\sfml-graphics-d-2.dll">

@ -125,6 +125,12 @@
<ClInclude Include="Roboto.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DllInjector.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UWPOverlayEnabler.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\deps\SFML\out\build\x64-Debug\lib\sfml-system-d-2.dll" />

@ -272,6 +272,8 @@ void HidHide::enableOverlayElement()
closeCtrlDevice();
overlay_elem_clock_.restart();
}
ImGui::SetNextWindowSizeConstraints({300, 250}, {1000, 1000});
ImGui::SetNextWindowPos({600, 100}, ImGuiCond_FirstUseEver);
ImGui::Begin("Hidden Devices");
ImGui::BeginChild("Inner", {0.f, ImGui::GetItemRectSize().y - 64}, true);
std::ranges::for_each(avail_devices_, [this](const auto& device) {

@ -84,7 +84,7 @@ Overlay::Overlay(
colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.18f, 0.21f, 0.24f, 0.94f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.26f, 0.29f, 0.34f, 0.93f);
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.16f, 0.19f, 0.22f, 0.81f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
@ -151,8 +151,9 @@ void Overlay::update()
if (enabled_ || force_enable_) {
window_.clear(sf::Color(0, 0, 0, 128)); // make window slightly dim screen with overlay
std::ranges::for_each(OVERLAY_ELEMS_, [](const auto& fn) { fn(); });
std::ranges::for_each(OVERLAY_ELEMS_, [this](const auto& fn) {
fn();
});
// ImGui::ShowDemoWindow();
@ -199,6 +200,7 @@ void Overlay::showLogs() const
}
if (logs.empty())
return;
ImGui::SetNextWindowSizeConstraints({150, 150}, {1000, window_.getSize().y - 250.f});
if (!enabled_) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {32.f, 32.f});
ImGui::Begin("Log", nullptr,
@ -222,6 +224,7 @@ void Overlay::showLogs() const
ImGui::Text(msg.payload.data());
}
});
ImGui::SetScrollY(ImGui::GetScrollMaxY());
ImGui::End();
if (!enabled_) {
ImGui::PopStyleVar();

@ -51,8 +51,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,0,5419086
PRODUCTVERSION 0,0,0,5419086
FILEVERSION 0,0,0,0041050
PRODUCTVERSION 0,0,0,0041050
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Peter Repukat - FlatspotSoftware"
VALUE "FileDescription", "GlosSI - SteamTarget"
VALUE "FileVersion", "0.0.0.5419d86"
VALUE "FileVersion", "0.0.0.cb41e5f"
VALUE "InternalName", "GlosSITarget"
VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware"
VALUE "OriginalFilename", "GlosSITarget.exe"
VALUE "ProductName", "GlosSI"
VALUE "ProductVersion", "0.0.0.5419d86"
VALUE "ProductVersion", "0.0.0.cb41e5f"
END
END
BLOCK "VarFileInfo"
@ -316,6 +316,150 @@ END

@ -25,6 +25,11 @@ limitations under the License.
#include <spdlog/spdlog.h>
#include <vdf_parser.hpp>
#ifdef _WIN32
#include "UWPOverlayEnabler.h"
#endif
SteamTarget::SteamTarget(int argc, char* argv[])
: window_(
[this] { run_ = false; },
@ -41,6 +46,9 @@ SteamTarget::SteamTarget(int argc, char* argv[])
})
{
target_window_handle_ = window_.getSystemHandle();
#ifdef _WIN32
UWPOverlayEnabler::AddUwpOverlayOvWidget();
#endif
}
int SteamTarget::run()

@ -48,6 +48,7 @@ TargetWindow::TargetWindow(
Overlay::AddOverlayElem([this]() {
bool windowed_copy = windowed_;
ImGui::SetNextWindowPos({650, 450}, ImGuiCond_FirstUseEver);
ImGui::Begin("Window mode");
if (ImGui::Checkbox("Window mode", &windowed_copy)) {
toggle_window_mode_after_frame_ = true;

@ -0,0 +1,83 @@
#pragma once
#include <filesystem>
#include <string>
#include "DllInjector.h"
#include "Overlay.h"
namespace UWPOverlayEnabler {
namespace internal {
inline std::filesystem::path EnablerPath()
{
wchar_t buff[MAX_PATH];
GetModuleFileName(GetModuleHandle(NULL), buff, MAX_PATH);
const std::wstring path(buff);
return path.substr(0, 1 + path.find_last_of(L'\\')) + L"UWPOverlayEnablerDLL.dll";
}
inline DWORD ExplorerPid()
{
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE) {
while (Process32Next(snapshot, &entry) == TRUE) {
if (std::wstring(entry.szExeFile).find(L"explorer.exe") != std::string::npos) {
return entry.th32ProcessID;
}
}
}
CloseHandle(snapshot);
return 0;
}
}
inline void AddUwpOverlayOvWidget()
{
Overlay::AddOverlayElem([]() {
ImGui::SetNextWindowPos({950, 100}, ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSizeConstraints({170, 225}, {1000, 1000});
ImGui::SetNextWindowCollapsed(true, ImGuiCond_FirstUseEver);
ImGui::Begin("UWP-Overlay");
ImGui::Text("To enable the overlay on top of \"fullscreen\" UWP-Apps,");
ImGui::Text("a .dll has to be injected into explorer.exe");
ImGui::Spacing();
ImGui::Spacing();
ImGui::Text("This method also uses undocumented windows functions");
ImGui::Text("and is highly experimental");
ImGui::Spacing();
ImGui::Spacing();
ImGui::Text("This might cause issues!!!");
ImGui::Spacing();
if (ImGui::CollapsingHeader("I am sure!")) {
if (ImGui::Button(/* just */ "DO IT!")) { // insert meme gif here >.<
const auto enabler_path = internal::EnablerPath();
if (std::filesystem::exists(enabler_path)) {
const auto explorer_pid = internal::ExplorerPid();
if (explorer_pid != 0) {
if (DllInjector::TakeDebugPrivilege()) {
// No need to eject, as the dll is self-ejecting.
if (DllInjector::Inject(explorer_pid, enabler_path.wstring())) {
spdlog::info("Successfully injected UWPOverlay enabler into explorer.exe");
// Nesting level over 9000
}
}
}
else {
spdlog::error("explorer not found"); // needs loglevel WTF
}
}
else {
spdlog::error("UWPOverlayEnablerDLL not found");
}
}
}
ImGui::End();
});
}
}

@ -62,7 +62,7 @@ int main(int argc, char* argv[])
const auto overlay_sink = std::make_shared<spdlog::sinks::overlay_sink_mt>();
#ifdef _DEBUG
overlay_sink->set_level(spdlog::level::debug); // TODO: make configurable
overlay_sink->set_level(spdlog::level::debug);
#else
overlay_sink->set_level(spdlog::level::info);
#endif

Loading…
Cancel
Save