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/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