Skip to content

Commit

Permalink
feat(soyuz): 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
Fuwn committed Aug 18, 2021
0 parents commit 9cb8192
Show file tree
Hide file tree
Showing 9 changed files with 974 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# IDE
/.idea/

# CMake
/cmake-build-debug/
/build/
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.20)
project(soyuz)

add_subdirectory(${PROJECT_NAME})
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
🚀 Soyuz
=======

Soyuz has one simple purpose; listen for incoming Discord RPC requests from
Lunar Client and block them!

.. raw:: html

<a href="https://github.com/fuwn/soyuz">
<img
src="http://www.spacesafetymagazine.com/wp-content/uploads/2014/08/early-soyuz-capsule.gif"
alt="Soyuz"
width="220">
</a>

Limitations
-----------

- Windows only

Soon to come
------------

- Tray support
- "Startup" support

License
-------

`GNU General Public License v3.0 <./LICENSE>`_
68 changes: 68 additions & 0 deletions include/soyuz/library.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (C) 2021-2021 Fuwn
// SPDX-License-Identifier: GPL-3.0-only

#ifndef SOYUZ_LIBRARY_HH
#define SOYUZ_LIBRARY_HH

#pragma once

#include <Windows.h>

#define NT_SUCCESS(status) (status >= 0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)

enum PROCESSINFOCLASS {
ProcessHandleInformation = 51
};

typedef struct _PROCESS_HANDLE_TABLE_ENTRY_INFO {
HANDLE HandleValue;
ULONG_PTR HandleCount;
ULONG_PTR PointerCount;
ULONG GrantedAccess;
ULONG ObjectTypeIndex;
ULONG HandleAttributes;
ULONG Reserved;
} PROCESS_HANDLE_TABLE_ENTRY_INFO, * PPROCESS_HANDLE_TABLE_ENTRY_INFO;

typedef struct _PROCESS_HANDLE_SNAPSHOT_INFORMATION {
ULONG_PTR NumberOfHandles;
ULONG_PTR Reserved;
PROCESS_HANDLE_TABLE_ENTRY_INFO Handles[1];
} PROCESS_HANDLE_SNAPSHOT_INFORMATION, * PPROCESS_HANDLE_SNAPSHOT_INFORMATION;

extern "C" NTSTATUS NTAPI NtQueryInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);

typedef enum _OBJECT_INFORMATION_CLASS {
ObjectNameInformation = 1
} OBJECT_INFORMATION_CLASS;

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;

typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, * POBJECT_NAME_INFORMATION;

extern "C" NTSTATUS NTAPI NtQueryObject(
_In_opt_ HANDLE Handle,
_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
_Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation,
_In_ ULONG ObjectInformationLength,
_Out_opt_ PULONG ReturnLength
);

static auto enum_windows_proc(HWND hwnd, LPARAM lparam) -> BOOL;
auto find_lunar() -> DWORD;
auto delete_handle(DWORD pid) -> int;

#endif //SOYUZ_LIBRARY_HH
12 changes: 12 additions & 0 deletions include/soyuz/soyuz.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (C) 2021-2021 Fuwn
// SPDX-License-Identifier: GPL-3.0-only

#ifndef SOYUZ_SOYUZ_HH
#define SOYUZ_SOYUZ_HH

#pragma once

#define LUNAR_WINDOW_NAME_BASE "Lunar Client ("
#define DISCORD_IPC_NAMED_PIPE_NAME L"\\Device\\NamedPipe\\discord-ipc-0"

#endif //SOYUZ_SOYUZ_HH
23 changes: 23 additions & 0 deletions soyuz/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
add_executable(${PROJECT_NAME}
library.cc
soyuz.cc
)

target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/include)

set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON
CMAKE_CXX_EXTENSIONS OFF
)
target_compile_features(${PROJECT_NAME} PUBLIC
cxx_std_20
cxx_return_type_deduction
)

