@@ -147,6 +147,22 @@ def self.to_executable(framework, arch, plat, code = '', opts = {})
147
147
nil
148
148
end
149
149
150
+ # Clears the DYNAMIC_BASE flag for a Windows executable
151
+ # @param exe [String] The raw executable to be modified by the method
152
+ # @param pe [Rex::PeParsey::Pe] Use Rex::PeParsey::Pe.new_from_file
153
+ # @return [String] the modified executable
154
+ def self . clear_dynamic_base ( exe , pe )
155
+ c_bits = ( "%32d" %pe . hdr . opt . DllCharacteristics . to_s ( 2 ) ) . split ( '' ) . map { |e | e . to_i } . reverse
156
+ c_bits [ 6 ] = 0 # DYNAMIC_BASE
157
+ new_dllcharacteristics = c_bits . reverse . join . to_i ( 2 )
158
+
159
+ # PE Header Pointer offset = 60d
160
+ # SizeOfOptionalHeader offset = 94h
161
+ dll_ch_offset = exe [ 60 , 4 ] . unpack ( 'h4' ) [ 0 ] . reverse . hex + 94
162
+ exe [ dll_ch_offset , 2 ] = [ new_dllcharacteristics ] . pack ( "v" )
163
+ exe
164
+ end
165
+
150
166
def self . to_win32pe ( framework , code , opts = { } )
151
167
152
168
# For backward compatability, this is roughly equivalent to 'exe-small' fmt
@@ -168,6 +184,7 @@ def self.to_win32pe(framework, code, opts = {})
168
184
# Create a new PE object and run through sanity checks
169
185
fsize = File . size ( opts [ :template ] )
170
186
pe = Rex ::PeParsey ::Pe . new_from_file ( opts [ :template ] , true )
187
+
171
188
text = nil
172
189
pe . sections . each { |sec | text = sec if sec . name == ".text" }
173
190
@@ -178,7 +195,7 @@ def self.to_win32pe(framework, code, opts = {})
178
195
:template => opts [ :template ] ,
179
196
:arch => :x86
180
197
} )
181
- injector . generate_pe
198
+ return injector . generate_pe
182
199
end
183
200
184
201
raise RuntimeError , "No .text section found in the template" unless text
@@ -282,6 +299,7 @@ def self.to_win32pe(framework, code, opts = {})
282
299
exe [ exe . index ( [ cks ] . pack ( 'V' ) ) , 4 ] = [ 0 ] . pack ( "V" )
283
300
end
284
301
302
+ exe = clear_dynamic_base ( exe , pe )
285
303
pe . close
286
304
287
305
exe
@@ -348,6 +366,7 @@ def self.to_winpe_only(framework, code, opts = {}, arch="x86")
348
366
# put the shellcode at the entry point, overwriting template
349
367
entryPoint_file_offset = pe . rva_to_file_offset ( addressOfEntryPoint )
350
368
exe [ entryPoint_file_offset , code . length ] = code
369
+ exe = clear_dynamic_base ( exe , pe )
351
370
exe
352
371
end
353
372
@@ -429,7 +448,6 @@ def self.string_to_pushes(string)
429
448
end
430
449
431
450
def self . exe_sub_method ( code , opts = { } )
432
-
433
451
pe = self . get_file_contents ( opts [ :template ] )
434
452
435
453
case opts [ :exe_type ]
@@ -495,7 +513,7 @@ def self.to_win64pe(framework, code, opts = {})
495
513
:template => opts [ :template ] ,
496
514
:arch => :x64
497
515
} )
498
- injector . generate_pe
516
+ return injector . generate_pe
499
517
end
500
518
opts [ :exe_type ] = :exe_sub
501
519
exe_sub_method ( code , opts )
0 commit comments