resedit 1.8 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/resedit.rb +1 -1
- data/lib/resedit/app/mz_command.rb +17 -2
- data/lib/resedit/app/text_convert.rb +26 -8
- data/lib/resedit/classes/config.rb +39 -5
- data/lib/resedit/classes/env.rb +5 -3
- data/lib/resedit/classes/exefile.rb +99 -19
- data/lib/resedit/mz/bw.rb +1 -1
- data/lib/resedit/mz/le.rb +201 -80
- data/lib/resedit/mz/multiexe.rb +15 -1
- data/lib/resedit/mz/mz.rb +8 -8
- data/lib/resedit/text/escaper.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7e951763342994ca2eb391febf485c7af0b61b6d
|
|
4
|
+
data.tar.gz: 46699aaad4668d939f3a8bf5475d141aead053e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e51ae58c40d9aa5ea3704696256c5f8d1fa408dca322c77e3dd1264f776a0dcceb2ed27c2a1e2bb60b386f0f20375ea705a328ef68257b009c09ca6e8bc07316
|
|
7
|
+
data.tar.gz: 2561a3233ec457ac8de1035549228eeb3bead6ead35687c1fff12df9c3efb630572f08fb48767744128287b80d790c29df4ffcb78df8d54b25181377959ff60e
|
data/lib/resedit.rb
CHANGED
|
@@ -23,11 +23,14 @@ module Resedit
|
|
|
23
23
|
"append"=>[method(:append), "add bytes to current file", {"value" => "value", "type" => "value type", "where" => "append offset. default: above ss:sp"}],
|
|
24
24
|
"replace"=>[method(:replace), "replace added bytes", {"value" => "value", "type"=>"value type"}],
|
|
25
25
|
"change"=>[method(:change), "change bytes at offset", {"ofs" => "data ofset", "value" => "value", "disp" => "code/file", "type"=>"value type"}],
|
|
26
|
-
"reloc"=>[method(:reloc), "add relocation", {"
|
|
26
|
+
"reloc"=>[method(:reloc), "add relocation", {"offset" => "reloc offset", "target" => "address reloc points to"}],
|
|
27
27
|
"revert"=>[method(:revert), "revert changes", {"ofs"=>"change offset/all"}],
|
|
28
28
|
"hex"=>[method(:hex), "print hex file", {"ofs" => "data offset", "size" => "data size", "how"=>"original/modified", "disp" => "code/file"}],
|
|
29
29
|
"dasm"=>[method(:dasm), "print disasm", {"ofs" => "data offset", "size" => "data size", "how"=>"original/modified"}],
|
|
30
30
|
"eval"=>[method(:expr), "print expression", {"expr" => "expression"}],
|
|
31
|
+
"dump"=>[method(:dump), "dump exe parts", {"out" => "output filename", "parts"=>"list of parts", "how"=>"original/modified"}],
|
|
32
|
+
"relocfind"=>[method(:relocfind), "find relocation with value", {"value" => "value", "type"=>"value type"}],
|
|
33
|
+
"stringfind"=>[method(:stringfind), "search for strings in exe", {"size"=>"min string size"}],
|
|
31
34
|
}
|
|
32
35
|
@shorters = {"p"=>"print", "e"=>"eval"}
|
|
33
36
|
@files = []
|
|
@@ -144,7 +147,15 @@ module Resedit
|
|
|
144
147
|
end
|
|
145
148
|
|
|
146
149
|
def reloc(params)
|
|
147
|
-
cur().reloc(params['
|
|
150
|
+
cur().reloc(params['offset'],params['target'])
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def relocfind(params)
|
|
154
|
+
cur().relocfind(params['value'], params['type'])
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def stringfind(params)
|
|
158
|
+
cur().stringfind(params['size'])
|
|
148
159
|
end
|
|
149
160
|
|
|
150
161
|
def revert(params)
|
|
@@ -166,6 +177,10 @@ module Resedit
|
|
|
166
177
|
puts env.s2i(params['expr'])
|
|
167
178
|
end
|
|
168
179
|
|
|
180
|
+
def dump(params)
|
|
181
|
+
cur().dump(params['out'], params['parts'], params['how'])
|
|
182
|
+
end
|
|
183
|
+
|
|
169
184
|
|
|
170
185
|
def job(params)
|
|
171
186
|
cmd = params['cmd']
|
|
@@ -1,24 +1,41 @@
|
|
|
1
1
|
require 'resedit/app/io_commands'
|
|
2
|
+
require 'resedit/app/app_command'
|
|
2
3
|
|
|
3
4
|
module Resedit
|
|
4
5
|
|
|
6
|
+
class ITextConvert < AppCommand
|
|
7
|
+
attr_accessor :text
|
|
8
|
+
def initialize(resname, params)
|
|
9
|
+
@resname, @params = resname, params
|
|
10
|
+
end
|
|
11
|
+
def mktext(file, format, encoding); raise "NotImplemented" end
|
|
12
|
+
def expectedLines(file); raise "NotImplemented" end
|
|
13
|
+
def pack(file, outstream); raise "NotImplemented" end
|
|
14
|
+
def unpack(file); raise "NotImplemented" end
|
|
15
|
+
end
|
|
16
|
+
|
|
5
17
|
class TextConvertCommand < ConvertCommand
|
|
6
18
|
|
|
19
|
+
|
|
20
|
+
attr_accessor :text
|
|
7
21
|
def initialize(fname, cmdname='text')
|
|
8
22
|
super(cmdname, fname)
|
|
9
|
-
@
|
|
23
|
+
@text = nil
|
|
10
24
|
addOption('format','f',nil,'output file format')
|
|
11
25
|
addOption('encoding','e',nil,'output file encoding')
|
|
12
26
|
end
|
|
13
27
|
|
|
28
|
+
def getInterface(resname, params); self end
|
|
29
|
+
|
|
14
30
|
def import(inname)
|
|
31
|
+
@iface = getInterface(@resname, @params)
|
|
15
32
|
logd("importing text #{inname} to #{@resname}")
|
|
16
33
|
back = backup()
|
|
17
34
|
File.open(back,"rb"){|file|
|
|
18
|
-
@text = mktext(file, @params['format'], @params['encoding'])
|
|
19
|
-
@text.load(inname, expectedLines())
|
|
35
|
+
@iface.text = @iface.mktext(file, @params['format'], @params['encoding'])
|
|
36
|
+
@iface.text.load(inname, @iface.expectedLines())
|
|
20
37
|
StringIO.open("","w+b"){|stream|
|
|
21
|
-
pack(file, stream)
|
|
38
|
+
@iface.pack(file, stream)
|
|
22
39
|
stream.seek(0)
|
|
23
40
|
File.open(@resname,"wb"){|out|
|
|
24
41
|
out.write(stream.read())
|
|
@@ -29,13 +46,14 @@ module Resedit
|
|
|
29
46
|
|
|
30
47
|
|
|
31
48
|
def export(outname)
|
|
49
|
+
@iface = getInterface(@resname, @params)
|
|
32
50
|
logd("exporting text #{@resname} to #{outname}")
|
|
33
51
|
File.open(@resname, "rb"){|file|
|
|
34
|
-
@text = mktext(file, @params['format'], @params['encoding'])
|
|
35
|
-
unpack(file) if @text
|
|
52
|
+
@iface.text = @iface.mktext(file, @params['format'], @params['encoding'])
|
|
53
|
+
@iface.unpack(file) if @iface.text
|
|
36
54
|
}
|
|
37
|
-
raise "Text not unpacked" if !@text
|
|
38
|
-
@text.save(outname)
|
|
55
|
+
raise "Text not unpacked" if !@iface.text
|
|
56
|
+
@iface.text.save(outname)
|
|
39
57
|
end
|
|
40
58
|
|
|
41
59
|
|
|
@@ -6,24 +6,58 @@ module Resedit
|
|
|
6
6
|
|
|
7
7
|
attr_accessor :cfg
|
|
8
8
|
def initialize(fname, section=nil)
|
|
9
|
-
@fname
|
|
9
|
+
@fname = fname
|
|
10
|
+
@section = section ? section : []
|
|
11
|
+
@section = [@section] if !@section.is_a?(Array)
|
|
10
12
|
@cfg = load()
|
|
11
|
-
@
|
|
13
|
+
@section.each{|s|
|
|
14
|
+
@cfg = (@cfg[s] or {})
|
|
15
|
+
}
|
|
12
16
|
end
|
|
13
17
|
|
|
14
18
|
def [](nm); @cfg[nm] end
|
|
15
19
|
def []=(nm, value); @cfg[nm]=value end
|
|
20
|
+
def each(&block);@cfg.each(&block) end
|
|
21
|
+
def length; @cfg.length end
|
|
22
|
+
|
|
23
|
+
def enter(section, createOnAbsent = true)
|
|
24
|
+
section = [section] if !section.is_a?(Array)
|
|
25
|
+
section.each{|s|
|
|
26
|
+
raise "Config section not found #{s} at #{@section}" if !@cfg[s] && !createOnAbsent
|
|
27
|
+
@cfg = @cfg[s] or {}
|
|
28
|
+
@section += [s]
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def enterOnFile(path)
|
|
33
|
+
ret = nil
|
|
34
|
+
ent = ''
|
|
35
|
+
@cfg.each{|k, _|
|
|
36
|
+
fn = File.join(path, k)
|
|
37
|
+
ret = fn if File.exists?(fn)
|
|
38
|
+
ent = k if ret
|
|
39
|
+
break if ret
|
|
40
|
+
}
|
|
41
|
+
raise "Config not found for files at #{path}" if !ret
|
|
42
|
+
enter(ent, false)
|
|
43
|
+
return ret
|
|
44
|
+
end
|
|
16
45
|
|
|
17
46
|
def load();
|
|
18
47
|
File.exists?(@fname) ? JSON.parse(File.read(@fname)) : {}
|
|
19
48
|
end
|
|
20
49
|
|
|
21
50
|
def save()
|
|
22
|
-
if @section
|
|
51
|
+
if @section.length>0
|
|
23
52
|
c = load()
|
|
24
|
-
|
|
53
|
+
cur = c
|
|
54
|
+
@section[0..-2].each{|s|
|
|
55
|
+
cur[s] = {} if !cur[s]
|
|
56
|
+
cur = cur[s]
|
|
57
|
+
}
|
|
58
|
+
cur[@section[-1]]=@cfg
|
|
25
59
|
else
|
|
26
|
-
c = cfg
|
|
60
|
+
c = @cfg
|
|
27
61
|
end
|
|
28
62
|
open(@fname, "w"){|f|
|
|
29
63
|
f.write(JSON.pretty_generate(c))
|
data/lib/resedit/classes/env.rb
CHANGED
|
@@ -83,6 +83,8 @@ module Resedit
|
|
|
83
83
|
t = t[1..-1] while t.length > 0 && (t[0]<'0' || t[0]>'9')
|
|
84
84
|
tp[1] = t.to_i
|
|
85
85
|
end
|
|
86
|
+
return str if tp[0] == "s"
|
|
87
|
+
return str+"\x00" if tp[0] == "z"
|
|
86
88
|
if tp[0]=='f' || (File.exists?(str) && !tp[0])
|
|
87
89
|
return File.read(str)
|
|
88
90
|
end
|
|
@@ -91,10 +93,10 @@ module Resedit
|
|
|
91
93
|
res = eval(str, binding()) if !res
|
|
92
94
|
return res if res.is_a?(String)
|
|
93
95
|
res = valueHex(res.to_s(16), tp)
|
|
94
|
-
raise str if
|
|
96
|
+
raise str if res==nil
|
|
95
97
|
return res
|
|
96
|
-
|
|
97
|
-
raise "Bad value: "+e.to_s
|
|
98
|
+
#rescue Exception => e
|
|
99
|
+
# raise "Bad value: "+e.to_s
|
|
98
100
|
end
|
|
99
101
|
|
|
100
102
|
end
|
|
@@ -25,6 +25,7 @@ module Resedit
|
|
|
25
25
|
raise "Not EXE file" if fsize < self.class::HSIZE
|
|
26
26
|
@exe = exe
|
|
27
27
|
super(file, self.class::HSIZE)
|
|
28
|
+
@hdrtbl = nil
|
|
28
29
|
@_infoOrig = loadInfo()
|
|
29
30
|
@_info = nil
|
|
30
31
|
@info = @_infoOrig
|
|
@@ -47,7 +48,7 @@ module Resedit
|
|
|
47
48
|
|
|
48
49
|
def change(ofs, bytes)
|
|
49
50
|
super(ofs, bytes)
|
|
50
|
-
@_info = nil if (ofs < HSIZE)
|
|
51
|
+
@_info = nil if (ofs < self.class::HSIZE)
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
|
|
@@ -56,16 +57,50 @@ module Resedit
|
|
|
56
57
|
ret = self.class::HDRDESCR.map.with_index { |x, i| [x, v[i]] }.to_h
|
|
57
58
|
return ret
|
|
58
59
|
end
|
|
60
|
+
|
|
59
61
|
def loadTables(file); end
|
|
60
62
|
def loadTail(file);
|
|
61
63
|
addData(file, headerSize() - self.class::HSIZE)
|
|
62
64
|
end
|
|
63
65
|
|
|
66
|
+
def _headerTable()
|
|
67
|
+
return @hdrtbl if @hdrtbl
|
|
68
|
+
@hdrtbl = []
|
|
69
|
+
sz = ["acC","vnsS","VNlL","qQ"]
|
|
70
|
+
ofs = 0
|
|
71
|
+
len = self.class::HDRDESCR.length
|
|
72
|
+
self.class::HDRUNPACK.scan(/[a-zA-Z][\d*]*/).each{|s|
|
|
73
|
+
size = sz.index{|v| v.include?(s[0])}
|
|
74
|
+
raise "Unsupported header descr #{s}" if size==nil
|
|
75
|
+
size = 1 << size
|
|
76
|
+
cnt = s.length>1 && s[1]!='*' ? s[1..-1].to_i : 1
|
|
77
|
+
if s[0]=='a'
|
|
78
|
+
cnt = self.class::HSIZE - ofs if s[1]=='*'
|
|
79
|
+
@hdrtbl += [[ofs, cnt, s]]
|
|
80
|
+
ofs += cnt
|
|
81
|
+
next
|
|
82
|
+
end
|
|
83
|
+
cnt = len - @hdrtbl.length if s[1]=='*'
|
|
84
|
+
cnt.times{
|
|
85
|
+
@hdrtbl += [[ofs, size, s[0]]]
|
|
86
|
+
ofs += size
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
raise "Header descr unmatch #{@hdrtbl} #{self.class::HDRDESCR}" if @hdrtbl.length!=len
|
|
90
|
+
return @hdrtbl
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def fieldOffset(field); return _headerTable()[self.class::HDRDESCR.index(field)][0] end
|
|
94
|
+
def fieldSize(field); return _headerTable()[self.class::HDRDESCR.index(field)][1] end
|
|
64
95
|
|
|
65
|
-
def setInfo(field, values
|
|
96
|
+
def setInfo(field, values)
|
|
66
97
|
raise "Unknown header field #{field}" if !self.class::HDRDESCR.include?(field)
|
|
98
|
+
tbl = _headerTable()
|
|
67
99
|
values = [values] if !values.is_a?(Array)
|
|
68
|
-
|
|
100
|
+
ofs = 0
|
|
101
|
+
idx = self.class::HDRDESCR.index(field)
|
|
102
|
+
pack = tbl[idx, values.length].map{|v| v[2]}.join('')
|
|
103
|
+
change(tbl[idx][0], values.pack(pack))
|
|
69
104
|
end
|
|
70
105
|
|
|
71
106
|
def setBodySize(size); setFileSize(size + headerSize()) end
|
|
@@ -73,13 +108,10 @@ module Resedit
|
|
|
73
108
|
def headerSize(); self.class::HSIZE end
|
|
74
109
|
|
|
75
110
|
def print(what, how)
|
|
76
|
-
return
|
|
111
|
+
return super(what, how) if what!="header"
|
|
77
112
|
mode(parseHow(how))
|
|
78
|
-
ofs=0
|
|
79
|
-
wsz = @exe.wsize
|
|
80
113
|
@info.each{|k,v|
|
|
81
|
-
printf("%20s:\t%s\n", k.to_s, colStr(v, changed?(
|
|
82
|
-
ofs+=2
|
|
114
|
+
printf("%20s:\t%s\n", k.to_s, colStr(v, changed?(fieldOffset(k),fieldSize(k))))
|
|
83
115
|
}
|
|
84
116
|
puts
|
|
85
117
|
return true
|
|
@@ -89,6 +121,7 @@ module Resedit
|
|
|
89
121
|
def fileSize(); raise "NotImplemented" end
|
|
90
122
|
def setFileSize(size); raise "NotImplemented" end
|
|
91
123
|
def entry(size); raise "NotImplemented" end
|
|
124
|
+
def addReloc(ofs, value); raise "NotImplemented" end
|
|
92
125
|
end
|
|
93
126
|
|
|
94
127
|
|
|
@@ -102,12 +135,6 @@ module Resedit
|
|
|
102
135
|
@addsz = 0
|
|
103
136
|
end
|
|
104
137
|
|
|
105
|
-
def removeAppend()
|
|
106
|
-
mode(HOW_CHANGED)
|
|
107
|
-
undo(0) if @root.obuf.length==0
|
|
108
|
-
@addsz = 0
|
|
109
|
-
end
|
|
110
|
-
|
|
111
138
|
def revert(what)
|
|
112
139
|
super(what)
|
|
113
140
|
@addsz = 0
|
|
@@ -158,11 +185,33 @@ module Resedit
|
|
|
158
185
|
end
|
|
159
186
|
end
|
|
160
187
|
|
|
188
|
+
def textAt(pos, minlen, rexp=nil)
|
|
189
|
+
rexp = /^[[:print:][:space:]]+$/ if !rexp
|
|
190
|
+
sz = size
|
|
191
|
+
ln = [minlen+64, sz-pos].min
|
|
192
|
+
return nil if ln<minlen
|
|
193
|
+
data = getData(pos, ln)
|
|
194
|
+
prev = 0
|
|
195
|
+
while true
|
|
196
|
+
zpos = data.index("\x00")
|
|
197
|
+
return nil if zpos!=nil && zpos<minlen
|
|
198
|
+
data = data[0,zpos] if zpos!=nil
|
|
199
|
+
return nil if (data[prev..-1] =~ rexp) != 0
|
|
200
|
+
return data if zpos != nil
|
|
201
|
+
prev = data.length
|
|
202
|
+
return nil if pos+prev+64 > size
|
|
203
|
+
data += getData(pos+prev, 64)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def addrFormatter(hofs); nil end
|
|
161
208
|
def raw2addr(ofs); raise "Not implemented" end
|
|
162
209
|
def addr2raw(addr); raise "Not implemented" end
|
|
163
210
|
def append(bytes, where=nil); raise "NotImplemented" end
|
|
164
|
-
def
|
|
211
|
+
def removeAppend(); raise "Not Implemented" end
|
|
165
212
|
def readRelocated(ofs, size); raise "NotImplemented" end
|
|
213
|
+
def findRelocValue(value); raise "NotImplemented" end
|
|
214
|
+
def findStrings(minsize); raise "NotImplemented" end
|
|
166
215
|
end
|
|
167
216
|
|
|
168
217
|
class ExeFile
|
|
@@ -287,8 +336,6 @@ module Resedit
|
|
|
287
336
|
log("Change added at %08X", res) if res
|
|
288
337
|
end
|
|
289
338
|
|
|
290
|
-
def reloc(ofs); raise "NotImplemented" end
|
|
291
|
-
|
|
292
339
|
def readRelocated(ofs, size); @body.readRelocated(ofs, size) end
|
|
293
340
|
|
|
294
341
|
def dasm(ofs, size=nil, how=nil)
|
|
@@ -298,7 +345,7 @@ module Resedit
|
|
|
298
345
|
end
|
|
299
346
|
|
|
300
347
|
|
|
301
|
-
def valueof(str, type)
|
|
348
|
+
def valueof(str, type=nil)
|
|
302
349
|
puts "value of " + str + " is:"
|
|
303
350
|
p getValue(str, type).unpack("H*")
|
|
304
351
|
end
|
|
@@ -325,15 +372,48 @@ module Resedit
|
|
|
325
372
|
@body.saveData(f)
|
|
326
373
|
end
|
|
327
374
|
|
|
328
|
-
def save(filename)
|
|
375
|
+
def save(filename, final=nil)
|
|
376
|
+
raise "Wrong 'final' word" if final and final != 'final'
|
|
329
377
|
raise "Filename expected." if !filename
|
|
330
378
|
open(filename, "wb:ascii-8bit"){|f|
|
|
331
379
|
saveFile(f)
|
|
332
380
|
}
|
|
381
|
+
return if final
|
|
333
382
|
open(filename+CFGEXT, "w"){|f|
|
|
334
383
|
f.write(JSON.pretty_generate(saveConfig()))
|
|
335
384
|
}
|
|
336
385
|
end
|
|
386
|
+
|
|
387
|
+
def reloc(ofs, target=nil)
|
|
388
|
+
ofs = s2i(ofs)
|
|
389
|
+
trg = s2i(target) if target
|
|
390
|
+
res = @header.addReloc(ofs, trg)
|
|
391
|
+
log((res ? "Relocation added %08X" : "Relocation %08X already exists"), ofs)
|
|
392
|
+
return res
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def relocfind(value, type=nil);
|
|
396
|
+
value = getValue(value, type)
|
|
397
|
+
res = @body.findRelocValue(value)
|
|
398
|
+
log("relocs not found") if !res
|
|
399
|
+
return nil if !res
|
|
400
|
+
res.each{|k,v|
|
|
401
|
+
log("found at #{k.to_s(16)} relocs: #{v.map{|a| a.to_s(16)}}")
|
|
402
|
+
}
|
|
403
|
+
return res
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def stringfind(size=nil)
|
|
407
|
+
size = (size==nil || size=='') ? 3 : s2i(size)
|
|
408
|
+
res = @body.findStrings(size)
|
|
409
|
+
log("strings not found") if !res
|
|
410
|
+
return nil if !res
|
|
411
|
+
log("%d strings found:\n", res.length)
|
|
412
|
+
res.each{|a|
|
|
413
|
+
log("%s at %08X relocs: #{a[2].map{|v| v.to_s(16)}}", a[0], a[1])
|
|
414
|
+
}
|
|
415
|
+
return res
|
|
416
|
+
end
|
|
337
417
|
end
|
|
338
418
|
|
|
339
419
|
end
|
data/lib/resedit/mz/bw.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Resedit
|
|
|
9
9
|
:RuntimeGdtSize, :MAKEPMVer, :NextHeaderPos, :CVInfoOffset, :LastSelUsed, :PMemAlloc, :AllocIncr, :Reserved4, :Options,
|
|
10
10
|
:TransStackSel, :ExpFlags, :ProgramSize, :GdtImageSize, :FirstSelector, :DefaultMemStrategy, :Reserved5, :TransferBufferSize,
|
|
11
11
|
:Reserved6, :ExpPath]
|
|
12
|
-
HDRUNPACK = "
|
|
12
|
+
HDRUNPACK = "v14VVv3a6v6CCva48a64"
|
|
13
13
|
|
|
14
14
|
# unsigned_16 signature; /* BW signature to mark valid file */
|
|
15
15
|
# unsigned_16 last_page_bytes; /* length of image mod 512 */
|
data/lib/resedit/mz/le.rb
CHANGED
|
@@ -9,63 +9,11 @@ module Resedit
|
|
|
9
9
|
:PageSize, :PageShift, :FixupSize, :FixupCsum, :LoaderSize, :LoaderCsum, :ObjectTableOfs, :ObjectsInModule,
|
|
10
10
|
:ObjectPageOfs, :ObjectIterOfs, :ResourceTableOfs, :ResourceTableEntries, :ResidentTableOfs, :EntryTableOfs,
|
|
11
11
|
:ModuleDirectivesOfs, :ModuleDirectives, :FixupPageOfs, :FixupRecordOfs, :ImportTblOfs, :ImportEntries, :ImportProcOfs,
|
|
12
|
-
:
|
|
12
|
+
:PerPageCsumOfs, :DataPagesOfs, :PreloadPages, :NonResTableOfs, :NonResTableLen, :NonResTableCsum, :AutoDSObject,
|
|
13
13
|
:DebugInfoOfs, :DebugInfoLen, :InstancePreload, :InstanceDemand, :Heapsize]
|
|
14
|
-
HDRUNPACK = "
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
18
|
-
# 08h | CPU TYPE | OS TYPE | MODULE VERSION |
|
|
19
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
20
|
-
# 10h | MODULE FLAGS | MODULE # OF PAGES |
|
|
21
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
22
|
-
# 18h | EIP OBJECT # | EIP |
|
|
23
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
24
|
-
# 20h | ESP OBJECT # | ESP |
|
|
25
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
26
|
-
# 28h | PAGE SIZE | PAGE OFFSET SHIFT / LE: last page bytes !!! |
|
|
27
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
28
|
-
# 30h | FIXUP SECTION SIZE | FIXUP SECTION CHECKSUM|
|
|
29
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
30
|
-
# 38h | LOADER SECTION SIZE |LOADER SECTION CHECKSUM|
|
|
31
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
32
|
-
# 40h | OBJECT TABLE OFF | # OBJECTS IN MODULE |
|
|
33
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
34
|
-
# 48h | OBJECT PAGE TABLE OFF | OBJECT ITER PAGES OFF |
|
|
35
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
36
|
-
# 50h | RESOURCE TABLE OFFSET |#RESOURCE TABLE ENTRIES|
|
|
37
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
38
|
-
# 58h | RESIDENT NAME TBL OFF | ENTRY TABLE OFFSET |
|
|
39
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
40
|
-
# 60h | MODULE DIRECTIVES OFF | # MODULE DIRECTIVES |
|
|
41
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
42
|
-
# 68h | FIXUP PAGE TABLE OFF |FIXUP RECORD TABLE OFF |
|
|
43
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
44
|
-
# 70h | IMPORT MODULE TBL OFF | # IMPORT MOD ENTRIES |
|
|
45
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
46
|
-
# 78h | IMPORT PROC TBL OFF | PER-PAGE CHECKSUM OFF |
|
|
47
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
48
|
-
# 80h | DATA PAGES OFFSET FROM MZ !!! | #PRELOAD PAGES |
|
|
49
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
50
|
-
# 88h | NON-RES NAME TBL OFF | NON-RES NAME TBL LEN |
|
|
51
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
52
|
-
# 90h | NON-RES NAME TBL CKSM | AUTO DS OBJECT # |
|
|
53
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
54
|
-
# 98h | DEBUG INFO OFF | DEBUG INFO LEN |
|
|
55
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
56
|
-
# A0h | #INSTANCE PRELOAD | #INSTANCE DEMAND |
|
|
57
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
58
|
-
# A8h | HEAPSIZE |
|
|
59
|
-
#
|
|
60
|
-
|
|
61
|
-
# Object Table
|
|
62
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
63
|
-
# 00h | VIRTUAL SIZE | RELOC BASE ADDR |
|
|
64
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
65
|
-
# 08h | OBJECT FLAGS | PAGE TABLE INDEX |
|
|
66
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
67
|
-
# 10h | # PAGE TABLE ENTRIES | RESERVED |
|
|
68
|
-
# +-----+-----+-----+-----+-----+-----+-----+-----+
|
|
14
|
+
HDRUNPACK = "vCCVvvV*"
|
|
15
|
+
HDR_OFFSETS = [:ObjectTableOfs, :ObjectPageOfs, :ObjectIterOfs, :ResourceTableOfs,:ResidentTableOfs, :EntryTableOfs, :ModuleDirectivesOfs,
|
|
16
|
+
:FixupPageOfs, :FixupRecordOfs, :ImportTblOfs, :ImportProcOfs, :PerPageCsumOfs, :DataPagesOfs, :NonResTableOfs, :DebugInfoOfs]
|
|
69
17
|
|
|
70
18
|
attr_reader :tables
|
|
71
19
|
|
|
@@ -103,28 +51,6 @@ module Resedit
|
|
|
103
51
|
addData(file, headerSize() + @sofs - file.tell())
|
|
104
52
|
end
|
|
105
53
|
|
|
106
|
-
def readRelocs()
|
|
107
|
-
def read(pos,cnt, unp); [getData(@info[:FixupRecordOfs]+pos, cnt).unpack(unp),pos+cnt] end
|
|
108
|
-
ret = {}
|
|
109
|
-
pgs = getData(@info[:FixupPageOfs], 4*(@info[:ModulePages]+1)).unpack("V*")
|
|
110
|
-
for i in 0..@info[:ModulePages]-1
|
|
111
|
-
pos = pgs[i]
|
|
112
|
-
op = @tables[:Pages][i]
|
|
113
|
-
pgofs = ((op>>16) + ((op>>8) & 0xFF) -1) * @info[:PageSize]
|
|
114
|
-
ret[pgofs] = {}
|
|
115
|
-
while pos<pgs[i+1]
|
|
116
|
-
v,pos = read(pos, 5, "CCvC")
|
|
117
|
-
raise "Unknown fixup type #{v[0]} #{v[1]}" if (v[0]!=7 && v[0]!=2) || (v[1] & ~0x10 !=0 )
|
|
118
|
-
trg, pos=read(pos, v[1]==0x10 ? 4 : 2,v[1]==0x10 ? "V" : "v")
|
|
119
|
-
next if v[2]>0x7FFF
|
|
120
|
-
ofs = pgofs+v[2]
|
|
121
|
-
ret[pgofs][pgofs+v[2]] = @tables[:Objects][v[3]-1][1]+trg[0]
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
return ret
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
|
|
128
54
|
def mode(how)
|
|
129
55
|
super(how)
|
|
130
56
|
if @mode == HOW_ORIGINAL
|
|
@@ -135,11 +61,143 @@ module Resedit
|
|
|
135
61
|
end
|
|
136
62
|
end
|
|
137
63
|
|
|
138
|
-
def headerSize(); @info[:DataPagesOfs]-@exe.mzSize end
|
|
139
64
|
|
|
65
|
+
def headerSize(); @info[:DataPagesOfs]-@exe.mzSize end
|
|
140
66
|
def fileSize(); headerSize()+(@info[:ModulePages]-1)*@info[:PageSize]+@info[:PageShift] end
|
|
141
67
|
def entry; sprintf("0x%08X", @info[:EIP]) end
|
|
142
68
|
|
|
69
|
+
def pageRelocs(pageId, fixOfs=nil, fixObj=nil, fixVal=nil)
|
|
70
|
+
def read(pos,cnt, unp); [getData(@info[:FixupRecordOfs]+pos, cnt).unpack(unp), pos+cnt] end
|
|
71
|
+
pgs = getData(@info[:FixupPageOfs]+4*pageId, 8).unpack("V*")
|
|
72
|
+
pgofs = pageId * @info[:PageSize]
|
|
73
|
+
ret = {}
|
|
74
|
+
pos = pgs[0]
|
|
75
|
+
while pos<pgs[1]
|
|
76
|
+
v,pos = read(pos, 5, "CCs<C")
|
|
77
|
+
raise "Unknown fixup type #{v[0]} #{v[1]}" if (v[0]!=7 && v[0]!=2) || (v[1] & ~0x10 !=0 )
|
|
78
|
+
trg, pos=read(pos, v[1]==0x10 ? 4 : 2,v[1]==0x10 ? "V" : "v")
|
|
79
|
+
next if fixOfs!=nil && (v[2]!=fixOfs || (v[1]==0 && fixVal>0xFF))
|
|
80
|
+
if fixOfs
|
|
81
|
+
buf = [fixObj, fixVal].pack("C" + v[1]==0x10 ? "V" : "v")
|
|
82
|
+
change(@info[:FixupRecordOfs]+pos-1, buf) #change fixup object & value
|
|
83
|
+
return true
|
|
84
|
+
end
|
|
85
|
+
next if v[2]<0
|
|
86
|
+
ret[pgofs+v[2]] = @tables[:Objects][v[3]-1][1]+trg[0]
|
|
87
|
+
end
|
|
88
|
+
return false if fixOfs
|
|
89
|
+
return ret
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def addPageReloc(pageId, ofs, obj, val)
|
|
94
|
+
return true if pageRelocs(pageId, ofs, obj, val)
|
|
95
|
+
#extend page fixups
|
|
96
|
+
buf = [7, 0x10, ofs, obj, val].pack("CCs<CV")
|
|
97
|
+
#change fixups offsets
|
|
98
|
+
pgs = getData(@info[:FixupPageOfs]+4*(pageId+1), (@info[:ModulePages]-pageId)*4).unpack("V*")
|
|
99
|
+
d = buf.length
|
|
100
|
+
insert(@info[:FixupRecordOfs]+pgs[0], buf)
|
|
101
|
+
pgs = pgs.map{|v| v+d} #fixup sizes change
|
|
102
|
+
change(@info[:FixupPageOfs]+4*(pageId+1), pgs.pack("V*"))
|
|
103
|
+
#fix header
|
|
104
|
+
fixOffsets(@info[:FixupRecordOfs], d)
|
|
105
|
+
@info[:FixupSize]+=d
|
|
106
|
+
setInfo(:FixupSize, @info[:FixupSize])
|
|
107
|
+
@info[:LoaderSize]+=d
|
|
108
|
+
setInfo(:LoaderSize, @info[:LoaderSize])
|
|
109
|
+
@_tables = nil
|
|
110
|
+
mode(HOW_CHANGED)
|
|
111
|
+
rels = pageRelocs(pageId)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def readRelocs()
|
|
116
|
+
ret = {}
|
|
117
|
+
for i in 0..@info[:ModulePages]-1
|
|
118
|
+
pgofs = i * @info[:PageSize]
|
|
119
|
+
ret[pgofs] = pageRelocs(i)
|
|
120
|
+
end
|
|
121
|
+
return ret
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def fixOffsets(after, val)
|
|
126
|
+
HDR_OFFSETS.each{|ofs|
|
|
127
|
+
next if @info[ofs]==0 or @info[ofs]<=after
|
|
128
|
+
@info[ofs]+=val
|
|
129
|
+
setInfo(ofs, @info[ofs])
|
|
130
|
+
}
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def addSegment(size)
|
|
135
|
+
mode(HOW_CHANGED)
|
|
136
|
+
psz = @info[:PageSize]
|
|
137
|
+
tail = size % psz
|
|
138
|
+
pgs = size / psz + (tail==0 ? 0 : 1)
|
|
139
|
+
tail = psz if tail==0
|
|
140
|
+
|
|
141
|
+
#add new object
|
|
142
|
+
last = @tables[:Objects][-1]
|
|
143
|
+
virt = last[1]+last[0] #lastobject virt base+size
|
|
144
|
+
virt = (virt+psz-1) & ~(psz-1) #align vbase to page size
|
|
145
|
+
obj = [psz*pgs, virt, 0x2047, last[3]+last[4], pgs, 0].pack("V*") # 32b rwx preloaded object
|
|
146
|
+
insert(@info[:ObjectTableOfs] + 0x18*@info[:ObjectsInModule], obj)
|
|
147
|
+
fixOffsets(@info[:ObjectTableOfs], 0x18)
|
|
148
|
+
setInfo(:ObjectsInModule, @info[:ObjectsInModule]+1)
|
|
149
|
+
|
|
150
|
+
#add pages info
|
|
151
|
+
pinfo = ''
|
|
152
|
+
pgs.times{|i|
|
|
153
|
+
pid = @info[:ModulePages]+i+1
|
|
154
|
+
pinfo+=[(pid*@info[:PageSize])<<4].pack("V")
|
|
155
|
+
}
|
|
156
|
+
insert(@info[:ObjectPageOfs]+@info[:ModulePages]*4, pinfo)
|
|
157
|
+
fixOffsets(@info[:ObjectPageOfs], pinfo.length)
|
|
158
|
+
|
|
159
|
+
#add empty fixups
|
|
160
|
+
fixofs = 4*@info[:ModulePages]
|
|
161
|
+
fixval = getData(@info[:FixupPageOfs]+fixofs, 4).unpack("V")[0]
|
|
162
|
+
pinfo = [fixval].pack("V") * pgs #end of fixup table <added pages> times
|
|
163
|
+
insert(@info[:FixupPageOfs]+fixofs+4, pinfo)
|
|
164
|
+
fixOffsets(@info[:FixupPageOfs], pinfo.length)
|
|
165
|
+
setInfo(:FixupSize, @info[:FixupSize]+pinfo.length)
|
|
166
|
+
|
|
167
|
+
#change pages and tail, fix loader size
|
|
168
|
+
setInfo(:ModulePages, @info[:ModulePages]+pgs)
|
|
169
|
+
setInfo(:PageShift, tail)
|
|
170
|
+
setInfo(:LoaderSize, @info[:ImportTblOfs]-@info[:ObjectTableOfs]+1)
|
|
171
|
+
|
|
172
|
+
@_tables = nil
|
|
173
|
+
#reload tables
|
|
174
|
+
mode(HOW_CHANGED)
|
|
175
|
+
|
|
176
|
+
return (@info[:ModulePages]-pgs)*@info[:PageSize]
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def addReloc(ofs, trg=nil)
|
|
181
|
+
mode(HOW_CHANGED)
|
|
182
|
+
trg = trg ? @exe.body.raw2addr(trg) : getData(ofs, 4)
|
|
183
|
+
obj = val = -1
|
|
184
|
+
@tables[:Objects].each_with_index{|o,i|
|
|
185
|
+
obj,val = [i+1,trg-o[1]] if o[1]<=trg && o[0]+o[1]>trg
|
|
186
|
+
}
|
|
187
|
+
raise "Target not found for offset: #{trg.to_i(trg)}" if obj==-1
|
|
188
|
+
psz = @info[:PageSize]
|
|
189
|
+
pgid = ofs / psz
|
|
190
|
+
#puts "Adding reloc #{ofs.to_s(16)} -> #{trg.to_s(16)} #{obj}:#{val.to_s(16)} #{pgid}"
|
|
191
|
+
ofs = ofs % psz
|
|
192
|
+
addPageReloc(pgid, ofs, obj, val)
|
|
193
|
+
addPageReloc(pgid+1, ofs-psz, obj, val) if ofs+4>psz
|
|
194
|
+
@_tables = nil
|
|
195
|
+
mode(HOW_CHANGED)
|
|
196
|
+
@exe.body.clearRelocs()
|
|
197
|
+
return true
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
|
|
143
201
|
def print(what, how=nil)
|
|
144
202
|
ret = super(what, how)
|
|
145
203
|
if what=="tables"
|
|
@@ -172,6 +230,8 @@ module Resedit
|
|
|
172
230
|
@sex
|
|
173
231
|
end
|
|
174
232
|
|
|
233
|
+
def clearRelocs; @relocs=nil end
|
|
234
|
+
|
|
175
235
|
def relocations()
|
|
176
236
|
if !@relocs
|
|
177
237
|
@relocs = @exe.header.readRelocs().sort_by{|k,v| k}.reverse.to_h
|
|
@@ -192,8 +252,9 @@ module Resedit
|
|
|
192
252
|
return s[0]+ofs-s[1]
|
|
193
253
|
end
|
|
194
254
|
|
|
195
|
-
def addr2raw(addr)
|
|
255
|
+
def addr2raw(addr, raiseOnError=true)
|
|
196
256
|
s = sections.find{|s| s[0]<=addr && s[0]+s[2]>addr}
|
|
257
|
+
return nil if !s && !raiseOnError
|
|
197
258
|
raise "Not virtual address #{addr.to_s(16)}" if !s
|
|
198
259
|
return s[1]+addr-s[0]
|
|
199
260
|
end
|
|
@@ -214,6 +275,66 @@ module Resedit
|
|
|
214
275
|
return d[0,size]
|
|
215
276
|
end
|
|
216
277
|
|
|
278
|
+
def append(bytes, where=nil)
|
|
279
|
+
@relocs = nil
|
|
280
|
+
mode(HOW_CHANGED)
|
|
281
|
+
pos = @exe.header.addSegment(bytes.length)
|
|
282
|
+
sz = size
|
|
283
|
+
insert(sz, "\x00"*(pos-sz))
|
|
284
|
+
insert(pos, bytes)
|
|
285
|
+
return [raw2addr(pos), pos]
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def findRelocValue(value)
|
|
289
|
+
rel = relocations()
|
|
290
|
+
cnt = rel.length
|
|
291
|
+
ret={}
|
|
292
|
+
vlen = value.length
|
|
293
|
+
i = 1
|
|
294
|
+
fsz = size
|
|
295
|
+
rel.each{|o,r|
|
|
296
|
+
r.each{|k,v|
|
|
297
|
+
raw = addr2raw(v, false)
|
|
298
|
+
next if raw==nil || raw+vlen>fsz
|
|
299
|
+
vl = getData(raw, vlen)
|
|
300
|
+
next if vl!=value
|
|
301
|
+
ret[v] = [] if !ret[v]
|
|
302
|
+
ret[v] += [raw2addr(k)]
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return nil if ret.length==0
|
|
306
|
+
return ret
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def findStrings(minsize)
|
|
310
|
+
rel = relocations()
|
|
311
|
+
cnt = rel.length
|
|
312
|
+
fsz = size
|
|
313
|
+
proced = {}
|
|
314
|
+
i = 1
|
|
315
|
+
ret = []
|
|
316
|
+
rel.each{|o,r|
|
|
317
|
+
r.each{|k,v|
|
|
318
|
+
if proced[v]!=nil
|
|
319
|
+
ret[proced[v]][2]+=[raw2addr(k)] if proced[v]>=0
|
|
320
|
+
next
|
|
321
|
+
end
|
|
322
|
+
raw = addr2raw(v, false)
|
|
323
|
+
if raw==nil || raw+minsize>fsz
|
|
324
|
+
proced[v] = -1
|
|
325
|
+
next
|
|
326
|
+
end
|
|
327
|
+
txt = textAt(raw, minsize)
|
|
328
|
+
if txt != nil
|
|
329
|
+
ret+= [[txt, v, [raw2addr(k)]]]
|
|
330
|
+
end
|
|
331
|
+
proced[v] = txt==nil ? -1 : ret.length-1
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return nil if ret.length==0
|
|
335
|
+
return ret
|
|
336
|
+
end
|
|
337
|
+
|
|
217
338
|
end
|
|
218
339
|
|
|
219
340
|
|
data/lib/resedit/mz/multiexe.rb
CHANGED
|
@@ -39,6 +39,18 @@ module Resedit
|
|
|
39
39
|
}
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
def dump(out, parts, how=nil)
|
|
43
|
+
prts = eval(parts)
|
|
44
|
+
open(out,"wb"){|f|
|
|
45
|
+
prts.each{|i|
|
|
46
|
+
pr = @parts[i]
|
|
47
|
+
pr.header.mode(pr.header.parseHow(how))
|
|
48
|
+
pr.body.mode(pr.header.parseHow(how))
|
|
49
|
+
pr.saveFile(f)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
42
54
|
def header; @cur.header end
|
|
43
55
|
def body; @cur.body end
|
|
44
56
|
def env; @cur.env end
|
|
@@ -62,7 +74,9 @@ module Resedit
|
|
|
62
74
|
def append(value, type=nil, where=nil); @cur.append(value, type, where) end
|
|
63
75
|
def replace(value, type=nil, where=nil); @cur.replace(value, type, where) end
|
|
64
76
|
def change(ofs, value, disp=nil, type=nil); @cur.change(ofs, value, disp, type) end
|
|
65
|
-
def reloc(ofs); @cur.reloc(ofs) end
|
|
77
|
+
def reloc(ofs, target=nil); @cur.reloc(ofs, target) end
|
|
78
|
+
def relocfind(value, type=nil); @cur.relocfind(value, type) end
|
|
79
|
+
def stringfind(size=nil); @cur.stringfind(size) end
|
|
66
80
|
def dasm(ofs, size=nil, how=nil) @cur.dasm(ofs, size, how) end
|
|
67
81
|
def valueof(str, type); @cur.valueof(str, type) end
|
|
68
82
|
def revert(what); @cur.revert(what) end
|
data/lib/resedit/mz/mz.rb
CHANGED
|
@@ -104,7 +104,7 @@ module Resedit
|
|
|
104
104
|
mode(HOW_CHANGED)
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
def addReloc(ofs)
|
|
107
|
+
def addReloc(ofs, trg)
|
|
108
108
|
mode(HOW_CHANGED)
|
|
109
109
|
#check relocation exists
|
|
110
110
|
for i in 0..@info[:NumberOfRelocations]-1
|
|
@@ -250,6 +250,13 @@ module Resedit
|
|
|
250
250
|
return res
|
|
251
251
|
end
|
|
252
252
|
|
|
253
|
+
def removeAppend()
|
|
254
|
+
mode(HOW_CHANGED)
|
|
255
|
+
undo(0) if @root.obuf.length==0
|
|
256
|
+
@addsz = 0
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
|
|
253
260
|
|
|
254
261
|
def print(what, how)
|
|
255
262
|
if what=="header"
|
|
@@ -272,13 +279,6 @@ module Resedit
|
|
|
272
279
|
class MZ < ExeFile
|
|
273
280
|
HDRCLASS = MZHeader
|
|
274
281
|
BODYCLASS = MZBody
|
|
275
|
-
|
|
276
|
-
def reloc(ofs)
|
|
277
|
-
ofs = s2i(ofs)
|
|
278
|
-
res = @header.addReloc(ofs)
|
|
279
|
-
log((res ? "Relocation added %08X" : "Relocation %08X already exists"), ofs)
|
|
280
|
-
end
|
|
281
|
-
|
|
282
282
|
end
|
|
283
283
|
|
|
284
284
|
end
|
data/lib/resedit/text/escaper.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: resedit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- bjfn
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-12-
|
|
11
|
+
date: 2017-12-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: chunky_png
|