class Ronin::Support::Binary::Stack
Represents a stack that can have binary data pushed to or popped from it.
## Features
-
Supports configurable endianness and architecture.
-
Can dump out a formatting binary string for new a stack.
-
Can parse an existing stack dump string.
-
Supports negative indexing.
## Examples
Creating a new stack:
stack = Binary::Stack.new # => #<Ronin::Support::Binary::Stack: ""> stack.push 0x41414141 # => #<Ronin::Support::Binary::Stack: "AAAA\x00\x00\x00\x00"> stack.push 0x7fffffffdde0 # => #<Ronin::Support::Binary::Stack: "\xE0\xDD\xFF\xFF\xFF\x7F\x00\x00AAAA\x00\x00\x00\x00"> stack.push -1 # => #<Ronin::Support::Binary::Stack: "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xDD\xFF\xFF\xFF\x7F\x00\x00AAAA\x00\x00\x00\x00"> stack.to_s # => => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xDD\xFF\xFF\xFF\x7F\x00\x00AAAA\x00\x00\x00\x00"
Creating a stack from an existing String:
stack = Binary::Stack.new("\x41\x00\x00\x00\x00\x00\x00\x00\x42\x00\x00\x00\x00\x00\x00\x00") stack[0] # => 65 stack[8] # => 66
Negative indexing within the stack:
stack.push(65) stack.push(66) stack[-8] # => 65 stack[-16] # => 66
Note: negative indexes are treated relative to the beginning of the stack, since stacks grow downward in the address space.
@api public
@since 1.0.0
Attributes
The number of machine words on the stack.
@return [Integer]
The “machine word” from the {#type_system}.
@return [CTypes::UInt32Type, CTypes::UInt64Type
]
The size of the stack in bytes.
@return [Integer]
The underlying buffer for the stack.
@return [String]
Public Class Methods
Source
# File lib/ronin/support/binary/stack.rb, line 118 def initialize(string=nil, **kwargs) initialize_type_system(**kwargs) @machine_word = @type_system::MACHINE_WORD if string @string = string @size = @string.bytesize @length = @size / @machine_word.size else @string = String.new @size = 0 @length = 0 end end
Initializes the stack.
@param [String, nil] string
Optional existing stack contents.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments.
@option kwargs [:little, :big, :net, nil] :endian
The desired endianness of the values within the stack.
@option kwargs [:x86, :x86_64,
:ppc, :ppc64, :mips, :mips_le, :mips_be, :mips64, :mips64_le, :mips64_be, :arm, :arm_le, :arm_be, :arm64, :arm64_le, :arm64_be] :arch The desired architecture for the values within the stack.
Public Instance Methods
Source
# File lib/ronin/support/binary/stack.rb, line 150 def [](index) offset = if index < 0 then @size + index else index end if (offset + @machine_word.size) > @size raise(IndexError,"index #{index} is out of bounds: 0...#{@size}") end data = @string[offset,@machine_word.size] return @machine_word.unpack(data) end
Accesses a machine word at the given index within the stack.
@param [Integer] index
The byte offset within the stack to read from.
@return [Integer]
The value at the index within the stack.
@raise [IndexError]
@note
negative offsets are treated as relative to the bottom or the beginning of the stack, since stack grow downward in the address space.
Source
# File lib/ronin/support/binary/stack.rb, line 182 def []=(index,value) offset = if index < 0 then @size + index else index end if (offset + @machine_word.size) > @size raise(IndexError,"index #{index} is out of bounds: 0...#{@size}") end @string[offset,@machine_word.size] = @machine_word.pack(value) return value end
Sets a machine word at the given index within the stack.
@param [Integer] index
The byte offset within the stack to write to.
@param [Integer] value
The value to write at the index within the stack.
@return [Integer]
The written value.
@raise [IndexError]
@note
negative offsets are treated as relative to the bottom or the beginning of the stack, since stacks grow downward in the address space.
Source
# File lib/ronin/support/binary/stack.rb, line 248 def inspect "#<#{self.class}: #{@string.inspect}>" end
Inspects the stack object.
@return [String]
Source
# File lib/ronin/support/binary/stack.rb, line 220 def pop data = @string.byteslice(0,@machine_word.size) value = @machine_word.unpack(data) @length -= 1 @size -= @machine_word.size @string = @string.byteslice(@machine_word.size,@size) return value end
Pops a value off the top of the stack (or to the end of the underlying buffer).
@return [Integer]
The value popped from the stack.
Source
# File lib/ronin/support/binary/stack.rb, line 204 def push(value) data = @machine_word.pack(value) @string.insert(0,data) @length += 1 @size += @machine_word.size return self end
Pushes a value onto the top of the stack (or to the end of the underlying buffer).
@param [Integer] value
The value to push onto the stack.
@return [self]