pedump 0.4.14 → 0.4.15

Sign up to get free protection for your applications and to get access to all the features.
data/data/sig.bin CHANGED
Binary file
@@ -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", "fs.txt")
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), args )
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, args)
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] ? x : Regexp::escape(x)
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 optimize sigs
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
- sig.name = (h[sig.name] ||= sig.name)
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
@@ -2,7 +2,7 @@ class PEdump
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 4
5
- PATCH = 14
5
+ PATCH = 15
6
6
  BUILD = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
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.14"
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-17"
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-17 00:00:00.000000000 Z
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: -4041753216980716747
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