Class: Resedit::MZBody

Inherits:
Changeable show all
Defined in:
lib/resedit/mz/mz_body.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

Instance Method Summary collapse

Methods inherited from Changeable

#addData, #bytes, #change, #changed?, #colStr, #colVal, #curcol, #dbgdump, #debug, #getChanges, #getData, #hex, #insert, #loadChanges, #mode, #parseHow, #saveChanges, #saveData, #undo

Constructor Details

#initialize(mz, file, size) ⇒ MZBody

Returns a new instance of MZBody.



18
19
20
21
22
23
# File 'lib/resedit/mz/mz_body.rb', line 18

def initialize(mz, file, size)
    @mz = mz
    super(file, size)
    @segments = nil
    @addsz = 0
end

Instance Attribute Details

#appSegObject (readonly)

Returns the value of attribute appSeg.



16
17
18
# File 'lib/resedit/mz/mz_body.rb', line 16

def appSeg
  @appSeg
end

#mzObject (readonly)

Returns the value of attribute mz.



16
17
18
# File 'lib/resedit/mz/mz_body.rb', line 16

def mz
  @mz
end

#segmentsObject (readonly)

Returns the value of attribute segments.



16
17
18
# File 'lib/resedit/mz/mz_body.rb', line 16

def segments
  @segments
end

Instance Method Details

#append(bytes, where = nil) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/resedit/mz/mz_body.rb', line 88

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

#dasm(ofs, size, how) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/resedit/mz/mz_body.rb', line 115

def dasm(ofs, size, how)
    raise "Crabstone gem required to disasm." if $nocrabstone
    mode(parseHow(how))
    cs = Disassembler.new(ARCH_X86, MODE_16)
    begin
        while true
            begin
                d = getData(ofs,size)
                cs.disasm(d, ofs).each {|i|
                    seg = linear2seg(i.address)
                    bts = i.bytes.map { |b| sprintf("%02X",b) }.join
                    inst = colStr(sprintf("%14s\t%s\t%s", bts, i.mnemonic, i.op_str), changed?(i.address, i.bytes.length))
                    printf("%08X %04X:%04X%s\n",i.address, seg[1], seg[0], inst)
                }
                break
            rescue
                ofs-=1
            end
        end

    ensure
        cs.close()
    end
end

#linear2seg(linear, inSegments = nil) ⇒ Object



57
58
59
60
61
62
63
64
65
66
# File 'lib/resedit/mz/mz_body.rb', line 57

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



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/resedit/mz/mz_body.rb', line 35

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


104
105
106
107
108
109
110
111
112
# File 'lib/resedit/mz/mz_body.rb', line 104

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

#reloadSegmentsObject



25
26
27
28
29
30
31
32
33
# File 'lib/resedit/mz/mz_body.rb', line 25

def reloadSegments()
    @segments = Set.new()
    for i in 0..@mz.header.info[:NumberOfRelocations]-1
        r = @mz.header.getRelocation(i)
        @segments.add(r[1])
        val = segData(r, 2).unpack('v')[0]
        @segments.add(val)
    end
end

#removeAppendObject



77
78
79
80
81
# File 'lib/resedit/mz/mz_body.rb', line 77

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

#revert(what) ⇒ Object



83
84
85
86
# File 'lib/resedit/mz/mz_body.rb', line 83

def revert(what)
    super(what)
    @addsz = 0
end

#seg2Linear(a, s) ⇒ Object



47
# File 'lib/resedit/mz/mz_body.rb', line 47

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

#seg4Linear(linear) ⇒ Object



49
50
51
52
53
54
# File 'lib/resedit/mz/mz_body.rb', line 49

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



69
70
71
72
73
74
# File 'lib/resedit/mz/mz_body.rb', line 69

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