pedump 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.
@@ -0,0 +1,10 @@
1
+ class PEdump
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 4
5
+ PATCH = 0
6
+ BUILD = nil
7
+
8
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
9
+ end
10
+ end
@@ -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
@@ -0,0 +1,87 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "pedump"
8
+ s.version = "0.4.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Andrey \"Zed\" Zaikin"]
12
+ s.date = "2011-12-17"
13
+ s.description = "dump headers, sections, extract resources of win32 PE exe,dll,etc"
14
+ s.email = "zed.0xff@gmail.com"
15
+ s.executables = ["pedump"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE.txt",
18
+ "README.md",
19
+ "README.md.tpl"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".rspec",
24
+ "Gemfile",
25
+ "Gemfile.lock",
26
+ "LICENSE.txt",
27
+ "README.md",
28
+ "README.md.tpl",
29
+ "Rakefile",
30
+ "VERSION",
31
+ "bin/pedump",
32
+ "data/fs.txt",
33
+ "data/sig.bin",
34
+ "data/signatures.txt",
35
+ "data/userdb.txt",
36
+ "lib/pedump.rb",
37
+ "lib/pedump/cli.rb",
38
+ "lib/pedump/packer.rb",
39
+ "lib/pedump/sig_parser.rb",
40
+ "lib/pedump/version.rb",
41
+ "lib/pedump/version_info.rb",
42
+ "pedump.gemspec",
43
+ "samples/calc.7z",
44
+ "samples/zlib.dll",
45
+ "spec/pedump_spec.rb",
46
+ "spec/resource_spec.rb",
47
+ "spec/sig_all_packers_spec.rb",
48
+ "spec/sig_spec.rb",
49
+ "spec/spec_helper.rb"
50
+ ]
51
+ s.homepage = "http://github.com/zed-0xff/pedump"
52
+ s.licenses = ["MIT"]
53
+ s.require_paths = ["lib"]
54
+ s.rubygems_version = "1.8.10"
55
+ s.summary = "dump win32 PE executable files with a pure ruby"
56
+
57
+ if s.respond_to? :specification_version then
58
+ s.specification_version = 3
59
+
60
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
61
+ s.add_runtime_dependency(%q<multipart-post>, ["~> 1.1.4"])
62
+ s.add_runtime_dependency(%q<progressbar>, ["~> 0.9.2"])
63
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
64
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
65
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
66
+ s.add_development_dependency(%q<rcov>, [">= 0"])
67
+ s.add_development_dependency(%q<awesome_print>, [">= 0"])
68
+ else
69
+ s.add_dependency(%q<multipart-post>, ["~> 1.1.4"])
70
+ s.add_dependency(%q<progressbar>, ["~> 0.9.2"])
71
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
72
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
73
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
74
+ s.add_dependency(%q<rcov>, [">= 0"])
75
+ s.add_dependency(%q<awesome_print>, [">= 0"])
76
+ end
77
+ else
78
+ s.add_dependency(%q<multipart-post>, ["~> 1.1.4"])
79
+ s.add_dependency(%q<progressbar>, ["~> 0.9.2"])
80
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
81
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
82
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
83
+ s.add_dependency(%q<rcov>, [">= 0"])
84
+ s.add_dependency(%q<awesome_print>, [">= 0"])
85
+ end
86
+ end
87
+
Binary file
Binary file
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
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
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
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'pedump'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pedump
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrey "Zed" Zaikin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: multipart-post
16
+ requirement: &70304131999160 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70304131999160
25
+ - !ruby/object:Gem::Dependency
26
+ name: progressbar
27
+ requirement: &70304131998620 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.9.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70304131998620
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70304131998140 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 2.3.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70304131998140
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: &70304131997660 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70304131997660
58
+ - !ruby/object:Gem::Dependency
59
+ name: jeweler
60
+ requirement: &70304131997180 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.6.4
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70304131997180
69
+ - !ruby/object:Gem::Dependency
70
+ name: rcov
71
+ requirement: &70304131996680 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
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
91
+ description: dump headers, sections, extract resources of win32 PE exe,dll,etc
92
+ email: zed.0xff@gmail.com
93
+ executables:
94
+ - pedump
95
+ extensions: []
96
+ extra_rdoc_files:
97
+ - LICENSE.txt
98
+ - README.md
99
+ - README.md.tpl
100
+ files:
101
+ - .document
102
+ - .rspec
103
+ - Gemfile
104
+ - Gemfile.lock
105
+ - LICENSE.txt
106
+ - README.md
107
+ - README.md.tpl
108
+ - Rakefile
109
+ - VERSION
110
+ - bin/pedump
111
+ - data/fs.txt
112
+ - data/sig.bin
113
+ - data/signatures.txt
114
+ - data/userdb.txt
115
+ - lib/pedump.rb
116
+ - lib/pedump/cli.rb
117
+ - lib/pedump/packer.rb
118
+ - lib/pedump/sig_parser.rb
119
+ - lib/pedump/version.rb
120
+ - lib/pedump/version_info.rb
121
+ - pedump.gemspec
122
+ - samples/calc.7z
123
+ - samples/zlib.dll
124
+ - spec/pedump_spec.rb
125
+ - spec/resource_spec.rb
126
+ - spec/sig_all_packers_spec.rb
127
+ - spec/sig_spec.rb
128
+ - spec/spec_helper.rb
129
+ homepage: http://github.com/zed-0xff/pedump
130
+ licenses:
131
+ - MIT
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ segments:
143
+ - 0
144
+ hash: 2685694954412936403
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubyforge_project:
153
+ rubygems_version: 1.8.10
154
+ signing_key:
155
+ specification_version: 3
156
+ summary: dump win32 PE executable files with a pure ruby
157
+ test_files: []