one_gadget 1.6.1 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff8578d867b076e1c59b2b271879d5448fc2c985c94b67a5e3fc8febcabb01ef
4
- data.tar.gz: 39c681c497cfb5bce05eb993fcb47aa0b6e0ef77aba6af2507d4184ccb23ef20
3
+ metadata.gz: 2e26da79b62658e7dd1ce9efcaeda04fbe805b98eb1fecf234948311d70553e3
4
+ data.tar.gz: 2ed832df9cffecaba987753e1ed9c9ebe8068e410c00da108c1348e80efe6637
5
5
  SHA512:
6
- metadata.gz: 6aa7f7a80a3d0a096a02d40802df7d8014896ef15cba222610a334d80bab9d0fddf5db95fd2f1de47b86327d160b38eee65048f7300d40f6c6d69f0e4021aca7
7
- data.tar.gz: adf5eaf2d3a70a3c17d5daddc0aa6f773911aea65eb82b633b73ef060d35073944d92a0feb440573f68c5badf522aba8b86b67fa51e89afd56a3c86e63980c5d
6
+ metadata.gz: 47732f230a683edcb699a21f3891812326b1a7d9b966c13fb3a50c8d07b7ffbb3ce4244d324c0f13907f8b5d64e6a16a824d44946d97f6f131df7cf0b1380b8e
7
+ data.tar.gz: 0a90f8f323ee47f78314eeb420eec22a36f8954b12806a47d493d8996128abb4ac40c2cb4ec25b236b3723a390391903e5082f1af6751a061645e4dfc442e8e0
@@ -4,70 +4,12 @@
4
4
 
5
5
  # Main module.
6
6
  module OneGadget
7
- class << self
8
- # The man entry of gem +one_gadget+.
9
- # If want to find gadgets from file, it will search gadgets by its
10
- # build id first.
11
- #
12
- # @param [String] file
13
- # The relative path of libc.so.6.
14
- # @param [String] build_id
15
- # The BuildID of target libc.so.6.
16
- # @param [Boolean] details
17
- # Return gadget objects or offset only.
18
- # @param [Boolean] force_file
19
- # When +file+ is given, {OneGadget} will search gadgets according its
20
- # build id first. +force_file = true+ to disable this feature.
21
- # @param [Integer] level
22
- # Output level.
23
- # If +level+ equals to zero, only gadgets with highest successful probability would be output.
24
- # @return [Array<OneGadget::Gadget::Gadget>, Array<Integer>]
25
- # The gadgets found.
26
- # @example
27
- # OneGadget.gadgets(file: './libc.so.6')
28
- # OneGadget.gadgets(build_id: '60131540dadc6796cab33388349e6e4e68692053')
29
- def gadgets(file: nil, build_id: nil, details: false, force_file: false, level: 0)
30
- ret = if build_id
31
- OneGadget::Fetcher.from_build_id(build_id) || OneGadget::Logger.not_found(build_id)
32
- else
33
- from_file(OneGadget::Helper.abspath(file), force: force_file)
34
- end
35
- ret = refine_gadgets(ret, level)
36
- ret.map!(&:offset) unless details
37
- ret
38
- rescue OneGadget::Error::Error => e
39
- OneGadget::Logger.error("#{e.class.name.split('::').last}: #{e.message}")
40
- []
41
- end
42
-
43
- private
44
-
45
- # Try from build id first, then file
46
- def from_file(path, force: false)
47
- OneGadget::Helper.verify_elf_file!(path)
48
- gadgets = try_from_build(path) unless force
49
- gadgets || OneGadget::Fetcher.from_file(path)
50
- end
51
-
52
- def try_from_build(file)
53
- build_id = OneGadget::Helper.build_id_of(file)
54
- return unless build_id
55
-
56
- OneGadget::Fetcher.from_build_id(build_id, remote: false)
57
- end
58
-
59
- # Remove hard-to-reach-constrains gadgets according to level
60
- def refine_gadgets(gadgets, level)
61
- return [] if gadgets.empty?
62
- return gadgets if level > 0 # currently only supports level > 0 or not
63
-
64
- # remain gadgets with the fewest constraints
65
- best = gadgets.map { |g| g.constraints.size }.min
66
- gadgets.select { |g| g.constraints.size == best }
67
- end
68
- end
69
7
  end
70
8
 
9
+ require 'one_gadget/helper'
10
+ require 'one_gadget/one_gadget'
11
+ require 'one_gadget/version'
12
+
71
13
  # Shorter way to use one gadget.
72
14
  # @param [String?] arg
73
15
  # Can be either +build_id+ or path to libc.
@@ -92,9 +34,3 @@ end
92
34
 
