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/obfuscation/crandomizer/random_statements.rb
Views: 1904
1
require 'metasploit/framework/obfuscation/crandomizer/utility'
2
3
module Metasploit
4
module Framework
5
module Obfuscation
6
module CRandomizer
7
8
class RandomStatements
9
10
attr_reader :parser
11
attr_reader :fake_function_collection
12
attr_reader :statements
13
14
# Initializes the RandomStatements class.
15
#
16
# @param fake_functions [Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory::FakeFunctionCollection]
17
# @param s [Metasm::C::Declaration]
18
def initialize(p, fake_functions, s=nil)
19
@parser = p
20
@fake_function_collection = fake_functions
21
@statements = [ Proc.new { get_random_statements } ]
22
23
# Only generate fake function calls when the function we are modifying isn't
24
# from one of those fake functions (to avoid a recursion).
25
if s && fake_function_collection && !fake_function_collection.has_function_name?(s.var.name)
26
@statements << Proc.new { get_random_function_call }
27
end
28
end
29
30
# Returns a random statement.
31
#
32
# @return [Array<Metasm::C::CExpression>]
33
# @return [Array<Metasm::C::Declaration>]
34
def get
35
statements.sample.call
36
end
37
38
private
39
40
# Returns function arguments as a string.
41
#
42
# @param args [Array<Metasm::C::Variable>]
43
# @return [String]
44
def make_func_arg_str(args)
45
arg_array = []
46
47
args.each do |arg|
48
case arg.name
49
when 'i'
50
arg_array << %Q|#{Metasploit::Framework::Obfuscation::CRandomizer::Utility.rand_int}|
51
when 's'
52
arg_array << %Q|"#{Metasploit::Framework::Obfuscation::CRandomizer::Utility.rand_string}"|
53
else
54
raise "Unknown argument type to process"
55
end
56
end
57
58
%Q|(#{arg_array.join(', ')})|
59
end
60
61
# Returns the arguments (in string) for function declaration.
62
#
63
# @param args [Array<Metasm::C::Variable]
64
# @return [String]
65
def make_func_declare_arg_str(args)
66
arg_array = []
67
args.each do |a|
68
case a.name
69
when 'i'
70
arg_array << 'int'
71
when 's'
72
arg_array << 'char*'
73
else
74
raise "Unknown argument type to process"
75
end
76
end
77
78
%Q|(#{arg_array.join(', ')})|
79
end
80
81
# Returns a random statement from the Code Factory, excluding:
82
# * The base class
83
# * FakeFunction class
84
# * FakeFunctionCollection class
85
#
86
# @return [Array]
87
def get_random_statements
88
ignored_classes = [:Base, :FakeFunction, :FakeFunctionCollection]
89
class_name = Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory.constants.select { |c|
90
next if ignored_classes.include?(c)
91
Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory.const_get(c).instance_of?(Class)
92
}.sample
93
94
instance = Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory.const_get(class_name).new
95
96
if instance.good_dep?(parser)
97
return Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory.const_get(class_name).new.code
98
else
99
# Call again
100
get_random_statements
101
end
102
end
103
104
# This function is kind of dangerous, because it could cause an
105
# infinitely loop by accident when random functions call each other.
106
#
107
# @return [Array]
108
def get_random_function_call
109
# There is no fake function collection
110
return [] if fake_function_collection.empty?
111
112
fake_function = fake_function_collection.sample
113
fake_function_name = fake_function.var.name
114
fake_function_args = fake_function.var.type.args
115
fake_function_declare_args_str = make_func_declare_arg_str(fake_function_args)
116
117
arg_str = make_func_arg_str(fake_function_args)
118
template = %Q|
119
void #{fake_function_name}#{fake_function_declare_args_str};
120
void stub() {
121
#{fake_function_name}#{arg_str};
122
}|
123
124
parser = Metasploit::Framework::Obfuscation::CRandomizer::Utility.parse(template)
125
parser.toplevel.statements.last.var.initializer.statements
126
end
127
end
128
129
end
130
end
131
end
132
end
133