Skip to content
This repository has been archived by the owner on May 18, 2021. It is now read-only.

Commit

Permalink
Bump version, update spec, move fastlib script into bin
Browse files Browse the repository at this point in the history
  • Loading branch information
HD Moore committed Sep 7, 2014
1 parent 6befc13 commit 961ef90
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 67 deletions.
116 changes: 116 additions & 0 deletions bin/fastlib.rb
@@ -0,0 +1,116 @@
#!/usr/bin/env ruby

$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))

require 'fastlib'
require 'optparse'
require 'ostruct'


options = OpenStruct.new(action: nil, archive: nil, required: nil, included: nil, compress: nil, encrypt: nil, verbose: nil)

option_parser = OptionParser.new do |opts|
opts.banner = "Usage: #{$0} <action> [options] <arguments>"
opts.separator "Create or list the contents of a fastlib archive"
opts.separator ""
opts.separator "Options"

opts.on("-c", "--compress", "Compresses the archive with Zlib ") do
options.compress = true
end

opts.on("-e", "--encrypt 0x<Algorithm ID>", "Encrypt the archive with the specified algorithm ID (0x00 for XOR)") do |opt_encrypt|
if opt_encrypt =~ /^0x/
options.encrypt = opt_encrypt.to_i(16)
else
options.encrypt = opt_encrypt.to_i
end

if options.encrypt > 0xffffff
$stderr.puts "Error: Algorithm IDs must be between 0 and 0xffffff"
exit(1)
end
end

opts.on("-r", "--require library", "Require the specified library to support custom encryption methods") do |opt_require|
options.required ||= []
options.required << opt_require
end

opts.on("-I", "--include library_path", "Search the specified path for required libraries") do |opt_include|
$:.append opt_include
end

opts.on("-V", "--version", "Show the FastLib version") do
$stderr.puts "FastLib v#{FastLib::VERSION}"
exit(0)
end

opts.on("-h", "--help", "Show this message.") do
$stderr.puts opts
exit(1)
end
end
option_parser.parse!(ARGV)

# Load any libraries required to support custom encryption providers
if options.required
options.required.each {|lname| require(lname) }
end

if options.encrypt
# Verify that our 24-bit algorithm ID maps to a FastLib namespace method
# The user may need to specify -r provider to load the right library first
unless FastLib.respond_to?(sprintf("encrypt_%.8x", (options.encrypt<<8) ))
$stderr.puts "Error: Unknown algorithm ID, you may need to specify the provider library with -r"
exit(1)
end
end
options.action = ARGV.shift
options.archive = ARGV.shift
unless options.archive
$stderr.puts "Error: No archive file has been specified"
exit(1)
end
case options.action
when 'create'
source_path = ARGV.shift
unless source_path
$stderr.puts "Error: No source directory has been specified"
exit(1)
end
source_path = File.expand_path(source_path)
source_files = Dir["#{source_path}/*"]
create_flags = 0
if options.compress
create_flags |= FastLib::FLAG_COMPRESS
end
if options.encrypt
create_flags |= (options.encrypt<<8)
create_flags |= FastLib::FLAG_ENCRYPT
end
FastLib.create(options.archive, create_flags, source_path, *source_files)
when 'list'
$stdout.puts "Library: #{options.archive}"
$stdout.puts "====================================================="
FastLib.list(options.archive).each do |name|
fsize = FastLib.cache[options.archive][name][1]
ftime = ::Time.at(FastLib.cache[options.archive][name][2]).strftime("%Y-%m-%d %H:%M:%S")
$stdout.puts sprintf("%9d\t%20s\t%s\n", fsize, ftime, name)
end
$stdout.puts ""
else
$stderr.puts "Error: Unknown action '#{options.action}'"
exit(1)
end
12 changes: 7 additions & 5 deletions fastlib.gemspec
@@ -1,7 +1,7 @@
# encoding: utf-8

APP_NAME = "fastlib"
VERSION = "0.0.7"
VERSION = "0.0.8"

Gem::Specification.new do |s|
s.name = APP_NAME
Expand All @@ -11,10 +11,12 @@ Gem::Specification.new do |s|
s.description = "This gem provides a way to load libraries from an archive"
s.license = "BSD"
s.authors = ["HD Moore"]
s.email = ["hdm@metasploit.com"]
s.files = Dir['[A-Z]*'] + Dir['lib/**/*']
s.require_paths = ["lib"]
s.email = ["hdm@rapid7.com"]
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ['lib']
s.extra_rdoc_files = ["README.markdown"]
s.required_ruby_version = ">= 1.8.7"
s.required_ruby_version = ">= 1.9.3"
s.platform = "ruby"
end
78 changes: 16 additions & 62 deletions lib/fastlib.rb
Expand Up @@ -11,18 +11,10 @@
# AV-resistance of the Metasploit Framework and Rex libraries.
#