93
35
  require 'one_gadget/update'
94
36
  OneGadget::Update.check!
95
-
96
- require 'one_gadget/error'
97
- require 'one_gadget/fetcher'
98
- require 'one_gadget/helper'
99
- require 'one_gadget/logger'
100
- require 'one_gadget/version'
@@ -46,8 +46,8 @@ module OneGadget
46
46
  false
47
47
  end
48
48
 
49
- # Support instruction set.
50
- # @return [Array<Instruction>] The support instructions.
49
+ # Supported instruction set.
50
+ # @return [Array<Instruction>] The supported instructions.
51
51
  def instructions
52
52
  [
53
53
  Instruction.new('add', 2),
@@ -72,6 +72,13 @@ module OneGadget
72
72
  end
73
73
  end
74
74
 
75
+ # To be inherited.
76
+ #
77
+ # @param [Integer] _idx
78
+ # The idx-th argument.
79
+ #
80
+ # @return [Lambda, Integer]
81
+ # Return value can be a {Lambda} or an +Integer+.
75
82
  def argument(_idx); raise NotImplementedError
76
83
  end
77
84
 
@@ -1,14 +1,19 @@
1
1
  module OneGadget
2
+ # OneGadget errors.
2
3
  module Error
4
+ # Generic error class.
3
5
  class Error < StandardError
4
6
  end
5
7
 
8
+ # Unsupported arguments of intructions.
6
9
  class UnsupportedInstructionArgumentsError < Error
7
10
  end
8
11
 
12
+ # Unsupported architecture.
9
13
  class UnsupportedArchitectureError < Error
10
14
  end
11
15
 
16
+ # Argument error of ruby methods.
12
17
  class ArgumentError < Error
13
18
  end
14
19
  end
@@ -19,7 +19,7 @@ module OneGadget
19
19
 
20
20
  true
21
21
  end
22
- cands + jmp_case_candidates # + sigaction_case_candidates
22
+ cands + jmp_case_candidates
23
23
  end
24
24
 
25
25
  # find gadgets in form:
@@ -30,7 +30,6 @@ module OneGadget
30
30
  # ...
31
31
  # call execve
32
32
  def jmp_case_candidates
33
- bin_sh_hex = str_offset('/bin/sh').to_s(16)
34
33
  `#{objdump_cmd}|egrep 'rdi.*# #{bin_sh_hex}' -A 3`.split('--').map do |cand|
35
34
  cand = cand.lines.map(&:strip).reject(&:empty?)
36
35
  jmp_at = cand.index { |c| c.include?('jmp') }
@@ -60,7 +60,7 @@ module OneGadget
60
60
  return build_not_found if table.nil? # remote doesn't have this one either.
61
61
 
62
62
  # builds found in remote! Ask update gem and download remote gadgets.
63
- OneGadget::Helper.ask_update(msg: 'The desired one-gadget can be found in lastest version!')
63
+ OneGadget::Logger.ask_update(msg: 'The desired one-gadget can be found in lastest version!')
64
64
  tmp_file = OneGadget::Helper.download_build(table)
65
65
  require tmp_file.path
66
66
  tmp_file.unlink
@@ -6,7 +6,6 @@ require 'tempfile'
6
6
  require 'elftools'
7
7
 
8
8
  require 'one_gadget/error'
9
- require 'one_gadget/logger'
10
9
 
11
10
  module OneGadget
12
11
  # Define some helpful methods here.
@@ -103,7 +102,7 @@ module OneGadget
103
102
  # True or false.
104
103
  def color_enabled?
105
104
  # if not set, use tty to check
106
- return $stdout.tty? if @disable_color.nil?
105
+ return $stdout.tty? unless instance_variable_defined?(:@disable_color)
107
106
 
108
107
  !@disable_color
109
108
  end
@@ -184,14 +183,6 @@ module OneGadget
184
183
  nil
185
184
  end
186
185
 
187
- # Show the message of ask user to update gem.
188
- # @return [void]
189
- def ask_update(msg: '')
190
- name = 'one_gadget'
191
- cmd = colorize("gem update #{name} && gem cleanup #{name}")
192
- OneGadget::Logger.info(msg + "\n" + "Update with: $ #{cmd}" + "\n")
193
- end
194
-
195
186
  # Fetch the file archiecture of +file+.
196
187
  # @param [String] file The target ELF filename.
197
188
  # @return [Symbol]
@@ -31,6 +31,14 @@ module OneGadget
31
31
  []
32
32
  end
33
33
 
34
+ # Show the message of ask user to update gem.
35
+ # @return [void]
36
+ def ask_update(msg: '')
37
+ name = 'one_gadget'
38
+ cmd = OneGadget::Helper.colorize("gem update #{name} && gem cleanup #{name}")
39
+ OneGadget::Logger.info(msg + "\n" + "Update with: $ #{cmd}" + "\n")
40
+ end
41
+
34
42
  %i[info warn error].each do |sym|
35
43
  define_method(sym) do |msg|
36
44
  @logger.__send__(sym, msg)
@@ -0,0 +1,70 @@
1
+ require 'one_gadget/error'
2
+ require 'one_gadget/fetcher'
3
+ require 'one_gadget/helper'
4
+ require 'one_gadget/logger'
5
+
6
+ # Main module.
7
+ module OneGadget
8
+ class << self
9
+ # The man entry of gem +one_gadget+.
10
+ # If want to find gadgets from file, it will search gadgets by its
11
+ # build id first.
12
+ #
13
+ # @param [String] file
14
+ # The relative path of libc.so.6.
15
+ # @param [String] build_id
16
+ # The BuildID of target libc.so.6.
17
+ # @param [Boolean] details
18
+ # Return gadget objects or offset only.
19
+ # @param [Boolean] force_file
20
+ # When +file+ is given, {OneGadget} will search gadgets according its
21
+ # build id first. +force_file = true+ to disable this feature.
22
+ # @param [Integer] level
23
+ # Output level.
24
+ # If +level+ equals to zero, only gadgets with highest successful probability would be output.
25
+ # @return [Array<OneGadget::Gadget::Gadget>, Array<Integer>]
26
+ # The gadgets found.
27
+ # @example
28
+ # OneGadget.gadgets(file: './libc.so.6')
29
+ # OneGadget.gadgets(build_id: '60131540dadc6796cab33388349e6e4e68692053')
30
+ def gadgets(file: nil, build_id: nil, details: false, force_file: false, level: 0)
31
+ ret = if build_id
32
+ OneGadget::Fetcher.from_build_id(build_id) || OneGadget::Logger.not_found(build_id)
33
+ else
34
+ from_file(OneGadget::Helper.abspath(file), force: force_file)
35
+ end
36
+ ret = refine_gadgets(ret, level)
37
+ ret.map!(&:offset) unless details
38
+ ret
39
+ rescue OneGadget::Error::Error => e
40
+ OneGadget::Logger.error("#{e.class.name.split('::').last}: #{e.message}")
41
+ []
42
+ end
43
+
44
+ private
45
+
46
+ # Try from build id first, then file
47
+ def from_file(path, force: false)
48
+ OneGadget::Helper.verify_elf_file!(path)
49
+ gadgets = try_from_build(path) unless force
50
+ gadgets || OneGadget::Fetcher.from_file(path)
51
+ end
52
+
53
+ def try_from_build(file)
54
+ build_id = OneGadget::Helper.build_id_of(file)
55
+ return unless build_id
56
+
57
+ OneGadget::Fetcher.from_build_id(build_id, remote: false)
58
+ end
59
+
60
+ # Remove hard-to-reach-constrains gadgets according to level
61
+ def refine_gadgets(gadgets, level)
62
+ return [] if gadgets.empty?
63
+ return gadgets if level > 0 # currently only supports level > 0 or not
64
+
65
+ # remain gadgets with the fewest constraints
66
+ best = gadgets.map { |g| g.constraints.size }.min
67
+ gadgets.select { |g| g.constraints.size == best }
68
+ end
69
+ end
70
+ end
@@ -29,7 +29,7 @@ module OneGadget
29
29
 
30
30
  # show update message
31
31
  msg = format('A newer version of OneGadget is available (%s --> %s).', OneGadget::VERSION, latest)
32
- OneGadget::Helper.ask_update(msg: msg)
32
+ OneGadget::Logger.ask_update(msg: msg)
33
33
  end
34
34
 
35
35
  private
@@ -1,4 +1,4 @@
1
1
  module OneGadget
2
2
  # Current gem version.
3
- VERSION = '1.6.1'.freeze
3
+ VERSION = '1.6.2'.freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: one_gadget
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 1.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - david942j
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-13 00:00:00.000000000 Z
11
+ date: 2018-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: elftools
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: 1.0.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: 1.0.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -796,6 +796,7 @@ files:
796
796
  - lib/one_gadget/gadget.rb
797
797
  - lib/one_gadget/helper.rb
798
798
  - lib/one_gadget/logger.rb
799
+ - lib/one_gadget/one_gadget.rb
799
800
  - lib/one_gadget/update.rb
800
801
  - lib/one_gadget/version.rb
801
802
  homepage: https://github.com/david942j/one_gadget