resilience 0.0.2 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/bin/axe.rb +18 -0
  3. data/bin/fcomp.rb +15 -0
  4. data/bin/pex.rb +16 -0
  5. data/bin/rarser.rb +15 -0
  6. data/bin/reach.rb +16 -0
  7. data/bin/rex.rb +7 -66
  8. data/bin/rinfo.rb +19 -0
  9. data/lib/resilience.rb +5 -0
  10. data/lib/resilience/attribute.rb +21 -4
  11. data/lib/resilience/cli/all.rb +14 -0
  12. data/lib/resilience/cli/bin/axe.rb +34 -0
  13. data/lib/resilience/cli/bin/fcomp.rb +28 -0
  14. data/lib/resilience/cli/bin/pex.rb +43 -0
  15. data/lib/resilience/cli/bin/rarser.rb +72 -0
  16. data/lib/resilience/cli/bin/reach.rb +34 -0
  17. data/lib/resilience/cli/bin/rex.rb +33 -0
  18. data/lib/resilience/cli/bin/rinfo.rb +19 -0
  19. data/lib/resilience/cli/conf.rb +14 -0
  20. data/lib/resilience/cli/default.rb +17 -0
  21. data/lib/resilience/cli/disk.rb +40 -0
  22. data/lib/resilience/cli/file.rb +23 -0
  23. data/lib/resilience/cli/image.rb +45 -0
  24. data/lib/resilience/cli/metadata.rb +24 -0
  25. data/lib/resilience/cli/output.rb +84 -0
  26. data/lib/resilience/collections/dirs.rb +8 -0
  27. data/lib/resilience/collections/files.rb +41 -0
  28. data/lib/resilience/collections/pages.rb +16 -0
  29. data/lib/resilience/conf.rb +28 -0
  30. data/lib/resilience/constants.rb +31 -7
  31. data/lib/resilience/core_ext.rb +39 -0
  32. data/lib/resilience/fs_dir.rb +3 -0
  33. data/lib/resilience/fs_dir/dir_base.rb +16 -6
  34. data/lib/resilience/fs_dir/dir_entry.rb +33 -0
  35. data/lib/resilience/fs_dir/file_entry.rb +53 -0
  36. data/lib/resilience/image.rb +33 -0
  37. data/lib/resilience/mixins/on_image.rb +25 -0
  38. data/lib/resilience/page.rb +104 -0
  39. data/lib/resilience/tables.rb +1 -0
  40. data/lib/resilience/tables/boot.rb +89 -0
  41. data/lib/resilience/tables/object.rb +6 -2
  42. data/lib/resilience/tables/system.rb +5 -2
  43. data/lib/resilience/trees.rb +5 -0
  44. data/lib/resilience/trees/object_tree.rb +45 -0
  45. metadata +55 -15
  46. data/bin/cle.rb +0 -24
  47. data/bin/clum.py +0 -28
  48. data/bin/fs.rb +0 -21
  49. data/bin/ref.rb +0 -49
  50. data/bin/rels.rb +0 -269
  51. data/bin/resilience.rb +0 -351
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4ce546fb9a6dcfd401ccb8adbfa16bb3147f3a3b
4
- data.tar.gz: 6c47f4c2c0c3f89d74a30335928ef8bb991dcd0b
3
+ metadata.gz: 5c196b5ebd4046ddcc6cd0298b62639063cd9a42
4
+ data.tar.gz: b70a64738927837777702e75b6a6ff087babc9f7
5
5
  SHA512:
