module Rex::Text

This class formats text in various fashions and also provides a mechanism for wrapping text at a given column.

Constants

AllChars
Alpha
AlphaNumeric
Base32
DefaultPatternSets
DefaultWrap
HighAscii
Iconv_ASCII
Iconv_EBCDIC

In case Iconv isn’t loaded

LowAscii
LowerAlpha
Names_Female
Names_Male
Numerals
Punctuation
States
Surnames

Most 100 common surnames, male/female names in the U.S. (names.mongabay.com/)

TLDs

Constants

UpperAlpha

Public Class Methods

ascii_safe_hex(str, whitespace=false) click to toggle source

Turn non-printable chars into hex representations, leaving others alone

If whitespace is true, converts whitespace (0x20, 0x09, etc) to hex as well.

@see hexify @see to_hex Converts all the chars

# File lib/rex/text.rb, line 972
def self.ascii_safe_hex(str, whitespace=false)
  if whitespace
    str.gsub(/([\x00-\x20\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0] }
  else
    str.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0]}
  end
end
b32decode(bytes_in) click to toggle source

Base32 decoder

# File lib/rex/text.rb, line 1100
def self.b32decode(bytes_in)
  bytes = bytes_in.take_while {|c| c != 61} # strip padding
  n = (bytes.length * 5.0 / 8.0).floor
  p = bytes.length < 8 ? 5 - (n * 8) % 5 : 0
  c = bytes.inject(0) {|m,o| (m << 5) + Base32.index(o.chr)} >> p
  (0..n-1).to_a.reverse.collect {|i| ((c >> i * 8) & 0xff).chr}
end
b32encode(bytes_in) click to toggle source

Base32 encoder

# File lib/rex/text.rb, line 1075
def self.b32encode(bytes_in)
  n = (bytes_in.length * 8.0 / 5.0).ceil
  p = n < 8 ? 5 - (bytes_in.length * 8) % 5 : 0
  c = bytes_in.inject(0) {|m,o| (m << 8) + o} << p
  [(0..n-1).to_a.reverse.collect {|i| Base32[(c >> i * 5) & 0x1f].chr},
  ("=" * (8-n))]
end
badchar_index(data, badchars = '') click to toggle source

Return the index of the first badchar in data, otherwise return nil if there wasn’t any badchar occurences.

@param data [String] The string to check for bad characters @param badchars [String] A list of characters considered to be bad @return [Fixnum] Index of the first bad character if any exist in data @return [nil] If data contains no bad characters

# File lib/rex/text.rb, line 1509
def self.badchar_index(data, badchars = '')
  badchars.unpack("C*").each { |badchar|
    pos = data.index(badchar.chr)
    return pos if pos
  }
  return nil
end
charset_exclude(keepers) click to toggle source

Returns all chars that are not in the supplied set

@param keepers [String] @return [String] All characters not contained in keepers

# File lib/rex/text.rb, line 1533
def self.charset_exclude(keepers)
  [*(0..255)].pack('C*').delete(keepers)
end
compress(str) click to toggle source

Compresses a string, eliminating all superfluous whitespace before and after lines and eliminating all lines.

@param str [String] The string in which to crunch whitespace @return [String] Just like str, but with repeated whitespace characters

trimmed down to a single space
# File lib/rex/text.rb, line 1398
def self.compress(str)
  str.gsub(/\n/m, ' ').gsub(/\s+/, ' ').gsub(/^\s+/, '').gsub(/\s+$/, '')
end
decode_base32(str) click to toggle source
# File lib/rex/text.rb, line 1108
def self.decode_base32(str)
  bytes = str.bytes
  result = ''
  size= 8
  while bytes.any? do
    bytes.each_slice(size) do |a|
    bytes_out = b32decode(a).flatten.join
    result << bytes_out
    bytes = bytes.drop(size)
    end
  end
  return result
end
decode_base64(str) click to toggle source

Base64 decoder

# File lib/rex/text.rb, line 1132
def self.decode_base64(str)
  str.to_s.unpack("m")[0]
end
dehex(str) click to toggle source

Convert hex-encoded characters to literals.

@example

Rex::Text.dehex("AA\\x42CC") # => "AABCC"

@see hex_to_raw @param str [String]

# File lib/rex/text.rb, line 1172
def self.dehex(str)
  return str unless str.respond_to? :match
  return str unless str.respond_to? :gsub
  regex = /\x5cx[0-9a-f]{2}/nmi
  if str.match(regex)
    str.gsub(regex) { |x| x[2,2].to_i(16).chr }
  else
    str
  end
end
dehex!(str) click to toggle source

Convert and replace hex-encoded characters to literals.

@param (see dehex)

# File lib/rex/text.rb, line 1187
def self.dehex!(str)
  return str unless str.respond_to? :match
  return str unless str.respond_to? :gsub
  regex = /\x5cx[0-9a-f]{2}/nmi
  str.gsub!(regex) { |x| x[2,2].to_i(16).chr }
end
encode_base32(str) click to toggle source
# File lib/rex/text.rb, line 1083
def self.encode_base32(str)
  bytes = str.bytes
  result = ''
  size= 5
  while bytes.any? do
    bytes.each_slice(size) do |a|
    bytes_out = b32encode(a).flatten.join
    result << bytes_out
    bytes = bytes.drop(size)
    end
  end
  return result
end
encode_base64(str, delim='') click to toggle source

Base64 encoder

# File lib/rex/text.rb, line 1125
def self.encode_base64(str, delim='')
  [str.to_s].pack("m").gsub(/\s+/, delim)
end
from_ebcdic(str) click to toggle source

Converts EBCIDC to ASCII

# File lib/rex/text.rb, line 437
def self.from_ebcdic(str)
  begin
    Iconv.iconv("ASCII", "EBCDIC-US", str).first
  rescue ::Iconv::IllegalSequence => e
    raise e
  rescue
    self.from_ebcdic_rex(str)
  end
end
from_ebcdic_rex(str) click to toggle source

A native implementation of the EBCDIC->ASCII table, used to fall back from using Iconv

# File lib/rex/text.rb, line 412
def self.from_ebcdic_rex(str)
  new_str = []
  str.each_byte do |x|
    if Iconv_EBCDIC.index(x.chr)
      new_str << Iconv_ASCII[Iconv_EBCDIC.index(x.chr)]
    else
      raise Rex::Text::IllegalSequence, ("\\x%x" % x)
    end
  end
  new_str.join
end
gzip(str, level = 9) click to toggle source

Compresses a string using gzip

@param str (see zlib_deflate) @param level [Fixnum] Compression level, 1 (fast) to 9 (best) @return (see zlib_deflate)

