pedump 0.4.14 → 0.4.15
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.
- data/Gemfile +1 -1
- data/Gemfile.lock +0 -2
- data/Rakefile +6 -5
- data/VERSION +1 -1
- data/data/fs.txt +37 -1408
- data/data/jc-userdb.txt +14371 -0
- data/data/sig.bin +0 -0
- data/lib/pedump/sig_parser.rb +89 -11
- data/lib/pedump/version.rb +1 -1
- data/pedump.gemspec +3 -5
- data/spec/sig_spec.rb +6 -1
- metadata +33 -48
data/data/sig.bin
CHANGED
Binary file
|
data/lib/pedump/sig_parser.rb
CHANGED
@@ -6,9 +6,14 @@ class PEdump
|
|
6
6
|
TEXT_SIGS_FILES = [
|
7
7
|
File.join(DATA_ROOT, "data", "userdb.txt"),
|
8
8
|
File.join(DATA_ROOT, "data", "signatures.txt"),
|
9
|
-
File.join(DATA_ROOT, "data", "
|
9
|
+
File.join(DATA_ROOT, "data", "jc-userdb.txt"),
|
10
|
+
File.join(DATA_ROOT, "data", "fs.txt"), # has special parse options!
|
10
11
|
]
|
11
12
|
|
13
|
+
SPECIAL_PARSE_OPTIONS = {
|
14
|
+
File.join(DATA_ROOT, "data", "fs.txt") => {:fix1 => true}
|
15
|
+
}
|
16
|
+
|
12
17
|
class OrBlock < Array; end
|
13
18
|
|
14
19
|
class << self
|
@@ -19,19 +24,20 @@ class PEdump
|
|
19
24
|
sigs = {}; sig = nil
|
20
25
|
|
21
26
|
args[:fnames].each do |fname|
|
22
|
-
n0 = sigs.size
|
27
|
+
n0 = sigs.size; add_sig_args = args.dup
|
28
|
+
add_sig_args.merge!(SPECIAL_PARSE_OPTIONS[fname] || {})
|
23
29
|
File.open(fname,'r:utf-8') do |f|
|
24
30
|
while line = f.gets
|
25
31
|
case line.strip
|
26
32
|
when /^[<;#]/, /^$/ # comments & blank lines
|
27
33
|
next
|
28
34
|
when /^\[(.+)=(.+)\]$/
|
29
|
-
_add_sig(sigs, Packer.new($1, $2, true),
|
30
|
-
when /^\[([^=]+)\]
|
35
|
+
_add_sig(sigs, Packer.new($1, $2, true), add_sig_args )
|
36
|
+
when /^\[([^=]+)\](\s+\/\/.+)?$/
|
31
37
|
sig = Packer.new($1)
|
32
38
|
when /^signature = (.+)$/
|
33
39
|
sig.re = $1
|
34
|
-
_add_sig(sigs, sig,
|
40
|
+
_add_sig(sigs, sig, add_sig_args)
|
35
41
|
when /^ep_only = (.+)$/
|
36
42
|
sig.ep_only = ($1.strip.downcase == 'true')
|
37
43
|
else raise line
|
@@ -61,7 +67,13 @@ class PEdump
|
|
61
67
|
when /\A[a-f0-9]{2}\Z/i
|
62
68
|
x = x.to_i(16).chr
|
63
69
|
bins[sig] << x
|
64
|
-
args[:raw]
|
70
|
+
if args[:raw]
|
71
|
+
x
|
72
|
+
elsif args[:raword]
|
73
|
+
x.ord
|
74
|
+
else
|
75
|
+
Regexp::escape(x)
|
76
|
+
end
|
65
77
|
else
|
66
78
|
puts "[?] unknown re element: #{x.inspect} in #{sig.inspect}" if args[:verbose]
|
67
79
|
"BAD_RE"
|
@@ -72,10 +84,10 @@ class PEdump
|
|
72
84
|
a = sig.name.split(/-+>/,2).map(&:strip)
|
73
85
|
sig.name = "#{a[0]} (#{a[1]})"
|
74
86
|
end
|
75
|
-
sig.re.pop while sig.re.last == '??'
|
87
|
+
sig.re.pop while sig.re && sig.re.last == '??'
|
76
88
|
end
|
77
89
|
sigs.delete_if{ |sig| !sig.re || sig.re.index('BAD_RE') }
|
78
|
-
return sigs if args[:raw]
|
90
|
+
return sigs if args[:raw] || args[:raword]
|
79
91
|
|
80
92
|
# require 'awesome_print'
|
81
93
|
# bins.each do |bin_sig, bin|
|
@@ -125,6 +137,9 @@ class PEdump
|
|
125
137
|
# bad sigs
|
126
138
|
return if sig.re[/\A538BD833C0A30:::::/]
|
127
139
|
return if sig.name == "Name of the Packer v1.0"
|
140
|
+
return if sig.name == "Alias PIX/Vivid IMG Graphics format"
|
141
|
+
return if sig.name == "JAR Archive"
|
142
|
+
return if sig.name == "Turbo / Borland Pascal v7.x Unit"
|
128
143
|
return if sig.re == "54 68 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 6D 6F" # dos stub
|
129
144
|
|
130
145
|
sig.name.sub!(/^\*\s+/, '')
|
@@ -135,10 +150,47 @@ class PEdump
|
|
135
150
|
sig.name.sub! 'RLP ','RLPack '
|
136
151
|
sig.name.sub! '.beta', ' beta'
|
137
152
|
sig.name.sub! '(com)','[com]'
|
153
|
+
sig.name.gsub!(/ V(\d)/, " v\\1") # V1.1 -> v1.1
|
138
154
|
sig.name = sig.name.split(/\s*-+>\s*/).join(' -> ') # fix spaces around '->'
|
155
|
+
sig.name = sig.name.split(' ').delete_if do |x|
|
156
|
+
# delete words: vX.X, v?.?, ?.?, x.x
|
157
|
+
x =~ /\Av?[?x]\.[?x]\Z/i
|
158
|
+
end.join(' ')
|
139
159
|
|
140
160
|
sig.re = sig.re.strip.upcase.tr(':','?')
|
141
161
|
sig.re = sig.re.scan(/../).join(' ') if sig.re.split.first.size > 2
|
162
|
+
|
163
|
+
# sig contains entirely zeroes or masks or only both
|
164
|
+
a_bad = [%w'00', %w'??', %w'00 ??', %w'90', %w'90 ??']
|
165
|
+
# ?a, 0? => ??, ??
|
166
|
+
a_cur = sig.re.split.map{ |x| x['?'] ? '??' : x }.uniq.sort
|
167
|
+
return if a_bad.include?(a_cur)
|
168
|
+
|
169
|
+
# first byte is unique and all others are zeroes or masks
|
170
|
+
a_cur = sig.re.split[1..-1].map{ |x| x['?'] ? '??' : x }.uniq.sort
|
171
|
+
return if a_bad.include?(a_cur)
|
172
|
+
|
173
|
+
# too short signatures
|
174
|
+
# if sig.re.split.delete_if{ |x| x['?'] }.size < 6
|
175
|
+
# require 'awesome_print'
|
176
|
+
# puts sig.inspect.red
|
177
|
+
# end
|
178
|
+
|
179
|
+
# fs.txt contains a lot of signatures that copied from other sources
|
180
|
+
# BUT have all 01 replaced with '??'
|
181
|
+
# // replaced the file with filtered one (see 'fs-good' below) // zzz
|
182
|
+
if args[:fix1]
|
183
|
+
sigs.keys.each do |re|
|
184
|
+
if re.gsub("01","??") == sig.re
|
185
|
+
puts "[.] fix1: rejecting #{sig.name} - already present with 01 in place" if args[:verbose]
|
186
|
+
return
|
187
|
+
end
|
188
|
+
end
|
189
|
+
# File.open("fs-good.txt","a") do |f|
|
190
|
+
# f << "[#{sig.name}=#{sig.re.tr(' ','')}]\n"
|
191
|
+
# end
|
192
|
+
end
|
193
|
+
|
142
194
|
if sigs[sig.re]
|
143
195
|
a = [sig, sigs[sig.re]].map{ |x| x.name.upcase.split('->').first.tr('V ','') }
|
144
196
|
return if a[0][a[1]] || a[1][a[0]]
|
@@ -161,7 +213,6 @@ class PEdump
|
|
161
213
|
d.map! do |x|
|
162
214
|
x - [
|
163
215
|
'EXE','[EXE]',
|
164
|
-
'vx.x','v?.?',
|
165
216
|
'DLL','(DLL)','[DLL]',
|
166
217
|
'[LZMA]','(LZMA)','LZMA',
|
167
218
|
'-','~','(pack)','(1)','(2)',
|
@@ -264,14 +315,41 @@ class PEdump
|
|
264
315
|
sigs.delete_if{ |sig| sig.re.empty? }
|
265
316
|
end
|
266
317
|
|
267
|
-
def
|
318
|
+
def _name2wordonly name
|
319
|
+
name.downcase.split(/[^a-z0-9_.]+/).join(' ').strip
|
320
|
+
end
|
321
|
+
|
322
|
+
def optimize_names sigs
|
268
323
|
# replaces all duplicate names with references to one name
|
269
324
|
# saves ~30k out of ~200k mem
|
270
325
|
h = {}
|
326
|
+
|
327
|
+
# find shortest names
|
271
328
|
sigs.each do |sig|
|
272
|
-
|
329
|
+
t = _name2wordonly(sig.name)
|
330
|
+
if h[t]
|
331
|
+
# keep shortest name
|
332
|
+
if h[t] != sig.name
|
333
|
+
#print "[d] #{[h[t], sig.name].inspect} -> "
|
334
|
+
h[t] = [h[t], sig.name].sort_by(&:size).first
|
335
|
+
#puts h[t]
|
336
|
+
else
|
337
|
+
# fully identical names
|
338
|
+
end
|
339
|
+
else
|
340
|
+
h[t] = sig.name
|
341
|
+
end
|
273
342
|
end
|
274
343
|
|
344
|
+
# assign names back to sigs
|
345
|
+
sigs.each{ |sig| sig.name = h[_name2wordonly(sig.name)] }
|
346
|
+
|
347
|
+
puts "[.] sigs merge: #{h.size} unique names"
|
348
|
+
end
|
349
|
+
|
350
|
+
def optimize sigs
|
351
|
+
optimize_names sigs
|
352
|
+
|
275
353
|
print "[.] sigs merge: #{sigs.size}"; _optimize(sigs); puts " -> #{sigs.size}"
|
276
354
|
|
277
355
|
# try to merge signatures with same name, size & ep_only
|
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.15"
|
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 = "2012-12-
|
12
|
+
s.date = "2012-12-28"
|
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"]
|
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
"VERSION",
|
30
30
|
"bin/pedump",
|
31
31
|
"data/fs.txt",
|
32
|
+
"data/jc-userdb.txt",
|
32
33
|
"data/sig.bin",
|
33
34
|
"data/signatures.txt",
|
34
35
|
"data/userdb.txt",
|
@@ -104,7 +105,6 @@ Gem::Specification.new do |s|
|
|
104
105
|
s.add_development_dependency(%q<bundler>, [">= 0"])
|
105
106
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
106
107
|
s.add_development_dependency(%q<what_methods>, [">= 0"])
|
107
|
-
s.add_development_dependency(%q<looksee>, [">= 0"])
|
108
108
|
else
|
109
109
|
s.add_dependency(%q<multipart-post>, ["~> 1.1.4"])
|
110
110
|
s.add_dependency(%q<progressbar>, [">= 0"])
|
@@ -113,7 +113,6 @@ Gem::Specification.new do |s|
|
|
113
113
|
s.add_dependency(%q<bundler>, [">= 0"])
|
114
114
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
115
115
|
s.add_dependency(%q<what_methods>, [">= 0"])
|
116
|
-
s.add_dependency(%q<looksee>, [">= 0"])
|
117
116
|
end
|
118
117
|
else
|
119
118
|
s.add_dependency(%q<multipart-post>, ["~> 1.1.4"])
|
@@ -123,7 +122,6 @@ Gem::Specification.new do |s|
|
|
123
122
|
s.add_dependency(%q<bundler>, [">= 0"])
|
124
123
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
125
124
|
s.add_dependency(%q<what_methods>, [">= 0"])
|
126
|
-
s.add_dependency(%q<looksee>, [">= 0"])
|
127
125
|
end
|
128
126
|
end
|
129
127
|
|
data/spec/sig_spec.rb
CHANGED
@@ -31,6 +31,11 @@ describe "PEdump::Packer" do
|
|
31
31
|
next unless row =~ /^\[(.*)=(.*)\]$/
|
32
32
|
s = ''
|
33
33
|
title,hexstring = $1,$2
|
34
|
+
|
35
|
+
# bad sigs
|
36
|
+
next if hexstring == '909090909090909090909090909090909090909090909090909090909090909090909090'
|
37
|
+
next if hexstring == 'E9::::0000000000000000'
|
38
|
+
|
34
39
|
(hexstring.size/2).times do |i|
|
35
40
|
c = hexstring[i*2,2]
|
36
41
|
if c == '::'
|
@@ -52,7 +57,7 @@ describe "PEdump::Packer" do
|
|
52
57
|
# puts "\t= #{x}"
|
53
58
|
# end
|
54
59
|
else
|
55
|
-
puts "[?] #{title}"
|
60
|
+
puts "[?] #{title}: #{hexstring}"
|
56
61
|
n += 1
|
57
62
|
end
|
58
63
|
end
|
metadata
CHANGED
@@ -1,144 +1,128 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pedump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.14
|
5
4
|
prerelease:
|
5
|
+
version: 0.4.15
|
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: 2012-12-
|
12
|
+
date: 2012-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
+
prerelease: false
|
16
|
+
type: :runtime
|
15
17
|
name: multipart-post
|
16
18
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
19
|
requirements:
|
19
20
|
- - ~>
|
20
21
|
- !ruby/object:Gem::Version
|
21
22
|
version: 1.1.4
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
23
|
none: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
25
|
requirements:
|
27
26
|
- - ~>
|
28
27
|
- !ruby/object:Gem::Version
|
29
28
|
version: 1.1.4
|
29
|
+
none: false
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
+
prerelease: false
|
32
|
+
type: :runtime
|
31
33
|
name: progressbar
|
32
34
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
35
|
requirements:
|
35
36
|
- - ! '>='
|
36
37
|
- !ruby/object:Gem::Version
|
37
38
|
version: '0'
|
38
|
-
type: :runtime
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
41
|
requirements:
|
43
42
|
- - ! '>='
|
44
43
|
- !ruby/object:Gem::Version
|
45
44
|
version: '0'
|
45
|
+
none: false
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
+
prerelease: false
|
48
|
+
type: :runtime
|
47
49
|
name: awesome_print
|
48
50
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
51
|
requirements:
|
51
52
|
- - ! '>='
|
52
53
|
- !ruby/object:Gem::Version
|
53
54
|
version: '0'
|
54
|
-
type: :runtime
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
55
|
none: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
57
|
requirements:
|
59
58
|
- - ! '>='
|
60
59
|
- !ruby/object:Gem::Version
|
61
60
|
version: '0'
|
61
|
+
none: false
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
+
prerelease: false
|
64
|
+
type: :development
|
63
65
|
name: rspec
|
64
66
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
67
|
requirements:
|
67
68
|
- - ! '>='
|
68
69
|
- !ruby/object:Gem::Version
|
69
70
|
version: '0'
|
70
|
-
type: :development
|
71
|
-
prerelease: false
|
72
|
-
version_requirements: !ruby/object:Gem::Requirement
|
73
71
|
none: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
73
|
requirements:
|
75
74
|
- - ! '>='
|
76
75
|
- !ruby/object:Gem::Version
|
77
76
|
version: '0'
|
77
|
+
none: false
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
+
prerelease: false
|
80
|
+
type: :development
|
79
81
|
name: bundler
|
80
82
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
83
|
requirements:
|
83
84
|
- - ! '>='
|
84
85
|
- !ruby/object:Gem::Version
|
85
86
|
version: '0'
|
86
|
-
type: :development
|
87
|
-
prerelease: false
|
88
|
-
version_requirements: !ruby/object:Gem::Requirement
|
89
87
|
none: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
89
|
requirements:
|
91
90
|
- - ! '>='
|
92
91
|
- !ruby/object:Gem::Version
|
93
92
|
version: '0'
|
93
|
+
none: false
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
|
+
prerelease: false
|
96
|
+
type: :development
|
95
97
|
name: jeweler
|
96
98
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
99
|
requirements:
|
99
100
|
- - ! '>='
|
100
101
|
- !ruby/object:Gem::Version
|
101
102
|
version: '0'
|
102
|
-
type: :development
|
103
|
-
prerelease: false
|
104
|
-
version_requirements: !ruby/object:Gem::Requirement
|
105
103
|
none: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
105
|
requirements:
|
107
106
|
- - ! '>='
|
108
107
|
- !ruby/object:Gem::Version
|
109
108
|
version: '0'
|
109
|
+
none: false
|
110
110
|
- !ruby/object:Gem::Dependency
|
111
|
+
prerelease: false
|
112
|
+
type: :development
|
111
113
|
name: what_methods
|
112
114
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
|
-
requirements:
|
115
|
-
- - ! '>='
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
115
|
requirements:
|
123
116
|
- - ! '>='
|
124
117
|
- !ruby/object:Gem::Version
|
125
118
|
version: '0'
|
126
|
-
- !ruby/object:Gem::Dependency
|
127
|
-
name: looksee
|
128
|
-
requirement: !ruby/object:Gem::Requirement
|
129
119
|
none: false
|
130
|
-
requirements:
|
131
|
-
- - ! '>='
|
132
|
-
- !ruby/object:Gem::Version
|
133
|
-
version: '0'
|
134
|
-
type: :development
|
135
|
-
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
122
|
- - ! '>='
|
140
123
|
- !ruby/object:Gem::Version
|
141
124
|
version: '0'
|
125
|
+
none: false
|
142
126
|
description: dump headers, sections, extract resources of win32 PE exe,dll,etc
|
143
127
|
email: zed.0xff@gmail.com
|
144
128
|
executables:
|
@@ -159,6 +143,7 @@ files:
|
|
159
143
|
- VERSION
|
160
144
|
- bin/pedump
|
161
145
|
- data/fs.txt
|
146
|
+
- data/jc-userdb.txt
|
162
147
|
- data/sig.bin
|
163
148
|
- data/signatures.txt
|
164
149
|
- data/userdb.txt
|
@@ -224,20 +209,20 @@ rdoc_options: []
|
|
224
209
|
require_paths:
|
225
210
|
- lib
|
226
211
|
required_ruby_version: !ruby/object:Gem::Requirement
|
227
|
-
none: false
|
228
212
|
requirements:
|
229
213
|
- - ! '>='
|
230
214
|
- !ruby/object:Gem::Version
|
231
215
|
version: '0'
|
232
216
|
segments:
|
233
217
|
- 0
|
234
|
-
hash: -
|
235
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
218
|
+
hash: -4443824394784718020
|
236
219
|
none: false
|
220
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
221
|
requirements:
|
238
222
|
- - ! '>='
|
239
223
|
- !ruby/object:Gem::Version
|
240
224
|
version: '0'
|
225
|
+
none: false
|
241
226
|
requirements: []
|
242
227
|
rubyforge_project:
|
243
228
|
rubygems_version: 1.8.24
|