summaryrefslogtreecommitdiffstats
path: root/ceee/common/process_utils_win.h
blob: e928791aa332f41f09c2c488570208754c99dd5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Utilities for process/threads in Windows.

#ifndef CEEE_COMMON_PROCESS_UTILS_WIN_H_
#define CEEE_COMMON_PROCESS_UTILS_WIN_H_

#include <windows.h>
#include <wtypes.h>

#include <string>

#include "base/basictypes.h"
#include "base/singleton.h"
#include "base/process_util.h"

namespace process_utils_win {

// Sets the integrity level of the specified thread, or the current thread
// if thread is NULL. The level is a string as #defined in sddl.h, e.g.,
// SDDL_ML_LOW or any string of the proper SID Component format as described
// here: http://msdn.microsoft.com/en-us/library/aa379597(v=VS.85).aspx
// Will return HRESULT_FROM_WIN32(ERROR_PRIVILEGE_NOT_HELD) if the provided
// thread (or its process) have lower priviliges then the ones requested.
HRESULT SetThreadIntegrityLevel(HANDLE* thread, const std::wstring& level);

// Reset the thread integrity level to the process level. Again, if thread
// is NULL, set the integrity level of the current thread.
HRESULT ResetThreadIntegrityLevel(HANDLE* thread);

// The bool pointer will be set to true if the current process has been started
// in administrator's mode ('Run As Adminstrator') while UAC was active.
// Programs started that way run at different integrity level than these
// invoked by the user in a regular way.
// More detailed analysis is with the implementation.
HRESULT IsCurrentProcessUacElevated(bool* running_as_admin);

// Checks if a given process is compatible with the current process.
// Two processes are compatible if they run on the same platform-compatible and
// are security-compatible.
// The former makes sense on a 64-bit platform, where 32-bit processes inhabit
// a separate subsystem (WOW64). Thus, two processes are platform-compatible
// when both are 32-bit or both are 64-bit. It is noop on 32-bit systems.
// Two processes are security-compatible when their integrity levels permit COM
// communication between them. High integrity processes are compatible only with
// other high integrity processes. A low or a medium integrity process is
// compatible with any process that is either low or medium integrity.
// Some considerations of security-compatibility are expanded upon in comments
// with implementation.
class ProcessCompatibilityCheck {
 public:
  // Is the process associated with the given window compatible with the
  // current process. If the call returns an error code, the value of
  // *is_compatible is undefined.
  static HRESULT IsCompatible(HWND process_window, bool* is_compatible);

  // Is the process of given ID compatible with the current process. If the
  // call returns an error code, the value of *is_compatible is undefined.
  static HRESULT IsCompatible(DWORD process_id, bool* is_compatible);

 protected:
  typedef HANDLE (WINAPI *OpenProcessFuncType)(DWORD, BOOL, DWORD);
  typedef BOOL (WINAPI *CloseHandleFuncType)(HANDLE);
  typedef BOOL (WINAPI *IsWOW64ProcessFuncType)(HANDLE, PBOOL);

  // Non-trivial constructor will initialize default state. Possible error code
  // will be stored for reference.
  ProcessCompatibilityCheck();

  // Exposed for unittesting only.
  static void PatchState(WORD system_type, bool current_process_wow64,
                         bool check_integrity,
                         base::IntegrityLevel current_process_integrity,
                         OpenProcessFuncType open_process_func,
                         CloseHandleFuncType close_handle_func,
                         IsWOW64ProcessFuncType is_wow64_process_func);
  static void PatchState(OpenProcessFuncType open_process_func,
                         CloseHandleFuncType close_handle_func,
                         IsWOW64ProcessFuncType is_wow64_process_func);
  // Reset to normal state.
  static void ResetState();

  // Is the process of given ID compatible with the current process?
  HRESULT IsProcessCompatible(DWORD process_id, bool* is_compatible);

 private:
  // Initialization function taking true system state.
  void StandardInitialize();

  // Initialize call assigning given values to objects.
  void KnownStateInitialize(WORD system_type, bool current_process_wow64,
                            bool check_integrity,
                            base::IntegrityLevel current_process_integrity);

  // Functions checking aspects of 'compatibility' of processes with the
  // current process.
  HRESULT IsProcessPlatformCompatible(HANDLE process_handle,
                                      bool* is_compatible);
  HRESULT IsProcessIntegrityCompatible(HANDLE process_handle,
                                       bool* is_compatible);

  HRESULT initialization_result_;
  bool running_on_amd64_platform_;
  bool running_as_wow_64_;
  bool integrity_checks_on_;
  base::IntegrityLevel running_integrity_;

  // Function pointers held to allow substituting with a test harness.
  static OpenProcessFuncType open_process_func_;
  static CloseHandleFuncType close_handle_func_;
  static IsWOW64ProcessFuncType is_wow64_process_func_;

  friend struct DefaultSingletonTraits<ProcessCompatibilityCheck>;

  DISALLOW_COPY_AND_ASSIGN(ProcessCompatibilityCheck);
};

}  // namespace process_utils_win

#endif  // CEEE_COMMON_PROCESS_UTILS_WIN_H_