6
- metadata.gz: 7d25ff402e660223d44333beab243b7281d8382a8a2f31caeea6670e1adef46fc6fd54d218475ecd2b0f7061148b2f0111b297e45ffcbc412886920dbcf23bee
7
- data.tar.gz: 9767ac37ea16d858c02d89a217d33a8959509f03c1e7974d8b37d81db05b50576b8501a69ea1392338afafff7a06fae8c8a58dee3418198af1625d5120a1d199
6
+ metadata.gz: 3383922ed92c83ec17c7478c7053135897efe55effa28f29e908c01707e077b30d1a312aa67f933ee6eed1c1d81b90c3a17b61c042b7dbe2a3e22166cdcaefdf
7
+ data.tar.gz: f1828e8c195862117c8369c655b3788972edf65c07586f47cc687bf3267d230944b96c8949e8d49a5feaee916270076adeac8e51913da81399c4c6d1e15a74d8
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/ruby
2
+ # ReFS File Attribute Extractor
3
+ # Copyright (C) 2015 Red Hat Inc.
4
+
5
+ require 'resilience'
6
+
7
+ require 'resilience/cli/all'
8
+ require 'resilience/cli/bin/axe'
9
+
10
+ include Resilience::CLI
11
+
12
+ optparse = axe_option_parser
13
+ optparse.parse!
14
+
15
+ verify_image!
16
+ verify_file!
17
+ parse_image
18
+ write_results
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/ruby
2
+ # ReFS File Metadata Comparer
3
+ # Copyright (C) 2015 Red Hat Inc.
4
+
5
+ require 'resilience'
6
+ require 'resilience/cli/all'
7
+ require 'resilience/cli/bin/fcomp'
8
+
9
+ include Resilience::CLI
10
+
11
+ optparse = fcomp_option_parser
12
+ optparse.parse!
13
+
14
+ verify_image!
15
+ write_results parse_image
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/ruby
2
+ # ReFS 0x4000 Page Extractor
3
+ # By mmorsi - 2014-07-14
4
+
5
+ require 'resilience'
6
+ require 'resilience/cli/all'
7
+ require 'resilience/cli/bin/pex'
8
+
9
+ include Resilience::CLI
10
+
11
+ optparse = pex_option_parser
12
+ optparse.parse!
13
+
14
+ verify_image!
15
+ verify_output_dir!
16
+ extract
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/ruby
2
+ # rarser.rb - Ruby ReFS Parser
3
+ # Copyright (C) 2015 Red Hat Inc.
4
+
5
+ require 'resilience'
6
+ require 'resilience/cli/all'
7
+ require 'resilience/cli/bin/rarser'
8
+
9
+ include Resilience::CLI
10
+
11
+ optparse = rarser_option_parser
12
+ optparse.parse!
13
+
14
+ verify_image!
15
+ write_results parse_image
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/ruby
2
+ # ReFS file searcher
3
+ # Copyright (C) 2015 Red Hat Inc.
4
+
5
+ require 'resilience'
6
+ require 'resilience/cli/all'
7
+ require 'resilience/cli/bin/reach'
8
+
9
+ include Resilience::CLI
10
+
11
+ optparse = reach_option_parser
12
+ optparse.parse!
13
+
14
+ verify_image!
15
+ setup_image
16
+ run_search
data/bin/rex.rb CHANGED
@@ -2,73 +2,14 @@
2
2
  # ReFS File Extractor
3
3
  # Copyright (C) 2015 Red Hat Inc.
4
4
 
5
- require 'optparse'
6
5
  require 'resilience'
6
+ require 'resilience/cli/all'
7
+ require 'resilience/cli/bin/rex'
7
8
 
8
- def main
9
- cli_opts = parse_cli(ARGV)
10
- results = parse_image cli_opts
11
- write_results cli_opts, results
12
- end
9
+ include Resilience::CLI
13
10
 
14
- def write_results(opts, results)
15
- dir = opts[:dir]
16
- Dir.mkdir(dir) unless File.directory?(dir)
11
+ optparse = rex_option_parser
12
+ optparse.parse!
17
13
 
18
- results[:files].each do |name, contents|
19
- puts "Got #{name}"
20
- path = "#{dir}/#{name}".delete("\0")
21
- File.write(path, contents)
22
- end
23
- end
24
-
25
- def parse_image(opts)
26
- file = File.open(opts[:image], 'rb')
27
- image = Resilience::OnImage.image
28
- image.file = file
29
- image.offset = opts[:offset]
30
- image.opts = opts
31
-
32
- image.parse
33
- files = image.root_dir.files
34
- dirs = image.root_dir.dirs
35
- {:files => files, :dirs => dirs}
36
- end
37
-
38
- def parse_cli(cli)
39
- opts = {}
40
- parser = OptionParser.new do |popts|
41
- popts.on("-h", "--help", "Print help message") do
42
- puts parser
43
- exit
44
- end
45
-
46
- popts.on("-i", "--image path", "Path to the disk image to parse") do |path|
47
- opts[:image] = path
48
- end
49
-
50
- popts.on("-o", "--offset bytes", "Start of volume with ReFS filesystem") do |offset|
51
- opts[:offset] = offset.to_i
52
- end
53
-
54
- popts.on("-d", "--dir dir", "Output directory") do |dir|
55
- opts[:dir] = dir
56
- end
57
- end
58
-
59
- begin
60
- parser.parse!(cli)
61
- rescue OptionParser::InvalidOption
62
- puts parser
63
- exit
64
- end
65
-
66
- if !opts[:image] || !opts[:offset] || !opts[:dir]
67
- puts "--image, --offset, and --dir params are needed"
68
- exit 1
69
- end
70
-
71
- opts
72
- end
73
-
74
- main if __FILE__ == $0
14
+ verify_image!
15
+ write_results parse_image
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # ReFS Filesystem Info
4
+ # Copyright (C) 2015 Red Hat Inc.
5
+ ###########################################################
6
+
7
+ require 'resilience'
8
+ require 'resilience/cli/all'
9
+ require 'resilience/cli/bin/rinfo'
10
+
11
+ include Resilience::CLI
12
+
13
+ optparse = rinfo_option_parser
14
+ optparse.parse!
15
+
16
+ boot2offset
17
+ verify_image!
18
+ parse_image
19
+ dump_info
@@ -2,12 +2,17 @@
2
2
  # ReFS Parser (expiremental)
