2012-06-29 05:18:28 +00:00
|
|
|
# -*- coding: binary -*-
|
2010-02-11 18:36:38 +00:00
|
|
|
|
|
|
|
##
|
|
|
|
# Rex::OLE - an OLE implementation
|
|
|
|
# written in 2010 by Joshua J. Drake <jduck [at] metasploit.com>
|
|
|
|
##
|
|
|
|
|
|
|
|
module Rex
|
|
|
|
module OLE
|
|
|
|
|
|
|
|
class MiniFAT < DIFAT
|
|
|
|
|
|
|
|
#
|
|
|
|
# low-level functions
|
|
|
|
#
|
|
|
|
def read
|
|
|
|
@entries = []
|
|
|
|
|
|
|
|
visited = []
|
|
|
|
sect = @stg.header._sectMiniFatStart
|
|
|
|
@stg.header._csectMiniFat.times { |idx|
|
|
|
|
break if sect == SECT_END
|
|
|
|
|
|
|
|
if (visited.include?(sect))
|
|
|
|
raise RuntimeError, 'Sector chain loop detected (0x%08x)' % sect
|
|
|
|
end
|
|
|
|
visited << sect
|
|
|
|
|
|
|
|
buf = @stg.read_sector(sect, @stg.header.sector_size)
|
|
|
|
@stg.header.idx_per_sect.times { |idx|
|
|
|
|
@entries << Util.get32(buf, (idx*4))
|
|
|
|
}
|
|
|
|
sect = @stg.next_sector(sect)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def allocate_sector
|
|
|
|
idx = @entries.index(SECT_FREE)
|
|
|
|
|
|
|
|
if (not idx)
|
|
|
|
# add a sector worth
|
|
|
|
idx = @entries.length
|
|
|
|
@stg.header.idx_per_sect.times {
|
|
|
|
@entries << SECT_FREE
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
# default mini-sectors to end of chain
|
|
|
|
@entries[idx] = SECT_END
|
|
|
|
idx
|
|
|
|
end
|
|
|
|
|
|
|
|
def write
|
|
|
|
return if (@entries.length < 1)
|
|
|
|
|
|
|
|
mf_start = nil
|
|
|
|
mfs_count = 0
|
|
|
|
prev_sect = nil
|
|
|
|
copy = @entries.dup
|
|
|
|
while (copy.length > 0)
|
|
|
|
part = copy.slice!(0, @stg.header.idx_per_sect)
|
|
|
|
sbuf = Util.pack32array(part)
|
|
|
|
idx = @stg.write_sector(sbuf, nil, prev_sect)
|
|
|
|
mfs_count += 1
|
|
|
|
mf_start ||= idx
|
|
|
|
end
|
|
|
|
@stg.header._sectMiniFatStart = mf_start
|
|
|
|
@stg.header._csectMiniFat = mfs_count
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|