module OneGadget

Main module.

Main module.

Constants

VERSION

Current gem version.

Public Class Methods

gadgets(file: nil, build_id: nil, details: false, force_file: false, level: 0) click to toggle source

The man entry of gem one_gadget. If want to find gadgets from file, it will search gadgets by its build id first.

@param [String] file

The relative path of libc.so.6.

@param [String] build_id

The BuildID of target libc.so.6.

@param [Boolean] details

Return gadget objects or offset only.

@param [Boolean] force_file

When +file+ is given, {OneGadget} will search gadgets according its
build id first. +force_file = true+ to disable this feature.

@param [Integer] level

Output level.
If +level+ equals to zero, only gadgets with highest successful probability would be output.

@return [Array<OneGadget::Gadget::Gadget>, Array<Integer>]

The gadgets found.

@example

OneGadget.gadgets(file: './libc.so.6')
OneGadget.gadgets(build_id: '60131540dadc6796cab33388349e6e4e68692053')
# File lib/one_gadget/one_gadget.rb, line 32
def gadgets(file: nil, build_id: nil, details: false, force_file: false, level: 0)
  ret = if build_id
          OneGadget::Fetcher.from_build_id(build_id) || OneGadget::Logger.not_found(build_id)
        else
          from_file(OneGadget::Helper.abspath(file), force: force_file)
        end
  ret = refine_gadgets(ret, level)
  ret = ret.map(&:offset) unless details
  ret
rescue OneGadget::Error::Error => e
  OneGadget::Logger.error("#{e.class.name.split('::').last}: #{e.message}")
  []
end

Private Class Methods

from_file(path, force: false) click to toggle source

Try from build id first, then file

# File lib/one_gadget/one_gadget.rb, line 49
def from_file(path, force: false)
  OneGadget::Helper.verify_elf_file!(path)
  gadgets = try_from_build(path) unless force
  gadgets || OneGadget::Fetcher.from_file(path)
end
refine_gadgets(gadgets, level) click to toggle source

Remove hard-to-reach-constraints gadgets according to level

# File lib/one_gadget/one_gadget.rb, line 63
def refine_gadgets(gadgets, level)
  return [] if gadgets.empty?
  return gadgets if level.positive? # currently only supports level > 0 or not

  high, low = gadgets.partition { |g| g.score >= 0.2 }
  return take_until(low, 3) if high.empty?

  take_until(high, 3)
end
take_until(ary, count) click to toggle source
# File lib/one_gadget/one_gadget.rb, line 73
def take_until(ary, count)
  return ary if ary.size <= count

  threshold = ary.sort_by(&:score)[-count].score
  ary.select { |g| g.score >= threshold }
end
try_from_build(file) click to toggle source
# File lib/one_gadget/one_gadget.rb, line 55
def try_from_build(file)
  build_id = OneGadget::Helper.build_id_of(file)
  return unless build_id

  OneGadget::Fetcher.from_build_id(build_id, remote: false)
end