win-capture: Add ability to open UWP named kernel objects
The only way to open named kernel objects within a UWP "app" is to get the AppContainer SID, and then open the objects with their full system namespace names via undocumented NT functions.master
parent
b5f216ef88
commit
aeb1d7ae1b
|
@ -1,7 +1,9 @@
|
|||
project(win-capture)
|
||||
|
||||
set(win-capture_HEADERS
|
||||
nt-stuff.h
|
||||
obfuscate.h
|
||||
app-helpers.h
|
||||
hook-helpers.h
|
||||
inject-library.h
|
||||
cursor-capture.h
|
||||
|
@ -12,6 +14,7 @@ set(win-capture_HEADERS
|
|||
set(win-capture_SOURCES
|
||||
dc-capture.c
|
||||
obfuscate.c
|
||||
app-helpers.c
|
||||
inject-library.c
|
||||
cursor-capture.c
|
||||
game-capture.c
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "app-helpers.h"
|
||||
#include "nt-stuff.h"
|
||||
|
||||
WINADVAPI WINAPI ConvertSidToStringSidW(PSID sid, LPWSTR *str);
|
||||
|
||||
bool is_app(HANDLE process)
|
||||
{
|
||||
DWORD size_ret;
|
||||
DWORD ret = 0;
|
||||
HANDLE token;
|
||||
|
||||
if (OpenProcessToken(process, TOKEN_QUERY, &token)) {
|
||||
BOOL success = GetTokenInformation(token, TokenIsAppContainer,
|
||||
&ret, sizeof(ret), &size_ret);
|
||||
if (!success) {
|
||||
DWORD error = GetLastError();
|
||||
int test = 0;
|
||||
}
|
||||
|
||||
CloseHandle(token);
|
||||
}
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
wchar_t *get_app_sid(HANDLE process)
|
||||
{
|
||||
wchar_t *ret = NULL;
|
||||
DWORD size_ret;
|
||||
BOOL success;
|
||||
HANDLE token;
|
||||
|
||||
if (OpenProcessToken(process, TOKEN_QUERY, &token)) {
|
||||
DWORD info_len = GetSidLengthRequired(12) +
|
||||
sizeof(TOKEN_APPCONTAINER_INFORMATION);
|
||||
|
||||
PTOKEN_APPCONTAINER_INFORMATION info = malloc(info_len);
|
||||
|
||||
success = GetTokenInformation(token, TokenAppContainerSid,
|
||||
info, info_len, &size_ret);
|
||||
if (success)
|
||||
ConvertSidToStringSidW(info->TokenAppContainer, &ret);
|
||||
|
||||
free(info);
|
||||
CloseHandle(token);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const wchar_t *path_format =
|
||||
L"\\Sessions\\%lu\\AppContainerNamedObjects\\%s\\%s";
|
||||
|
||||
HANDLE open_app_mutex(const wchar_t *sid, const wchar_t *name)
|
||||
{
|
||||
wchar_t path[MAX_PATH];
|
||||
DWORD session_id = WTSGetActiveConsoleSessionId();
|
||||
_snwprintf(path, MAX_PATH, path_format, session_id, sid, name);
|
||||
return nt_open_mutex(path);
|
||||
}
|
||||
|
||||
HANDLE open_app_event(const wchar_t *sid, const wchar_t *name)
|
||||
{
|
||||
wchar_t path[MAX_PATH];
|
||||
DWORD session_id = WTSGetActiveConsoleSessionId();
|
||||
_snwprintf(path, MAX_PATH, path_format, session_id, sid, name);
|
||||
return nt_open_event(path);
|
||||
}
|
||||
|
||||
HANDLE open_app_map(const wchar_t *sid, const wchar_t *name)
|
||||
{
|
||||
wchar_t path[MAX_PATH];
|
||||
DWORD session_id = WTSGetActiveConsoleSessionId();
|
||||
_snwprintf(path, MAX_PATH, path_format, session_id, sid, name);
|
||||
return nt_open_map(path);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
extern bool is_app(HANDLE process);
|
||||
extern wchar_t *get_app_sid(HANDLE process);
|
||||
extern HANDLE open_app_mutex(const wchar_t *sid, const wchar_t *name);
|
||||
extern HANDLE open_app_event(const wchar_t *sid, const wchar_t *name);
|
||||
extern HANDLE open_app_map(const wchar_t *sid, const wchar_t *name);
|
|
@ -0,0 +1,94 @@
|
|||
#pragma once
|
||||
|
||||
#include <winternl.h>
|
||||
|
||||
#ifndef NT_SUCCESS
|
||||
#define NT_SUCCESS(status) ((NTSTATUS)(status) >= 0)
|
||||
#endif
|
||||
|
||||
#define init_named_attribs(o, name) \
|
||||
do { \
|
||||
(o)->Length = sizeof(*(o)); \
|
||||
(o)->ObjectName = name; \
|
||||
(o)->RootDirectory = NULL; \
|
||||
(o)->Attributes = 0; \
|
||||
(o)->SecurityDescriptor = NULL; \
|
||||
(o)->SecurityQualityOfService = NULL; \
|
||||
} while (false)
|
||||
|
||||
typedef void (WINAPI *RTLINITUNICODESTRINGFUNC)(PCUNICODE_STRING pstr, const wchar_t *lpstrName);
|
||||
typedef NTSTATUS (WINAPI *NTOPENFUNC)(PHANDLE phandle, ACCESS_MASK access, POBJECT_ATTRIBUTES objattr);
|
||||
|
||||
static FARPROC get_nt_func(const char *name)
|
||||
{
|
||||
static bool initialized = false;
|
||||
static HANDLE ntdll = NULL;
|
||||
if (!initialized) {
|
||||
ntdll = GetModuleHandleW(L"ntdll");
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return GetProcAddress(ntdll, name);
|
||||
}
|
||||
|
||||
static void nt_set_last_error(NTSTATUS status)
|
||||
{
|
||||
static bool initialized = false;
|
||||
static RTLNTSTATUSTODOSERRORFUNC func = NULL;
|
||||
|
||||
if (!initialized) {
|
||||
func = (RTLNTSTATUSTODOSERRORFUNC)get_nt_func(
|
||||
"RtlNtStatusToDosError");
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
if (func)
|
||||
SetLastError(func(status));
|
||||
}
|
||||
|
||||
static void rtl_init_str(UNICODE_STRING *unistr, const wchar_t *str)
|
||||
{
|
||||
static bool initialized = false;
|
||||
static RTLINITUNICODESTRINGFUNC func = NULL;
|
||||
|
||||
if (!initialized) {
|
||||
func = (RTLINITUNICODESTRINGFUNC)get_nt_func(
|
||||
"RtlInitUnicodeString");
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
if (func)
|
||||
func(unistr, str);
|
||||
}
|
||||
|
||||
#define MAKE_NT_OPEN_FUNC(func_name, nt_name, access) \
|
||||
static HANDLE func_name(const wchar_t *name) \
|
||||
{ \
|
||||
static bool initialized = false; \
|
||||
static NTOPENFUNC open = NULL; \
|
||||
HANDLE handle; \
|
||||
NTSTATUS status; \
|
||||
UNICODE_STRING unistr; \
|
||||
OBJECT_ATTRIBUTES attr; \
|
||||
\
|
||||
if (!initialized) { \
|
||||
open = (NTOPENFUNC)get_nt_func(#nt_name); \
|
||||
initialized = true; \
|
||||
} \
|
||||
\
|
||||
if (!open) \
|
||||
return NULL; \
|
||||
\
|
||||
rtl_init_str(&unistr, name); \
|
||||
init_named_attribs(&attr, &unistr); \
|
||||
\
|
||||
status = open(&handle, access, &attr); \
|
||||
if (NT_SUCCESS(status)) \
|
||||
return handle; \
|
||||
nt_set_last_error(status); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
MAKE_NT_OPEN_FUNC(nt_open_mutex, NtOpenMutant, SYNCHRONIZE)
|
||||
MAKE_NT_OPEN_FUNC(nt_open_event, NtOpenEvent, EVENT_MODIFY_STATE | SYNCHRONIZE)
|
||||
MAKE_NT_OPEN_FUNC(nt_open_map, NtOpenSection, FILE_MAP_READ | FILE_MAP_WRITE)
|
Loading…
Reference in New Issue