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/modifier.rb
Views: 11624
require 'metasploit/framework/obfuscation/crandomizer/random_statements'12module Metasploit3module Framework4module Obfuscation5module CRandomizer67class Modifier8attr_reader :parser9attr_reader :fake_functions10attr_reader :weight1112# Initializes a Metasploit::Framework::Obfuscation::CRandomizer::Modifier instance.13#14# @param p [Metasploit::C::Parser]15# @param f [Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory::FakeFunctionCollection]16# @param w [Integer] Weight of the randomness.17def initialize(p, f, w)18@parser = p19@fake_functions = f20@weight = w21end2223# Modifies different if-else blocks recursively.24#25# @param s [Metasm::C::Declaration]26# @return [Metasm::C::Declaration]27def modify_if_else_blocks(s)28modify_if(s)29modify_else_if(s)30modify_else(s)31s32end3334# Modifies an if block.35#36# @param s [Metasm::C::Declaration]37# return [void]38def modify_if(s)39new_if_statements = []4041s.bthen.statements.each do |stmt|42modify_nested_blocks(stmt)43new_if_statements.concat(get_fake_statement)44new_if_statements << stmt45end4647s.bthen.statements = new_if_statements48end4950# Modifies an else-if block.51#52# @param s [Metasm::C::Declaration]53# @param [void]54def modify_else_if(s)55# There could be multiple else if blocks,56# this gives the current else if block57elseif_block = s.belse5859while (elseif_block && elseif_block.respond_to?(:bthen)) do60new_else_if_statements = []6162elseif_block.bthen.statements.each do |stmt|63modify_nested_blocks(stmt)64new_else_if_statements.concat(get_fake_statement)65new_else_if_statements << stmt66end6768elseif_block.bthen.statements = new_else_if_statements6970# Move on to the next else if block71elseif_block = elseif_block.belse72end73end7475# Modifies an else block.76#77# @param s [Metasm::C::Declaration]78def modify_else(s)79else_block = s.belse8081# The else block is retrieved this way when there is an else if block82else_block = s.belse.belse if s.belse.respond_to?(:belse)8384# There is really no else block, let's bail.85# return unless else_block86return unless else_block.respond_to?(:statements)8788new_else_statements = []8990else_block.statements.each do |stmt|91modify_nested_blocks(stmt)92new_else_statements.concat(get_fake_statement)93new_else_statements << stmt94end9596else_block.statements = new_else_statements97end9899# Modifies a for block.100#101# @param s [Metasm::C::Declaration]102def modify_for(s)103new_for_statements = []104105s.body.statements.each do |stmt|106modify_nested_blocks(stmt)107new_for_statements.concat(get_fake_statement)108new_for_statements << stmt109end110111s.body.statements = new_for_statements112113s114end115116# Modifies a nested block.117#118# @param s [Metasm::C::Declaration]119def modify_nested_blocks(s)120case s121when Metasm::C::If122modify_if_else_blocks(s)123when Metasm::C::For124modify_for(s)125end126end127128# Modifies a function.129#130# @param s [Metasploit::C::Declaration]131def modify_function(s)132function_statements = s.var.initializer.statements133new_function_statements = []134135function_statements.each do |func_stmt|136unless feeling_lucky?137new_function_statements << func_stmt138next139end140141case func_stmt142when Metasm::C::If143new_function_statements << modify_if_else_blocks(func_stmt)144when Metasm::C::For145new_function_statements << modify_for(func_stmt)146else147new_function_statements.concat(get_fake_statement(s))148new_function_statements << func_stmt149end150end151152unless new_function_statements.empty?153s.var.initializer.statements = new_function_statements154end155end156157private158159# Returns fake statements.160#161# @param s [Metasploit::C::Declaration]162# @return [Array<Metasm::C::CExpression>]163def get_fake_statement(s=nil)164random_statements = Metasploit::Framework::Obfuscation::CRandomizer::RandomStatements.new(parser, fake_functions, s)165random_statements.get166end167168# Returns a boolean indicating whether a random is above (or equal to) a number or not.169#170# @return [Boolean]171def feeling_lucky?172n = (rand * 100).to_i173weight >= n174end175176end177178end179end180end181end182183