peter50216/pwntools-ruby

View on GitHub
lib/pwnlib/shellcraft/generators/i386/common/pushstr.rb

Summary

Maintainability
A
25 mins
Test Coverage
A
100%
# encoding: ASCII-8BIT
# frozen_string_literal: true

require 'pwnlib/shellcraft/generators/i386/common/common'

module Pwnlib
  module Shellcraft
    module Generators
      module I386
        module Common
          # Push a string to stack.
          #
          # See {Amd64::Common#pushstr} for parameters' details.
          def pushstr(str, append_null: true)
            # This will not affect callee's +str+.
            str += "\x00" if append_null && !str.end_with?("\x00")
            return if str.empty?

            padding = str[-1].ord >= 128 ? "\xff" : "\x00"
            cat "/* push #{str.inspect} */"
            group(4, str, underfull_action: :fill, fill_value: padding).reverse_each do |word|
              sign = u32(word, endian: 'little', signed: true)
              if [0, 0xa].include?(sign) # simple forbidden byte case
                cat "push #{pretty(sign + 1)}"
                cat 'dec byte ptr [esp]'
              elsif sign >= -128 && sign <= 127
                cat "push #{pretty(sign)}"
              elsif okay(word)
                cat "push #{pretty(sign)}"
              else
                a = u32(xor_pair(word).first, endian: 'little', signed: false)
                cat "push #{pretty(a)}"
                cat "xor dword ptr [esp], #{pretty(a ^ sign)} /* #{pretty(a)} ^ #{pretty(sign)} */"
              end
            end
          end
        end
      end
    end
  end
end