resilience 0.0.2 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,34 @@
1
+ # Resilience reach cli util
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2015 Red Hat, Inc.
5
+ ###########################################################
6
+
7
+ require 'optparse'
8
+
9
+ def reach_option_parser
10
+ OptionParser.new do |opts|
11
+ default_options opts
12
+ image_options opts
13
+ end
14
+ end
15
+
16
+ def check_sequence
17
+ @check_sequence ||= 0xe010002800000038 # inverted due to endian ordering
18
+ end
19
+
20
+ def sequence_length
21
+ @sequence_length ||= 8
22
+ end
23
+
24
+ def run_search
25
+ while check = image.read(sequence_length)
26
+ unpacked = check.unpack('Q').first
27
+ write_match if unpacked == check_sequence
28
+ end
29
+ end
30
+
31
+ def write_match
32
+ puts 'File at: 0x' + image.total_pos.to_s(16) +
33
+ ' cluster ' + (image.pos / 0x4000).to_s(16)
34
+ end
@@ -0,0 +1,33 @@
1
+ # Resilience rex cli util
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2015 Red Hat, Inc.
5
+ ###########################################################
6
+
7
+ require 'optparse'
8
+
9
+ def rex_option_parser
10
+ OptionParser.new do |opts|
11
+ default_options opts
12
+ image_options opts
13
+ output_fs_options opts
14
+ stdout_options opts
15
+ end
16
+ end
17
+
18
+ def write_results(image)
19
+ create_output_dir!
20
+
21
+ dirs = image.root_dir.dirs
22
+ dirs.each do |dir|
23
+ puts "Dir: #{dir.fullname} at #{dir.total_offset}" if conf.dirs?
24
+ end
25
+
26
+ files = image.root_dir.files
27
+ files.each do |file|
28
+ puts "File: #{file.fullname} at #{file.total_offset}" if conf.files?
29
+
30
+ path = "#{output_dir}/#{file.fullname}".delete("\0")
31
+ File.write(path, file.metadata) if write_to_output_dir?
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ # Resilience rinfo cli util
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2015 Red Hat, Inc.
5
+ ###########################################################
6
+
7
+ require 'optparse'
8
+
9
+ def rinfo_option_parser
10
+ OptionParser.new do |opts|
11
+ default_options opts
12
+ image_options opts
13
+ disk_options opts
14
+ end
15
+ end
16
+
17
+ def dump_info
18
+ puts header_output
19
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/ruby
2
+ # Reslience CLI Conf
3
+ #
4
+ # Licensed under the MIT license
5
+ # Copyright (C) 2015 Red Hat, Inc.
6
+ ###########################################################
7
+
8
+ module Resilience
9
+ module CLI
10
+ def conf
11
+ Conf
12
+ end
13
+ end # mdoule CLI
14
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/ruby
2
+ # Reslience CLI Default Options
3
+ #
4
+ # Licensed under the MIT license
5
+ # Copyright (C) 2015 Red Hat, Inc.
6
+ ###########################################################
7
+
8
+ module Resilience
9
+ module CLI
10
+ def default_options(option_parser)
11
+ option_parser.on('-h', '--help', 'Print help message') do
12
+ puts option_parser
13
+ exit
14
+ end
15
+ end
16
+ end # module CLI
17
+ end # module Resilience
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/ruby
2
+ # Resilience Disk Options
3
+ #
4
+ # Licensed under the MIT license
5
+ # Copyright (C) 2015 Red Hat, Inc.
6
+ ###########################################################
7
+
8
+ module Resilience
9
+ module CLI
10
+ def disk_options(option_parser)
11
+ option_parser.on("-m", "--mbr", "Extract FS Info From MBR") do
12
+ conf.mbr = true
13
+ end
14
+
15
+ option_parser.on("-g", "--gpt", "Extract FS Info From GUID Partition Table") do
16
+ conf.gpt = true
17
+ end
18
+ end
19
+
20
+ def mbr2offset
21
+ return unless conf.mbr
22
+ image.offset = 0
23
+ offset = MBR.new.refs_offset
24
+ conf[:offset] = offset unless offset.nil?
25
+ end
26
+
27
+ def gpt2offset
28
+ return unless conf.gpt
29
+ image.offset = 0
30
+ image.offset = MBR.new.gpt_offset
31
+ image.offset = conf.offset = GPT.new.refs_offset
32
+ end
33
+
34
+ def boot2offset
35
+ setup_image
36
+ mbr2offset if conf.mbr
37
+ gpt2offset if conf.gpt
38
+ end
39
+ end # module CLI
40
+ end # module Resilience
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/ruby
2
+ # Reslience File Options
3
+ #
4
+ # Licensed under the MIT license
5
+ # Copyright (C) 2015 Red Hat, Inc.
6
+ ###########################################################
7
+
8
+ module Resilience
9
+ module CLI
10
+ def file_select_options(option_parser)
11
+ option_parser.on("-f", "--file [file]", "File to analyze") do |file|
12
+ conf.file = file
13
+ end
14
+ end
15
+
16
+ def verify_file!
17
+ unless conf.file
18
+ puts "--file param needed"
19
+ exit 1
20
+ end
21
+ end
22
+ end # module CLI
23
+ end # module Resilience
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/ruby
2
+ # Reslience CLI Image Options
3
+ #
4
+ # Licensed under the MIT license
5
+ # Copyright (C) 2015 Red Hat, Inc.
6
+ ###########################################################
7
+
8
+ module Resilience
9
+ module CLI
10
+ def image_options(option_parser)
11
+ option_parser.on("-i", "--image path", "Path to the disk image to parse") do |path|
12
+ conf.image_file = path
13
+ end
14
+
15
+ option_parser.on("-o", "--offset bytes", "Start of volume with ReFS filesystem") do |offset|
16
+ conf.offset = offset.to_i
17
+ end
18
+ end
19
+
20
+ def verify_image!
21
+ unless conf.image && conf.offset
22
+ puts "--image and --offset params needed"
23
+ exit 1
24
+ end
25
+ end
26
+
27
+ def setup_image
28
+ file = File.open(conf.image_file, 'rb')
29
+ image.file = file
30
+ image.offset = conf.offset
31
+ image.opts = conf
32
+ image
33
+ end
34
+
35
+ def parse_image
36
+ setup_image
37
+ image.parse
38
+ image
39
+ end
40
+
41
+ def image
42
+ Resilience::OnImage.image
43
+ end
44
+ end # module CLI
45
+ end # module Resilience
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/ruby
2
+ # Reslience Metadata Default Options
3
+ #
4
+ # Licensed under the MIT license
5
+ # Copyright (C) 2015 Red Hat, Inc.
6
+ ###########################################################
7
+
8
+ module Resilience
9
+ module CLI
10
+ def metadata_options(option_parser)
11
+ option_parser.on("-a", "--attributes", "Include attribute analysis in output") do
12
+ conf.attributes = true
13
+ end
14
+
15
+ option_parser.on("--table", "Include object table analysis in output") do
16
+ conf.object_table = true
17
+ end
18
+
19
+ option_parser.on("--tree", "Include object tree analysis in output") do
20
+ conf.object_tree = true
21
+ end
22
+ end
23
+ end # module CLI
24
+ end # module Resilience
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/ruby
2
+ # Reslience CLI Output Options
3
+ #
4
+ # Licensed under the MIT license
5
+ # Copyright (C) 2015 Red Hat, Inc.
6
+ ###########################################################
7
+
8
+ require 'colored'
9
+
10
+ module Resilience
11
+ module CLI
12
+ OUTPUT_LABELS = {
13
+ :bps => "(bytes per sector)",
14
+ :spc => "(sectors per cluster)",
15
+ :bpc => "(bytes per cluster)",
16
+ :vbr => "VBR",
17
+ :image => "Analyzed ReFS filesystem on",
18
+ :offset => "starting at"
19
+ }
20
+
21
+ def output_fs_options(option_parser)
22
+ option_parser.on("--write dir", "Write output to directory") do |dir|
23
+ conf.dir = dir
24
+ end
25
+ end
26
+
27
+ def stdout_options(option_parser)
28
+ option_parser.on("-f", "--files", "List files in output") do
29
+ conf.files = true
30
+ end
31
+
32
+ option_parser.on("-d", "--dirs", "List dirs in output") do
33
+ conf.dirs = true
34
+ end
35
+ end
36
+
37
+ def verify_output_dir!
38
+ unless conf.dir
39
+ puts "--write param needed"
40
+ exit 1
41
+ end
42
+ end
43
+
44
+ def output_dir
45
+ conf.dir
46
+ end
47
+
48
+ def write_to_output_dir?
49
+ !!output_dir
50
+ end
51
+
52
+ def create_output_dir!
53
+ return unless write_to_output_dir?
54
+ Dir.mkdir(output_dir) unless File.directory?(output_dir)
55
+ end
56
+
57
+ def image_output
58
+ "#{OUTPUT_LABELS[:image]} #{conf.image_file.green.bold} "\
59
+ "#{OUTPUT_LABELS[:offset]} #{conf.offset.to_s.green.bold}\n"
60
+ end
61
+
62
+ def header_output
63
+ image_output + vbr_output
64
+ end
65
+
66
+ def bytes_per_sector_output
67
+ "#{image.bytes_per_sector.indented.yellow.bold} (#{OUTPUT_LABELS[:bps]})"
68
+ end
69
+
70
+ def sectors_per_cluster_output
71
+ "#{image.sectors_per_cluster.indented.yellow.bold} (#{OUTPUT_LABELS[:spc]})"
72
+ end
73
+
74
+ def cluster_size_output
75
+ "#{image.cluster_size.indented.yellow.bold} (#{OUTPUT_LABELS[:bpc]})\n"
76
+ end
77
+
78
+ def vbr_output
79
+ "#{OUTPUT_LABELS[:vbr]}: #{bytes_per_sector_output} * " \
80
+ "#{sectors_per_cluster_output} = " \
81
+ "#{cluster_size_output}"
82
+ end
83
+ end # module CLI
84
+ end # module Resilience
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/ruby
2
+ # ReFS Dirs Collection
3
+ # Copyright (C) 2015 Red Hat Inc.
4
+
5
+ module Resilience
6
+ class Dirs < Array
7
+ end
8
+ end
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/ruby
2
+ # ReFS Files Collection
3
+ # Copyright (C) 2015 Red Hat Inc.
4
+
5
+ module Resilience
6
+ class Files < Array
7
+ def names
8
+ collect { |f| f.name }
9
+ end
10
+
11
+ def fullnames
12
+ collect { |f| f.fullname }
13
+ end
14
+
15
+ def at(path)
16
+ find { |f| f.fullname == path }
17
+ end
18
+
19
+ def byte_map
20
+ bytes = []
21
+ each do |file|
22
+ 0.upto(file.metadata.size-1) do |byte_index|
23
+ bytes[byte_index] ||= {}
24
+ bytes[byte_index][file] = file.metadata[byte_index]
25
+ end
26
+ end
27
+ bytes
28
+ end
29
+
30
+ def bytes_diff
31
+ map = byte_map
32
+ different_bytes = []
33
+ 0.upto(map.size-1).each do |byte_index|
34
+ bytes = map[byte_index].values
35
+ different = bytes.uniq.size != 1 || bytes.size != size
36
+ different_bytes << (different ? map[byte_index] : nil)
37
+ end
38
+ different_bytes
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/ruby
2
+ # ReFS Pages Collection
3
+ # Copyright (C) 2015 Red Hat Inc.
4
+
5
+ module Resilience
6
+ class Pages < Hash
7
+ def with_number(virtual_page_number)
8
+ select { |page_id, page| page.virtual_page_number == virtual_page_number }
9
+ end
10
+
11
+ def newest_for(virtual_page_number)
12
+ pages = with_number(virtual_page_number)
13
+ pages.values.sort { |p1, p2| p2.sequence <=> p1.sequence }.first
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/ruby
2
+ # Reslience Conf
3
+ #
4
+ # Licensed under the MIT license
5
+ # Copyright (C) 2015 Red Hat, Inc.
6
+ ###########################################################
7
+
8
+ module Resilience
9
+ module Conf
10
+ def self.conf
11
+ @conf ||= {}
12
+ end
13
+
14
+ def self.method_missing(method, *args)
15
+ if method.to_s =~ /=$/
16
+ conf[method.to_s.match(/^(.*)=$/)[1].to_sym] = args.first
17
+ elsif method.to_s =~ /\?$/
18
+ !!conf[method.to_s.match(/^(.*)\?$/)[1].to_sym]
19
+ else
20
+ conf[method]
21
+ end
22
+ end
23
+
24
+ def conf
25
+ Conf
26
+ end
27
+ end # module Conf
28
+ end