@@ -276,6 +276,15 @@ def self.to_unescape(data, endian=ENDIAN_LITTLE)
276
276
return buff
277
277
end
278
278
279
+ #
280
+ # Returns the escaped octal version of the supplied string
281
+ #
282
+ # @example
283
+ # Rex::Text.to_octal("asdf") # => "\\141\\163\\144\\146"
284
+ #
285
+ # @param str [String] The string to be converted
286
+ # @param prefix [String]
287
+ # @return [String] The escaped octal version of +str+
279
288
def self . to_octal ( str , prefix = "\\ " )
280
289
octal = ""
281
290
str . each_byte { |b |
@@ -286,8 +295,15 @@ def self.to_octal(str, prefix = "\\")
286
295
end
287
296
288
297
#
289
- # Returns the hex version of the supplied string
298
+ # Returns the escaped hex version of the supplied string
299
+ #
300
+ # @example
301
+ # Rex::Text.to_hex("asdf") # => "\\x61\\x73\\x64\\x66"
290
302
#
303
+ # @param str (see to_octal)
304
+ # @param prefix (see to_octal)
305
+ # @param count [Fixnum] Number of bytes to put in each escape chunk
306
+ # @return [String] The escaped hex version of +str+
291
307
def self . to_hex ( str , prefix = "\\ x" , count = 1 )
292
308
raise ::RuntimeError , "unable to chunk into #{ count } byte chunks" if ( ( str . length % count ) > 0 )
293
309
@@ -299,9 +315,18 @@ def self.to_hex(str, prefix = "\\x", count = 1)
299
315
end
300
316
301
317
#
302
- # Returns the string with nonprintable hex characters sanitized to ascii. Similiar to to_hex,
303
- # but regular ASCII is not translated if count is 1.
318
+ # Returns the string with nonprintable hex characters sanitized to ascii.
319
+ # Similiar to {.to_hex}, but regular ASCII is not translated if + count+ is 1.
304
320
#
321
+ # @example
322
+ # Rex::Text.to_hex_ascii("\x7fABC\0") # => "\\x7fABC\\x00"
323
+ #
324
+ # @param str (see to_hex)
325
+ # @param prefix (see to_hex)
326
+ # @param count (see to_hex)
327
+ # @param suffix [String,nil] A string to append to the converted bytes
328
+ # @return [String] The original string with non-printables converted to
329
+ # their escaped hex representation
305
330
def self . to_hex_ascii ( str , prefix = "\\ x" , count = 1 , suffix = nil )
306
331
raise ::RuntimeError , "unable to chunk into #{ count } byte chunks" if ( ( str . length % count ) > 0 )
307
332
return str . unpack ( 'H*' ) [ 0 ] . gsub ( Regexp . new ( ".{#{ count * 2 } }" , nil , 'n' ) ) { |s |
@@ -557,6 +582,10 @@ def self.uri_encode(str, mode = 'hex-normal')
557
582
#
558
583
# Encode a string in a manner useful for HTTP URIs and URI Parameters.
559
584
#
585
+ # @param str [String] The string to be encoded
586
+ # @param mode ["hex","int","int-wide"]
587
+ # @return [String]
588
+ # @raise [TypeError] if +mode+ is not one of the three available modes
560
589
def self . html_encode ( str , mode = 'hex' )
561
590
case mode
562
591
when 'hex'
@@ -595,6 +624,13 @@ def self.uri_decode(str)
595
624
#
596
625
# Converts a string to random case
597
626
#
627
+ # @example
628
+ # Rex::Text.to_rand_case("asdf") # => "asDf"
629
+ #
630
+ # @param str [String] The string to randomize
631
+ # @return [String]
632
+ # @see permute_case
633
+ # @see to_mixed_case_array
598
634
def self . to_rand_case ( str )
599
635
buf = str . dup
600
636
0 . upto ( str . length ) do |i |
@@ -606,11 +642,13 @@ def self.to_rand_case(str)
606
642
#
607
643
# Takes a string, and returns an array of all mixed case versions.
608
644
#
609
- # Example:
610
- #
611
- # >> Rex::Text.to_mixed_case_array "abc1"
612
- # => ["abc1", "abC1", "aBc1", "aBC1", "Abc1", "AbC1", "ABc1", "ABC1"]
645
+ # @example
646
+ # >> Rex::Text.to_mixed_case_array "abc1"
647
+ # => ["abc1", "abC1", "aBc1", "aBC1", "Abc1", "AbC1", "ABc1", "ABC1"]
613
648
#
649
+ # @param str [String] The string to randomize
650
+ # @return [Array<String>]
651
+ # @see permute_case
614
652
def self . to_mixed_case_array ( str )
615
653
letters = [ ]
616
654
str . scan ( /./ ) . each { |l | letters << [ l . downcase , l . upcase ] }
@@ -627,8 +665,10 @@ def self.to_mixed_case_array(str)
627
665
end
628
666
629
667
#
630
- # Converts a string a nicely formatted hex dump
668
+ # Converts a string to a nicely formatted hex dump
631
669
#
670
+ # @param str [String] The string to convert
671
+ # @param width [Fixnum] Number of bytes to convert before adding a newline
632
672
def self . to_hex_dump ( str , width = 16 )
633
673
buf = ''
634
674
idx = 0
@@ -711,6 +751,9 @@ def self.to_addr_hex_dump(str, start_addr=0, width=16)
711
751
#
712
752
# Converts a hex string to a raw string
713
753
#
754
+ # @example
755
+ # Rex::Text.hex_to_raw("\\x41\\x7f\\x42") # => "A\x7fB"
756
+ #
714
757
def self . hex_to_raw ( str )
715
758
[ str . downcase . gsub ( /'/ , '' ) . gsub ( /\\ ?x([a-f0-9][a-f0-9])/ , '\1' ) ] . pack ( "H*" )
716
759
end
@@ -721,6 +764,9 @@ def self.hex_to_raw(str)
721
764
# If +whitespace+ is true, converts whitespace (0x20, 0x09, etc) to hex as
722
765
# well.
723
766
#
767
+ # @see hexify
768
+ # @see to_hex Converts all the chars
769
+ #
724
770
def self . ascii_safe_hex ( str , whitespace = false )
725
771
if whitespace
726
772
str . gsub ( /([\x00 -\x20 \x80 -\xFF ])/ ) { |x | "\\ x%.2x" % x . unpack ( "C*" ) [ 0 ] }
@@ -915,8 +961,12 @@ def self.sha1(str)
915
961
916
962
#
917
963
# Convert hex-encoded characters to literals.
918
- # Example: "AA\\x42CC" becomes "AABCC"
919
964
#
965
+ # @example
966
+ # Rex::Text.dehex("AA\\x42CC") # => "AABCC"
967
+ #
968
+ # @see hex_to_raw
969
+ # @param str [String]
920
970
def self . dehex ( str )
921
971
return str unless str . respond_to? :match
922
972
return str unless str . respond_to? :gsub
@@ -931,6 +981,7 @@ def self.dehex(str)
931
981
#
932
982
# Convert and replace hex-encoded characters to literals.
933
983
#
984
+ # @param (see dehex)
934
985
def self . dehex! ( str )
935
986
return str unless str . respond_to? :match
936
987
return str unless str . respond_to? :gsub
@@ -1020,7 +1071,12 @@ def self.rand_text_highascii(len, bad='')
1020
1071
rand_base ( len , bad , *foo )
1021
1072
end
1022
1073
1023
- # Generate a random GUID, of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
1074
+ # Generate a random GUID
1075
+ #
1076
+ # @example
1077
+ # Rex::Text.rand_guid # => "{ca776ced-4ab8-2ed6-6510-aa71e5e2508e}"
1078
+ #
1079
+ # @return [String]
1024
1080
def self . rand_guid
1025
1081
"{#{ [ 8 , 4 , 4 , 4 , 12 ] . map { |a | rand_text_hex ( a ) } . join ( "-" ) } }"
1026
1082
end
@@ -1031,9 +1087,15 @@ def self.rand_guid
1031
1087
# supplied number of identifiable characters (slots). The supplied sets
1032
1088
# should not contain any duplicate characters or the logic will fail.
1033
1089
#
1090
+ # @param length [Fixnum]
1091
+ # @param sets [Array<(String,String,String)>] The character sets to choose
1092
+ # from. Should have 3 elements, each of which must be a string containing
1093
+ # no characters contained in the other sets.
1094
+ # @return [String] A pattern of +length+ bytes, in which any 4-byte chunk is
1095
+ # unique
1096
+ # @see pattern_offset
1034
1097
def self . pattern_create ( length , sets = nil )
1035
1098
buf = ''
1036
- idx = 0
1037
1099
offsets = [ ]
1038
1100
1039
1101
# Make sure there's something in sets even if we were given an explicit nil
@@ -1084,6 +1146,12 @@ def self.patt2(len, sets = nil)
1084
1146
#
1085
1147
# Calculate the offset to a pattern
1086
1148
#
1149
+ # @param pattern [String] The pattern to search. Usually the return value
1150
+ # from {.pattern_create}
1151
+ # @param value [String,Fixnum,Bignum]
1152
+ # @return [Fixnum] Index of the given +value+ within +pattern+, if it exists
1153
+ # @return [nil] if +pattern+ does not contain +value+
1154
+ # @see pattern_create
1087
1155
def self . pattern_offset ( pattern , value , start = 0 )
1088
1156
if ( value . kind_of? ( String ) )
1089
1157
pattern . index ( value , start )
@@ -1098,6 +1166,9 @@ def self.pattern_offset(pattern, value, start=0)
1098
1166
# Compresses a string, eliminating all superfluous whitespace before and
1099
1167
# after lines and eliminating all lines.
1100
1168
#
1169
+ # @param str [String] The string in which to crunch whitespace
1170
+ # @return [String] Just like +str+, but with repeated whitespace characters
1171
+ # trimmed down to a single space
1101
1172
def self . compress ( str )
1102
1173
str . gsub ( /\n /m , ' ' ) . gsub ( /\s +/ , ' ' ) . gsub ( /^\s +/ , '' ) . gsub ( /\s +$/ , '' )
1103
1174
end
@@ -1136,6 +1207,9 @@ def self.gzip_present?
1136
1207
#
1137
1208
# Compresses a string using zlib
1138
1209
#
1210
+ # @param str [String] The string to be compressed
1211
+ # @param level [Fixnum] One of the Zlib compression level constants
1212
+ # @return [String] The compressed version of +str+
1139
1213
def self . zlib_deflate ( str , level = Zlib ::BEST_COMPRESSION )
1140
1214
if self . zlib_present?
1141
1215
z = Zlib ::Deflate . new ( level )
@@ -1150,6 +1224,8 @@ def self.zlib_deflate(str, level = Zlib::BEST_COMPRESSION)
1150
1224
#
1151
1225
# Uncompresses a string using zlib
1152
1226
#
1227
+ # @param str [String] Compressed string to inflate
1228
+ # @return [String] The uncompressed version of +str+
1153
1229
def self . zlib_inflate ( str )
1154
1230
if ( self . zlib_present? )
1155
1231
zstream = Zlib ::Inflate . new
@@ -1165,6 +1241,9 @@ def self.zlib_inflate(str)
1165
1241
#
1166
1242
# Compresses a string using gzip
1167
1243
#
1244
+ # @param str (see zlib_deflate)
1245
+ # @param level [Fixnum] Compression level, 1 (fast) to 9 (best)
1246
+ # @return (see zlib_deflate)
1168
1247
def self . gzip ( str , level = 9 )
1169
1248
raise RuntimeError , "Gzip support is not present." if ( !zlib_present? )
1170
1249
raise RuntimeError , "Invalid gzip compression level" if ( level < 1 or level > 9 )
@@ -1180,6 +1259,8 @@ def self.gzip(str, level = 9)
1180
1259
#
1181
1260
# Uncompresses a string using gzip
1182
1261
#
1262
+ # @param str (see zlib_inflate)
1263
+ # @return (see zlib_inflate)
1183
1264
def self . ungzip ( str )
1184
1265
raise RuntimeError , "Gzip support is not present." if ( !zlib_present? )
1185
1266
@@ -1192,9 +1273,13 @@ def self.ungzip(str)
1192
1273
end
1193
1274
1194
1275
#
1195
- # Return the index of the first badchar in data, otherwise return
1276
+ # Return the index of the first badchar in + data+ , otherwise return
1196
1277
# nil if there wasn't any badchar occurences.
1197
1278
#
1279
+ # @param data [String] The string to check for bad characters
1280
+ # @param badchars [String] A list of characters considered to be bad
1281
+ # @return [Fixnum] Index of the first bad character if any exist in +data+
1282
+ # @return [nil] If +data+ contains no bad characters
1198
1283
def self . badchar_index ( data , badchars = '' )
1199
1284
badchars . unpack ( "C*" ) . each { |badchar |
1200
1285
pos = data . index ( badchar . chr )
@@ -1204,29 +1289,42 @@ def self.badchar_index(data, badchars = '')
1204
1289
end
1205
1290
1206
1291
#
1207
- # This method removes bad characters from a string.
1292
+ # Removes bad characters from a string.
1293
+ #
1294
+ # Modifies +data+ in place
1208
1295
#
1296
+ # @param data [#delete]
1297
+ # @param badchars [String] A list of characters considered to be bad
1209
1298
def self . remove_badchars ( data , badchars = '' )
1210
1299
data . delete ( badchars )
1211
1300
end
1212
1301
1213
1302
#
1214
- # This method returns all chars but the supplied set
1303
+ # Returns all chars that are not in the supplied set
1215
1304
#
1305
+ # @param keepers [String]
1306
+ # @return [String] All characters not contained in +keepers+
1216
1307
def self . charset_exclude ( keepers )
1217
1308
[ *( 0 ..255 ) ] . pack ( 'C*' ) . delete ( keepers )
1218
1309
end
1219
1310
1220
1311
#
1221
- # Shuffles a byte stream
1312
+ # Shuffles a byte stream
1222
1313
#
1314
+ # @param str [String]
1315
+ # @return [String] The shuffled result
1316
+ # @see shuffle_a
1223
1317
def self . shuffle_s ( str )
1224
1318
shuffle_a ( str . unpack ( "C*" ) ) . pack ( "C*" )
1225
1319
end
1226
1320
1227
1321
#
1228
1322
# Performs a Fisher-Yates shuffle on an array
1229
1323
#
1324
+ # Modifies +arr+ in place
1325
+ #
1326
+ # @param arr [Array] The array to be shuffled
1327
+ # @return [Array]
1230
1328
def self . shuffle_a ( arr )
1231
1329
len = arr . length
1232
1330
max = len - 1
@@ -1268,6 +1366,8 @@ def self.permute_case(word, idx=0)
1268
1366
end
1269
1367
1270
1368
# Generate a random hostname
1369
+ #
1370
+ # @return [String] A random string conforming to the rules of FQDNs
1271
1371
def self . rand_hostname
1272
1372
host = [ ]
1273
1373
( rand ( 5 ) + 1 ) . times {
@@ -1287,15 +1387,18 @@ def self.rand_state()
1287
1387
#
1288
1388
# Calculate the ROR13 hash of a given string
1289
1389
#
1390
+ # @return [Fixnum]
1290
1391
def self . ror13_hash ( name )
1291
1392
hash = 0
1292
1393
name . unpack ( "C*" ) . each { |c | hash = ror ( hash , 13 ) ; hash += c }
1293
1394
hash
1294
1395
end
1295
1396
1296
1397
#
1297
- # Rotate a 32-bit value to the right by cnt bits
1398
+ # Rotate a 32-bit value to the right by + cnt+ bits
1298
1399
#
1400
+ # @param val [Fixnum] The value to rotate
1401
+ # @param cnt [Fixnum] Number of bits to rotate by
1299
1402
def self . ror ( val , cnt )
1300
1403
bits = [ val ] . pack ( "N" ) . unpack ( "B32" ) [ 0 ] . split ( // )
1301
1404
1 . upto ( cnt ) do |c |
@@ -1305,8 +1408,11 @@ def self.ror(val, cnt)
1305
1408
end
1306
1409
1307
1410
#
1308
- # Rotate a 32-bit value to the left by cnt bits
1411
+ # Rotate a 32-bit value to the left by + cnt+ bits
1309
1412
#
1413
+ # @param val (see ror)
1414
+ # @param cnt (see ror)
1415
+ # @return (see ror)
1310
1416
def self . rol ( val , cnt )
1311
1417
bits = [ val ] . pack ( "N" ) . unpack ( "B32" ) [ 0 ] . split ( // )
1312
1418
1 . upto ( cnt ) do |c |
@@ -1316,7 +1422,7 @@ def self.rol(val, cnt)
1316
1422
end
1317
1423
1318
1424
#
1319
- # Split a string by n charachter into an array
1425
+ # Split a string by n character into an array
1320
1426
#
1321
1427
def self . split_to_a ( str , n )
1322
1428
if n > 0
@@ -1331,7 +1437,7 @@ def self.split_to_a(str, n)
1331
1437
end
1332
1438
1333
1439
#
1334
- #Pack a value as 64 bit litle endian; does not exist for Array.pack
1440
+ # Pack a value as 64 bit litle endian; does not exist for Array.pack
1335
1441
#
1336
1442
def self . pack_int64le ( val )
1337
1443
[ val & 0x00000000ffffffff , val >> 32 ] . pack ( "V2" )
0 commit comments