3
3
  # Copyright (C) 2015 Red Hat Inc.
4
4
 
5
+ require 'resilience/core_ext'
6
+
5
7
  require 'resilience/mixins'
6
8
  require 'resilience/constants'
7
9
 
10
+ require 'resilience/conf'
8
11
  require 'resilience/fs_dir'
9
12
  require 'resilience/attribute'
13
+ require 'resilience/page'
10
14
  require 'resilience/image'
11
15
 
12
16
  require 'resilience/dirs'
13
17
  require 'resilience/tables'
18
+ require 'resilience/trees'
@@ -6,23 +6,40 @@ module Resilience
6
6
  class Attribute
7
7
  include OnImage
8
8
 
9
+ attr_accessor :pos
9
10
  attr_accessor :bytes
10
11
 
11
12
  def initialize(args={})
12
- @bytes = args[:bytes] if args.key?(:bytes)
13
+ @pos = args[:pos]
14
+ @bytes = args[:bytes]
15
+ end
16
+
17
+ def empty?
18
+ bytes.nil? || bytes.empty?
13
19
  end
14
20
 
15
21
  def self.read
16
- pos = image.pos
17
- attr_len = image.read(4).unpack('L').first
22
+ pos = image.pos
23
+ packed = image.read(4)
24
+ return new if packed.nil?
25
+ attr_len = packed.unpack('L').first
18
26
  return new if attr_len == 0
19
27
 
20
28
  image.seek pos
21
- new(:bytes => image.read(attr_len))
29
+ value = image.read(attr_len)
30
+ new(:pos => pos, :bytes => value)
22
31
  end
23
32
 
24
33
  def unpack(format)
25
34
  bytes.unpack(format)
26
35
  end
36
+
37
+ def [](key)
38
+ return bytes[key]
39
+ end
40
+
41
+ def to_s
42
+ bytes.collect { |a| a.to_s(16) }.join(' ')
43
+ end
27
44
  end
