Class: Rex::OLE::DIFAT

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/ole/difat.rb

Direct Known Subclasses

FAT, MiniFAT

Instance Method Summary collapse

Constructor Details

#initialize(stg) ⇒ DIFAT

Returns a new instance of DIFAT.



13
14
15
16
# File 'lib/rex/ole/difat.rb', line 13

def initialize stg
  @stg = stg
  @entries = []
end

Instance Method Details

#+(expr) ⇒ Object



29
30
31
32
# File 'lib/rex/ole/difat.rb', line 29

def +(expr)
  @entries += expr
  self
end

#<<(expr) ⇒ Object



34
35
36
# File 'lib/rex/ole/difat.rb', line 34

def <<(expr)
  @entries << expr
end

#[](idx) ⇒ Object



25
26
27
# File 'lib/rex/ole/difat.rb', line 25

def [](idx)
  @entries[idx]
end

#[]=(idx, expr) ⇒ Object

convenience access to entries



21
22
23
# File 'lib/rex/ole/difat.rb', line 21

def []=(idx,expr)
  @entries[idx] = expr
end

#eachObject



50
51
52
53
54
# File 'lib/rex/ole/difat.rb', line 50

def each
  @entries.each { |el|
    yield el
  }
end

#lengthObject



38
39
40
# File 'lib/rex/ole/difat.rb', line 38

def length
  @entries.length
end

#readObject

low-level functions



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rex/ole/difat.rb', line 83

def read
  @entries = []

  # start with the header part
  @entries += @stg.header._sectFat

  # double indirect fat
  sect = @stg.header._sectDifStart
  while (sect != SECT_END)
    if (@entries.include?(sect))
      raise RuntimeError, 'Sector chain loop detected (0x%08x)' % sect
    end

    @entries << sect
    buf = @stg.read_sector(sect, @stg.header.sector_size)

    # the last sect ptr in the block becomes the next entry
    sect = Util.get32(buf, ((@stg.header.idx_per_sect)-1) * 4)
  end

  # don't need these free ones, but it doesn't hurt to keep them.
  #@difat.delete(SECT_FREE)
end

#resetObject



46
47
48
# File 'lib/rex/ole/difat.rb', line 46

def reset
  @entries = []
end

#slice!(start, stop) ⇒ Object



42
43
44
# File 'lib/rex/ole/difat.rb', line 42

def slice!(start,stop)
  @entries.slice!(start,stop)
end

#to_sObject

woop



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rex/ole/difat.rb', line 59

def to_s
  ret = "{ "
  @entries.each { |el|
    ret << ", " if (ret.length > 2)
    case el
    when SECT_END
      ret << "END"
    when SECT_DIF
      ret << "DIF"
    when SECT_FAT
      ret << "FAT"
    when SECT_FREE
      ret << "FREE"
    else
      ret << "0x%x" % el
    end
  }
  ret << " }"
  ret
end

#writeObject



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/rex/ole/difat.rb', line 107

def write
  len = @entries.length
  first109 = @entries.dup

  rest = nil
  if (len > 109)
    rest = first109.slice!(109,len)
  end

  @stg.header._sectFat = []
  @stg.header._sectFat += first109
  if (len < 109)
    need = 109 - len
    need.times {
      @stg.header._sectFat << SECT_FREE
    }
  end

  if (rest and rest.length > 0)
    raise RuntimeError, 'TODO: support writing DIF properly!'
    # may require adding more fat sectors :-/
    #@stg.header._csectDif = rest.length
    #@stg.header._sectDifStart = idx
  end

  @stg.header._csectFat = len
end