1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "util/win/nt_internals.h"
16 
17 #include "util/win/get_function.h"
18 
19 // Declarations that the system headers should provide but don’t.
20 
21 extern "C" {
22 
23 NTSTATUS NTAPI NtCreateThreadEx(PHANDLE ThreadHandle,
24                                 ACCESS_MASK DesiredAccess,
25                                 POBJECT_ATTRIBUTES ObjectAttributes,
26                                 HANDLE ProcessHandle,
27                                 PVOID StartRoutine,
28                                 PVOID Argument,
29                                 ULONG CreateFlags,
30                                 SIZE_T ZeroBits,
31                                 SIZE_T StackSize,
32                                 SIZE_T MaximumStackSize,
33                                 PVOID /*PPS_ATTRIBUTE_LIST*/ AttributeList);
34 
35 NTSTATUS NTAPI NtOpenThread(HANDLE* ThreadHandle,
36                             ACCESS_MASK DesiredAccess,
37                             OBJECT_ATTRIBUTES* ObjectAttributes,
38                             CLIENT_ID* ClientId);
39 
40 NTSTATUS NTAPI NtSuspendProcess(HANDLE);
41 
42 NTSTATUS NTAPI NtResumeProcess(HANDLE);
43 
44 VOID NTAPI RtlGetUnloadEventTraceEx(PULONG* ElementSize,
45                                     PULONG* ElementCount,
46                                     PVOID* EventTrace);
47 
48 }  // extern "C"
49 
50 namespace crashpad {
51 
NtClose(HANDLE handle)52 NTSTATUS NtClose(HANDLE handle) {
53   static const auto nt_close = GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtClose);
54   return nt_close(handle);
55 }
56 
57 NTSTATUS
NtCreateThreadEx(PHANDLE thread_handle,ACCESS_MASK desired_access,POBJECT_ATTRIBUTES object_attributes,HANDLE process_handle,PVOID start_routine,PVOID argument,ULONG create_flags,SIZE_T zero_bits,SIZE_T stack_size,SIZE_T maximum_stack_size,PVOID attribute_list)58 NtCreateThreadEx(PHANDLE thread_handle,
59                  ACCESS_MASK desired_access,
60                  POBJECT_ATTRIBUTES object_attributes,
61                  HANDLE process_handle,
62                  PVOID start_routine,
63                  PVOID argument,
64                  ULONG create_flags,
65                  SIZE_T zero_bits,
66                  SIZE_T stack_size,
67                  SIZE_T maximum_stack_size,
68                  PVOID attribute_list) {
69   static const auto nt_create_thread_ex =
70       GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtCreateThreadEx);
71   return nt_create_thread_ex(thread_handle,
72                              desired_access,
73                              object_attributes,
74                              process_handle,
75                              start_routine,
76                              argument,
77                              create_flags,
78                              zero_bits,
79                              stack_size,
80                              maximum_stack_size,
81                              attribute_list);
82 }
83 
NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS system_information_class,PVOID system_information,ULONG system_information_length,PULONG return_length)84 NTSTATUS NtQuerySystemInformation(
85     SYSTEM_INFORMATION_CLASS system_information_class,
86     PVOID system_information,
87     ULONG system_information_length,
88     PULONG return_length) {
89   static const auto nt_query_system_information =
90       GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQuerySystemInformation);
91   return nt_query_system_information(system_information_class,
92                                      system_information,
93                                      system_information_length,
94                                      return_length);
95 }
96 
NtQueryInformationThread(HANDLE thread_handle,THREADINFOCLASS thread_information_class,PVOID thread_information,ULONG thread_information_length,PULONG return_length)97 NTSTATUS NtQueryInformationThread(HANDLE thread_handle,
98                                   THREADINFOCLASS thread_information_class,
99                                   PVOID thread_information,
100                                   ULONG thread_information_length,
101                                   PULONG return_length) {
102   static const auto nt_query_information_thread =
103       GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQueryInformationThread);
104   return nt_query_information_thread(thread_handle,
105                                      thread_information_class,
106                                      thread_information,
107                                      thread_information_length,
108                                      return_length);
109 }
110 
111 template <class Traits>
NtOpenThread(PHANDLE thread_handle,ACCESS_MASK desired_access,POBJECT_ATTRIBUTES object_attributes,const process_types::CLIENT_ID<Traits> * client_id)112 NTSTATUS NtOpenThread(PHANDLE thread_handle,
113                       ACCESS_MASK desired_access,
114                       POBJECT_ATTRIBUTES object_attributes,
115                       const process_types::CLIENT_ID<Traits>* client_id) {
116   static const auto nt_open_thread =
117       GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtOpenThread);
118   return nt_open_thread(
119       thread_handle,
120       desired_access,
121       object_attributes,
122       const_cast<CLIENT_ID*>(reinterpret_cast<const CLIENT_ID*>(client_id)));
123 }
124 
NtQueryObject(HANDLE handle,OBJECT_INFORMATION_CLASS object_information_class,void * object_information,ULONG object_information_length,ULONG * return_length)125 NTSTATUS NtQueryObject(HANDLE handle,
126                        OBJECT_INFORMATION_CLASS object_information_class,
127                        void* object_information,
128                        ULONG object_information_length,
129                        ULONG* return_length) {
130   static const auto nt_query_object =
131       GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQueryObject);
132   return nt_query_object(handle,
133                          object_information_class,
134                          object_information,
135                          object_information_length,
136                          return_length);
137 }
138 
NtSuspendProcess(HANDLE handle)139 NTSTATUS NtSuspendProcess(HANDLE handle) {
140   static const auto nt_suspend_process =
141       GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtSuspendProcess);
142   return nt_suspend_process(handle);
143 }
144 
NtResumeProcess(HANDLE handle)145 NTSTATUS NtResumeProcess(HANDLE handle) {
146   static const auto nt_resume_process =
147       GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtResumeProcess);
148   return nt_resume_process(handle);
149 }
150 
RtlGetUnloadEventTraceEx(ULONG ** element_size,ULONG ** element_count,void ** event_trace)151 void RtlGetUnloadEventTraceEx(ULONG** element_size,
152                               ULONG** element_count,
153                               void** event_trace) {
154   static const auto rtl_get_unload_event_trace_ex =
155       GET_FUNCTION_REQUIRED(L"ntdll.dll", ::RtlGetUnloadEventTraceEx);
156   rtl_get_unload_event_trace_ex(element_size, element_count, event_trace);
157 }
158 
159 // Explicit instantiations with the only 2 valid template arguments to avoid
160 // putting the body of the function in the header.
161 template NTSTATUS NtOpenThread<process_types::internal::Traits32>(
162     PHANDLE thread_handle,
163     ACCESS_MASK desired_access,
164     POBJECT_ATTRIBUTES object_attributes,
165     const process_types::CLIENT_ID<process_types::internal::Traits32>*
166         client_id);
167 
168 template NTSTATUS NtOpenThread<process_types::internal::Traits64>(
169     PHANDLE thread_handle,
170     ACCESS_MASK desired_access,
171     POBJECT_ATTRIBUTES object_attributes,
172     const process_types::CLIENT_ID<process_types::internal::Traits64>*
173         client_id);
174 
175 }  // namespace crashpad
176