# -*- coding: binary -*- require "rex/arch/version" module Rex ### # # This module provides generalized methods for performing operations that are # architecture specific. Furthermore, the modules contained within this # module provide features that are specific to a given architecture. # ### module Arch # # Architecture classes # require 'rex/arch/x86' require 'rex/arch/sparc' require 'rex/arch/zarch' # # Architecture constants # ARCH_ANY = '_any_' ARCH_ALL = ARCH_TYPES = [ ARCH_X86 = 'x86', ARCH_X86_64 = 'x86_64', ARCH_X64 = 'x64', # To be used for compatability with ARCH_X86_64 ARCH_MIPS = 'mips', ARCH_MIPSLE = 'mipsle', ARCH_MIPSBE = 'mipsbe', ARCH_MIPS64 = 'mips64', ARCH_MIPS64LE = 'mips64le', ARCH_PPC = 'ppc', ARCH_PPC64 = 'ppc64', ARCH_PPC64LE = 'ppc64le', ARCH_CBEA = 'cbea', ARCH_CBEA64 = 'cbea64', ARCH_SPARC = 'sparc', ARCH_SPARC64 = 'sparc64', ARCH_ARMLE = 'armle', ARCH_ARMBE = 'armbe', ARCH_AARCH64 = 'aarch64', ARCH_CMD = 'cmd', ARCH_PHP = 'php', ARCH_TTY = 'tty', ARCH_JAVA = 'java', ARCH_RUBY = 'ruby', ARCH_DALVIK = 'dalvik', ARCH_PYTHON = 'python', ARCH_NODEJS = 'nodejs', ARCH_FIREFOX = 'firefox', ARCH_ZARCH = 'zarch', ] # # Endian constants # ENDIAN_LITTLE = 0 ENDIAN_BIG = 1 IS_ENDIAN_LITTLE = ( [1].pack('s') == "\x01\x00" ) ? true : false IS_ENDIAN_BIG = ( not IS_ENDIAN_LITTLE ) # # This routine adjusts the stack pointer for a given architecture. # def self.adjust_stack_pointer(arch, adjustment) if ( arch.is_a?(::Array)) arch = arch[0] end case arch when /x86/ Rex::Arch::X86.adjust_reg(Rex::Arch::X86::ESP, adjustment) else nil end end # # This route provides address packing for the specified arch # def self.pack_addr(arch, addr) if ( arch.is_a?(::Array)) arch = arch[0] end case arch when ARCH_X86 [addr].pack('V') when ARCH_X86_64, ARCH_X64 [addr].pack('Q<') when ARCH_MIPS # ambiguous [addr].pack('N') when ARCH_MIPSBE [addr].pack('N') when ARCH_MIPSLE [addr].pack('V') when ARCH_MIPS64 [addr].pack('Q>') when ARCH_MIPS64LE [addr].pack('Q<') when ARCH_PPC # ambiguous [addr].pack('N') when ARCH_PPC64LE [addr].pack('Q<') when ARCH_SPARC [addr].pack('N') when ARCH_SPARC64 [addr].pack('Q>') when ARCH_ARMLE [addr].pack('V') when ARCH_ARMBE [addr].pack('N') when ARCH_AARCH64 [addr].pack('Q<') when ARCH_ZARCH [addr].pack('Q>') end end # # This routine reports the endianess of a given architecture # def self.endian(arch) if ( arch.is_a?(::Array)) arch = arch[0] end case arch when ARCH_X86 return ENDIAN_LITTLE when ARCH_X86_64 return ENDIAN_LITTLE when ARCH_X64 return ENDIAN_LITTLE when ARCH_MIPS # ambiguous return ENDIAN_BIG when ARCH_MIPSLE return ENDIAN_LITTLE when ARCH_MIPSBE return ENDIAN_BIG when ARCH_MIPS64 return ENDIAN_BIG when ARCH_MIPS64LE return ENDIAN_LITTLE when ARCH_PPC # ambiguous return ENDIAN_BIG when ARCH_PPC64LE return ENDIAN_LITTLE when ARCH_SPARC return ENDIAN_BIG when ARCH_SPARC64 return ENDIAN_BIG when ARCH_ARMLE return ENDIAN_LITTLE when ARCH_ARMBE return ENDIAN_BIG when ARCH_AARCH64 return ENDIAN_LITTLE when ARCH_ZARCH return ENDIAN_BIG end return ENDIAN_LITTLE end end end