ronin-rb/ronin-exploits

View on GitHub
lib/ronin/exploits/mixins/binary.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true
#
# ronin-exploits - A Ruby library for ronin-rb that provides exploitation and
# payload crafting functionality.
#
# Copyright (c) 2007-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
#
# ronin-exploits is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ronin-exploits is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ronin-exploits.  If not, see <https://www.gnu.org/licenses/>.
#

require 'ronin/exploits/exceptions'
require 'ronin/support/binary/ctypes'

module Ronin
  module Exploits
    module Mixins
      #
      # Adds methods for packing binary data.
      #
      # @api public
      #
      # @since 1.0.0
      #
      module Binary
        #
        # Validates that the exploit defines an `arch` method and that all
        # required params are set.
        #
        # @raise [ValidationError]
        #   The exploit did not define an `arch` method, usually defined by
        #   {Mixins::HasTargets} or {Metadata::Arch}.
        #
        # @raise [Ronin::Core::Params::RequiredParam]
        #   One of the required params was not set.
        #
        # @api semipublic
        #
        def perform_validate
          unless respond_to?(:arch)
            raise(ValidationError,"exploit #{self.class} did not include Ronin::Exploits::Metadata::Arch or Ronin::Exploits::Mixins::HasTargets")
          end

          unless arch
            raise(ValidationError,"exploit #{self.class} did not include define an architecture")
          end

          super()
        end

        #
        # The target platform.
        #
        # @return [Ronin::Support::Binary::CTypes,
        #          Ronin::Support::Binary::CTypes::LittleEndian,
        #          Ronin::Support::Binary::CTypes::BigEndian,
        #          Ronin::Support::Binary::CTypes::Network,
        #          Ronin::Support::Binary::CTypes::Arch::ARM,
        #          Ronin::Support::Binary::CTypes::Arch::ARM::BigEndian,
        #          Ronin::Support::Binary::CTypes::Arch::ARM64,
        #          Ronin::Support::Binary::CTypes::Arch::ARM64::BigEndian,
        #          Ronin::Support::Binary::CTypes::Arch::MIPS,
        #          Ronin::Support::Binary::CTypes::Arch::MIPS::LittleEndian,
        #          Ronin::Support::Binary::CTypes::Arch::MIPS64,
        #          Ronin::Support::Binary::CTypes::Arch::MIPS64::LittleEndian,
        #          Ronin::Support::Binary::CTypes::Arch::PPC,
        #          Ronin::Support::Binary::CTypes::Arch::PPC64,
        #          Ronin::Support::Binary::CTypes::Arch::X86,
        #          Ronin::Support::Binary::CTypes::Arch::X86_64,
        #          Ronin::Support::Binary::CTypes::OS]
        #
        # @raise [ArgumentError]
        #   The exploit defined an unknown `arch` or `os` value.
        #
        def platform
          @platform ||= Support::Binary::CTypes.platform(
                          arch: arch,
                          os:   (os if respond_to?(:os))
                        )
        end

        #
        # Packs a binary value for the given type.
        #
        # @param [Symbol] type
        #   The type name to pack for.
        #
        # @param [Integer, Float, String] value
        #   The value to pack.
        #
        # @return [String]
        #   The packed value.
        #
        def pack(type,value)
          platform[type].pack(value)
        end
      end
    end
  end
end