pedump 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,8 @@
1
1
  class PEdump
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 3
5
- PATCH = 3
4
+ MINOR = 4
5
+ PATCH = 0
6
6
  BUILD = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
@@ -0,0 +1,166 @@
1
+ class PEdump
2
+ class VS_VERSIONINFO < PEdump.create_struct( 'v3a32v',
3
+ :wLength,
4
+ :wValueLength,
5
+ :wType,
6
+ :szKey, # The Unicode string L"VS_VERSION_INFO".
7
+ :Padding1,
8
+ # manual:
9
+ :Value, # VS_FIXEDFILEINFO
10
+ :Padding2,
11
+ :Children
12
+ )
13
+ def self.read f, size = SIZE
14
+ super.tap do |vi|
15
+ vi.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
16
+ vi.Padding1 = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
17
+ vi.Value = VS_FIXEDFILEINFO.read(f,vi.wValueLength)
18
+ # As many zero words as necessary to align the Children member on a 32-bit boundary.
19
+ # These bytes are not included in wValueLength. This member is optional.
20
+ vi.Padding2 = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
21
+ vi.Children = [] # An array of zero or one StringFileInfo structures,
22
+ # and zero or one VarFileInfo structures
23
+
24
+ 2.times do
25
+ pos = f.tell
26
+ f.seek(pos+6) # seek 6 bytes forward
27
+ t = f.read(6)
28
+ f.seek(pos) # return back
29
+ case t
30
+ when "V\x00a\x00r\x00"
31
+ vi.Children << VarFileInfo.read(f)
32
+ when "S\x00t\x00r\x00"
33
+ vi.Children << StringFileInfo.read(f)
34
+ else
35
+ PEdump.logger.warn "[?] invalid VS_VERSIONINFO child type #{t.inspect}"
36
+ break
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ class VS_FIXEDFILEINFO < PEdump.create_struct( 'V13',
44
+ :dwSignature,
45
+ :dwStrucVersion,
46
+ :dwFileVersionMS,
47
+ :dwFileVersionLS,
48
+ :dwProductVersionMS,
49
+ :dwProductVersionLS,
50
+ :dwFileFlagsMask,
51
+ :dwFileFlags,
52
+ :dwFileOS,
53
+ :dwFileType,
54
+ :dwFileSubtype,
55
+ :dwFileDateMS,
56
+ :dwFileDateLS,
57
+ # manual:
58
+ :valid
59
+ )
60
+ def self.read f, size = SIZE
61
+ super.tap do |ffi|
62
+ ffi.valid = (ffi.dwSignature == 0xFEEF04BD)
63
+ end
64
+ end
65
+ end
66
+
67
+ class StringFileInfo < PEdump.create_struct( 'v3a30',
68
+ :wLength,
69
+ :wValueLength, # always 0
70
+ :wType, # 1 => text data, 0 => binary data
71
+ :szKey, # The Unicode string L"StringFileInfo"
72
+ :Padding, # As many zero words as necessary to align the Children member on a 32-bit boundary
73
+ :Children # An array of one or more StringTable structures
74
+ )
75
+ def self.read f, size = SIZE
76
+ pos0 = f.tell
77
+ super.tap do |x|
78
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
79
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
80
+ x.Children = []
81
+ while !f.eof? && f.tell < pos0+x.wLength
82
+ x.Children << StringTable.read(f)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ class StringTable < PEdump.create_struct( 'v3a16v',
89
+ :wLength, # The length, in bytes, of this StringTable structure,
90
+ # including all structures indicated by the Children member.
91
+ :wValueLength, # always 0
92
+ :wType, # 1 => text data, 0 => binary data
93
+ :szKey, # An 8-digit hexadecimal number stored as a Unicode string
94
+ :Padding, # As many zero words as necessary to align the Children member on a 32-bit boundary
95
+ :Children # An array of one or more String structures.
96
+ )
97
+ def self.read f, size = SIZE
98
+ pos0 = f.tell
99
+ super.tap do |x|
100
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
101
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
102
+ x.Children = []
103
+ while !f.eof? && f.tell < pos0+x.wLength
104
+ x.Children << VersionString.read(f)
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ class VersionString < PEdump.create_struct( 'v3',
111
+ :wLength, # The length, in bytes, of this String structure.
112
+ :wValueLength, # The size, in words, of the Value member
113
+ :wType, # 1 => text data, 0 => binary data
114
+ :szKey, # An arbitrary Unicode string
115
+ :Padding, # As many zero words as necessary to align the Value member on a 32-bit boundary
116
+ :Value # A zero-terminated string. See the szKey member description for more information
117
+ )
118
+ def self.read f, size = SIZE
119
+ super.tap do |x|
120
+ x.szKey = ''
121
+ x.szKey << f.read(2) until x.szKey[-2..-1] == "\x00\x00" || f.eof?
122
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
123
+ x.Value = f.read(x.wValueLength*2)
124
+ if f.tell%4 > 0
125
+ f.read(4-f.tell%4) # undoc padding?
126
+ end
127
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
128
+ x.Value.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
129
+ end
130
+ end
131
+ end
132
+
133
+ class VarFileInfo < PEdump.create_struct( 'v3a24v',
134
+ :wLength,
135
+ :wValueLength, # always 0
136
+ :wType, # 1 => text data, 0 => binary data
137
+ :szKey, # The Unicode string L"VarFileInfo"
138
+ :Padding, # As many zero words as necessary to align the Children member on a 32-bit boundary
139
+ :Children # Typically contains a list of languages that the application or DLL supports
140
+ )
141
+ def self.read f, size = SIZE
142
+ super.tap do |x|
143
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
144
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
145
+ x.Children = Var.read(f)
146
+ end
147
+ end
148
+ end
149
+
150
+ class Var < PEdump.create_struct( 'v3a24',
151
+ :wLength,
152
+ :wValueLength, # The length, in bytes, of the Value member
153
+ :wType, # 1 => text data, 0 => binary data
154
+ :szKey, # The Unicode string L"Translation"
155
+ :Padding, # As many zero words as necessary to align the Children member on a 32-bit boundary
156
+ :Value # An array of one or more values that are language and code page identifier pairs
157
+ )
158
+ def self.read f, size = SIZE
159
+ super.tap do |x|
160
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
161
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
162
+ x.Value = f.read(x.wValueLength).unpack('v*')
163
+ end
164
+ end
165
+ end
166
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "pedump"
8
- s.version = "0.3.3"
8
+ s.version = "0.4.0"
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 = "2011-12-13"
12
+ s.date = "2011-12-17"
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,15 +29,23 @@ Gem::Specification.new do |s|
29
29
  "Rakefile",
