class Rex::OLE::FAT

Public Instance Methods

allocate_sector(type=nil) click to toggle source
# File lib/rex/ole/fat.rb, line 41
def allocate_sector(type=nil)
  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

  # mark the sector as in use
  if (type)
    @entries[idx] = type
  else
    # default normal sectors to end of chain
    @entries[idx] = SECT_END
  end
  idx
end
read(difat) click to toggle source

low-level functions

# File lib/rex/ole/fat.rb, line 15
def read(difat)
  @entries = []
  cnt = left = @stg.header._csectFat
  difat.each { |fs|
    break if (left == 0)

    if (fs != SECT_FREE)
      buf = @stg.read_sector(fs, @stg.header.sector_size)
      arr = Util.get32array(buf)

      # hax!
      if (@entries[fs] == SECT_DIF)
        # chop the next ptr
        @entries += arr.slice!(0, arr.length - 1)
      else
        @entries += arr
      end
      left -= 1
    end
  }

  if (left != 0)
    raise RuntimeError, 'Only found %u of %u sectors' % [(cnt - left), cnt]
  end
end
write(difat) click to toggle source
# File lib/rex/ole/fat.rb, line 61
def write(difat)
  # we build the difat as we write these..
  difat.reset

  # allocate the sectors
  fat_sects = []
  left = @entries.length
  while (left > 0)
    if (left > @stg.header.idx_per_sect)
      left -= @stg.header.idx_per_sect
    else
      left = 0
    end
    fat_sects << allocate_sector(SECT_FAT)
  end

  # write the fat into the difat/allocated sectors
  copy = @entries.dup
  fat_sects.each { |fs|
    part = copy.slice!(0, @stg.header.idx_per_sect)
    sbuf = Util.pack32array(part)

    if (sbuf.length != @stg.header.sector_size)
      raise RuntimeError, 'Unsupported number of fat sectors (not multiple of idx per sect)'
    end

    @stg.write_sector_raw(fs, sbuf)
    difat << fs
  }
end