# File lib/rex/text.rb, line 1473
def self.gzip(str, level = 9)
  raise RuntimeError, "Gzip support is not present." if (!zlib_present?)
  raise RuntimeError, "Invalid gzip compression level" if (level < 1 or level > 9)

  s = ""
  s.force_encoding('ASCII-8BIT') if s.respond_to?(:encoding)
  gz = Zlib::GzipWriter.new(StringIO.new(s, 'wb'), level)
  gz << str
  gz.close
  return s
end
gzip_present?() click to toggle source

backwards compat for just a bit…

# File lib/rex/text.rb, line 1429
def self.gzip_present?
  self.zlib_present?
end
hex_to_raw(str) click to toggle source

Converts a hex string to a raw string

@example

Rex::Text.hex_to_raw("\\x41\\x7f\\x42") # => "A\x7fB"
# File lib/rex/text.rb, line 959
def self.hex_to_raw(str)
  [ str.downcase.gsub(/'/,'').gsub(/\\?x([a-f0-9][a-f0-9])/, '\1') ].pack("H*")
end
hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '') click to toggle source

Converts a string to a hex version with wrapping support

# File lib/rex/text.rb, line 991
def self.hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '')
  output       = buf_start
  cur  = 0
  count        = 0
  new_line = true

  # Go through each byte in the string
  str.each_byte { |byte|
    count  += 1
    append    = ''

    # If this is a new line, prepend with the
    # line start text
    if (new_line == true)
      append   << line_start
      new_line  = false
    end

    # Append the hexified version of the byte
    append << sprintf("\\x%.2x", byte)
    cur    += append.length

    # If we're about to hit the column or have gone past it,
    # time to finish up this line
    if ((cur + line_end.length >= col) or (cur + buf_end.length  >= col))
      new_line  = true
      cur       = 0

      # If this is the last byte, use the buf_end instead of
      # line_end
      if (count == str.length)
        append << buf_end + "\n"
      else
        append << line_end + "\n"
      end
    end

    output << append
  }

  # If we were in the middle of a line, finish the buffer at this point
  if (new_line == false)
    output << buf_end + "\n"
  end

  return output
end
html_decode(str) click to toggle source

Decode a string that’s html encoded

# File lib/rex/text.rb, line 845
def self.html_decode(str)
  decoded_str = CGI.unescapeHTML(str)
  return decoded_str
end
html_encode(str, mode = 'hex') click to toggle source

Encode a string in a manner useful for HTTP URIs and URI Parameters.

@param str [String] The string to be encoded @param mode [“hex”,“int”,“int-wide”] @return [String] @raise [TypeError] if mode is not one of the three available modes

# File lib/rex/text.rb, line 829
def self.html_encode(str, mode = 'hex')
  case mode
  when 'hex'
    return str.unpack('C*').collect{ |i| "&#x" + ("%.2x" % i) + ";"}.join
  when 'int'
    return str.unpack('C*').collect{ |i| "&#" + i.to_s + ";"}.join
  when 'int-wide'
    return str.unpack('C*').collect{ |i| "&#" + ("0" * (7 - i.to_s.length)) + i.to_s + ";" }.join
  else
    raise TypeError, 'invalid mode'
  end
end
md5(str) click to toggle source

Hexidecimal MD5 digest of the supplied string

# File lib/rex/text.rb, line 1146
def self.md5(str)
  Digest::MD5.hexdigest(str)
end
md5_raw(str) click to toggle source

Raw MD5 digest of the supplied string

# File lib/rex/text.rb, line 1139
def self.md5_raw(str)
  Digest::MD5.digest(str)
end
pack_int64le(val) click to toggle source

Pack a value as 64 bit litle endian; does not exist for Array.pack

# File lib/rex/text.rb, line 1701
def self.pack_int64le(val)
  [val & 0x00000000ffffffff, val >> 32].pack("V2")
end
patt2(len, sets = nil) click to toggle source

Step through an arbitrary number of sets of bytes to build up a findable pattern. This is mostly useful for experimentially determining offset lengths into memory structures. Note that the supplied sets should never contain duplicate bytes, or else it can become impossible to measure the offset accurately.

