pedump 0.4.15 → 0.4.16
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/data/sig.bin +0 -0
- data/lib/pedump/resources.rb +38 -1
- data/lib/pedump/sig_parser.rb +60 -17
- data/lib/pedump/version.rb +1 -1
- data/pedump.gemspec +2 -2
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.16
|
data/data/sig.bin
CHANGED
Binary file
|
data/lib/pedump/resources.rb
CHANGED
@@ -65,6 +65,36 @@ class PEdump
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
# only valid for types BITMAP, ICON & CURSOR
|
69
|
+
def restore_icon src_fname
|
70
|
+
File.open(src_fname, "rb") do |f|
|
71
|
+
parse f
|
72
|
+
if data.first == "PNG"
|
73
|
+
"\x89PNG" +f.read(self.size-4)
|
74
|
+
else
|
75
|
+
icondir = [
|
76
|
+
0, # Reserved. Must always be 0.
|
77
|
+
1, # image type: 1 for icon (.ICO), 2 for cursor (.CUR). Other values are invalid
|
78
|
+
1, # number of images in the file
|
79
|
+
].pack("v3")
|
80
|
+
bitmap_hdr = data.first # BITMAPINFOHEADER
|
81
|
+
icondirentry = ICODIRENTRY.new(
|
82
|
+
bitmap_hdr.biWidth,
|
83
|
+
bitmap_hdr.biHeight / (%w'ICON CURSOR'.include?(type) ? 2 : 1),
|
84
|
+
0, # XXX: bColors: may be wrong here
|
85
|
+
0,
|
86
|
+
1,
|
87
|
+
bitmap_hdr.biBitCount,
|
88
|
+
bitmap_hdr.biSizeImage,
|
89
|
+
icondir.size + 2 + ICODIRENTRY::SIZE # offset of BMP data from the beginning of ICO file
|
90
|
+
)
|
91
|
+
# ICONDIRENTRY is 2 bytes larger than ICODIRENTRY
|
92
|
+
icondir + icondirentry.pack + "\x00\x00" + bitmap_hdr.pack + f.read(self.size)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# only valid for types BITMAP, ICON & CURSOR
|
68
98
|
def bitmap_mask src_fname
|
69
99
|
File.open(src_fname, "rb") do |f|
|
70
100
|
parse f
|
@@ -175,14 +205,21 @@ class PEdump
|
|
175
205
|
end
|
176
206
|
|
177
207
|
def validate
|
178
|
-
self.valid =
|
208
|
+
self.valid = self.file_offset &&
|
179
209
|
case type
|
180
210
|
when 'BITMAP','ICON','CURSOR'
|
181
211
|
data.any?{ |x| x.is_a?(BITMAPINFOHEADER) && x.valid? } || data.first == 'PNG'
|
212
|
+
when 'GROUP_ICON'
|
213
|
+
# rough validation
|
214
|
+
data.first.is_a?(CUR_ICO_HEADER) && data.size == data.first.wNumImages.to_i+1
|
182
215
|
else
|
183
216
|
true
|
184
217
|
end
|
185
218
|
end
|
219
|
+
|
220
|
+
def valid?
|
221
|
+
valid
|
222
|
+
end
|
186
223
|
end
|
187
224
|
|
188
225
|
STRING = Struct.new(:id, :lang, :value)
|
data/lib/pedump/sig_parser.rb
CHANGED
@@ -171,10 +171,10 @@ class PEdump
|
|
171
171
|
return if a_bad.include?(a_cur)
|
172
172
|
|
173
173
|
# too short signatures
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
174
|
+
if sig.re.split.delete_if{ |x| x['?'] }.size < 3
|
175
|
+
require 'awesome_print'
|
176
|
+
puts sig.inspect.red
|
177
|
+
end
|
178
178
|
|
179
179
|
# fs.txt contains a lot of signatures that copied from other sources
|
180
180
|
# BUT have all 01 replaced with '??'
|
@@ -216,10 +216,18 @@ class PEdump
|
|
216
216
|
'DLL','(DLL)','[DLL]',
|
217
217
|
'[LZMA]','(LZMA)','LZMA',
|
218
218
|
'-','~','(pack)','(1)','(2)',
|
219
|
-
'19??'
|
219
|
+
'19??',
|
220
|
+
'with:', 'with?'
|
220
221
|
]
|
221
222
|
end
|
222
|
-
return if d.all?(&:empty?) # no different words
|
223
|
+
return if d.all?(&:empty?) # no different words => can keep ANY name
|
224
|
+
|
225
|
+
|
226
|
+
# if name1 =~ /pecompact/i
|
227
|
+
# require 'awesome_print'
|
228
|
+
# puts "[d] #{name1}".yellow
|
229
|
+
# puts "[d] #{name2}".yellow
|
230
|
+
# end
|
223
231
|
|
224
232
|
# [["v1.14/v1.20"], ["v1.14,", "v1.20"]]]
|
225
233
|
# [["EXEShield", "v0.3b/v0.3", "v0.6"], ["Shield", "v0.3b,", "v0.3"]]]
|
@@ -233,21 +241,53 @@ class PEdump
|
|
233
241
|
end
|
234
242
|
end
|
235
243
|
|
244
|
+
# require 'awesome_print'
|
245
|
+
# puts "[d] #{name1.yellow} #{name2.green}"
|
246
|
+
|
236
247
|
a = name1.split
|
237
248
|
b = name2.split
|
249
|
+
|
250
|
+
# merge common head
|
238
251
|
new_name_head = []
|
239
252
|
while a.any? && b.any? && a.first.upcase == b.first.upcase
|
240
253
|
new_name_head << a.shift
|
241
254
|
b.shift
|
242
255
|
end
|
256
|
+
|
257
|
+
# merge common tail
|
243
258
|
new_name_tail = []
|
244
259
|
while a.any? && b.any? && a.last.upcase == b.last.upcase
|
245
260
|
new_name_tail.unshift a.pop
|
246
261
|
b.pop
|
247
262
|
end
|
263
|
+
|
264
|
+
# rm common words from middle
|
265
|
+
separators = [ "/", "->" ]
|
266
|
+
was = true
|
267
|
+
while was
|
268
|
+
was = false
|
269
|
+
b.each do |bw|
|
270
|
+
next if bw == "/" || bw == "->"
|
271
|
+
if a.include?(bw) || a.include?(bw+")") || a.include?("("+bw) || a.include?("(#{bw})")
|
272
|
+
b -= [bw]
|
273
|
+
was = true
|
274
|
+
break
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
while separators.include?(b.last)
|
279
|
+
b.pop
|
280
|
+
end
|
281
|
+
|
248
282
|
new_name = new_name_head
|
249
283
|
new_name << [a.join(' '), b.join(' ')].delete_if{|x| x.empty?}.join(' / ')
|
250
284
|
new_name += new_name_tail
|
285
|
+
# if name1 =~ /pecompact/i
|
286
|
+
# p a
|
287
|
+
# p b
|
288
|
+
# p new_name_tail
|
289
|
+
# puts "[=] #{new_name.inspect}".red
|
290
|
+
# end
|
251
291
|
new_name = new_name.join(' ')
|
252
292
|
end
|
253
293
|
|
@@ -291,14 +331,16 @@ class PEdump
|
|
291
331
|
if rd = _re_diff(sig1.re, sig2.re, max_diff)
|
292
332
|
if rd.all?{ |x| x[0].nil? || x[0] == '.' } && sig2.re.size >= sig1.re.size
|
293
333
|
if new_name = _merge_names(sig2.name, sig1.name)
|
294
|
-
|
334
|
+
# require 'pp'
|
335
|
+
# pp ["FIRST", sig1.name, sig2.name, new_name, sig1.re.join, sig2.re.join] if new_name =~ /pecompact/i
|
295
336
|
sig1.name = new_name
|
296
337
|
end
|
297
338
|
sig2.ep_only ||= sig1.ep_only
|
298
339
|
sig2.re = []
|
299
340
|
elsif rd.all?{ |x| x[1].nil? || x[1] == '.' } && sig1.re.size >= sig2.re.size
|
300
341
|
if new_name = _merge_names(sig2.name, sig1.name)
|
301
|
-
|
342
|
+
# require 'pp'
|
343
|
+
# pp ["SECOND", sig1.name, sig2.name, new_name, sig1.re.join, sig2.re.join] if new_name =~ /pecompact/i
|
302
344
|
sig2.name = new_name
|
303
345
|
end
|
304
346
|
sig1.re = []
|
@@ -350,18 +392,18 @@ class PEdump
|
|
350
392
|
def optimize sigs
|
351
393
|
optimize_names sigs
|
352
394
|
|
353
|
-
|
395
|
+
# XXX no optimize from now, prefer more precise sigs
|
396
|
+
#print "[.] sigs merge: #{sigs.size}"; _optimize(sigs); puts " -> #{sigs.size}"
|
354
397
|
|
355
398
|
# try to merge signatures with same name, size & ep_only
|
356
|
-
sigs.group_by{ |sig|
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
399
|
+
sigs.group_by{ |sig| [sig.re.size, sig.name, sig.ep_only] }.
|
400
|
+
values.each do |a|
|
401
|
+
next if a.size == 1
|
402
|
+
if merged_re = _merge(a)
|
403
|
+
a.first.re = merged_re
|
404
|
+
a[1..-1].each{ |sig| sig.re = nil }
|
405
|
+
end
|
363
406
|
end
|
364
|
-
end
|
365
407
|
print "[.] sigs merge: #{sigs.size}"; sigs.delete_if{ |x| x.re.nil? }; puts " -> #{sigs.size}"
|
366
408
|
|
367
409
|
|
@@ -439,6 +481,7 @@ class PEdump
|
|
439
481
|
end
|
440
482
|
prev_eq = eq
|
441
483
|
end
|
484
|
+
dstart ||= 0
|
442
485
|
r = dstart..dend
|
443
486
|
r == (0..(size-1)) ? nil : r
|
444
487
|
end
|
data/lib/pedump/version.rb
CHANGED
data/pedump.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "pedump"
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.16"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Andrey \"Zed\" Zaikin"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2013-01-03"
|
13
13
|
s.description = "dump headers, sections, extract resources of win32 PE exe,dll,etc"
|
14
14
|
s.email = "zed.0xff@gmail.com"
|
15
15
|
s.executables = ["pedump"]
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: pedump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.4.
|
5
|
+
version: 0.4.16
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Andrey "Zed" Zaikin
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
prerelease: false
|
@@ -215,7 +215,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
215
|
version: '0'
|
216
216
|
segments:
|
217
217
|
- 0
|
218
|
-
hash: -
|
218
|
+
hash: -2417171475449588298
|
219
219
|
none: false
|
220
220
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
221
221
|
requirements:
|