CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/compiler/mingw.rb
Views: 1904
1
require 'open3'
2
module Metasploit
3
module Framework
4
module Compiler
5
module Mingw
6
MINGW_X86 = 'i686-w64-mingw32-gcc'
7
MINGW_X64 = 'x86_64-w64-mingw32-gcc'
8
9
INCLUDE_DIR = File.join(Msf::Config.data_directory, 'headers', 'windows', 'c_payload_util')
10
UTILITY_DIR = File.join(Msf::Config.data_directory, 'utilities', 'encrypted_payload')
11
OPTIMIZATION_FLAGS = [ 'Os', 'O0', 'O1', 'O2', 'O3', 'Og' ]
12
13
def compile_c(src)
14
cmd = build_cmd(src)
15
16
if self.show_compile_cmd
17
print("#{cmd}\n")
18
end
19
20
stdin_err, status = Open3.capture2e(cmd)
21
stdin_err
22
end
23
24
def build_cmd(src)
25
src_file = "#{self.file_name}.c"
26
exe_file = "#{self.file_name}.exe"
27
28
cmd = ''
29
link_options = '-Wl,'
30
31
File.write(src_file, src)
32
33
opt_level = OPTIMIZATION_FLAGS.include?(self.opt_lvl) ? "-#{self.opt_lvl} " : "-O2 "
34
35
cmd << "#{self.mingw_bin} "
36
cmd << "#{src_file} -I #{INCLUDE_DIR} "
37
cmd << "#{self.include_dirs.map { |include_dir| "-iquote #{include_dir}" }.join(' ')} " if self.include_dirs.any?
38
cmd << "-o #{exe_file} "
39
40
# gives each function its own section
41
# allowing them to be reordered
42
cmd << '-ffunction-sections '
43
cmd << '-fno-asynchronous-unwind-tables '
44
cmd << '-fno-ident '
45
cmd << opt_level
46
47
if self.compile_options
48
cmd << self.compile_options
49
else
50
link_options << '--image-base=0x0,'
51
cmd << '-nostdlib '
52
end
53
54
link_options << '--no-seh'
55
link_options << ',-s' if self.strip_syms
56
link_options << ",-T#{self.link_script}" if self.link_script
57
58
cmd << link_options
59
60
cmd
61
end
62
63
def cleanup_files
64
src_file = "#{self.file_name}.c"
65
exe_file = "#{self.file_name}.exe"
66
67
unless self.keep_src
68
File.delete(src_file) if File.exist?(src_file)
69
end
70
71
unless self.keep_exe
72
File.delete(exe_file) if File.exist?(exe_file)
73
end
74
rescue Errno::ENOENT
75
print_error("Failed to delete file")
76
end
77
78
class X86
79
include Mingw
80
81
attr_reader :file_name, :keep_exe, :keep_src, :strip_syms, :link_script, :opt_lvl, :mingw_bin, :compile_options, :show_compile_cmd, :include_dirs
82
83
def initialize(opts={})
84
@file_name = opts[:f_name]
85
@keep_exe = opts[:keep_exe]
86
@keep_src = opts[:keep_src]
87
@strip_syms = opts[:strip_symbols]
88
@show_compile_cmd = opts[:show_compile_cmd]
89
@link_script = opts[:linker_script]
90
@compile_options = opts[:compile_options]
91
@opt_lvl = opts[:opt_lvl]
92
@include_dirs = opts[:include_dirs] || []
93
@mingw_bin = MINGW_X86
94
end
95
96
def self.available?
97
!!(Msf::Util::Helper.which(MINGW_X86))
98
end
99
end
100
101
class X64
102
include Mingw
103
104
attr_reader :file_name, :keep_exe, :keep_src, :strip_syms, :link_script, :opt_lvl, :mingw_bin, :compile_options, :show_compile_cmd, :include_dirs
105
106
def initialize(opts={})
107
@file_name = opts[:f_name]
108
@keep_exe = opts[:keep_exe]
109
@keep_src = opts[:keep_src]
110
@strip_syms = opts[:strip_symbols]
111
@show_compile_cmd = opts[:show_compile_cmd]
112
@link_script = opts[:linker_script]
113
@compile_options = opts[:compile_options]
114
@opt_lvl = opts[:opt_lvl]
115
@include_dirs = opts[:include_dirs] || []
116
@mingw_bin = MINGW_X64
117
end
118
119
def self.available?
120
!!(Msf::Util::Helper.which(MINGW_X64))
121
end
122
end
123
124
class UncompilablePayloadError < StandardError
125
def initialize(msg='')
126
super(msg)
127
end
128
end
129
130
class CompiledPayloadNotFoundError < StandardError
131
def initialize(msg='Compiled executable not found')
132
super(msg)
133
end
134
end
135
end
136
end
137
end
138
end
139
140