# File lib/rex/text.rb, line 1354
def self.patt2(len, sets = nil)
  buf = ""
  counter = []
  sets ||= [ UpperAlpha, LowerAlpha, Numerals ]
  len ||= len.to_i
  return "" if len.zero?

  sets = sets.map {|a| a.split(//)}
  sets.size.times { counter << 0}
  0.upto(len-1) do |i|
    setnum = i % sets.size

    #puts counter.inspect
  end

  return buf
end
pattern_create(length, sets = nil) click to toggle source

Creates a pattern that can be used for offset calculation purposes. This routine is capable of generating patterns using a supplied set and a supplied number of identifiable characters (slots). The supplied sets should not contain any duplicate characters or the logic will fail.

@param length [Fixnum] @param sets [Array<(String,String,String)>] The character sets to choose

from. Should have 3 elements, each of which must be a string containing
no characters contained in the other sets.

@return [String] A pattern of length bytes, in which any 4-byte chunk is

unique

@see pattern_offset

# File lib/rex/text.rb, line 1323
def self.pattern_create(length, sets = nil)
  buf = ''
  offsets = []

  # Make sure there's something in sets even if we were given an explicit nil
  sets ||= [ UpperAlpha, LowerAlpha, Numerals ]

  # Return stupid uses
  return "" if length.to_i < 1
  return sets[0][0].chr * length if sets.size == 1 and sets[0].size == 1

  sets.length.times { offsets << 0 }

  until buf.length >= length
    begin
      buf << converge_sets(sets, 0, offsets, length)
    end
  end

  # Maximum permutations reached, but we need more data
  if (buf.length < length)
    buf = buf * (length / buf.length.to_f).ceil
  end

  buf[0,length]
end
pattern_offset(pattern, value, start=0) click to toggle source

Calculate the offset to a pattern

@param pattern [String] The pattern to search. Usually the return value

from {.pattern_create}

@param value [String,Fixnum,Bignum] @return [Fixnum] Index of the given value within pattern, if it exists @return [nil] if pattern does not contain value @see pattern_create

# File lib/rex/text.rb, line 1381
def self.pattern_offset(pattern, value, start=0)
  if (value.kind_of?(String))
    pattern.index(value, start)
  elsif (value.kind_of?(Fixnum) or value.kind_of?(Bignum))
    pattern.index([ value ].pack('V'), start)
  else
    raise ::ArgumentError, "Invalid class for value: #{value.class}"
  end
end
permute_case(word, idx=0) click to toggle source

Permute the case of a word

# File lib/rex/text.rb, line 1570
def self.permute_case(word, idx=0)
  res = []

  if( (UpperAlpha+LowerAlpha).index(word[idx,1]))

    word_ucase = word.dup
    word_ucase[idx, 1] = word[idx, 1].upcase

    word_lcase = word.dup
    word_lcase[idx, 1] = word[idx, 1].downcase

    if (idx == word.length)
      return [word]
    else
      res << permute_case(word_ucase, idx+1)
      res << permute_case(word_lcase, idx+1)
    end
  else
    res << permute_case(word, idx+1)
  end

  res.flatten
end
rand_base(len, bad, *foo) click to toggle source

Base text generator method

# File lib/rex/text.rb, line 1207
def self.rand_base(len, bad, *foo)
  cset = (foo.join.unpack("C*") - bad.to_s.unpack("C*")).uniq
  return "" if cset.length == 0
  outp = []
  len.times { outp << cset[rand(cset.length)] }
  outp.pack("C*")
end
rand_char(bad, chars = AllChars) click to toggle source

Generates a random character.

# File lib/rex/text.rb, line 1202
def self.rand_char(bad, chars = AllChars)
  rand_text(1, bad, chars)
end
rand_guid() click to toggle source

Generate a random GUID

@example

Rex::Text.rand_guid # => "{ca776ced-4ab8-2ed6-6510-aa71e5e2508e}"

@return [String]

# File lib/rex/text.rb, line 1282
def self.rand_guid
  "{#{[8,4,4,4,12].map {|a| rand_text_hex(a) }.join("-")}}"
end
rand_hostname() click to toggle source

Generate a random hostname

@return [String] A random string conforming to the rules of FQDNs

# File lib/rex/text.rb, line 1597
def self.rand_hostname
  host = []
  (rand(5) + 1).times {
    host.push(Rex::Text.rand_text_alphanumeric(rand(10) + 1))
  }
  host.push(TLDs.sample)
  host.join('.').downcase
end
rand_mail_address() click to toggle source

Generate a random mail address

# File lib/rex/text.rb, line 1636
def self.rand_mail_address
  mail_address = ''
  mail_address << Rex::Text.rand_name
  mail_address << '.'
  mail_address << Rex::Text.rand_surname
  mail_address << '@'
  mail_address << Rex::Text.rand_hostname
end
rand_name() click to toggle source

Generate a name

# File lib/rex/text.rb, line 1617
def self.rand_name
  if rand(10) % 2 == 0
    Names_Male.sample
  else
    Names_Female.sample
  end
end
rand_name_female() click to toggle source

Generate a female name

# File lib/rex/text.rb, line 1631
def self.rand_name_female
  Names_Female.sample
end
rand_name_male() click to toggle source

Generate a male name

# File lib/rex/text.rb, line 1626
def self.rand_name_male
  Names_Male.sample
end
rand_state() click to toggle source

Generate a state

# File lib/rex/text.rb, line 1607
def self.rand_state()
  States.sample
end
rand_surname() click to toggle source

Generate a surname

# File lib/rex/text.rb, line 1612
def self.rand_surname
  Surnames.sample
end
rand_text(len, bad='', chars = AllChars) click to toggle source

Generate random bytes of data

# File lib/rex/text.rb, line 1216
def self.rand_text(len, bad='', chars = AllChars)
  foo = chars.split('')
  rand_base(len, bad, *foo)
end
rand_text_alpha(len, bad='') click to toggle source

Generate random bytes of alpha data

# File lib/rex/text.rb, line 1222
def self.rand_text_alpha(len, bad='')
  foo = []
  foo += ('A' .. 'Z').to_a
  foo += ('a' .. 'z').to_a
  rand_base(len, bad, *foo )
end
rand_text_alpha_lower(len, bad='') click to toggle source

Generate random bytes of lowercase alpha data

# File lib/rex/text.rb, line 1230
def self.rand_text_alpha_lower(len, bad='')
  rand_base(len, bad, *('a' .. 'z').to_a)
end
rand_text_alpha_upper(len, bad='') click to toggle source

Generate random bytes of uppercase alpha data

# File lib/rex/text.rb, line 1235
def self.rand_text_alpha_upper(len, bad='')
  rand_base(len, bad, *('A' .. 'Z').to_a)
end
rand_text_alphanumeric(len, bad='') click to toggle source

Generate random bytes of alphanumeric data

# File lib/rex/text.rb, line 1240
def self.rand_text_alphanumeric(len, bad='')
  foo = []
  foo += ('A' .. 'Z').to_a
  foo += ('a' .. 'z').to_a
  foo += ('0' .. '9').to_a
  rand_base(len, bad, *foo )
end
rand_text_english(len, bad='') click to toggle source

Generate random bytes of english-like data

# File lib/rex/text.rb, line 1263
def self.rand_text_english(len, bad='')
  foo = []
  foo += (0x21 .. 0x7e).map{ |c| c.chr }
  rand_base(len, bad, *foo )
end
rand_text_hex(len, bad='') click to toggle source

Generate random bytes of alphanumeric hex.

# File lib/rex/text.rb, line 1249
def self.rand_text_hex(len, bad='')
  foo = []
  foo += ('0' .. '9').to_a
  foo += ('a' .. 'f').to_a
  rand_base(len, bad, *foo)
end
rand_text_highascii(len, bad='') click to toggle source

Generate random bytes of high ascii data

# File lib/rex/text.rb, line 1270
def self.rand_text_highascii(len, bad='')
  foo = []
  foo += (0x80 .. 0xff).map{ |c| c.chr }
  rand_base(len, bad, *foo )
end
rand_text_numeric(len, bad='') click to toggle source

Generate random bytes of numeric data

# File lib/rex/text.rb, line 1257
def self.rand_text_numeric(len, bad='')
  foo = ('0' .. '9').to_a
  rand_base(len, bad, *foo )
end
randomize_space(str) click to toggle source

Randomize the whitespace in a string

# File lib/rex/text.rb, line 1405
def self.randomize_space(str)
  set = ["\x09", "\x20", "\x0d", "\x0a"]
  str.gsub(/\s+/) { |s|
    len = rand(50)+2
    buf = ''
    while (buf.length < len)
      buf << set.sample
    end

    buf
  }
end
refine( str1, str2 ) click to toggle source

Removes noise from 2 Strings and return a refined String version.

# File lib/rex/text.rb, line 461
def self.refine( str1, str2 )
  return str1 if str1 == str2

  # get the words of the first str in an array
  s_words = to_words( str1 )

  # get the words of the second str in an array
  o_words = to_words( str2 )

  # get what hasn't changed (the rdiff, so to speak) as a string
  (s_words - (s_words - o_words)).join
end
remove_badchars(data, badchars = '') click to toggle source

Removes bad characters from a string.

Modifies data in place

@param data [#delete] @param badchars [String] A list of characters considered to be bad

# File lib/rex/text.rb, line 1524
def self.remove_badchars(data, badchars = '')
  data.delete(badchars)
end
rol(val, cnt) click to toggle source

Rotate a 32-bit value to the left by cnt bits

@param val (see ror) @param cnt (see ror) @return (see ror)

# File lib/rex/text.rb, line 1675
def self.rol(val, cnt)
  bits = [val].pack("N").unpack("B32")[0].split(//)
  1.upto(cnt) do |c|
    bits.push( bits.shift )
  end
  [bits.join].pack("B32").unpack("N")[0]
end
ror(val, cnt) click to toggle source

Rotate a 32-bit value to the right by cnt bits

@param val [Fixnum] The value to rotate @param cnt [Fixnum] Number of bits to rotate by

# File lib/rex/text.rb, line 1661
def self.ror(val, cnt)
  bits = [val].pack("N").unpack("B32")[0].split(//)
  1.upto(cnt) do |c|
    bits.unshift( bits.pop )
  end
  [bits.join].pack("B32").unpack("N")[0]
end
ror13_hash(name) click to toggle source

Calculate the ROR13 hash of a given string

@return [Fixnum]

# File lib/rex/text.rb, line 1650
def self.ror13_hash(name)
  hash = 0
  name.unpack("C*").each {|c| hash = ror(hash, 13); hash += c }
  hash
end
sha1(str) click to toggle source

Hexidecimal SHA1 digest of the supplied string

# File lib/rex/text.rb, line 1160
def self.sha1(str)
  Digest::SHA1.hexdigest(str)
end
sha1_raw(str) click to toggle source

Raw SHA1 digest of the supplied string

# File lib/rex/text.rb, line 1153
def self.sha1_raw(str)
  Digest::SHA1.digest(str)
end
shuffle_a(arr) click to toggle source

Performs a Fisher-Yates shuffle on an array

Modifies arr in place

@param arr [Array] The array to be shuffled @return [Array]

# File lib/rex/text.rb, line 1554
def self.shuffle_a(arr)
  len = arr.length
  max = len - 1
  cyc = [* (0..max) ]
  for d in cyc
    e = rand(d+1)
    next if e == d
    f = arr[d];
    g = arr[e];
    arr[d] = g;
    arr[e] = f;
  end
  return arr
end
shuffle_s(str) click to toggle source

Shuffles a byte stream

@param str [String] @return [String] The shuffled result @see shuffle_a

# File lib/rex/text.rb, line 1543
def self.shuffle_s(str)
  shuffle_a(str.unpack("C*")).pack("C*")
end
split_to_a(str, n) click to toggle source

Split a string by n character into an array

# File lib/rex/text.rb, line 1686
def self.split_to_a(str, n)
  if n > 0
    s = str.dup
    until s.empty?
      (ret ||= []).push s.slice!(0, n)
    end
  else
    ret = str
  end
  ret
end
to_ascii(str='', type = 'utf-16le', mode = '', size = '') click to toggle source

Converts a unicode string to standard ASCII text.

# File lib/rex/text.rb, line 747
def self.to_ascii(str='', type = 'utf-16le', mode = '', size = '')
  return '' if not str
  case type
  when 'utf-16le'
    return str.unpack('v*').pack('C*')
  when 'utf-16be'
    return str.unpack('n*').pack('C*')
  when 'utf-32le'
    return str.unpack('V*').pack('C*')
  when 'utf-32be'
    return str.unpack('N*').pack('C*')
  when 'utf-7'
    raise TypeError, 'invalid utf type, not yet implemented'
  when 'utf-8'
    raise TypeError, 'invalid utf type, not yet implemented'
  when 'uhwtfms' # suggested name from HD :P
    raise TypeError, 'invalid utf type, not yet implemented'
  when 'uhwtfms-half' # suggested name from HD :P
    raise TypeError, 'invalid utf type, not yet implemented'
  else
    raise TypeError, 'invalid utf type'
  end
end
to_bash(str, wrap = DefaultWrap, name = "buf") click to toggle source

Converts a raw string into a Bash buffer

# File lib/rex/text.rb, line 277
def self.to_bash(str, wrap = DefaultWrap, name = "buf")
  return hexify(str, wrap, '$\'', '\'\\', "export #{name}=\\\n", '\'')
end
to_bash_comment(str, wrap = DefaultWrap) click to toggle source

Creates a Bash-style comment

# File lib/rex/text.rb, line 363
def self.to_bash_comment(str, wrap = DefaultWrap)
  return wordwrap(str, 0, wrap, '', '# ')
end
to_c(str, wrap = DefaultWrap, name = "buf") click to toggle source

Converts a raw string into a C buffer

# File lib/rex/text.rb, line 231
def self.to_c(str, wrap = DefaultWrap, name = "buf")
  return hexify(str, wrap, '"', '"', "unsigned char #{name}[] = \n", '";')
end
to_c_comment(str, wrap = DefaultWrap) click to toggle source

Creates a c-style comment

# File lib/rex/text.rb, line 249
def self.to_c_comment(str, wrap = DefaultWrap)
  return "/*\n" + wordwrap(str, 0, wrap, '', ' * ') + " */\n"
end
to_csharp(str, wrap = DefaultWrap, name = "buf") click to toggle source
# File lib/rex/text.rb, line 235
def self.to_csharp(str, wrap = DefaultWrap, name = "buf")
  ret = "byte[] #{name} = new byte[#{str.length}] {"
  i = -1;
  while (i += 1) < str.length
    ret << "\n" if i%(wrap/4) == 0
    ret << "0x" << str[i].unpack("H*")[0] << ","
  end
  ret = ret[0..ret.length-2] #cut off last comma
  ret << " };\n"
end
to_dword(str, wrap = DefaultWrap) click to toggle source

Creates a comma separated list of dwords

# File lib/rex/text.rb, line 196
def self.to_dword(str, wrap = DefaultWrap)
  code = str
  alignnr = str.length % 4
  if (alignnr > 0)
    code << "\x00" * (4 - alignnr)
  end
  codevalues = Array.new
  code.split("").each_slice(4) do |chars4|
    chars4 = chars4.join("")
    dwordvalue = chars4.unpack('*V')
    codevalues.push(dwordvalue[0])
  end
  buff = ""
  0.upto(codevalues.length-1) do |byte|
    if(byte % 8 == 0) and (buff.length > 0)
      buff << "\r\n"
    end
    buff << sprintf('0x%.8x, ', codevalues[byte])
  end
   # strip , at the end
  buff = buff.chomp(', ')
  buff << "\r\n"
  return buff
end
to_ebcdic(str) click to toggle source
# File lib/rex/text.rb, line 424
def self.to_ebcdic(str)
  begin
    Iconv.iconv("EBCDIC-US", "ASCII", str).first
  rescue ::Iconv::IllegalSequence => e
    raise e
  rescue
    self.to_ebcdic_rex(str)
  end
end
to_ebcdic_rex(str) click to toggle source

A native implementation of the ASCII->EBCDIC table, used to fall back from using Iconv

# File lib/rex/text.rb, line 398
def self.to_ebcdic_rex(str)
  new_str = []
  str.each_byte do |x|
    if Iconv_ASCII.index(x.chr)
      new_str << Iconv_EBCDIC[Iconv_ASCII.index(x.chr)]
    else
      raise Rex::Text::IllegalSequence, ("\\x%x" % x)
    end
  end
  new_str.join
end
to_guid(bytes) click to toggle source

Convert 16-byte string to a GUID string

@example

str = "ABCDEFGHIJKLMNOP"
Rex::Text.to_guid(str) #=> "{44434241-4645-4847-494a-4b4c4d4e4f50}"

@param bytes [String] 16 bytes which represent a GUID in the proper

order.

@return [String]

# File lib/rex/text.rb, line 1297
def self.to_guid(bytes)
  return nil unless bytes
  s = bytes.unpack('H*')[0]
  parts = [
    s[6,  2] + s[4,  2] + s[2, 2] + s[0, 2],
    s[10, 2] + s[8,  2],
    s[14, 2] + s[12, 2],
    s[16, 4],
    s[20, 12]
  ]
  "{#{parts.join('-')}}"
end
to_hex(str, prefix = "\\x", count = 1) click to toggle source

Returns the escaped hex version of the supplied string

@example

Rex::Text.to_hex("asdf") # => "\\x61\\x73\\x64\\x66"

@param str (see to_octal) @param prefix (see to_octal) @param count [Fixnum] Number of bytes to put in each escape chunk @return [String] The escaped hex version of str

# File lib/rex/text.rb, line 524
def self.to_hex(str, prefix = "\\x", count = 1)
  raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0)

  # XXX: Regexp.new is used here since using /.{#{count}}/o would compile
  # the regex the first time it is used and never check again.  Since we
  # want to know how many to capture on every instance, we do it this
  # way.
  return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s| prefix + s }
end
to_hex_ascii(str, prefix = "\\x", count = 1, suffix=nil) click to toggle source

Returns the string with nonprintable hex characters sanitized to ascii. Similiar to {.to_hex}, but regular ASCII is not translated if count is 1.

@example

Rex::Text.to_hex_ascii("\x7fABC\0") # => "\\x7fABC\\x00"

@param str (see to_hex) @param prefix (see to_hex) @param count (see to_hex) @param suffix [String,nil] A string to append to the converted bytes @return [String] The original string with non-printables converted to

their escaped hex representation
# File lib/rex/text.rb, line 547
def self.to_hex_ascii(str, prefix = "\\x", count = 1, suffix=nil)
  raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0)
  return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s|
    (0x20..0x7e) === s.to_i(16) ? s.to_i(16).chr : prefix + s + suffix.to_s
  }
end
to_hex_dump(str, width=16, base=nil) click to toggle source

Converts a string to a nicely formatted hex dump

@param str [String] The string to convert @param width [Fixnum] Number of bytes to convert before adding a newline @param base [Fixnum] The base address of the dump

# File lib/rex/text.rb, line 913
def self.to_hex_dump(str, width=16, base=nil)
  buf = ''
  idx = 0
  cnt = 0
  snl = false
  lst = 0
  lft_col_len = (base.to_i+str.length).to_s(16).length
  lft_col_len = 8 if lft_col_len < 8

  while (idx < str.length)
    chunk = str[idx, width]
    addr = base ? "%0#{lft_col_len}x  " %(base.to_i + idx) : ''
    line  = chunk.unpack("H*")[0].scan(/../).join(" ")
    buf << addr + line

    if (lst == 0)
      lst = line.length
      buf << " " * 4
    else
      buf << " " * ((lst - line.length) + 4).abs
    end

    buf << "|"

    chunk.unpack("C*").each do |c|
      if (c > 0x1f and c < 0x7f)
        buf << c.chr
      else
        buf << "."
      end
    end

    buf << "|\n"

    idx += width
  end

  buf << "\n"
end
to_java(str, name = "shell") click to toggle source

Converts a raw string into a java byte array

# File lib/rex/text.rb, line 284
def self.to_java(str, name = "shell")
  buff = "byte #{name}[] = new byte[]\n{\n"
  cnt = 0
  max = 0
  str.unpack('C*').each do |c|
    buff << ", " if max > 0
    buff << "\t" if max == 0
    buff << sprintf('(byte) 0x%.2x', c)
    max +=1
    cnt +=1

    if (max > 7)
      buff << ",\n" if cnt != str.length
      max = 0
    end
  end
  buff << "\n};\n"
  return buff
end
to_js_comment(str, wrap = DefaultWrap) click to toggle source

Creates a javascript-style comment

# File lib/rex/text.rb, line 256
def self.to_js_comment(str, wrap = DefaultWrap)
  return wordwrap(str, 0, wrap, '', '// ')
end
to_mixed_case_array(str) click to toggle source

Takes a string, and returns an array of all mixed case versions.

@example

>> Rex::Text.to_mixed_case_array "abc1"
=> ["abc1", "abC1", "aBc1", "aBC1", "Abc1", "AbC1", "ABc1", "ABC1"]

@param str [String] The string to randomize @return [Array<String>] @see permute_case

# File lib/rex/text.rb, line 892
def self.to_mixed_case_array(str)
  letters = []
  str.scan(/./).each { |l| letters << [l.downcase, l.upcase] }
  coords = []
  (1 << str.size).times { |i| coords << ("%0#{str.size}b" % i) }
  mixed = []
  coords.each do |coord|
    c = coord.scan(/./).map {|x| x.to_i}
    this_str = ""
    c.each_with_index { |d,i| this_str << letters[i][d] }
    mixed << this_str
  end
  return mixed.uniq
end
to_num(str, wrap = DefaultWrap) click to toggle source

Creates a comma separated list of numbers

# File lib/rex/text.rb, line 178
def self.to_num(str, wrap = DefaultWrap)
  code = str.unpack('C*')
  buff = ""
  0.upto(code.length-1) do |byte|
    if(byte % 15 == 0) and (buff.length > 0)
      buff << "\r\n"
    end
    buff << sprintf('0x%.2x, ', code[byte])
  end
  # strip , at the end
  buff = buff.chomp(', ')
  buff << "\r\n"
  return buff
end
to_octal(str, prefix = "\\") click to toggle source

Returns the escaped octal version of the supplied string

@example

Rex::Text.to_octal("asdf") # => "\\141\\163\\144\\146"

@param str [String] The string to be converted @param prefix [String] @return [String] The escaped octal version of str

# File lib/rex/text.rb, line 505
def self.to_octal(str, prefix = "\\")
  octal = ""
  str.each_byte { |b|
    octal << "#{prefix}#{b.to_s 8}"
  }

  return octal
end
to_perl(str, wrap = DefaultWrap, name = "buf") click to toggle source

Converts a raw string into a perl buffer

# File lib/rex/text.rb, line 263
def self.to_perl(str, wrap = DefaultWrap, name = "buf")
  return hexify(str, wrap, '"', '" .', "my $#{name} = \n", '";')
end
to_perl_comment(str, wrap = DefaultWrap) click to toggle source

Creates a perl-style comment

# File lib/rex/text.rb, line 356
def self.to_perl_comment(str, wrap = DefaultWrap)
  return wordwrap(str, 0, wrap, '', '# ')
end
to_powershell(str, name = "buf") click to toggle source

Converts a raw string to a powershell byte array

# File lib/rex/text.rb, line 307
def self.to_powershell(str, name = "buf")
  return Rex::Exploitation::Powershell::Script.to_byte_array(str, name)
end
to_python(str, wrap = DefaultWrap, name = "buf") click to toggle source

Converts a raw string into a python buffer

# File lib/rex/text.rb, line 270
def self.to_python(str, wrap = DefaultWrap, name = "buf")
  return hexify(str, wrap, "#{name} += \"", '"', "#{name} =  \"\"\n", '"')
end
to_rand_case(str) click to toggle source

Converts a string to random case

@example

Rex::Text.to_rand_case("asdf") # => "asDf"

@param str [String] The string to randomize @return [String] @see permute_case @see to_mixed_case_array

# File lib/rex/text.rb, line 874
def self.to_rand_case(str)
  buf = str.dup
  0.upto(str.length) do |i|
    buf[i,1] = rand(2) == 0 ? str[i,1].upcase : str[i,1].downcase
  end
  return buf
end
to_raw(str) click to toggle source

Returns the raw string

# File lib/rex/text.rb, line 370
def self.to_raw(str)
  return str
end
to_ruby(str, wrap = DefaultWrap, name = "buf") click to toggle source

Converts a raw string into a ruby buffer

# File lib/rex/text.rb, line 171
def self.to_ruby(str, wrap = DefaultWrap, name = "buf")
  return hexify(str, wrap, '"', '" +', "#{name} = \n", '"')
end
to_ruby_comment(str, wrap = DefaultWrap) click to toggle source

Creates a ruby-style comment

# File lib/rex/text.rb, line 224
def self.to_ruby_comment(str, wrap = DefaultWrap)
  return wordwrap(str, 0, wrap, '', '# ')
end
to_unescape(data, endian=ENDIAN_LITTLE, prefix='%%u') click to toggle source

Returns a unicode escaped string for Javascript

# File lib/rex/text.rb, line 477
def self.to_unescape(data, endian=ENDIAN_LITTLE, prefix='%%u')
  data << "\x41" if (data.length % 2 != 0)
  dptr = 0
  buff = ''
  while (dptr < data.length)
    c1 = data[dptr,1].unpack("C*")[0]
    dptr += 1
    c2 = data[dptr,1].unpack("C*")[0]
    dptr += 1

    if (endian == ENDIAN_LITTLE)
      buff << sprintf("#{prefix}%.2x%.2x", c2, c1)
    else
      buff << sprintf("#{prefix}%.2x%.2x", c1, c2)
    end
  end
  return buff
end
to_unicode(str='', type = 'utf-16le', mode = '', size = '') click to toggle source

Converts standard ASCII text to a unicode string.

Supported unicode types include: utf-16le, utf16-be, utf32-le, utf32-be, utf-7, and utf-8

Providing ‘mode’ provides hints to the actual encoder as to how it should encode the string.

Only UTF-7 and UTF-8 use “mode”.

utf-7 by default does not encode alphanumeric and a few other characters. By specifying the mode of “all”, then all of the characters are encoded, not just the non-alphanumeric set. to_unicode(str, ‘utf-7’, ‘all’)

utf-8 specifies that alphanumeric characters are used directly, eg “a” is just “a”. However, there exist 6 different overlong encodings of “a” that are technically not valid, but parse just fine in most utf-8 parsers. (0xC1A1, 0xE081A1, 0xF08081A1, 0xF8808081A1, 0xFC80808081A1, 0xFE8080808081A1). How many bytes to use for the overlong enocding is specified providing ‘size’. to_unicode(str, ‘utf-8’, ‘overlong’, 2)

Many utf-8 parsers also allow invalid overlong encodings, where bits that are unused when encoding a single byte are modified. Many parsers will ignore these bits, rendering simple string matching to be ineffective for dealing with UTF-8 strings. There are many more invalid overlong encodings possible for “a”. For example, three encodings are available for an invalid 2 byte encoding of “a”. (0xC1E1 0xC161 0xC121).

By specifying “invalid”, a random invalid encoding is chosen for the given byte size. to_unicode(str, ‘utf-8’, ‘invalid’, 2)

utf-7 defaults to ‘normal’ utf-7 encoding utf-8 defaults to 2 byte ‘normal’ encoding

# File lib/rex/text.rb, line 591
def self.to_unicode(str='', type = 'utf-16le', mode = '', size = '')
  return '' if not str
  case type
  when 'utf-16le'
    return str.unpack('C*').pack('v*')
  when 'utf-16be'
    return str.unpack('C*').pack('n*')
  when 'utf-32le'
    return str.unpack('C*').pack('V*')
  when 'utf-32be'
    return str.unpack('C*').pack('N*')
  when 'utf-7'
    case mode
    when 'all'
      return str.gsub(/./){ |a|
        out = ''
        if 'a' != '+'
          out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '')
        end
        '+' + out + '-'
      }
    else
      return str.gsub(/[^\n\r\t\ A-Za-z0-9\'\(\),-.\/\:\?]/){ |a|
        out = ''
        if a != '+'
          out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '')
        end
        '+' + out + '-'
      }
    end
  when 'utf-8'
    if size == ''
      size = 2
    end

    if size >= 2 and size <= 7
      string = ''
      str.each_byte { |a|
        if (a < 21 || a > 0x7f) || mode != ''
          # ugh.      turn a single byte into the binary representation of it, in array form
          bin = [a].pack('C').unpack('B8')[0].split(//)

          # even more ugh.
          bin.collect!{|a_| a_.to_i}

          out = Array.new(8 * size, 0)

          0.upto(size - 1) { |i|
            out[i] = 1
            out[i * 8] = 1
          }

          i = 0
          byte = 0
          bin.reverse.each { |bit|
            if i < 6
              mod = (((size * 8) - 1) - byte * 8) - i
              out[mod] = bit
            else
              byte = byte + 1
              i = 0
              redo
            end
            i = i + 1
          }

          if mode != ''
            case mode
            when 'overlong'
              # do nothing, since we already handle this as above...
            when 'invalid'
              done = 0
              while done == 0
                # the ghetto...
                bits = [7, 8, 15, 16, 23, 24, 31, 32, 41]
                bits.each { |bit|
                  bit = (size * 8) - bit
                  if bit > 1
                    set = rand(2)
                    if out[bit] != set
                      out[bit] = set
                      done = 1
                    end
                  end
                }
              end
            else
              raise TypeError, 'Invalid mode.  Only "overlong" and "invalid" are acceptable modes for utf-8'
            end
          end
          string << [out.join('')].pack('B*')
        else
          string << [a].pack('C')
        end
      }
      return string
    else
      raise TypeError, 'invalid utf-8 size'
    end
  when 'uhwtfms' # suggested name from HD :P
    load_codepage()

    string = ''
    # overloading mode as codepage
    if mode == ''
      mode = 1252 # ANSI - Latan 1, default for US installs of MS products
    else
      mode = mode.to_i
    end
    if @@codepage_map_cache[mode].nil?
      raise TypeError, "Invalid codepage #{mode}"
    end
    str.each_byte {|byte|
      char = [byte].pack('C*')
      possible = @@codepage_map_cache[mode]['data'][char]
      if possible.nil?
        raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}"
      end
      string << possible[ rand(possible.length) ]
    }
    return string
  when 'uhwtfms-half' # suggested name from HD :P
    load_codepage()
    string = ''
    # overloading mode as codepage
    if mode == ''
      mode = 1252 # ANSI - Latan 1, default for US installs of MS products
    else
      mode = mode.to_i
    end
    if mode != 1252
      raise TypeError, "Invalid codepage #{mode}, only 1252 supported for uhwtfms_half"
    end
    str.each_byte {|byte|
      if ((byte >= 33 && byte <= 63) || (byte >= 96 && byte <= 126))
        string << "\xFF" + [byte ^ 32].pack('C')
      elsif (byte >= 64 && byte <= 95)
        string << "\xFF" + [byte ^ 96].pack('C')
      else
        char = [byte].pack('C')
        possible = @@codepage_map_cache[mode]['data'][char]
        if possible.nil?
          raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}"
        end
        string << possible[ rand(possible.length) ]
      end
    }
    return string
  else
    raise TypeError, 'invalid utf type'
  end
