From fbd6445c68745d484d5df8c75b0c12054185958f Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Fri, 16 Sep 2016 01:47:56 +0300 Subject: move source files to src/ --- CMakeLists.txt | 6 +- error.hpp | 26 ------- handle.hpp | 64 ---------------- main.cpp | 210 ----------------------------------------------------- main.rc | 112 ---------------------------- os.hpp | 30 -------- process.hpp | 40 ---------- resource_ids.h | 23 ------ sid.hpp | 68 ----------------- src/error.hpp | 26 +++++++ src/handle.hpp | 64 ++++++++++++++++ src/main.cpp | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rc | 112 ++++++++++++++++++++++++++++ src/os.hpp | 30 ++++++++ src/process.hpp | 40 ++++++++++ src/resource_ids.h | 23 ++++++ src/sid.hpp | 68 +++++++++++++++++ src/token.hpp | 175 ++++++++++++++++++++++++++++++++++++++++++++ token.hpp | 175 -------------------------------------------- 19 files changed, 751 insertions(+), 751 deletions(-) delete mode 100644 error.hpp delete mode 100644 handle.hpp delete mode 100644 main.cpp delete mode 100644 main.rc delete mode 100644 os.hpp delete mode 100644 process.hpp delete mode 100644 resource_ids.h delete mode 100644 sid.hpp create mode 100644 src/error.hpp create mode 100644 src/handle.hpp create mode 100644 src/main.cpp create mode 100644 src/main.rc create mode 100644 src/os.hpp create mode 100644 src/process.hpp create mode 100644 src/resource_ids.h create mode 100644 src/sid.hpp create mode 100644 src/token.hpp delete mode 100644 token.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d01997b..3b9aabf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ project(privilege_test) -file(GLOB ${PROJECT_NAME}_source_files "*.cpp") -file(GLOB ${PROJECT_NAME}_header_files "*.h" "*.hpp") -file(GLOB ${PROJECT_NAME}_resource_files "*.rc") +file(GLOB ${PROJECT_NAME}_source_files "src/*.cpp") +file(GLOB ${PROJECT_NAME}_header_files "src/*.h" "src/*.hpp") +file(GLOB ${PROJECT_NAME}_resource_files "src/*.rc") add_executable(${PROJECT_NAME} WIN32 ${${PROJECT_NAME}_source_files} ${${PROJECT_NAME}_header_files} diff --git a/error.hpp b/error.hpp deleted file mode 100644 index 2ea7f85..0000000 --- a/error.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include - -#include - -typedef std::system_error Error; - -namespace error -{ - inline void raise(const char* function_name) - { - const auto ec = GetLastError(); - throw std::system_error(ec, std::system_category(), function_name); - } - - void report(const Error& e) - { - MessageBoxA(NULL, e.what(), NULL, MB_OK); - } - - int get_code(const Error& e) - { - return e.code().value(); - } -} diff --git a/handle.hpp b/handle.hpp deleted file mode 100644 index 5f83f24..0000000 --- a/handle.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include - -#include - -#include -#include - -class Handle -{ -public: - Handle() = default; - - explicit Handle(HANDLE raw) - : impl{raw} - { } - - Handle(Handle&& other) noexcept - { - swap(other); - } - - Handle& operator=(Handle other) noexcept - { - swap(other); - return *this; - } - - void swap(Handle& other) noexcept - { - using std::swap; - swap(impl, other.impl); - } - - operator HANDLE() const - { - return impl.get(); - } - -private: - struct Close - { - void operator()(HANDLE raw) const - { - if (raw == NULL || raw == INVALID_HANDLE_VALUE) - return; - const auto ret = CloseHandle(raw); - assert(ret); - } - }; - - std::unique_ptr impl; - - Handle(const Handle&) = delete; -}; - -namespace std -{ - void swap(Handle& a, Handle& b) noexcept - { - a.swap(b); - } -} diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 1777d79..0000000 --- a/main.cpp +++ /dev/null @@ -1,210 +0,0 @@ -#include "error.hpp" -#include "os.hpp" -#include "process.hpp" -#include "resource_ids.h" -#include "sid.hpp" -#include "token.hpp" - -#include -#include -#include - -#include - -#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") - -bool is_user_in_administrators() -{ - const auto token = token::impersonate( - token::get_linked( - token::open_for_current_process(token::permissions::query() | token::permissions::duplicate()))); - - return token::belongs(token, sid::builtin_administrators()); -} - -bool is_run_as_administrator() -{ - return token::belongs(token::dumb(), sid::builtin_administrators()); -} - -bool is_elevated() -{ - return token::is_elevated(token::open_for_current_process()); -} - -void set_label(HWND root, int id, bool val) -{ - const auto label = GetDlgItem(root, id); - SetWindowTextW(label, val ? L"True" : L"False"); -} - -void set_label(HWND root, int id, const wchar_t* s) -{ - const auto label = GetDlgItem(root, id); - SetWindowTextW(label, s); -} - -void set_label(HWND root, int id, const std::wstring& s) -{ - const auto label = GetDlgItem(root, id); - SetWindowTextW(label, s.c_str()); -} - -BOOL on_init_dialog(HWND wnd, HWND, LPARAM) -{ - try - { - set_label(wnd, IDC_ADMINISTRATOR, is_user_in_administrators()); - } - catch (const Error& e) - { - set_label(wnd, IDC_ADMINISTRATOR, L"N/A"); - error::report(e); - } - - try - { - set_label(wnd, IDC_RUN_AS_ADMINISTRATOR, is_run_as_administrator()); - } - catch (const Error& e) - { - set_label(wnd, IDC_RUN_AS_ADMINISTRATOR, L"N/A"); - error::report(e); - } - - if (os::is_vista_or_later()) - { - try - { - const auto elevated = is_elevated(); - set_label(wnd, IDC_ELEVATED, elevated); - - const auto elevate_button = GetDlgItem(wnd, IDC_BUTTON_ELEVATE); - Button_SetElevationRequiredState(elevate_button, !elevated); - } - catch (const Error& e) - { - set_label(wnd, IDC_ELEVATED, L"N/A"); - error::report(e); - } - - try - { - set_label(wnd, IDC_INTEGRITY_LEVEL, token::integrity_level_to_string( - token::query_integrity_level(token::open_for_current_process()))); - } - catch (const Error& e) - { - set_label(wnd, IDC_INTEGRITY_LEVEL, L"N/A"); - error::report(e); - } - } - else - { - set_label(wnd, IDC_ELEVATED, L"N/A"); - set_label(wnd, IDC_INTEGRITY_LEVEL, L"N/A"); - } - - return TRUE; -} - -void on_button_elevate_click(HWND wnd) -{ - bool as_admin = false; - - try - { - as_admin = is_run_as_administrator(); - } - catch (const Error& e) - { - error::report(e); - return; - } - - if (as_admin) - { - MessageBoxW(wnd, L"Already elevated!", L"Elevation", MB_OK); - return; - } - - try - { - process::runas(process::get_executable_path()); - } - catch (const Error& e) - { - if (error::get_code(e) != ERROR_CANCELLED) - error::report(e); - return; - } - - EndDialog(wnd, 1); -} - -void on_command(HWND wnd, int id, HWND, unsigned int) -{ - switch (id) - { - case IDC_BUTTON_ELEVATE: - on_button_elevate_click(wnd); - break; - - case IDOK: - case IDCANCEL: - EndDialog(wnd, 0); - break; - } -} - -void on_close(HWND wnd) -{ - EndDialog(wnd, 0); -} - -INT_PTR CALLBACK dialog_main( - HWND wnd, - UINT msg, - WPARAM wParam, - LPARAM lParam) -{ - switch (msg) - { - HANDLE_MSG(wnd, WM_INITDIALOG, on_init_dialog); - HANDLE_MSG(wnd, WM_COMMAND, on_command); - HANDLE_MSG(wnd, WM_CLOSE, on_close); - - default: - return FALSE; - } -} - -int APIENTRY wWinMain( - HINSTANCE instance, - HINSTANCE, - wchar_t*, - int) -{ - const auto ret = DialogBoxW( - instance, - MAKEINTRESOURCE(IDD_MAINDIALOG), - NULL, - dialog_main); - - switch (ret) - { - case -1: - try - { - error::raise("DialogBoxW"); - } - catch (const Error& e) - { - error::report(e); - return 1; - } - - default: - return static_cast(ret); - } -} diff --git a/main.rc b/main.rc deleted file mode 100644 index f98abe4..0000000 --- a/main.rc +++ /dev/null @@ -1,112 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource_ids.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_MAINDIALOG DIALOGEX 0, 0, 120, 79 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Privilege test" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Administrator?",IDC_STATIC,7,7,75,12 - RTEXT "",IDC_ADMINISTRATOR,85,7,28,12 - LTEXT "Run as administrator?",IDC_STATIC,7,19,75,12 - RTEXT "",IDC_RUN_AS_ADMINISTRATOR,85,19,28,12 - LTEXT "Elevated?",IDC_STATIC,7,31,75,12 - RTEXT "",IDC_ELEVATED,85,31,28,12 - LTEXT "Integrity level:",IDC_STATIC,7,43,75,12 - RTEXT "",IDC_INTEGRITY_LEVEL,85,43,28,15 - PUSHBUTTON "Elevate",IDC_BUTTON_ELEVATE,63,58,50,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_MAINDIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 113 - VERTGUIDE, 82 - VERTGUIDE, 85 - TOPMARGIN, 7 - BOTTOMMARGIN, 72 - HORZGUIDE, 19 - HORZGUIDE, 31 - HORZGUIDE, 43 - HORZGUIDE, 58 - END -END -#endif // APSTUDIO_INVOKED - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource_ids.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/os.hpp b/os.hpp deleted file mode 100644 index 1a3c52d..0000000 --- a/os.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "error.hpp" - -#include - -namespace os -{ - OSVERSIONINFOW get_version_info() - { - OSVERSIONINFOW info; - ZeroMemory(&info, sizeof(info)); - info.dwOSVersionInfoSize = sizeof(info); - - if (!GetVersionExW(&info)) - error::raise("GetVersionExW"); - - return info; - } - - bool is_vista_or_later(const OSVERSIONINFOW& info) - { - return info.dwMajorVersion >= 6; - } - - bool is_vista_or_later() - { - return is_vista_or_later(get_version_info()); - } -} diff --git a/process.hpp b/process.hpp deleted file mode 100644 index 864d452..0000000 --- a/process.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "error.hpp" - -#include -#include - -#include -#include - -namespace process -{ - std::wstring get_executable_path() - { - static constexpr DWORD max_path = MAX_PATH; - - std::array buf; - - const auto ret = GetModuleFileNameW(NULL, buf.data(), max_path); - - if (GetLastError() != ERROR_SUCCESS) - error::raise("GetModuleFileNameW"); - - return buf.data(); - } - - void runas(const std::wstring& exe_path, HWND hwnd = NULL, int nShow = SW_NORMAL) - { - SHELLEXECUTEINFOW info; - ZeroMemory(&info, sizeof(info)); - info.cbSize = sizeof(info); - info.lpVerb = L"runas"; - info.lpFile = exe_path.c_str(); - info.hwnd = hwnd; - info.nShow = nShow; - - if (!ShellExecuteExW(&info)) - error::raise("ShellExecuteExW"); - } -} diff --git a/resource_ids.h b/resource_ids.h deleted file mode 100644 index 353dbd2..0000000 --- a/resource_ids.h +++ /dev/null @@ -1,23 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by resource.rc -// -#define IDD_MAINDIALOG 100 -#define IDC_BUTTON_ELEVATE 1000 -#define IDC_ADMINISTRATOR 1001 -#define IDC_RUN_AS_ADMINISTRATOR 1002 -#define IDC_ELEVATED 1003 -#define IDC_INTEGRITY_LEVEL 1004 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 129 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1005 -#define _APS_NEXT_SYMED_VALUE 110 -#endif -#endif diff --git a/sid.hpp b/sid.hpp deleted file mode 100644 index 15ce73b..0000000 --- a/sid.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include "error.hpp" - -#include -#include - -#include -#include -#include - -constexpr DWORD max_sid_size = SECURITY_MAX_SID_SIZE; -typedef std::array SidBuffer; - -namespace sid -{ - SidBuffer well_known(WELL_KNOWN_SID_TYPE type) - { - SidBuffer buffer; - DWORD cb = static_cast(buffer.size()); - - if (!CreateWellKnownSid(type, NULL, buffer.data(), &cb)) - error::raise("CreateWellKnownSid"); - - return buffer; - } - - SidBuffer builtin_administrators() - { - /* - void* sid = nullptr; - SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY; - - if (!AllocateAndInitializeSid( - &authority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, - &sid)) - { - error::raise("AllocateAndInitializeSid"); - } - - return std::unique_ptr{sid}; - */ - - return well_known(WinBuiltinAdministratorsSid); - } - - struct DeleteSidString - { - void operator()(wchar_t* s) const - { - LocalFree(s); - } - }; - - std::wstring to_string(const SidBuffer& sid) - { - wchar_t* s = nullptr; - - if (!ConvertSidToStringSidW(const_cast(sid.data()), &s)) - error::raise("ConvertSidToStringSidW"); - - return std::unique_ptr{s}.get(); - } -} diff --git a/src/error.hpp b/src/error.hpp new file mode 100644 index 0000000..2ea7f85 --- /dev/null +++ b/src/error.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include + +typedef std::system_error Error; + +namespace error +{ + inline void raise(const char* function_name) + { + const auto ec = GetLastError(); + throw std::system_error(ec, std::system_category(), function_name); + } + + void report(const Error& e) + { + MessageBoxA(NULL, e.what(), NULL, MB_OK); + } + + int get_code(const Error& e) + { + return e.code().value(); + } +} diff --git a/src/handle.hpp b/src/handle.hpp new file mode 100644 index 0000000..5f83f24 --- /dev/null +++ b/src/handle.hpp @@ -0,0 +1,64 @@ +#pragma once + +#include + +#include + +#include +#include + +class Handle +{ +public: + Handle() = default; + + explicit Handle(HANDLE raw) + : impl{raw} + { } + + Handle(Handle&& other) noexcept + { + swap(other); + } + + Handle& operator=(Handle other) noexcept + { + swap(other); + return *this; + } + + void swap(Handle& other) noexcept + { + using std::swap; + swap(impl, other.impl); + } + + operator HANDLE() const + { + return impl.get(); + } + +private: + struct Close + { + void operator()(HANDLE raw) const + { + if (raw == NULL || raw == INVALID_HANDLE_VALUE) + return; + const auto ret = CloseHandle(raw); + assert(ret); + } + }; + + std::unique_ptr impl; + + Handle(const Handle&) = delete; +}; + +namespace std +{ + void swap(Handle& a, Handle& b) noexcept + { + a.swap(b); + } +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..1777d79 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,210 @@ +#include "error.hpp" +#include "os.hpp" +#include "process.hpp" +#include "resource_ids.h" +#include "sid.hpp" +#include "token.hpp" + +#include +#include +#include + +#include + +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") + +bool is_user_in_administrators() +{ + const auto token = token::impersonate( + token::get_linked( + token::open_for_current_process(token::permissions::query() | token::permissions::duplicate()))); + + return token::belongs(token, sid::builtin_administrators()); +} + +bool is_run_as_administrator() +{ + return token::belongs(token::dumb(), sid::builtin_administrators()); +} + +bool is_elevated() +{ + return token::is_elevated(token::open_for_current_process()); +} + +void set_label(HWND root, int id, bool val) +{ + const auto label = GetDlgItem(root, id); + SetWindowTextW(label, val ? L"True" : L"False"); +} + +void set_label(HWND root, int id, const wchar_t* s) +{ + const auto label = GetDlgItem(root, id); + SetWindowTextW(label, s); +} + +void set_label(HWND root, int id, const std::wstring& s) +{ + const auto label = GetDlgItem(root, id); + SetWindowTextW(label, s.c_str()); +} + +BOOL on_init_dialog(HWND wnd, HWND, LPARAM) +{ + try + { + set_label(wnd, IDC_ADMINISTRATOR, is_user_in_administrators()); + } + catch (const Error& e) + { + set_label(wnd, IDC_ADMINISTRATOR, L"N/A"); + error::report(e); + } + + try + { + set_label(wnd, IDC_RUN_AS_ADMINISTRATOR, is_run_as_administrator()); + } + catch (const Error& e) + { + set_label(wnd, IDC_RUN_AS_ADMINISTRATOR, L"N/A"); + error::report(e); + } + + if (os::is_vista_or_later()) + { + try + { + const auto elevated = is_elevated(); + set_label(wnd, IDC_ELEVATED, elevated); + + const auto elevate_button = GetDlgItem(wnd, IDC_BUTTON_ELEVATE); + Button_SetElevationRequiredState(elevate_button, !elevated); + } + catch (const Error& e) + { + set_label(wnd, IDC_ELEVATED, L"N/A"); + error::report(e); + } + + try + { + set_label(wnd, IDC_INTEGRITY_LEVEL, token::integrity_level_to_string( + token::query_integrity_level(token::open_for_current_process()))); + } + catch (const Error& e) + { + set_label(wnd, IDC_INTEGRITY_LEVEL, L"N/A"); + error::report(e); + } + } + else + { + set_label(wnd, IDC_ELEVATED, L"N/A"); + set_label(wnd, IDC_INTEGRITY_LEVEL, L"N/A"); + } + + return TRUE; +} + +void on_button_elevate_click(HWND wnd) +{ + bool as_admin = false; + + try + { + as_admin = is_run_as_administrator(); + } + catch (const Error& e) + { + error::report(e); + return; + } + + if (as_admin) + { + MessageBoxW(wnd, L"Already elevated!", L"Elevation", MB_OK); + return; + } + + try + { + process::runas(process::get_executable_path()); + } + catch (const Error& e) + { + if (error::get_code(e) != ERROR_CANCELLED) + error::report(e); + return; + } + + EndDialog(wnd, 1); +} + +void on_command(HWND wnd, int id, HWND, unsigned int) +{ + switch (id) + { + case IDC_BUTTON_ELEVATE: + on_button_elevate_click(wnd); + break; + + case IDOK: + case IDCANCEL: + EndDialog(wnd, 0); + break; + } +} + +void on_close(HWND wnd) +{ + EndDialog(wnd, 0); +} + +INT_PTR CALLBACK dialog_main( + HWND wnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + switch (msg) + { + HANDLE_MSG(wnd, WM_INITDIALOG, on_init_dialog); + HANDLE_MSG(wnd, WM_COMMAND, on_command); + HANDLE_MSG(wnd, WM_CLOSE, on_close); + + default: + return FALSE; + } +} + +int APIENTRY wWinMain( + HINSTANCE instance, + HINSTANCE, + wchar_t*, + int) +{ + const auto ret = DialogBoxW( + instance, + MAKEINTRESOURCE(IDD_MAINDIALOG), + NULL, + dialog_main); + + switch (ret) + { + case -1: + try + { + error::raise("DialogBoxW"); + } + catch (const Error& e) + { + error::report(e); + return 1; + } + + default: + return static_cast(ret); + } +} diff --git a/src/main.rc b/src/main.rc new file mode 100644 index 0000000..70c04e5 --- /dev/null +++ b/src/main.rc @@ -0,0 +1,112 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource_ids.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MAINDIALOG DIALOGEX 0, 0, 120, 79 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Privilege test" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Administrator?",IDC_STATIC,7,7,75,12 + RTEXT "",IDC_ADMINISTRATOR,85,7,28,12 + LTEXT "Run as administrator?",IDC_STATIC,7,19,75,12 + RTEXT "",IDC_RUN_AS_ADMINISTRATOR,85,19,28,12 + LTEXT "Elevated?",IDC_STATIC,7,31,75,12 + RTEXT "",IDC_ELEVATED,85,31,28,12 + LTEXT "Integrity level:",IDC_STATIC,7,43,75,12 + RTEXT "",IDC_INTEGRITY_LEVEL,85,43,28,15 + PUSHBUTTON "Elevate",IDC_BUTTON_ELEVATE,63,58,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_MAINDIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 113 + VERTGUIDE, 82 + VERTGUIDE, 85 + TOPMARGIN, 7 + BOTTOMMARGIN, 72 + HORZGUIDE, 19 + HORZGUIDE, 31 + HORZGUIDE, 43 + HORZGUIDE, 58 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource_ids.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/os.hpp b/src/os.hpp new file mode 100644 index 0000000..1a3c52d --- /dev/null +++ b/src/os.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "error.hpp" + +#include + +namespace os +{ + OSVERSIONINFOW get_version_info() + { + OSVERSIONINFOW info; + ZeroMemory(&info, sizeof(info)); + info.dwOSVersionInfoSize = sizeof(info); + + if (!GetVersionExW(&info)) + error::raise("GetVersionExW"); + + return info; + } + + bool is_vista_or_later(const OSVERSIONINFOW& info) + { + return info.dwMajorVersion >= 6; + } + + bool is_vista_or_later() + { + return is_vista_or_later(get_version_info()); + } +} diff --git a/src/process.hpp b/src/process.hpp new file mode 100644 index 0000000..864d452 --- /dev/null +++ b/src/process.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "error.hpp" + +#include +#include + +#include +#include + +namespace process +{ + std::wstring get_executable_path() + { + static constexpr DWORD max_path = MAX_PATH; + + std::array buf; + + const auto ret = GetModuleFileNameW(NULL, buf.data(), max_path); + + if (GetLastError() != ERROR_SUCCESS) + error::raise("GetModuleFileNameW"); + + return buf.data(); + } + + void runas(const std::wstring& exe_path, HWND hwnd = NULL, int nShow = SW_NORMAL) + { + SHELLEXECUTEINFOW info; + ZeroMemory(&info, sizeof(info)); + info.cbSize = sizeof(info); + info.lpVerb = L"runas"; + info.lpFile = exe_path.c_str(); + info.hwnd = hwnd; + info.nShow = nShow; + + if (!ShellExecuteExW(&info)) + error::raise("ShellExecuteExW"); + } +} diff --git a/src/resource_ids.h b/src/resource_ids.h new file mode 100644 index 0000000..4c6d90f --- /dev/null +++ b/src/resource_ids.h @@ -0,0 +1,23 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDD_MAINDIALOG 100 +#define IDC_BUTTON_ELEVATE 1000 +#define IDC_ADMINISTRATOR 1001 +#define IDC_RUN_AS_ADMINISTRATOR 1002 +#define IDC_ELEVATED 1003 +#define IDC_INTEGRITY_LEVEL 1004 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1005 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/src/sid.hpp b/src/sid.hpp new file mode 100644 index 0000000..15ce73b --- /dev/null +++ b/src/sid.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include "error.hpp" + +#include +#include + +#include +#include +#include + +constexpr DWORD max_sid_size = SECURITY_MAX_SID_SIZE; +typedef std::array SidBuffer; + +namespace sid +{ + SidBuffer well_known(WELL_KNOWN_SID_TYPE type) + { + SidBuffer buffer; + DWORD cb = static_cast(buffer.size()); + + if (!CreateWellKnownSid(type, NULL, buffer.data(), &cb)) + error::raise("CreateWellKnownSid"); + + return buffer; + } + + SidBuffer builtin_administrators() + { + /* + void* sid = nullptr; + SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY; + + if (!AllocateAndInitializeSid( + &authority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &sid)) + { + error::raise("AllocateAndInitializeSid"); + } + + return std::unique_ptr{sid}; + */ + + return well_known(WinBuiltinAdministratorsSid); + } + + struct DeleteSidString + { + void operator()(wchar_t* s) const + { + LocalFree(s); + } + }; + + std::wstring to_string(const SidBuffer& sid) + { + wchar_t* s = nullptr; + + if (!ConvertSidToStringSidW(const_cast(sid.data()), &s)) + error::raise("ConvertSidToStringSidW"); + + return std::unique_ptr{s}.get(); + } +} diff --git a/src/token.hpp b/src/token.hpp new file mode 100644 index 0000000..5669970 --- /dev/null +++ b/src/token.hpp @@ -0,0 +1,175 @@ +#pragma once + +#include "error.hpp" +#include "handle.hpp" +#include "os.hpp" +#include "sid.hpp" + +#include + +#include +#include +#include +#include + +namespace token +{ + namespace permissions + { + constexpr DWORD query() { return TOKEN_QUERY; } + + constexpr DWORD duplicate() { return TOKEN_DUPLICATE; } + } + + constexpr DWORD default_permissions = permissions::query(); + + // Current thread's primary impersonation token. + Handle dumb() { return Handle{NULL}; } + + Handle open_for_process( + const Handle& process, + DWORD permissions = default_permissions) + { + HANDLE raw; + + if (!OpenProcessToken(process, permissions, &raw)) + error::raise("OpenProcessToken"); + + return Handle{raw}; + } + + Handle open_for_current_process( + DWORD permissions = default_permissions) + { + return open_for_process(Handle{GetCurrentProcess()}, permissions); + } + + Handle get_linked(Handle&& token) + { + if (!os::is_vista_or_later()) + return std::move(token); + + auto type = TokenElevationTypeDefault; + DWORD cb = 0; + + if (!GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &cb)) + error::raise("GetTokenInformation"); + + if (type != TokenElevationTypeLimited) + return std::move(token); + + HANDLE raw; + + if (!GetTokenInformation(token, TokenLinkedToken, &raw, sizeof(raw), &cb)) + error::raise("GetTokenInformation"); + + return Handle{raw}; + } + + Handle impersonate(const Handle& token) + { + HANDLE raw; + + if (!DuplicateToken(token, SecurityIdentification, &raw)) + error::raise("DuplicateToken"); + + return Handle{raw}; + } + + // + // FUNCTION: query_integrity_level() + // + // RETURN VALUE: Returns the integrity level of the current process. It is + // usually one of these values: + // + // SECURITY_MANDATORY_UNTRUSTED_RID (SID: S-1-16-0x0) + // Means untrusted level. It is used by processes started by the + // Anonymous group. Blocks most write access. + // + // SECURITY_MANDATORY_LOW_RID (SID: S-1-16-0x1000) + // Means low integrity level. It is used by Protected Mode Internet + // Explorer. Blocks write acess to most objects (such as files and + // registry keys) on the system. + // + // SECURITY_MANDATORY_MEDIUM_RID (SID: S-1-16-0x2000) + // Means medium integrity level. It is used by normal applications + // being launched while UAC is enabled. + // + // SECURITY_MANDATORY_HIGH_RID (SID: S-1-16-0x3000) + // Means high integrity level. It is used by administrative applications + // launched through elevation when UAC is enabled, or normal + // applications if UAC is disabled and the user is an administrator. + // + // SECURITY_MANDATORY_SYSTEM_RID (SID: S-1-16-0x4000) + // Means system integrity level. It is used by services and other + // system-level applications (such as Wininit, Winlogon, Smss, etc.) + // + DWORD query_integrity_level(const Handle& token) + { + DWORD cb = 0; + + if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &cb)) + { + switch (GetLastError()) + { + case ERROR_INSUFFICIENT_BUFFER: + break; + default: + error::raise("GetTokenInformation"); + } + } + + std::vector buf(cb); + const auto token_level = reinterpret_cast(buf.data()); + + if (!GetTokenInformation(token, TokenIntegrityLevel, token_level, cb, &cb)) + error::raise("GetTokenInformation"); + + // Integrity Level SIDs are in the form of S-1-16-0xXXXX. (e.g. + // S-1-16-0x1000 stands for low integrity level SID). There is one and + // only one subauthority. + return *GetSidSubAuthority(token_level->Label.Sid, 0); + } + + std::wstring integrity_level_to_string(DWORD level) + { + static const std::unordered_map names = + { + {SECURITY_MANDATORY_UNTRUSTED_RID, L"Untrusted"}, + {SECURITY_MANDATORY_LOW_RID, L"Low"}, + {SECURITY_MANDATORY_MEDIUM_RID, L"Medium"}, + {SECURITY_MANDATORY_HIGH_RID, L"High"}, + {SECURITY_MANDATORY_SYSTEM_RID, L"System"}, + }; + + static constexpr auto unknown_name = L"Unknown"; + + const auto it = names.find(level); + + if (it == names.cend()) + return unknown_name; + + return it->second; + } + + bool belongs(const Handle& token, const SidBuffer& sid) + { + BOOL b = FALSE; + + if (!CheckTokenMembership(token, const_cast(sid.data()), &b)) + error::raise("CheckTokenMembership"); + + return b != FALSE; + } + + bool is_elevated(const Handle& token) + { + TOKEN_ELEVATION elevation; + DWORD cb = 0; + + if (!GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &cb)) + error::raise("GetTokenInformation"); + + return elevation.TokenIsElevated != 0; + } +} diff --git a/token.hpp b/token.hpp deleted file mode 100644 index 5669970..0000000 --- a/token.hpp +++ /dev/null @@ -1,175 +0,0 @@ -#pragma once - -#include "error.hpp" -#include "handle.hpp" -#include "os.hpp" -#include "sid.hpp" - -#include - -#include -#include -#include -#include - -namespace token -{ - namespace permissions - { - constexpr DWORD query() { return TOKEN_QUERY; } - - constexpr DWORD duplicate() { return TOKEN_DUPLICATE; } - } - - constexpr DWORD default_permissions = permissions::query(); - - // Current thread's primary impersonation token. - Handle dumb() { return Handle{NULL}; } - - Handle open_for_process( - const Handle& process, - DWORD permissions = default_permissions) - { - HANDLE raw; - - if (!OpenProcessToken(process, permissions, &raw)) - error::raise("OpenProcessToken"); - - return Handle{raw}; - } - - Handle open_for_current_process( - DWORD permissions = default_permissions) - { - return open_for_process(Handle{GetCurrentProcess()}, permissions); - } - - Handle get_linked(Handle&& token) - { - if (!os::is_vista_or_later()) - return std::move(token); - - auto type = TokenElevationTypeDefault; - DWORD cb = 0; - - if (!GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &cb)) - error::raise("GetTokenInformation"); - - if (type != TokenElevationTypeLimited) - return std::move(token); - - HANDLE raw; - - if (!GetTokenInformation(token, TokenLinkedToken, &raw, sizeof(raw), &cb)) - error::raise("GetTokenInformation"); - - return Handle{raw}; - } - - Handle impersonate(const Handle& token) - { - HANDLE raw; - - if (!DuplicateToken(token, SecurityIdentification, &raw)) - error::raise("DuplicateToken"); - - return Handle{raw}; - } - - // - // FUNCTION: query_integrity_level() - // - // RETURN VALUE: Returns the integrity level of the current process. It is - // usually one of these values: - // - // SECURITY_MANDATORY_UNTRUSTED_RID (SID: S-1-16-0x0) - // Means untrusted level. It is used by processes started by the - // Anonymous group. Blocks most write access. - // - // SECURITY_MANDATORY_LOW_RID (SID: S-1-16-0x1000) - // Means low integrity level. It is used by Protected Mode Internet - // Explorer. Blocks write acess to most objects (such as files and - // registry keys) on the system. - // - // SECURITY_MANDATORY_MEDIUM_RID (SID: S-1-16-0x2000) - // Means medium integrity level. It is used by normal applications - // being launched while UAC is enabled. - // - // SECURITY_MANDATORY_HIGH_RID (SID: S-1-16-0x3000) - // Means high integrity level. It is used by administrative applications - // launched through elevation when UAC is enabled, or normal - // applications if UAC is disabled and the user is an administrator. - // - // SECURITY_MANDATORY_SYSTEM_RID (SID: S-1-16-0x4000) - // Means system integrity level. It is used by services and other - // system-level applications (such as Wininit, Winlogon, Smss, etc.) - // - DWORD query_integrity_level(const Handle& token) - { - DWORD cb = 0; - - if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &cb)) - { - switch (GetLastError()) - { - case ERROR_INSUFFICIENT_BUFFER: - break; - default: - error::raise("GetTokenInformation"); - } - } - - std::vector buf(cb); - const auto token_level = reinterpret_cast(buf.data()); - - if (!GetTokenInformation(token, TokenIntegrityLevel, token_level, cb, &cb)) - error::raise("GetTokenInformation"); - - // Integrity Level SIDs are in the form of S-1-16-0xXXXX. (e.g. - // S-1-16-0x1000 stands for low integrity level SID). There is one and - // only one subauthority. - return *GetSidSubAuthority(token_level->Label.Sid, 0); - } - - std::wstring integrity_level_to_string(DWORD level) - { - static const std::unordered_map names = - { - {SECURITY_MANDATORY_UNTRUSTED_RID, L"Untrusted"}, - {SECURITY_MANDATORY_LOW_RID, L"Low"}, - {SECURITY_MANDATORY_MEDIUM_RID, L"Medium"}, - {SECURITY_MANDATORY_HIGH_RID, L"High"}, - {SECURITY_MANDATORY_SYSTEM_RID, L"System"}, - }; - - static constexpr auto unknown_name = L"Unknown"; - - const auto it = names.find(level); - - if (it == names.cend()) - return unknown_name; - - return it->second; - } - - bool belongs(const Handle& token, const SidBuffer& sid) - { - BOOL b = FALSE; - - if (!CheckTokenMembership(token, const_cast(sid.data()), &b)) - error::raise("CheckTokenMembership"); - - return b != FALSE; - } - - bool is_elevated(const Handle& token) - { - TOKEN_ELEVATION elevation; - DWORD cb = 0; - - if (!GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &cb)) - error::raise("GetTokenInformation"); - - return elevation.TokenIsElevated != 0; - } -} -- cgit v1.2.3