@@ -41,9 +41,14 @@ def shell_exec(command, args)
41
41
end
42
42
end
43
43
44
+ #
45
+ # Create a STARTUP_INFO struct for use with CreateProcessa
46
+ #
47
+ # This struct will cause the process to be hidden
48
+ #
49
+ # @return [String] STARTUP_INFO struct
50
+ #
44
51
def startup_info
45
- # this is start info struct for a hidden process last two params are std out and in.
46
- #for hidden startup_info[12] = STARTF_USESHOWWINDOW and startup_info[13] = 0 = SW_HIDE
47
52
[ 0 , # cb
48
53
0 , # lpReserved
49
54
0 , # lpDesktop
@@ -65,6 +70,19 @@ def startup_info
65
70
] . pack ( 'VVVVVVVVVVVVvvVVVV' )
66
71
end
67
72
73
+ #
74
+ # Call CreateProcessWithLogonW to start a process with the supplier
75
+ # user credentials
76
+ #
77
+ # @param domain [String] The target user domain
78
+ # @param user [String] The target user
79
+ # @param password [String] The target user password
80
+ # @param application_name [String] The executable to be run, can be
81
+ # nil
82
+ # @param command_line [String] The command line or process arguments
83
+ #
84
+ # @return [Hash, nil] The values from the process_information struct
85
+ #
68
86
def create_process_with_logon ( domain , user , password , application_name , command_line )
69
87
return unless check_user_format ( user , domain )
70
88
return unless check_command_length ( application_name , command_line , 1024 )
@@ -92,11 +110,25 @@ def create_process_with_logon(domain, user, password, application_name, command_
92
110
pi
93
111
end
94
112
113
+ #
114
+ # Call CreateProcessAsUser to start a process with the supplier
115
+ # user credentials
116
+ #
95
117
# Can be used by SYSTEM processes with the SE_INCREASE_QUOTA_NAME and
96
118
# SE_ASSIGNPRIMARYTOKEN_NAME privileges.
97
119
#
98
120
# This will normally error with 0xc000142 on later OS's (Vista+?) for
99
121
# gui apps but is ok for firing off cmd.exe...
122
+ #
123
+ # @param domain [String] The target user domain
124
+ # @param user [String] The target user
125
+ # @param password [String] The target user password
126
+ # @param application_name [String] The executable to be run, can be
127
+ # nil
128
+ # @param command_line [String] The command line or process arguments
129
+ #
130
+ # @return [Hash, nil] The values from the process_information struct
131
+ #
100
132
def create_process_as_user ( domain , user , password , application_name , command_line )
101
133
return unless check_user_format ( user , domain )
102
134
return unless check_command_length ( application_name , command_line , 32000 )
@@ -148,11 +180,30 @@ def create_process_as_user(domain, user, password, application_name, command_lin
148
180
nil
149
181
end
150
182
183
+ #
184
+ # Parse the PROCESS_INFORMATION struct
185
+ #
186
+ # @param process_information [String] The PROCESS_INFORMATION value
187
+ # from the CreateProcess call
188
+ #
189
+ # @return [Hash] The values from the process_information struct
190
+ #
151
191
def parse_process_information ( process_information )
152
192
pi = process_information . unpack ( 'LLLL' )
153
193
{ :process_handle => pi [ 0 ] , :thread_handle => pi [ 1 ] , :process_id => pi [ 2 ] , :thread_id => pi [ 3 ] }
154
194
end
155
195
196
+ #
197
+ # Checks the username and domain is in the correct format
198
+ # for the CreateProcess_x WinAPI calls.
199
+ #
200
+ # @param username [String] The target user
201
+ # @param domain [String] The target user domain
202
+ #
203
+ # @raise [ArgumentError] If the username format is incorrect
204
+ #
205
+ # @return [True] True if username is in the correct format
206
+ #
156
207
def check_user_format ( username , domain )
157
208
if domain && username . include? ( '@' )
158
209
raise ArgumentError , 'Username is in UPN format (user@domain) so the domain parameter must be nil'
@@ -161,6 +212,20 @@ def check_user_format(username, domain)
161
212
true
162
213
end
163
214
215
+ #
216
+ # Checks the command_length parameter is the correct length
217
+ # for the CreateProcess_x WinAPI calls depending on the presence
218
+ # of application_name
219
+ #
220
+ # @param application_name [String] lpApplicationName
221
+ # @param command_line [String] lpCommandLine
222
+ # @param max_length [Integer] The max command length of the respective
223
+ # CreateProcess function
224
+ #
225
+ # @raise [ArgumentError] If the command_line is too large
226
+ #
227
+ # @return [True] True if the command_line is within the correct bounds
228
+ #
164
229
def check_command_length ( application_name , command_line , max_length )
165
230
if application_name . nil? && command_line . nil?
166
231
raise ArgumentError , 'Both application_name and command_line are nil'
0 commit comments