end
to_utf8(str) click to toggle source

Converts ISO-8859-1 to UTF-8

# File lib/rex/text.rb, line 377
def self.to_utf8(str)

  if str.respond_to?(:encode)
    # Skip over any bytes that fail to convert to UTF-8
    return str.encode('utf-8', { :invalid => :replace, :undef => :replace, :replace => '' })
  end

  begin
    Iconv.iconv("utf-8","iso-8859-1", str).join(" ")
  rescue
    raise ::RuntimeError, "Your installation does not support iconv (needed for utf8 conversion)"
  end
end
to_vbapplication(str, name = "buf") click to toggle source

Converts a raw string into a vba buffer

# File lib/rex/text.rb, line 335
def self.to_vbapplication(str, name = "buf")
  return "#{name} = Array()" if str.nil? or str.empty?

  code  = str.unpack('C*')
  buff = "#{name} = Array("
  maxbytes = 20

  1.upto(code.length) do |idx|
    buff << code[idx].to_s
    buff << "," if idx < code.length - 1
    buff << " _\r\n" if (idx > 1 and (idx % maxbytes) == 0)
  end

  buff << ")\r\n"

  return buff
end
to_vbscript(str, name = "buf") click to toggle source

Converts a raw string to a vbscript byte array

# File lib/rex/text.rb, line 314
def self.to_vbscript(str, name = "buf")
  return "#{name}" if str.nil? or str.empty?

  code = str.unpack('C*')
  buff = "#{name}=Chr(#{code[0]})"
  1.upto(code.length-1) do |byte|
    if(byte % 100 == 0)
      buff << "\r\n#{name}=#{name}"
    end
    # exe is an Array of bytes, not a String, thanks to the unpack
    # above, so the following line is not subject to the different
    # treatments of String#[] between ruby 1.8 and 1.9
    buff << "&Chr(#{code[byte]})"
  end

  return buff
