Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/metasploit/framework/obfuscation/crandomizer/random_statements.rb
Views: 11789
require 'metasploit/framework/obfuscation/crandomizer/utility'12module Metasploit3module Framework4module Obfuscation5module CRandomizer67class RandomStatements89attr_reader :parser10attr_reader :fake_function_collection11attr_reader :statements1213# Initializes the RandomStatements class.14#15# @param fake_functions [Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory::FakeFunctionCollection]16# @param s [Metasm::C::Declaration]17def initialize(p, fake_functions, s=nil)18@parser = p19@fake_function_collection = fake_functions20@statements = [ Proc.new { get_random_statements } ]2122# Only generate fake function calls when the function we are modifying isn't23# from one of those fake functions (to avoid a recursion).24if s && fake_function_collection && !fake_function_collection.has_function_name?(s.var.name)25@statements << Proc.new { get_random_function_call }26end27end2829# Returns a random statement.30#31# @return [Array<Metasm::C::CExpression>]32# @return [Array<Metasm::C::Declaration>]33def get34statements.sample.call35end3637private3839# Returns function arguments as a string.40#41# @param args [Array<Metasm::C::Variable>]42# @return [String]43def make_func_arg_str(args)44arg_array = []4546args.each do |arg|47case arg.name48when 'i'49arg_array << %Q|#{Metasploit::Framework::Obfuscation::CRandomizer::Utility.rand_int}|50when 's'51arg_array << %Q|"#{Metasploit::Framework::Obfuscation::CRandomizer::Utility.rand_string}"|52else53raise "Unknown argument type to process"54end55end5657%Q|(#{arg_array.join(', ')})|58end5960# Returns the arguments (in string) for function declaration.61#62# @param args [Array<Metasm::C::Variable]63# @return [String]64def make_func_declare_arg_str(args)65arg_array = []66args.each do |a|67case a.name68when 'i'69arg_array << 'int'70when 's'71arg_array << 'char*'72else73raise "Unknown argument type to process"74end75end7677%Q|(#{arg_array.join(', ')})|78end7980# Returns a random statement from the Code Factory, excluding:81# * The base class82# * FakeFunction class83# * FakeFunctionCollection class84#85# @return [Array]86def get_random_statements87ignored_classes = [:Base, :FakeFunction, :FakeFunctionCollection]88class_name = Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory.constants.select { |c|89next if ignored_classes.include?(c)90Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory.const_get(c).instance_of?(Class)91}.sample9293instance = Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory.const_get(class_name).new9495if instance.good_dep?(parser)96return Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory.const_get(class_name).new.code97else98# Call again99get_random_statements100end101end102103# This function is kind of dangerous, because it could cause an104# infinitely loop by accident when random functions call each other.105#106# @return [Array]107def get_random_function_call108# There is no fake function collection109return [] if fake_function_collection.empty?110111fake_function = fake_function_collection.sample112fake_function_name = fake_function.var.name113fake_function_args = fake_function.var.type.args114fake_function_declare_args_str = make_func_declare_arg_str(fake_function_args)115116arg_str = make_func_arg_str(fake_function_args)117template = %Q|118void #{fake_function_name}#{fake_function_declare_args_str};119void stub() {120#{fake_function_name}#{arg_str};121}|122123parser = Metasploit::Framework::Obfuscation::CRandomizer::Utility.parse(template)124parser.toplevel.statements.last.var.initializer.statements125end126end127128end129end130end131end132133