#
# This library is still in its early form; a large number of performance and
# compatiblity improvements are not yet included. Do not depend on the FASTLIB
# file format at this time.
#

require "find"


#
# Copyright (C) 2011 Rapid7. You can redistribute it and/or
# Copyright (C) 2011-2014 Rapid7, Inc. You can redistribute it and/or
# modify it under the terms of the ruby license.
#
#
Expand All @@ -37,7 +29,7 @@
#
class FastLib

VERSION = "0.0.7"
VERSION = "0.0.8"

FLAG_COMPRESS = 0x01
FLAG_ENCRYPT = 0x02
Expand Down Expand Up @@ -187,7 +179,7 @@ def self.fastlib_filter_encode(lib, buff)
# directory that should be excluded from the archived path, and finally
# the list of specific files and directories to include in the archive.
#
def self.dump(lib, flag, bdir, *dirs)
def self.create(lib, flags, bdir, *dirs)
head = ""
data = ""
hidx = 0
Expand All @@ -196,8 +188,16 @@ def self.dump(lib, flag, bdir, *dirs)
bdir = bdir.gsub(/\/$/, '')
brex = /^#{Regexp.escape(bdir)}\//

if flags.kind_of?(::String)
if flags =~ /^0x/
flags = flags.to_i(16)
else
flags = flags.to_i
end
end

@@cache[lib] = {
:fastlib_flags => flag.to_i(16)
:fastlib_flags => flags
}

dirs.each do |dir|
Expand All @@ -210,7 +210,6 @@ def self.dump(lib, flag, bdir, *dirs)
buff = fastlib_filter_encode(lib, fd.read(fd.stat.size))
end


head << [ name.length, didx, buff.length, ::File.stat(path).mtime.utc.to_i ].pack("NNNN")
head << name
hidx = hidx + 16 + name.length
Expand All @@ -224,14 +223,14 @@ def self.dump(lib, flag, bdir, *dirs)

::File.open(lib, "wb") do |fd|
fd.write("FAST")
fd.write( [ head.length, flag.to_i(16) ].pack("NN") )
fd.write( [ head.length, flags ].pack("NN") )
fd.write( head )
fd.write( data )
end
end

#
# This archive provides a way to list the contents of an archive
# This method provides a way to list the contents of an archive
# file, returning the names only in sorted order.
#
def self.list(lib)
Expand All @@ -240,8 +239,8 @@ def self.list(lib)
end

#
# This method is called on the loaded is required to expand __FILE__
# and other inline dynamic constants to map to the correct location.
# This method is expands __FILE__ sequences and other inline dynamic constants
# to map to the correct location.
#
def self.post_process(lib, name, data)
data.gsub('__FILE__', "'#{ ::File.expand_path(::File.join(::File.dirname(lib), name)) }'")
Expand Down Expand Up @@ -277,51 +276,6 @@ def self.cache
end


#
# Allow this library to be used as an executable to create and list
# FASTLIB archives
#
if __FILE__ == $0
cmd = ARGV.shift
unless ["store", "list", "version"].include?(cmd)
$stderr.puts "Usage: #{$0} [dump|list|version] <arguments>"
exit(0)
end

case cmd
when "store"
dst = ARGV.shift
flg = ARGV.shift
dir = ARGV.shift
src = ARGV
unless dst and dir and src.length > 0
$stderr.puts "Usage: #{$0} store destination.fastlib flags base_dir src1 src2 ... src99"
exit(0)
end
FastLib.dump(dst, flg, dir, *src)

when "list"
src = ARGV.shift
unless src
$stderr.puts "Usage: #{$0} list"
exit(0)
end
$stdout.puts "Library: #{src}"
$stdout.puts "====================================================="
FastLib.list(src).each do |name|
fsize = FastLib.cache[src][name][1]
ftime = ::Time.at(FastLib.cache[src][name][2]).strftime("%Y-%m-%d %H:%M:%S")
$stdout.puts sprintf("%9d\t%20s\t%s\n", fsize, ftime, name)
end
$stdout.puts ""

when "version"
$stdout.puts "FastLib Version #{FastLib.version}"
end

exit(0)
end

#
# FASTLIB archive format (subject to change without notice)
#
Expand Down

0 comments on commit 961ef90

Please sign in to comment.