end
to_words( str, strict = false ) click to toggle source

Returns the words in str as an Array.

strict - include only words, no boundary characters (like spaces, etc.)

# File lib/rex/text.rb, line 452
def self.to_words( str, strict = false )
  splits = str.split( /\b/ )
  splits.reject! { |w| !(w =~ /\w/) } if strict
  splits
end
ungzip(str) click to toggle source

Uncompresses a string using gzip

@param str (see zlib_inflate) @return (see zlib_inflate)

# File lib/rex/text.rb, line 1490
def self.ungzip(str)
  raise RuntimeError, "Gzip support is not present." if (!zlib_present?)

  s = ""
  s.force_encoding('ASCII-8BIT') if s.respond_to?(:encoding)
  gz = Zlib::GzipReader.new(StringIO.new(str, 'rb'))
  s << gz.read
  gz.close
  return s
end
unicode_filter_decode(str) click to toggle source
# File lib/rex/text.rb, line 1718
def self.unicode_filter_decode(str)
  str.to_s.gsub( /\$U\$([\x20-\x2c\x2e-\x7E]*)\-0x([A-Fa-f0-9]+)/n ){|m| [$2].pack("H*") }
end
unicode_filter_encode(str) click to toggle source

A custom unicode filter for dealing with multi-byte strings on a 8-bit console Punycode would have been more “standard”, but it requires valid Unicode chars

