Module: Pwnlib::Util::Fiddling
- Included in:
- Pwn, Shellcraft::Generators::Helper::Runner
- Defined in:
- lib/pwnlib/util/fiddling.rb
Overview
Some fiddling methods.
Class Method Summary collapse
-
.b64d(s) ⇒ String
Base64-decodes a string.
-
.b64e(s) ⇒ String
Base64-encodes a string.
-
.bits(s, endian: 'big', zero: 0, one: 1) ⇒ Array
Converts the argument to an array of bits.
-
.bits_str(s, endian: 'big', zero: 0, one: 1) ⇒ String
Simple wrapper around Fiddling.bits, which converts output to string.
-
.bitswap(s) ⇒ String
Reverse the bits of each byte in input string.
-
.bitswap_int(n, bits: nil) ⇒ Integer
Reverse the bits of a number, and returns the result as number.
-
.enhex(s) ⇒ String
Hex-encodes a string.
-
.hex(n) ⇒ String
Present number in hex format, same as python hex() do.
-
.unbits(s, endian: 'big') ⇒ String
Reverse of Fiddling.bits and Fiddling.bits_str, convert an array of bits back to string.
-
.unhex(s) ⇒ String
Hex-decodes a string.
-
.urldecode(s, ignore_invalid: false) ⇒ String
URL-decodes a string.
-
.urlencode(s) ⇒ String
URL-encodes a string.
-
.xor(s1, s2) ⇒ String
Xor two strings.
-
.xor_pair(data, avoid: "\x00\n") ⇒ (String, String)?
Find two strings that will xor into a given string, while only using a given alphabet.
Class Method Details
.b64d(s) ⇒ String
Base64-decodes a string.
266 267 268 |
# File 'lib/pwnlib/util/fiddling.rb', line 266 def b64d(s) s.unpack1('m0') end |
.b64e(s) ⇒ String
Base64-encodes a string. Do NOT contains those stupid newline (with RFC 4648).
252 253 254 |
# File 'lib/pwnlib/util/fiddling.rb', line 252 def b64e(s) [s].pack('m0') end |
.bits(s, endian: 'big', zero: 0, one: 1) ⇒ Array
Converts the argument to an array of bits.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/pwnlib/util/fiddling.rb', line 138 def bits(s, endian: 'big', zero: 0, one: 1) context.local(endian: endian) do is_little = context.endian == 'little' case s when String v = +'B*' v.downcase! if is_little s.unpack1(v).chars.map { |ch| ch == '1' ? one : zero } when Integer # TODO(Darkpi): What should we do to negative number? raise ArgumentError, 's must be non-negative' unless s >= 0 r = s.to_s(2).chars.map { |ch| ch == '1' ? one : zero } r.unshift(zero) until (r.size % 8).zero? is_little ? r.reverse : r else raise ArgumentError, 's must be either String or Integer' end end end |
.bits_str(s, endian: 'big', zero: 0, one: 1) ⇒ String
Simple wrapper around bits, which converts output to string.
168 169 170 |
# File 'lib/pwnlib/util/fiddling.rb', line 168 def bits_str(s, endian: 'big', zero: 0, one: 1) bits(s, endian: endian, zero: zero, one: one).join end |
.bitswap(s) ⇒ String
Reverse the bits of each byte in input string.
216 217 218 |
# File 'lib/pwnlib/util/fiddling.rb', line 216 def bitswap(s) unbits(bits(s, endian: 'big'), endian: 'little') end |
.bitswap_int(n, bits: nil) ⇒ Integer
Reverse the bits of a number, and returns the result as number.
233 234 235 236 237 238 239 |
# File 'lib/pwnlib/util/fiddling.rb', line 233 def bitswap_int(n, bits: nil) context.local(bits: bits) do bits = context.bits n &= (1 << bits) - 1 bits_str(n, endian: 'little').ljust(bits, '0').to_i(2) end end |
.enhex(s) ⇒ String
Hex-encodes a string.
29 30 31 |
# File 'lib/pwnlib/util/fiddling.rb', line 29 def enhex(s) s.unpack1('H*') end |
.hex(n) ⇒ String
Present number in hex format, same as python hex() do.
59 60 61 |
# File 'lib/pwnlib/util/fiddling.rb', line 59 def hex(n) (n.negative? ? '-' : '') + format('0x%x', n.abs) end |
.unbits(s, endian: 'big') ⇒ String
191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/pwnlib/util/fiddling.rb', line 191 def unbits(s, endian: 'big') s = s.chars if s.is_a?(String) context.local(endian: endian) do is_little = context.endian == 'little' bytes = s.map do |c| case c when '1', 1, true then '1' when '0', 0, false then '0' else raise ArgumentError, "cannot decode value #{c.inspect} into a bit" end end [bytes.join].pack(is_little ? 'b*' : 'B*') end end |
.unhex(s) ⇒ String
Hex-decodes a string.
43 44 45 |
# File 'lib/pwnlib/util/fiddling.rb', line 43 def unhex(s) [s].pack('H*') end |
.urldecode(s, ignore_invalid: false) ⇒ String
URL-decodes a string.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/pwnlib/util/fiddling.rb', line 95 def urldecode(s, ignore_invalid: false) res = +'' n = 0 while n < s.size if s[n] != '%' res << s[n] n += 1 else cur = s[n + 1, 2] if cur =~ /[0-9a-fA-F]{2}/ res << cur.to_i(16).chr n += 3 elsif ignore_invalid res << '%' n += 1 else raise ArgumentError, 'Invalid input to urldecode' end end end res end |
.urlencode(s) ⇒ String
URL-encodes a string.
73 74 75 |
# File 'lib/pwnlib/util/fiddling.rb', line 73 def urlencode(s) s.bytes.map { |b| format('%%%02x', b) }.join end |
.xor(s1, s2) ⇒ String
Xor two strings. If two strings have different length, the shorter one will be repeated until has the same length as another one.
294 295 296 297 |
# File 'lib/pwnlib/util/fiddling.rb', line 294 def xor(s1, s2) s1, s2 = s2, s1 if s1.size < s2.size s1.bytes.zip(''.ljust(s1.size, s2).bytes).map { |a, b| a ^ b }.pack('C*') end |
.xor_pair(data, avoid: "\x00\n") ⇒ (String, String)?
Find two strings that will xor into a given string, while only using a given alphabet.
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/pwnlib/util/fiddling.rb', line 311 def xor_pair(data, avoid: "\x00\n") data = pack(data) if data.is_a?(Integer) alphabet = 256.times.reject { |c| avoid.include?(c.chr) } res1 = +'' res2 = +'' data.bytes.each do |c1| # alphabet.shuffle! if context.randomize c2 = alphabet.find { |c| alphabet.include?(c1 ^ c) } return nil if c2.nil? res1 << c2.chr res2 << (c1 ^ c2).chr end [res1, res2] end |