if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
target_compile_options(${PROJECT_NAME} PUBLIC -W3)
else()
target_compile_options(${PROJECT_NAME} PUBLIC -Wall)
endif()
add_compile_options(-stdlib=libc++)
130 changes: 130 additions & 0 deletions soyuz/library.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright (C) 2021-2021 Fuwn
// SPDX-License-Identifier: GPL-3.0-only

#include <cstdio>
#include <memory>
#include <string>
#include <Windows.h>

#include "soyuz/library.hh"
#include "soyuz/soyuz.hh"

static auto enum_windows_proc(HWND hwnd, LPARAM lparam) -> BOOL {
int length = GetWindowTextLength(hwnd);
auto title = new CHAR[length + 1];
GetWindowText(hwnd, title, length);

if (strstr(title, LUNAR_WINDOW_NAME_BASE)) {
*((HWND*)lparam) = hwnd;

delete[] title;

return FALSE;
}

delete[] title;

return TRUE;
}

auto find_lunar() -> DWORD {
HWND window = nullptr;
EnumWindows(enum_windows_proc, (LPARAM)&window);

int length = GetWindowTextLength(window);
auto title = new CHAR[length + 1];
GetWindowText(window, title, length);

DWORD pid;
GetWindowThreadProcessId(window, &pid);
return pid;
}

auto delete_handle(DWORD pid) -> int {
HANDLE lunar = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE,
FALSE,
pid
);
if (!lunar) {
printf("could not open handle to lunar client: %lu\n", GetLastError());

return 1;
}

ULONG size = 1 << 10;
std::unique_ptr<BYTE[]> buffer;
for (;;) {
buffer = std::make_unique<BYTE[]>(size);

NTSTATUS status = NtQueryInformationProcess(
lunar,
ProcessHandleInformation,
buffer.get(),
size,
&size
);

if (NT_SUCCESS(status)) { break; }
if (status == STATUS_INFO_LENGTH_MISMATCH) { size += 1 << 10; continue; }

printf("could not enumerate handle\n");

return 1;
}

auto *info = reinterpret_cast<PROCESS_HANDLE_SNAPSHOT_INFORMATION*>(buffer.get());
for (ULONG i = 0; i < info->NumberOfHandles; ++i) {
HANDLE h = info->Handles[i].HandleValue;
HANDLE target;
if (!DuplicateHandle(
lunar,
h,
GetCurrentProcess(),
&target,
0,
FALSE,
DUPLICATE_SAME_ACCESS
)) { continue; }

BYTE name_buffer[1 << 10];
NTSTATUS status = NtQueryObject(
target,
ObjectNameInformation,
name_buffer,
sizeof(name_buffer),
nullptr
);
CloseHandle(target);
if (!NT_SUCCESS(status)) { continue; }

WCHAR target_name[256];
DWORD session_id;
ProcessIdToSessionId(pid, &session_id);
swprintf_s(target_name, DISCORD_IPC_NAMED_PIPE_NAME);
size_t length = wcslen(target_name);

auto *name = reinterpret_cast<UNICODE_STRING*>(name_buffer);
if (name->Buffer && _wcsnicmp(name->Buffer, target_name, length) == 0) {
printf("found lunar client's discord ipc named pipe\n");

DuplicateHandle(
lunar,
h,
GetCurrentProcess(),
&target,

0,
FALSE,
DUPLICATE_CLOSE_SOURCE
);
CloseHandle(target);

printf("closed lunar client's discord ipc named pipe\n");

return 0;
}
}

return 0;
}
27 changes: 27 additions & 0 deletions soyuz/soyuz.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2021-2021 Fuwn
// SPDX-License-Identifier: GPL-3.0-only

#pragma comment(lib, "ntdll.lib")

#include <cstdio>
#include <Windows.h>

#include "soyuz/library.hh"

auto main() -> int {
DWORD pid = find_lunar();
if (pid == 0 || pid == 3435973836) {
printf("could not locate lunar client\n");

return 1;
}
printf("located lunar client: %lu\n\n", pid);

for (;;) {
if (delete_handle(pid) == 1) {
printf("unable to close lunar client's discord ipc named pipe\n");
}
}

return 0;
}

0 comments on commit 9cb8192

Please sign in to comment.