30
30
  "VERSION",
31
31
  "bin/pedump",
32
+ "data/fs.txt",
32
33
  "data/sig.bin",
33
- "data/sig.txt",
34
+ "data/signatures.txt",
35
+ "data/userdb.txt",
34
36
  "lib/pedump.rb",
35
37
  "lib/pedump/cli.rb",
36
38
  "lib/pedump/packer.rb",
39
+ "lib/pedump/sig_parser.rb",
37
40
  "lib/pedump/version.rb",
41
+ "lib/pedump/version_info.rb",
38
42
  "pedump.gemspec",
39
43
  "samples/calc.7z",
44
+ "samples/zlib.dll",
40
45
  "spec/pedump_spec.rb",
46
+ "spec/resource_spec.rb",
47
+ "spec/sig_all_packers_spec.rb",
48
+ "spec/sig_spec.rb",
41
49
  "spec/spec_helper.rb"
42
50
  ]
43
51
  s.homepage = "http://github.com/zed-0xff/pedump"
@@ -56,6 +64,7 @@ Gem::Specification.new do |s|
56
64
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
57
65
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
58
66
  s.add_development_dependency(%q<rcov>, [">= 0"])
67
+ s.add_development_dependency(%q<awesome_print>, [">= 0"])
59
68
  else
60
69
  s.add_dependency(%q<multipart-post>, ["~> 1.1.4"])
61
70
  s.add_dependency(%q<progressbar>, ["~> 0.9.2"])
@@ -63,6 +72,7 @@ Gem::Specification.new do |s|
63
72
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
64
73
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
65
74
  s.add_dependency(%q<rcov>, [">= 0"])
75
+ s.add_dependency(%q<awesome_print>, [">= 0"])
66
76
  end
67
77
  else
68
78
  s.add_dependency(%q<multipart-post>, ["~> 1.1.4"])
@@ -71,6 +81,7 @@ Gem::Specification.new do |s|
71
81
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
72
82
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
73
83
  s.add_dependency(%q<rcov>, [">= 0"])
84
+ s.add_dependency(%q<awesome_print>, [">= 0"])
74
85
  end
75
86
  end
76
87
 
Binary file
@@ -1,7 +1,7 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "Pedump" do
4
- it "fails" do
5
- fail "hey buddy, you should probably rename this file and start specing for real"
6
- end
4
+ # it "fails" do
5
+ # fail "hey buddy, you should probably rename this file and start specing for real"
6
+ # end
7
7
  end
