CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/obfuscation/crandomizer/modifier.rb
Views: 11624
1
require 'metasploit/framework/obfuscation/crandomizer/random_statements'
2
3
module Metasploit
4
module Framework
5
module Obfuscation
6
module CRandomizer
7
8
class Modifier
9
attr_reader :parser
10
attr_reader :fake_functions
11
attr_reader :weight
12
13
# Initializes a Metasploit::Framework::Obfuscation::CRandomizer::Modifier instance.
14
#
15
# @param p [Metasploit::C::Parser]
16
# @param f [Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory::FakeFunctionCollection]
17
# @param w [Integer] Weight of the randomness.
18
def initialize(p, f, w)
19
@parser = p
20
@fake_functions = f
21
@weight = w
22
end
23
24
# Modifies different if-else blocks recursively.
25
#
26
# @param s [Metasm::C::Declaration]
27
# @return [Metasm::C::Declaration]
28
def modify_if_else_blocks(s)
29
modify_if(s)
30
modify_else_if(s)
31
modify_else(s)
32
s
33
end
34
35
# Modifies an if block.
36
#
37
# @param s [Metasm::C::Declaration]
38
# return [void]
39
def modify_if(s)
40
new_if_statements = []
41
42
s.bthen.statements.each do |stmt|
43
modify_nested_blocks(stmt)
44
new_if_statements.concat(get_fake_statement)
45
new_if_statements << stmt
46
end
47
48
s.bthen.statements = new_if_statements
49
end
50
51
# Modifies an else-if block.
52
#
53
# @param s [Metasm::C::Declaration]
54
# @param [void]
55
def modify_else_if(s)
56
# There could be multiple else if blocks,
57
# this gives the current else if block
58
elseif_block = s.belse
59
60
while (elseif_block && elseif_block.respond_to?(:bthen)) do
61
new_else_if_statements = []
62
63
elseif_block.bthen.statements.each do |stmt|
64
modify_nested_blocks(stmt)
65
new_else_if_statements.concat(get_fake_statement)
66
new_else_if_statements << stmt
67
end
68
69
elseif_block.bthen.statements = new_else_if_statements
70
71
# Move on to the next else if block
72
elseif_block = elseif_block.belse
73
end
74
end
75
76
# Modifies an else block.
77
#
78
# @param s [Metasm::C::Declaration]
79
def modify_else(s)
80
else_block = s.belse
81
82
# The else block is retrieved this way when there is an else if block
83
else_block = s.belse.belse if s.belse.respond_to?(:belse)
84
85
# There is really no else block, let's bail.
86
# return unless else_block
87
return unless else_block.respond_to?(:statements)
88
89
new_else_statements = []
90
91
else_block.statements.each do |stmt|
92
modify_nested_blocks(stmt)
93
new_else_statements.concat(get_fake_statement)
94
new_else_statements << stmt
95
end
96
97
else_block.statements = new_else_statements
98
end
99
100
# Modifies a for block.
101
#
102
# @param s [Metasm::C::Declaration]
103
def modify_for(s)
104
new_for_statements = []
105
106
s.body.statements.each do |stmt|
107
modify_nested_blocks(stmt)
108
new_for_statements.concat(get_fake_statement)
109
new_for_statements << stmt
110
end
111
112
s.body.statements = new_for_statements
113
114
s
115
end
116
117
# Modifies a nested block.
118
#
119
# @param s [Metasm::C::Declaration]
120
def modify_nested_blocks(s)
121
case s
122
when Metasm::C::If
123
modify_if_else_blocks(s)
124
when Metasm::C::For
125
modify_for(s)
126
end
127
end
128
129
# Modifies a function.
130
#
131
# @param s [Metasploit::C::Declaration]
132
def modify_function(s)
133
function_statements = s.var.initializer.statements
134
new_function_statements = []
135
136
function_statements.each do |func_stmt|
137
unless feeling_lucky?
138
new_function_statements << func_stmt
139
next
140
end
141
142
case func_stmt
143
when Metasm::C::If
144
new_function_statements << modify_if_else_blocks(func_stmt)
145
when Metasm::C::For
146
new_function_statements << modify_for(func_stmt)
147
else
148
new_function_statements.concat(get_fake_statement(s))
149
new_function_statements << func_stmt
150
end
151
end
152
153
unless new_function_statements.empty?
154
s.var.initializer.statements = new_function_statements
155
end
156
end
157
158
private
159
160
# Returns fake statements.
161
#
162
# @param s [Metasploit::C::Declaration]
163
# @return [Array<Metasm::C::CExpression>]
164
def get_fake_statement(s=nil)
165
random_statements = Metasploit::Framework::Obfuscation::CRandomizer::RandomStatements.new(parser, fake_functions, s)
166
random_statements.get
167
end
168
169
# Returns a boolean indicating whether a random is above (or equal to) a number or not.
170
#
171
# @return [Boolean]
172
def feeling_lucky?
173
n = (rand * 100).to_i
174
weight >= n
175
end
176
177
end
178
179
end
180
end
181
end
182
end
183