# File lib/rex/text.rb, line 1710
def self.unicode_filter_encode(str)
  if (str.to_s.unpack("C*") & ( LowAscii + HighAscii + "\x7f" ).unpack("C*")).length > 0
    str = "$U$" + str.unpack("C*").select{|c| c < 0x7f and c > 0x1f and c != 0x2d}.pack("C*") + "-0x" + str.unpack("H*")[0]
  else
    str
  end
end
uri_decode(str) click to toggle source

Decode a URI encoded string

# File lib/rex/text.rb, line 860
def self.uri_decode(str)
  str.gsub(/(%[a-z0-9]{2})/i){ |c| [c[1,2]].pack("H*") }
end
uri_encode(str, mode = 'hex-normal') click to toggle source

Encode a string in a manor useful for HTTP URIs and URI Parameters.

# File lib/rex/text.rb, line 774
def self.uri_encode(str, mode = 'hex-normal')
  return "" if str == nil

  return str if mode == 'none' # fast track no encoding

  all = /./
  noslashes = /[^\/\\]+/
  # http://tools.ietf.org/html/rfc3986#section-2.3
  normal = /[^a-zA-Z0-9\/\\\.\-_~]+/

  case mode
  when 'hex-all'
    return str.gsub(all) { |s| Rex::Text.to_hex(s, '%') }
  when 'hex-normal'
    return str.gsub(normal) { |s| Rex::Text.to_hex(s, '%') }
  when 'hex-noslashes'
    return str.gsub(noslashes) { |s| Rex::Text.to_hex(s, '%') }
  when 'hex-random'
    res = ''
    str.each_byte do |c|
      b = c.chr
      res << ((rand(2) == 0) ?
        b.gsub(all)   { |s| Rex::Text.to_hex(s, '%') } :
        b.gsub(normal){ |s| Rex::Text.to_hex(s, '%') } )
    end
    return res
  when 'u-all'
    return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
  when 'u-normal'
    return str.gsub(normal) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
  when 'u-noslashes'
    return str.gsub(noslashes) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
  when 'u-random'
    res = ''
    str.each_byte do |c|
      b = c.chr
      res << ((rand(2) == 0) ?
        b.gsub(all)   { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) } :
        b.gsub(normal){ |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) } )
    end
    return res
  when 'u-half'
    return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms-half'), '%u', 2) }
  else
    raise TypeError, "invalid mode #{mode.inspect}"
  end