28
45
  end # module Resilience
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/ruby
2
+ # Resilience CLI
3
+ #
4
+ # Licensed under the MIT license
5
+ # Copyright (C) 2015 Red Hat, Inc.
6
+ ###########################################################
7
+
8
+ require 'resilience/cli/default'
9
+ require 'resilience/cli/image'
10
+ require 'resilience/cli/output'
11
+ require 'resilience/cli/metadata'
12
+ require 'resilience/cli/file'
13
+ require 'resilience/cli/disk'
14
+ require 'resilience/cli/conf'
@@ -0,0 +1,34 @@
1
+ # Resilience axe cli util
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2015 Red Hat, Inc.
5
+ ###########################################################
6
+
7
+ require 'optparse'
8
+
9
+ def axe_option_parser
10
+ OptionParser.new do |opts|
11
+ default_options opts
12
+ image_options opts
13
+ file_select_options opts
14
+ end
15
+ end
16
+
17
+ def validate_file!(file)
18
+ if file.nil?
19
+ puts "File #{conf.file} not found"
20
+ exit 1
21
+ end
22
+ end
23
+
24
+ def write_results
25
+ file = image.root_dir.files.at(conf.file)
26
+ validate_file!(file)
27
+ puts "File: #{file.fullname} attributes: "
28
+ file.metadata_attrs.each_index { |attr_index|
29
+ attr = file.metadata_attrs[attr_index]
30
+ print "Attribute #{attr_index}: "
31
+ print attr.collect { |b| b.to_s(16) }.join(' ')
32
+ puts "\n\n"
33
+ }
34
+ end
@@ -0,0 +1,28 @@
1
+ # Resilience rcomp cli util
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2015 Red Hat, Inc.
5
+ ###########################################################
6
+
7
+ require 'optparse'
8
+
9
+ def fcomp_option_parser
10
+ OptionParser.new do |opts|
11
+ default_options opts
12
+ image_options opts
13
+ end
14
+ end
15
+
16
+ def write_results(image)
17
+ puts "Analyzed:"
18
+ puts "#{image.root_dir.files.collect { |f| f.fullname }.join("\n")}"
19
+ different_bytes = image.root_dir.files.bytes_diff
20
+ 0.upto(different_bytes.size-1) do |byte_index|
21
+ next if different_bytes[byte_index].nil?
22
+ puts "Byte 0x#{byte_index.to_s(16)} differs".red.bold
23
+ different_bytes[byte_index].each do |file, byte|
24
+ print " 0x#{byte.unpack('C*').first.to_s(16)}".blue
25
+ end
26
+ puts
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ # Resilience pex cli util
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2015 Red Hat, Inc.
5
+ ###########################################################
6
+
7
+ require 'optparse'
8
+
9
+ def pex_option_parser
10
+ OptionParser.new do |opts|
11
+ default_options opts
12
+ image_options opts
13
+ output_fs_options opts
14
+ end
15
+ end
16
+
17
+ def target_clusters
18
+ @target_clusters ||= [0x1e, 0x20, 0x21, 0x22, 0x28, 0x29,
19
+ 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
20
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
21
+ 0x36, 0x37, 0x38,
22
+ 0x2c0, 0x2c1, 0x2c2, 0x2c3, 0x2c4,
23
+ 0x2c5, 0x2c6, 0x2c7, 0x2c8, 0x2cc,
24
+ 0x2cd, 0x2ce, 0x2cf]
25
+ end
26
+
27
+ def extract
28
+ create_output_dir!
29
+ setup_image
30
+
31
+ target_clusters.each do |cluster|
32
+ extract_cluster cluster
33
+ end
34
+ end
35
+
36
+ def extract_cluster(cluster)
37
+ out = File.open("#{conf.dir}/#{cluster.to_s(16)}", 'wb')
38
+ offset = cluster * PAGE_SIZE
39
+ image.seek(offset)
40
+ contents = image.read(PAGE_SIZE)
41
+ out.write contents
42
+ out.close
43
+ end
@@ -0,0 +1,72 @@
1
+ # Resilience rarser cli util
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2015 Red Hat, Inc.
5
+ ###########################################################
6
+
7
+ require 'optparse'
8
+
9
+ def rarser_option_parser
10
+ conf.pages = true
11
+
12
+ OptionParser.new do |opts|
13
+ default_options opts
14
+ image_options opts
15
+ metadata_options opts
16
+ end
17
+ end
18
+
19
+
20
+ def page_attribute_output(page)
21
+ output = page.attributes.collect { |attribute|
22
+ " #{attribute.to_s[0...10]}...\n"
23
+ }.join
24
+
25
+ " Attributes:\n" + output
26
+ end
27
+
28
+ def page_output(page)
29
+ page_out = "Page #{page.id.indented(4).blue.bold}: " \
30
+ "number #{page.virtual_page_number.indented(3).blue.bold} - " \
31
+ "sequence #{page.sequence.indented(2).blue.bold} - " \
32
+ "object id #{page.object_id.indented(2).blue.bold} - " \
33
+ "records #{page.entries.indented(2).blue.bold}\n"
34
+
35
+ page_out += page_attribute_output(page) if conf.attributes? && page.has_attributes?
36
+ page_out
37
+ end
38
+
39
+ def pages_output
40
+ image.pages.collect { |page_id, page| page_output(page) }.join
41
+ end
42
+
43
+ def object_table_output
44
+ return "" unless conf.object_table?
45
+
46
+ output = image.object_table.pages.collect { |obj_id, cluster|
47
+ "#{obj_id.big_endian_str[0..4]} | #{cluster.big_endian_str}\n"
48
+ }.join
49
+
50
+ "\nObject table:\n" \
51
+ "Obj | Cluster\n" \
52
+ "-------------\n#{output}"
53
+ end
54
+
55
+ def object_tree_output
56
+ return "" unless conf.object_tree?
57
+
58
+ output = image.object_tree.map.collect { |obj, refs|
59
+ references = refs.collect { |ref| ref[0..4] }.join(', ')
60
+ "#{obj[0..4]} -> #{references}\n"
61
+ }.join
62
+
63
+ "\nObject tree:\n" \
64
+ "-------------\n#{output}"
65
+ end
66
+
67
+ def write_results(image)
68
+ puts header_output
69
+ puts pages_output
70
+ puts object_table_output
71
+ puts object_tree_output
72
+ end