pedump 0.3.3 → 0.4.0

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.
@@ -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: