class Metasm::ZIP
Constants
- COMPRESSION_METHOD
- MAGIC_CENTRALHEADER
- MAGIC_ENDCENTRALDIRECTORY
- MAGIC_LOCALHEADER
Attributes
files[RW]
header[RW]
Public Class Methods
autoexe_load(bin)
click to toggle source
when called as AutoExe, try to find a meaningful exefmt
# File metasm/exe_format/zip.rb, line 325 def self.autoexe_load(bin) z = decode(bin) if dex = z.file_data('classes.dex') puts "ZIP: APK file, loading 'classes.dex'" if $VERBOSE AutoExe.load(dex) else z end end
new(cpu = nil)
click to toggle source
Calls superclass method
Metasm::ExeFormat.new
# File metasm/exe_format/zip.rb, line 219 def initialize(cpu = nil) @endianness = :little @header = EndCentralDirectory.new @files = [] super(cpu) end
Public Instance Methods
add_file(fname, data, compress=:auto)
click to toggle source
add a new file to the zip archive
# File metasm/exe_format/zip.rb, line 266 def add_file(fname, data, compress=:auto) f = CentralHeader.new case compress when 'NONE', false; f.compress_method = 'NONE' when 'DEFLATE', true; f.compress_method = 'DEFLATE' end f.fname = fname f.data = data @files << f f end
decode()
click to toggle source
read the whole central directory file descriptors
# File metasm/exe_format/zip.rb, line 235 def decode decode_header @encoded.ptr = @header.directory_off while @encoded.ptr < @header.directory_off + @header.directory_sz @files << CentralHeader.decode(self) end end
decode_half(edata=@encoded)
click to toggle source
# File metasm/exe_format/zip.rb, line 210 def decode_half(edata=@encoded) edata.decode_imm(:u16, @endianness) end
decode_header()
click to toggle source
scan and decode the 'end of central directory' header
# File metasm/exe_format/zip.rb, line 227 def decode_header if not @encoded.ptr = @encoded.data.rindex([MAGIC_ENDCENTRALDIRECTORY].pack('V')) raise "ZIP: no end of central directory record" end @header = EndCentralDirectory.decode(self) end
decode_word(edata=@encoded)
click to toggle source
# File metasm/exe_format/zip.rb, line 211 def decode_word(edata=@encoded) edata.decode_imm(:u32, @endianness) end
encode()
click to toggle source
create a new zip file
# File metasm/exe_format/zip.rb, line 282 def encode edata = EncodedData.new central_dir = EncodedData.new @files.each { |f| encode_entry(f, edata, central_dir) } @header.directory_off = edata.length @header.directory_sz = central_dir.length edata << central_dir << @header.encode(self) @encoded = edata end
encode_entry(f, edata, central_dir)
click to toggle source
add one file to the zip stream
# File metasm/exe_format/zip.rb, line 299 def encode_entry(f, edata, central_dir) f.localhdr_off = edata.length # may autodetect compression method raw = f.encode_data(self) zipalign(f, edata) central_dir << f.encode(self) # calls f.set_default_values l = LocalHeader.from_central(f) edata << l.encode(self) edata << raw end
encode_half(w)
click to toggle source
# File metasm/exe_format/zip.rb, line 212 def encode_half(w) Expression[w].encode(:u16, @endianness) end
encode_word(w)
click to toggle source
# File metasm/exe_format/zip.rb, line 213 def encode_word(w) Expression[w].encode(:u32, @endianness) end
file_data(fname, lcase=true)
click to toggle source
returns the uncompressed raw file content from a given name nil if name not found case-insensitive if lcase is false
# File metasm/exe_format/zip.rb, line 259 def file_data(fname, lcase=true) if f = has_file(fname, lcase) f.file_data(self) end end
has_file(fname, lcase=true)
click to toggle source
checks if a given file name exists in the archive returns the CentralHeader or nil case-insensitive if lcase is false
# File metasm/exe_format/zip.rb, line 246 def has_file(fname, lcase=true) decode if @files.empty? if lcase @files.find { |f| f.fname == fname } else fname = fname.downcase @files.find { |f| f.fname.downcase == fname } end end
sizeof_half()
click to toggle source
# File metasm/exe_format/zip.rb, line 214 def sizeof_half ; 2 ; end
sizeof_word()
click to toggle source
# File metasm/exe_format/zip.rb, line 215 def sizeof_word ; 4 ; end
zipalign(f, edata)
click to toggle source
zipalign: ensure uncompressed data starts on a 4-aligned offset
# File metasm/exe_format/zip.rb, line 316 def zipalign(f, edata) if f.compress_method == 'NONE' and not f.extra o = (edata.length + f.fname.length + 2) & 3 f.extra = " "*(4-o) if o > 0 end end