end
wordwrap(str, indent = 0, col = DefaultWrap, append = '', prepend = '') click to toggle source

Wraps text at a given column using a supplied indention

# File lib/rex/text.rb, line 983
def self.wordwrap(str, indent = 0, col = DefaultWrap, append = '', prepend = '')
  return str.gsub(/.{1,#{col - indent}}(?:\s|\Z)/){
    ( (" " * indent) + prepend + $& + append + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")}
end
xml_char_encode(str) click to toggle source

Encode an ASCII string so it’s safe for XML. It’s a wrapper for to_hex_ascii.

# File lib/rex/text.rb, line 853
def self.xml_char_encode(str)
  self.to_hex_ascii(str, "&#x", 1, ";")
end
zlib_deflate(str, level = Zlib::BEST_COMPRESSION) click to toggle source

Compresses a string using zlib

@param str [String] The string to be compressed @param level [Fixnum] One of the Zlib compression level constants @return [String] The compressed version of str

# File lib/rex/text.rb, line 1439
def self.zlib_deflate(str, level = Zlib::BEST_COMPRESSION)
  if self.zlib_present?
    z = Zlib::Deflate.new(level)
    dst = z.deflate(str, Zlib::FINISH)
    z.close
    return dst
  else
    raise RuntimeError, "Gzip support is not present."
  end
end
zlib_inflate(str) click to toggle source

Uncompresses a string using zlib

@param str [String] Compressed string to inflate @return [String] The uncompressed version of str

# File lib/rex/text.rb, line 1455
def self.zlib_inflate(str)
  if(self.zlib_present?)
    zstream = Zlib::Inflate.new
    buf = zstream.inflate(str)
    zstream.finish
    zstream.close
    return buf
  else
    raise RuntimeError, "Gzip support is not present."
  end
end
zlib_present?() click to toggle source

Returns true if zlib can be used.

# File lib/rex/text.rb, line 1419
def self.zlib_present?
  begin
    temp = Zlib
    return true
  rescue
    return false
  end
end

Protected Class Methods

checksum16_be(str) click to toggle source

@param str [String] Big-endian data to checksum @return [Fixnum] 16-bit checksum

# File lib/rex/text.rb, line 1794
def self.checksum16_be(str)
  (str.unpack("n*").inject(:+) || 0) % 0x10000
end
checksum16_le(str) click to toggle source

@param str [String] Little-endian data to checksum @return [Fixnum] 16-bit checksum

# File lib/rex/text.rb, line 1788
def self.checksum16_le(str)
  (str.unpack("v*").inject(:+) || 0) % 0x10000
end
checksum32_be(str) click to toggle source

@param str [String] Big-endian data to checksum @return [Fixnum] 32-bit checksum

# File lib/rex/text.rb, line 1806
def self.checksum32_be(str)
  (str.unpack("N*").inject(:+) || 0) % 0x100000000
end
checksum32_le(str) click to toggle source

@param str [String] Little-endian data to checksum @return [Fixnum] 32-bit checksum

# File lib/rex/text.rb, line 1800
def self.checksum32_le(str)
  (str.unpack("V*").inject(:+) || 0) % 0x100000000
end
checksum8(str) click to toggle source

@param str [String] Data to checksum @return [Fixnum] 8-bit checksum

# File lib/rex/text.rb, line 1782
def self.checksum8(str)
  (str.unpack("C*").inject(:+) || 0) % 0x100
end
load_codepage() click to toggle source
# File lib/rex/text.rb, line 1748
def self.load_codepage()
  return if (!@@codepage_map_cache.nil?)
  file = File.join(File.dirname(__FILE__),'codepage.map')
  page = ''
  name = ''
  map = {}
  File.open(file).each { |line|
    next if line =~ /^#/
    next if line =~ /^\s*$/
    data = line.split
    if data[1] =~ /^\(/
      page = data.shift.to_i
      name = data.join(' ').sub(/^\(/,'').sub(/\)$/,'')
      map[page] = {}
      map[page]['name'] = name
      map[page]['data'] = {}
    else
      data.each { |entry|
        wide, char = entry.split(':')
        char = [char].pack('H*')
        wide = [wide].pack('H*')
        if map[page]['data'][char].nil?
          map[page]['data'][char] = [wide]
        else
          map[page]['data'][char].push(wide)
        end
      }
    end
  }
  @@codepage_map_cache = map
end