@@ -0,0 +1,13 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump')
3
+
4
+ describe 'PEdump' do
5
+ it "should get all resources" do
6
+ fname = File.expand_path(File.dirname(__FILE__) + '/../samples/calc.exe')
7
+ File.open(fname,"rb") do |f|
8
+ @pedump = PEdump.new(fname)
9
+ @resources = @pedump.resources(f)
10
+ end
11
+ @resources.size.should == 71
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump/packer')
3
+
4
+ describe "PEdump::Packer" do
5
+ describe "matchers" do
6
+ PEdump::SigParser.parse(:raw => true).each do |sig|
7
+ data = sig.re.join
8
+ next if data == "This program cannot be run in DOS mo"
9
+ it "should find #{sig.name}" do
10
+ PEdump::Packer.of(data).map(&:name).should include(sig.name)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,63 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump/packer')
3
+
4
+ describe "PEdump::Packer" do
5
+ it "should have enough signatures" do
6
+ PEdump::Packer.count.should > 1000
7
+ end
8
+
9
+ it "should not match" do
10
+ maxlen = PEdump::Packer.map(&:size).max
11
+ s = 'x'*maxlen
12
+ PEdump::Packer.of_data(s).should be_nil
13
+ end
14
+
15
+ it "should parse" do
16
+ a = PEdump::SigParser.parse
17
+ a.should be_instance_of(Array)
18
+ a.map(&:class).uniq.should == [PEdump::Packer]
19
+ end
20
+
21
+ it "should not react to DOS signature" do
22
+ data = "This program cannot be run in DOS mode"
23
+ PEdump::Packer.of(data).should be_nil
24
+ end
25
+
26
+ it "should match sigs" do
27
+ n = 0
28
+ File.open('data/signatures.txt', 'r:cp1252') do |f|
29
+ while row = f.gets
30
+ row.strip!
31
+ next unless row =~ /^\[(.*)=(.*)\]$/
32
+ s = ''
33
+ title,hexstring = $1,$2
34
+ (hexstring.size/2).times do |i|
35
+ c = hexstring[i*2,2]
36
+ if c == '::'
37
+ s << '.'
38
+ else
39
+ s << c.to_i(16).chr
40
+ end
41
+ end
42
+ packers = PEdump::Packer.of(s)
43
+ if packers
44
+ names = packers.map(&:name)
45
+ next if names.any? do |name|
46
+ a = name.upcase.tr('V','')
47
+ b = title.upcase.tr('V','')
48
+ a[b] || b[a]
49
+ end
50
+ # puts "[.] #{title}"
51
+ # names.each do |x|
52
+ # puts "\t= #{x}"
53
+ # end
54
+ else
55
+ puts "[?] #{title}"
56
+ n += 1
57
+ end
58
+ end
59
+ end
60
+ #puts "[.] diff = #{n}"
61
+ n.should == 0
62
+ end
63
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pedump
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-13 00:00:00.000000000 Z
12
+ date: 2011-12-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multipart-post
16
- requirement: &70135365235740 !ruby/object:Gem::Requirement
16
+ requirement: &70304131999160 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.1.4
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70135365235740
24
+ version_requirements: *70304131999160
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: progressbar
27
- requirement: &70135365807020 !ruby/object:Gem::Requirement
27
+ requirement: &70304131998620 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.2
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70135365807020
35
+ version_requirements: *70304131998620
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70135365806000 !ruby/object:Gem::Requirement
38
+ requirement: &70304131998140 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.3.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70135365806000
46
+ version_requirements: *70304131998140
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &70135365804780 !ruby/object:Gem::Requirement
49
+ requirement: &70304131997660 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70135365804780
57
+ version_requirements: *70304131997660
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: jeweler
60
- requirement: &70135365803680 !ruby/object:Gem::Requirement
60
+ requirement: &70304131997180 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.6.4
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70135365803680
68
+ version_requirements: *70304131997180
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rcov
71
- requirement: &70135365802300 !ruby/object:Gem::Requirement
71
+ requirement: &70304131996680 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,18 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70135365802300
79
+ version_requirements: *70304131996680
80
+ - !ruby/object:Gem::Dependency
81
+ name: awesome_print
82
+ requirement: &70304131996200 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70304131996200
80
91
  description: dump headers, sections, extract resources of win32 PE exe,dll,etc
81
92
  email: zed.0xff@gmail.com
82
93
  executables:
@@ -97,15 +108,23 @@ files:
97
108
  - Rakefile
98
109
  - VERSION
99
110
  - bin/pedump
111
+ - data/fs.txt
100
112
  - data/sig.bin
101
- - data/sig.txt
113
+ - data/signatures.txt
114
+ - data/userdb.txt
102
115
  - lib/pedump.rb
103
116
  - lib/pedump/cli.rb
104
117
  - lib/pedump/packer.rb
118
+ - lib/pedump/sig_parser.rb
105
119
  - lib/pedump/version.rb
120
+ - lib/pedump/version_info.rb
106
121
  - pedump.gemspec
107
122
  - samples/calc.7z
123
+ - samples/zlib.dll
108
124
  - spec/pedump_spec.rb
125
+ - spec/resource_spec.rb
126
+ - spec/sig_all_packers_spec.rb
127
+ - spec/sig_spec.rb
109
128
  - spec/spec_helper.rb
110
129
  homepage: http://github.com/zed-0xff/pedump
111
130
  licenses:
@@ -122,7 +141,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
141
  version: '0'
123
142
  segments:
124
143
  - 0
125
- hash: -3106600206779889876
144
+ hash: 2685694954412936403
126
145
  required_rubygems_version: !ruby/object:Gem::Requirement
127
146
  none: false
128
147
  requirements: