Class: Resedit::MZBody

Inherits:
ExeBody show all
Defined in:
lib/resedit/mz/mz.rb

Constant Summary

Constants inherited from Changeable

Changeable::COL_CHANGED, Changeable::COL_ORIGINAL, Changeable::HOW_CHANGED, Changeable::HOW_ORIGINAL, Changeable::LOG

Instance Attribute Summary collapse

Attributes inherited from ExeBody

#exe

Instance Method Summary collapse

Methods inherited from ExeBody

#addrFormatter, #dasm, #findRelocValue, #findStrings, #hex, #readRelocated, #revert, #textAt

Methods inherited from Changeable

#addData, #bytes, #change, #changed?, #colStr, #colVal, #curcol, #dbgdump, #debug, #fix, #getChanges, #getData, #hex, #hexify, #insert, #loadChanges, #mode, #parseHow, #revert, #saveChanges, #saveData, #setData, #size, #undo, #unhexify

Constructor Details

#initialize(exe, file, size) ⇒ MZBody

Returns a new instance of MZBody.



164
165
166
167
# File 'lib/resedit/mz/mz.rb', line 164

def initialize(exe, file, size)
    super(exe, file, size)
    @segments = nil
end

Instance Attribute Details

#segmentsObject (readonly)

Returns the value of attribute segments.



162
163
164
# File 'lib/resedit/mz/mz.rb', line 162

def segments
  @segments
end

Instance Method Details

#addr2raw(addr) ⇒ Object



233
# File 'lib/resedit/mz/mz.rb', line 233

def addr2raw(addr); seg2Linear(addr[0], addr[1]) end

#append(bytes, where = nil) ⇒ Object



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/resedit/mz/mz.rb', line 236

def append(bytes, where=nil)
    mode(HOW_CHANGED)
    relfix = @exe.header.relocFix
    res = @addsz
    buf = @addsz>0 ? @root.nbuf[0, @addsz] : ''
    buf += bytes
    removeAppend()
    @addsz = buf.length
    sz = @exe.header.rebuildHeader(@addsz)
    insert(0, bytes + "\x00"*(sz-@addsz))
    seg = linear2seg(res)
    res = [res, seg, sz/0x10]
    patchRelocs(sz/0x10 - relfix)
    return res
end

#formatAddress(addr) ⇒ Object



224
225
226
227
228
229
230
# File 'lib/resedit/mz/mz.rb', line 224

def formatAddress(addr)
    @sfix=0
    seg = (addr-@sfix) >> 4
    min = @msegs.find{|e| e <= seg}
    min = 0 if !min
    return sprintf("%08X %04X:%04X", addr, min, addr - @sfix - (min << 4))
end

#linear2seg(linear, inSegments = nil) ⇒ Object



205
206
207
208
209
210
211
212
213
214
# File 'lib/resedit/mz/mz.rb', line 205

def linear2seg(linear, inSegments=nil)
    inSegments = [seg4Linear(linear)] if !inSegments
    res = []
    inSegments.each{|s|
        raise sprintf("Linear %X less than segment %04X", inSegments[0], s) if linear < (s<<4)
        a = linear - (s << 4)
        res += [a,s]
    }
    return res
end

#patchRelocs(add) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/resedit/mz/mz.rb', line 182

def patchRelocs(add)
    @segments = Set.new()
    for i in 0..@exe.header.info[:NumberOfRelocations]-1
        r = @exe.header.getRelocation(i)
        @segments.add(r[1])
        ofs = seg2Linear(r[0], r[1])
        val = getData(ofs, 2).unpack('v')[0] + add
        fix(ofs, [val].pack('v'))
        @segments.add(val)
    end
    @msegs = @segments.sort.reverse
end


260
261
262
263
264
265
266
267
# File 'lib/resedit/mz/mz.rb', line 260

def print(what, how)
    if what=="header"
        reloadSegments() if !@segments
        puts "Known segments: " + @segments.sort.map{ |i| sprintf('%04X',i) }.join(", ")
        return true
    end
    return super(what, how)
end

#printDasm(inst, str) ⇒ Object



270
271
272
273
# File 'lib/resedit/mz/mz.rb', line 270

def printDasm(inst, str)
    seg = linear2seg(inst.address)
    printf("%08X %04X:%04X%s\n",inst.address, seg[1], seg[0], str)
end

#raw2addr(ofs) ⇒ Object



232
# File 'lib/resedit/mz/mz.rb', line 232

def raw2addr(ofs); linear2seg(ofs) end

#reloadSegmentsObject



169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/resedit/mz/mz.rb', line 169

def reloadSegments()
    @segments = Set.new()
    for i in 0..@exe.header.info[:NumberOfRelocations]-1
        r = @exe.header.getRelocation(i)
        @segments.add(r[1])
        sd = segData(r, 2)
        next if !sd
        val = sd.unpack('v')[0]
        @segments.add(val)
    end
    @msegs = @segments.sort.reverse
end

#removeAppendObject



252
253
254
255
256
# File 'lib/resedit/mz/mz.rb', line 252

def removeAppend()
    mode(HOW_CHANGED)
    undo(0) if @root.obuf.length==0
    @addsz = 0
end

#seg2Linear(a, s) ⇒ Object



195
# File 'lib/resedit/mz/mz.rb', line 195

def seg2Linear(a,s) (s << 4) + a end

#seg4Linear(linear) ⇒ Object



197
198
199
200
201
202
# File 'lib/resedit/mz/mz.rb', line 197

def seg4Linear(linear)
    linear >>= 4
    reloadSegments() if !@segments
    min = @segments.sort.reverse.find{|e| e <= linear}
    return min ? min : 0
end

#segData(reloc, size, isStr = false) ⇒ Object



217
218
219
220
221
222
# File 'lib/resedit/mz/mz.rb', line 217

def segData(reloc, size, isStr=false)
    ofs = seg2Linear(reloc[0], reloc[1])
    return nil if ofs > @root.size()
    return getData(ofs, size) if !isStr
    return colVal(ofs, size)
end