one_gadget 1.6.1 → 1.6.2

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.
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