Class: Rex::Zip::Archive

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/zip/archive.rb

Overview

This represents an entire archive.

Direct Known Subclasses

Jar

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(compmeth = CM_DEFLATE) ⇒ Archive


15
16
17
18
# File 'lib/rex/zip/archive.rb', line 15

def initialize(compmeth=CM_DEFLATE)
  @compmeth = compmeth
  @entries = []
end

Instance Attribute Details

#entriesObject (readonly)

An array of the Entry objects stored in this Archive.


12
13
14
# File 'lib/rex/zip/archive.rb', line 12

def entries
  @entries
end

Instance Method Details

#add_file(fname, fdata = nil, xtra = nil, comment = nil, central_dir_name = nil) ⇒ Object

Create a new Entry and add it to the archive.

If fdata is set, the file is populated with that data from the calling method. If fdata is nil, then the fs is checked for the file. If central_dir_name is set it will be used to spoof the name at the Central Directory at packing time.


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/rex/zip/archive.rb', line 45

def add_file(fname, fdata=nil, xtra=nil, comment=nil, central_dir_name=nil)
  if (not fdata)
    begin
      st = File.stat(fname)
    rescue
      return nil
    end

    ts = st.mtime
    if (st.directory?)
      attrs = EFA_ISDIR
      fdata = ''
      unless fname[-1,1] == '/'
        fname += '/'
      end
    else
      f = File.open(fname, 'rb')
      fdata = f.read(f.stat.size)
      f.close
    end
  end

  @entries << Entry.new(fname, fdata, @compmeth, ts, attrs, xtra, comment, central_dir_name)
end

#add_r(dir) ⇒ Object

Recursively adds a directory of files into the archive.


23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/rex/zip/archive.rb', line 23

def add_r(dir)
  path = File.dirname(dir)
  Dir[File.join(dir, "**", "**")].each do |file|
    relative = file.sub(/^#{path.chomp('/')}\//, '')
    if File.directory?(file)
      @entries << Entry.new(relative.chomp('/') + '/', '', @compmeth, nil, EFA_ISDIR, nil, nil)
    else
      contents = File.read(file, :mode => 'rb')
      @entries << Entry.new(relative, contents, @compmeth, nil, nil, nil, nil)
    end
  end
end

#inspectObject


123
124
125
# File 'lib/rex/zip/archive.rb', line 123

def inspect
  "#<#{self.class} entries = [#{@entries.map{|e| e.name}.join(",")}]>"
end

#packObject

Compress this archive and return the resulting zip file as a String.


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/rex/zip/archive.rb', line 89

def pack
  ret = ''

  # save the offests
  offsets = []

  # file 1 .. file n
  @entries.each { |ent|
    offsets << ret.length
    ret << ent.pack
  }

  # archive decryption header (unsupported)
  # archive extra data record (unsupported)

  # central directory
  cfd_offset = ret.length
  idx = 0
  @entries.each { |ent|
    cfd = CentralDir.new(ent, offsets[idx])
    ret << cfd.pack
    idx += 1
  }

  # zip64 end of central dir record (unsupported)
  # zip64 end of central dir locator (unsupported)

  # end of central directory record
  cur_offset = ret.length - cfd_offset
  ret << CentralDirEnd.new(@entries.length, cur_offset, cfd_offset, @comment).pack

  ret
end

#save_to(fname) ⇒ Object

Write the compressed file to fname.


79
80
81
82
83
# File 'lib/rex/zip/archive.rb', line 79

def save_to(fname)
  f = File.open(fname, 'wb')
  f.write(pack)
  f.close
end

#set_comment(comment) ⇒ Object


71
72
73
# File 'lib/rex/zip/archive.rb', line 71

def set_comment(comment)
  @comment = comment
end