pedump 0.7.1 → 0.7.4
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +58 -50
- data/LICENSE.txt +1 -1
- data/README.md +26 -0
- data/Rakefile +10 -10
- data/VERSION +1 -1
- data/lib/pedump/cli.rb +19 -9
- data/lib/pedump/clr/readytorun.rb +1 -1
- data/lib/pedump/clr.rb +4 -4
- data/lib/pedump/loader/minidump.rb +7 -7
- data/lib/pedump/packer.rb +1 -1
- data/lib/pedump/resources.rb +1 -1
- data/lib/pedump/te.rb +19 -19
- data/lib/pedump/tls.rb +12 -14
- data/lib/pedump/unpacker/aspack.rb +3 -3
- data/lib/pedump.rb +29 -17
- data/pedump.gemspec +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0a9b3066ff9e670b8562e068856e45b94e82cbcaf27f95626da87abc09b94f8f
|
|
4
|
+
data.tar.gz: 6f05ee901ce249c363ccafd0f54a04e693c8fcefd4c6ecca2663169a6db2cefd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c8a3eae0788ed2e1723324d1c4409f88f922ab23db56e899b1624847879506677cd98a437ce0f5980012fd6c1d6f70cae43bec9f9f8f75ad9ca09e7aad2e9cb5
|
|
7
|
+
data.tar.gz: 410622db1bc1052d2bbb114ea6e2d92989004a06e72ebbf9efaade47e4bc95d15ca028122901eba2ed087d40c97df765bc0e68bd38c4a0527d10925dc1c3954f
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: https://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
activesupport (8.
|
|
4
|
+
activesupport (8.1.2)
|
|
5
5
|
base64
|
|
6
|
-
benchmark (>= 0.3)
|
|
7
6
|
bigdecimal
|
|
8
7
|
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
9
8
|
connection_pool (>= 2.2.5)
|
|
10
9
|
drb
|
|
11
10
|
i18n (>= 1.6, < 2)
|
|
11
|
+
json
|
|
12
12
|
logger (>= 1.4.2)
|
|
13
13
|
minitest (>= 5.1)
|
|
14
14
|
securerandom (>= 0.3)
|
|
15
15
|
tzinfo (~> 2.0, >= 2.0.5)
|
|
16
16
|
uri (>= 0.13.1)
|
|
17
|
-
addressable (2.8.
|
|
18
|
-
public_suffix (>= 2.0.2, <
|
|
17
|
+
addressable (2.8.8)
|
|
18
|
+
public_suffix (>= 2.0.2, < 8.0)
|
|
19
19
|
awesome_print (1.9.2)
|
|
20
|
-
base64 (0.
|
|
21
|
-
|
|
22
|
-
bigdecimal (3.1.9)
|
|
20
|
+
base64 (0.3.0)
|
|
21
|
+
bigdecimal (4.0.1)
|
|
23
22
|
builder (3.3.0)
|
|
24
|
-
concurrent-ruby (1.3.
|
|
25
|
-
connection_pool (
|
|
26
|
-
date (3.
|
|
23
|
+
concurrent-ruby (1.3.6)
|
|
24
|
+
connection_pool (3.0.2)
|
|
25
|
+
date (3.5.1)
|
|
27
26
|
descendants_tracker (0.0.4)
|
|
28
27
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
29
|
-
diff-lcs (1.6.
|
|
30
|
-
drb (2.2.
|
|
28
|
+
diff-lcs (1.6.2)
|
|
29
|
+
drb (2.2.3)
|
|
30
|
+
erb (6.0.1)
|
|
31
31
|
faraday (1.10.4)
|
|
32
32
|
faraday-em_http (~> 1.0)
|
|
33
33
|
faraday-em_synchrony (~> 1.0)
|
|
@@ -41,21 +41,21 @@ GEM
|
|
|
41
41
|
faraday-retry (~> 1.0)
|
|
42
42
|
ruby2_keywords (>= 0.0.4)
|
|
43
43
|
faraday-em_http (1.0.0)
|
|
44
|
-
faraday-em_synchrony (1.0.
|
|
44
|
+
faraday-em_synchrony (1.0.1)
|
|
45
45
|
faraday-excon (1.1.0)
|
|
46
46
|
faraday-httpclient (1.0.1)
|
|
47
|
-
faraday-multipart (1.
|
|
47
|
+
faraday-multipart (1.2.0)
|
|
48
48
|
multipart-post (~> 2.0)
|
|
49
49
|
faraday-net_http (1.0.2)
|
|
50
50
|
faraday-net_http_persistent (1.2.0)
|
|
51
51
|
faraday-patron (1.0.0)
|
|
52
52
|
faraday-rack (1.0.0)
|
|
53
53
|
faraday-retry (1.0.3)
|
|
54
|
-
git (
|
|
54
|
+
git (4.3.0)
|
|
55
55
|
activesupport (>= 5.0)
|
|
56
56
|
addressable (~> 2.8)
|
|
57
|
-
process_executer (~>
|
|
58
|
-
rchardet (~> 1.
|
|
57
|
+
process_executer (~> 4.0)
|
|
58
|
+
rchardet (~> 1.9)
|
|
59
59
|
github_api (0.19.0)
|
|
60
60
|
addressable (~> 2.4)
|
|
61
61
|
descendants_tracker (~> 0.0.4)
|
|
@@ -65,10 +65,11 @@ GEM
|
|
|
65
65
|
hashie (3.6.0)
|
|
66
66
|
highline (3.1.2)
|
|
67
67
|
reline
|
|
68
|
-
i18n (1.14.
|
|
68
|
+
i18n (1.14.8)
|
|
69
69
|
concurrent-ruby (~> 1.0)
|
|
70
|
-
io-console (0.8.
|
|
71
|
-
iostruct (0.
|
|
70
|
+
io-console (0.8.2)
|
|
71
|
+
iostruct (0.7.0)
|
|
72
|
+
json (2.18.0)
|
|
72
73
|
juwelier (2.4.9)
|
|
73
74
|
builder
|
|
74
75
|
bundler
|
|
@@ -81,29 +82,30 @@ GEM
|
|
|
81
82
|
rake
|
|
82
83
|
rdoc
|
|
83
84
|
semver2
|
|
84
|
-
jwt (2.10.
|
|
85
|
+
jwt (2.10.2)
|
|
85
86
|
base64
|
|
86
87
|
kamelcase (0.0.2)
|
|
87
88
|
semver2 (~> 3)
|
|
88
|
-
logger (1.
|
|
89
|
-
mini_portile2 (2.8.
|
|
90
|
-
minitest (
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
logger (1.7.0)
|
|
90
|
+
mini_portile2 (2.8.9)
|
|
91
|
+
minitest (6.0.1)
|
|
92
|
+
prism (~> 1.5)
|
|
93
|
+
multi_json (1.19.1)
|
|
94
|
+
multi_xml (0.8.1)
|
|
95
|
+
bigdecimal (>= 3.1, < 5)
|
|
94
96
|
multipart-post (2.4.1)
|
|
95
|
-
nokogiri (1.
|
|
97
|
+
nokogiri (1.19.0)
|
|
96
98
|
mini_portile2 (~> 2.8.2)
|
|
97
99
|
racc (~> 1.4)
|
|
98
|
-
nokogiri (1.
|
|
100
|
+
nokogiri (1.19.0-aarch64-linux-gnu)
|
|
99
101
|
racc (~> 1.4)
|
|
100
|
-
nokogiri (1.
|
|
102
|
+
nokogiri (1.19.0-arm-linux-gnu)
|
|
101
103
|
racc (~> 1.4)
|
|
102
|
-
nokogiri (1.
|
|
104
|
+
nokogiri (1.19.0-arm64-darwin)
|
|
103
105
|
racc (~> 1.4)
|
|
104
|
-
nokogiri (1.
|
|
106
|
+
nokogiri (1.19.0-x86_64-darwin)
|
|
105
107
|
racc (~> 1.4)
|
|
106
|
-
nokogiri (1.
|
|
108
|
+
nokogiri (1.19.0-x86_64-linux-gnu)
|
|
107
109
|
racc (~> 1.4)
|
|
108
110
|
oauth2 (1.4.11)
|
|
109
111
|
faraday (>= 0.17.3, < 3.0)
|
|
@@ -111,45 +113,51 @@ GEM
|
|
|
111
113
|
multi_json (~> 1.3)
|
|
112
114
|
multi_xml (~> 0.5)
|
|
113
115
|
rack (>= 1.2, < 4)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
prism (1.9.0)
|
|
117
|
+
process_executer (4.0.2)
|
|
118
|
+
track_open_instances (~> 0.1)
|
|
119
|
+
psych (5.3.1)
|
|
116
120
|
date
|
|
117
121
|
stringio
|
|
118
|
-
public_suffix (
|
|
122
|
+
public_suffix (7.0.2)
|
|
119
123
|
racc (1.8.1)
|
|
120
|
-
rack (3.
|
|
124
|
+
rack (3.2.4)
|
|
121
125
|
rainbow (3.1.1)
|
|
122
|
-
rake (13.
|
|
123
|
-
rchardet (1.
|
|
124
|
-
rdoc (
|
|
126
|
+
rake (13.3.1)
|
|
127
|
+
rchardet (1.10.0)
|
|
128
|
+
rdoc (7.1.0)
|
|
129
|
+
erb
|
|
125
130
|
psych (>= 4.0.0)
|
|
126
|
-
|
|
131
|
+
tsort
|
|
132
|
+
reline (0.6.3)
|
|
127
133
|
io-console (~> 0.5)
|
|
128
|
-
rspec (3.13.
|
|
134
|
+
rspec (3.13.2)
|
|
129
135
|
rspec-core (~> 3.13.0)
|
|
130
136
|
rspec-expectations (~> 3.13.0)
|
|
131
137
|
rspec-mocks (~> 3.13.0)
|
|
132
|
-
rspec-core (3.13.
|
|
138
|
+
rspec-core (3.13.6)
|
|
133
139
|
rspec-support (~> 3.13.0)
|
|
134
|
-
rspec-expectations (3.13.
|
|
140
|
+
rspec-expectations (3.13.5)
|
|
135
141
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
136
142
|
rspec-support (~> 3.13.0)
|
|
137
143
|
rspec-its (2.0.0)
|
|
138
144
|
rspec-core (>= 3.13.0)
|
|
139
145
|
rspec-expectations (>= 3.13.0)
|
|
140
|
-
rspec-mocks (3.13.
|
|
146
|
+
rspec-mocks (3.13.7)
|
|
141
147
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
142
148
|
rspec-support (~> 3.13.0)
|
|
143
|
-
rspec-support (3.13.
|
|
149
|
+
rspec-support (3.13.6)
|
|
144
150
|
ruby2_keywords (0.0.5)
|
|
145
151
|
securerandom (0.4.1)
|
|
146
152
|
semver2 (3.4.2)
|
|
147
|
-
stringio (3.
|
|
153
|
+
stringio (3.2.0)
|
|
148
154
|
thread_safe (0.3.6)
|
|
155
|
+
track_open_instances (0.1.15)
|
|
156
|
+
tsort (0.2.0)
|
|
149
157
|
tzinfo (2.0.6)
|
|
150
158
|
concurrent-ruby (~> 1.0)
|
|
151
|
-
uri (1.
|
|
152
|
-
zhexdump (0.
|
|
159
|
+
uri (1.1.1)
|
|
160
|
+
zhexdump (0.3.0)
|
|
153
161
|
|
|
154
162
|
PLATFORMS
|
|
155
163
|
aarch64-linux
|
|
@@ -162,7 +170,7 @@ PLATFORMS
|
|
|
162
170
|
DEPENDENCIES
|
|
163
171
|
awesome_print
|
|
164
172
|
bundler
|
|
165
|
-
iostruct (>= 0.
|
|
173
|
+
iostruct (>= 0.7.0)
|
|
166
174
|
juwelier
|
|
167
175
|
multipart-post (>= 2.0.0)
|
|
168
176
|
rainbow
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -4,6 +4,8 @@ pedump [VA to file offset and back
|
|
229
|
+
|
|
230
|
+
# pedump --rva2file 0x4c000 calc.exe
|
|
231
|
+
|
|
232
|
+
rva2file(0x4c000) = 0x4ae00 (306688)
|
|
233
|
+
|
|
234
|
+
# pedump --file2rva 0x4ae00 calc.exe
|
|
235
|
+
|
|
236
|
+
file2rva(0x4ae00) = 0x4c000 (311296)
|
|
237
|
+
|
|
238
|
+
# pedump --va2file 0x104c000 calc.exe
|
|
239
|
+
|
|
240
|
+
va2file(0x104c000) = 0x4ae00 (306688)
|
|
241
|
+
|
|
242
|
+
# pedump --file2va 0x4ae00 calc.exe
|
|
243
|
+
|
|
244
|
+
file2va(0x4ae00) = 0x104c000 (17088512)
|
|
245
|
+
|
|
246
|
+
# pedump --file2va 0x4ae00 calc.exe --format hex
|
|
247
|
+
|
|
248
|
+
104c000
|
|
249
|
+
|
|
224
250
|
### Data Directory
|
|
225
251
|
|
|
226
252
|
# pedump --data-directory calc.exe
|
data/Rakefile
CHANGED
|
@@ -37,11 +37,15 @@ RSpec::Core::RakeTask.new
|
|
|
37
37
|
|
|
38
38
|
task :default => [:spec, :readme]
|
|
39
39
|
|
|
40
|
+
task :init do
|
|
41
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
|
42
|
+
require 'pedump'
|
|
43
|
+
require 'pedump/cli'
|
|
44
|
+
end
|
|
45
|
+
|
|
40
46
|
namespace :test do
|
|
41
47
|
desc "test on all files in given path"
|
|
42
|
-
task :all_files do
|
|
43
|
-
require './lib/pedump'
|
|
44
|
-
require './lib/pedump/cli'
|
|
48
|
+
task :all_files => :init do
|
|
45
49
|
path = ENV['path'] || raise("run me with path=...")
|
|
46
50
|
`find #{path} -type f`.split("\n").each do |fname|
|
|
47
51
|
puts "\n### #{fname}\n"
|
|
@@ -51,9 +55,7 @@ namespace :test do
|
|
|
51
55
|
|
|
52
56
|
namespace :all_files do
|
|
53
57
|
desc "output file name to stderr, use with stdout redirection"
|
|
54
|
-
task :stderr do
|
|
55
|
-
require './lib/pedump'
|
|
56
|
-
require './lib/pedump/cli'
|
|
58
|
+
task :stderr => :init do
|
|
57
59
|
path = ENV['path'] || raise("run me with path=...")
|
|
58
60
|
`find #{path} -type f`.split("\n").each do |fname|
|
|
59
61
|
STDERR.puts "\n### #{fname}\n"
|
|
@@ -63,9 +65,7 @@ namespace :test do
|
|
|
63
65
|
end
|
|
64
66
|
|
|
65
67
|
desc "test on corkami binaries"
|
|
66
|
-
task :corkami do
|
|
67
|
-
require './lib/pedump'
|
|
68
|
-
require './lib/pedump/cli'
|
|
68
|
+
task :corkami => :init do
|
|
69
69
|
path = "samples/corkami"
|
|
70
70
|
`find #{path} -type f`.split("\n").each do |fname|
|
|
71
71
|
STDERR.puts "\n### #{fname}\n"
|
|
@@ -183,7 +183,7 @@ task :readme do
|
|
|
183
183
|
r << "\n"
|
|
184
184
|
end
|
|
185
185
|
Dir.chdir 'samples'
|
|
186
|
-
result = ERB.new(tpl,
|
|
186
|
+
result = ERB.new(tpl, trim_mode: '%>').result
|
|
187
187
|
Dir.chdir '..'
|
|
188
188
|
File.open('README.md','w'){ |f| f << result }
|
|
189
189
|
end
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.7.
|
|
1
|
+
0.7.4
|
data/lib/pedump/cli.rb
CHANGED
|
@@ -145,6 +145,12 @@ class PEdump::CLI
|
|
|
145
145
|
opts.on "--file2va OFFSET", "Convert file offset to VA" do |offset|
|
|
146
146
|
@actions << [:file2va, offset]
|
|
147
147
|
end
|
|
148
|
+
opts.on "--rva2file RVA", "Convert RVA to file offset" do |va|
|
|
149
|
+
@actions << [:rva2file, va]
|
|
150
|
+
end
|
|
151
|
+
opts.on "--file2rva OFFSET", "Convert file offset to RVA" do |offset|
|
|
152
|
+
@actions << [:file2rva, offset]
|
|
153
|
+
end
|
|
148
154
|
|
|
149
155
|
opts.separator ''
|
|
150
156
|
opts.on "--set-os-version VER", "Patch OS version in PE header" do |ver|
|
|
@@ -385,13 +391,17 @@ class PEdump::CLI
|
|
|
385
391
|
case action[0]
|
|
386
392
|
when :disasm
|
|
387
393
|
return
|
|
388
|
-
when :va2file, :file2va
|
|
394
|
+
when :rva2file, :file2rva, :va2file, :file2va
|
|
389
395
|
cmd = action[0]
|
|
390
396
|
@pedump.sections(f)
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
if
|
|
394
|
-
|
|
397
|
+
arg = action[1] =~ /(^0x)|(h$)/i ? action[1].to_i(16) : action[1].to_i
|
|
398
|
+
result = @pedump.send(cmd, arg)
|
|
399
|
+
if result
|
|
400
|
+
if @options[:format] == :hex
|
|
401
|
+
puts result.to_s(16)
|
|
402
|
+
else
|
|
403
|
+
printf("%s(0x%x) = 0x%x (%d)\n", cmd, arg, result, result)
|
|
404
|
+
end
|
|
395
405
|
else
|
|
396
406
|
@success = false
|
|
397
407
|
end
|
|
@@ -652,7 +662,7 @@ class PEdump::CLI
|
|
|
652
662
|
|
|
653
663
|
def dump_clr_streams data
|
|
654
664
|
clr_header = @pedump.clr_header
|
|
655
|
-
clr_data_file_ofs = clr_header.MetaData.va.to_i > 0 && @pedump.
|
|
665
|
+
clr_data_file_ofs = clr_header.MetaData.va.to_i > 0 && @pedump.rva2file(clr_header.MetaData.va)
|
|
656
666
|
|
|
657
667
|
fmt = "%8x %8x %-32s\n"
|
|
658
668
|
printf fmt.tr('x','s'), *%w'offset size name'
|
|
@@ -675,7 +685,7 @@ class PEdump::CLI
|
|
|
675
685
|
blob_stream = @pedump.clr_streams.find{ |s| s.name == "#Blob" }
|
|
676
686
|
|
|
677
687
|
clr_header = @pedump.clr_header
|
|
678
|
-
clr_data_file_ofs = clr_header.MetaData.va.to_i > 0 && @pedump.
|
|
688
|
+
clr_data_file_ofs = clr_header.MetaData.va.to_i > 0 && @pedump.rva2file(clr_header.MetaData.va)
|
|
679
689
|
blob_file_ofs = blob_stream.offset + clr_data_file_ofs if blob_stream
|
|
680
690
|
blob_size = blob_stream&.size
|
|
681
691
|
|
|
@@ -892,7 +902,7 @@ class PEdump::CLI
|
|
|
892
902
|
if @options[:verbose] > 0
|
|
893
903
|
[%w'Names', %w'EntryPoints Functions', %w'Ordinals NameOrdinals'].each do |x|
|
|
894
904
|
va = data["AddressOf"+x.last]
|
|
895
|
-
ofs = @pedump.
|
|
905
|
+
ofs = @pedump.rva2file(va) || '?'
|
|
896
906
|
printf("# %-12s rva=0x%08x file_offset=%8s\n", x.first, va, ofs) if va
|
|
897
907
|
end
|
|
898
908
|
end
|
|
@@ -1132,7 +1142,7 @@ class PEdump::CLI
|
|
|
1132
1142
|
exit(1)
|
|
1133
1143
|
end
|
|
1134
1144
|
if entry.size != 0
|
|
1135
|
-
_copy_stream @pedump.io, $stdout, entry.size, @pedump.
|
|
1145
|
+
_copy_stream @pedump.io, $stdout, entry.size, @pedump.rva2file(entry.va)
|
|
1136
1146
|
end
|
|
1137
1147
|
end
|
|
1138
1148
|
|
data/lib/pedump/clr.rb
CHANGED
|
@@ -584,7 +584,7 @@ class PEdump
|
|
|
584
584
|
dir = @pe.ioh.DataDirectory[IMAGE_DATA_DIRECTORY::CLR_Header]
|
|
585
585
|
return nil if !dir || (dir.va == 0 && dir.size == 0)
|
|
586
586
|
|
|
587
|
-
file_offset =
|
|
587
|
+
file_offset = rva2file(dir.va)
|
|
588
588
|
return nil unless file_offset
|
|
589
589
|
|
|
590
590
|
if f.checked_seek(file_offset)
|
|
@@ -601,7 +601,7 @@ class PEdump
|
|
|
601
601
|
dir = hdr&.MetaData
|
|
602
602
|
return nil if !dir || (dir.va.to_i == 0 || dir.size.to_i == 0)
|
|
603
603
|
|
|
604
|
-
file_offset =
|
|
604
|
+
file_offset = rva2file(dir.va)
|
|
605
605
|
return nil unless file_offset
|
|
606
606
|
|
|
607
607
|
if f.checked_seek(file_offset)
|
|
@@ -635,7 +635,7 @@ class PEdump
|
|
|
635
635
|
streams.each do |stream|
|
|
636
636
|
next unless stream.name == '#Strings'
|
|
637
637
|
|
|
638
|
-
unless f.checked_seek(
|
|
638
|
+
unless f.checked_seek(rva2file(dir.va) + stream.offset)
|
|
639
639
|
logger.warn "[?] Error seeking to CLR strings stream"
|
|
640
640
|
return nil
|
|
641
641
|
end
|
|
@@ -678,7 +678,7 @@ class PEdump
|
|
|
678
678
|
streams.each do |stream|
|
|
679
679
|
next if stream.name != '#~' && stream.name != '#-' # Metadata Table Stream
|
|
680
680
|
|
|
681
|
-
unless f.checked_seek(
|
|
681
|
+
unless f.checked_seek(rva2file(dir.va) + stream.offset)
|
|
682
682
|
logger.warn "[?] Error seeking to CLR table stream"
|
|
683
683
|
return nil
|
|
684
684
|
end
|
|
@@ -21,13 +21,13 @@ class PEdump
|
|
|
21
21
|
|
|
22
22
|
MINIDUMP_LOCATION_DESCRIPTOR = IOStruct.new 'LL', :DataSize, :Rva
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
# Using nested struct - Location is automatically parsed
|
|
25
|
+
MINIDUMP_DIRECTORY = IOStruct.new(
|
|
26
|
+
fields: {
|
|
27
|
+
StreamType: 'uint32_t',
|
|
28
|
+
Location: MINIDUMP_LOCATION_DESCRIPTOR,
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
31
|
|
|
32
32
|
MINIDUMP_MEMORY_INFO = IOStruct.new 'QQLLQLLLL',
|
|
33
33
|
:BaseAddress,
|
data/lib/pedump/packer.rb
CHANGED
|
@@ -73,7 +73,7 @@ class PEdump
|
|
|
73
73
|
elsif va == 0 && pe.dll?
|
|
74
74
|
pedump.logger.debug "[.] it's a DLL with no EntryPoint"
|
|
75
75
|
nil
|
|
76
|
-
elsif !(ofs = pedump.
|
|
76
|
+
elsif !(ofs = pedump.rva2file(va))
|
|
77
77
|
pedump.logger.error "[?] can't find EntryPoint RVA (0x#{va.to_s(16)}) file offset"
|
|
78
78
|
nil
|
|
79
79
|
else
|
data/lib/pedump/resources.rb
CHANGED
|
@@ -403,7 +403,7 @@ class PEdump
|
|
|
403
403
|
end
|
|
404
404
|
end
|
|
405
405
|
when IMAGE_RESOURCE_DATA_ENTRY
|
|
406
|
-
file_offset =
|
|
406
|
+
file_offset = rva2file(entry.data.OffsetToData, :quiet => (@pe_res_errors > MAX_ERRORS))
|
|
407
407
|
unless file_offset
|
|
408
408
|
@pe_res_errors += 1
|
|
409
409
|
if @pe_res_errors > MAX_ERRORS
|
data/lib/pedump/te.rb
CHANGED
|
@@ -4,33 +4,33 @@ class PEdump
|
|
|
4
4
|
# https://formats.kaitai.io/uefi_te/index.html
|
|
5
5
|
# http://ho.ax/tag/efi/
|
|
6
6
|
# https://github.com/gdbinit/TELoader
|
|
7
|
-
|
|
8
|
-
EFI_IMAGE_DATA_DIRECTORY = IOStruct.new(
|
|
7
|
+
|
|
8
|
+
EFI_IMAGE_DATA_DIRECTORY = IOStruct.new("VV", :va, :size)
|
|
9
9
|
EFI_IMAGE_DATA_DIRECTORY::TYPES = %w'BASERELOC DEBUG'
|
|
10
|
-
EFI_IMAGE_DATA_DIRECTORY::TYPES.each_with_index do |type,idx|
|
|
11
|
-
EFI_IMAGE_DATA_DIRECTORY.const_set(type,idx)
|
|
10
|
+
EFI_IMAGE_DATA_DIRECTORY::TYPES.each_with_index do |type, idx|
|
|
11
|
+
EFI_IMAGE_DATA_DIRECTORY.const_set(type, idx)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
# Using hash format with nested struct array for DataDirectory
|
|
15
|
+
class EFI_TE_IMAGE_HEADER < IOStruct.new(
|
|
16
|
+
fields: {
|
|
17
|
+
Signature: 'uint16_t',
|
|
18
|
+
Machine: 'uint16_t',
|
|
19
|
+
NumberOfSections: 'uint8_t',
|
|
20
|
+
Subsystem: 'uint8_t',
|
|
21
|
+
StrippedSize: 'uint16_t',
|
|
22
|
+
AddressOfEntryPoint: 'uint32_t',
|
|
23
|
+
BaseOfCode: 'uint32_t',
|
|
24
|
+
ImageBase: 'uint64_t',
|
|
25
|
+
DataDirectory: { type: EFI_IMAGE_DATA_DIRECTORY, count: 2 },
|
|
26
|
+
}
|
|
27
|
+
)
|
|
28
|
+
REAL_SIZE = SIZE
|
|
26
29
|
|
|
27
30
|
attr_accessor :sections
|
|
28
31
|
|
|
29
32
|
def self.read io, args = {}
|
|
30
33
|
super(io).tap do |te|
|
|
31
|
-
te.DataDirectory = 2.times.map do
|
|
32
|
-
EFI_IMAGE_DATA_DIRECTORY.read(io)
|
|
33
|
-
end
|
|
34
34
|
te.sections = PE.read_sections(io, te.NumberOfSections, args)
|
|
35
35
|
end
|
|
36
36
|
end
|
data/lib/pedump/tls.rb
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
class PEdump
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
TLS_DIRECTORY_FIELDS = %i[
|
|
3
|
+
StartAddressOfRawData
|
|
4
|
+
EndAddressOfRawData
|
|
5
|
+
AddressOfIndex
|
|
6
|
+
AddressOfCallBacks
|
|
7
|
+
SizeOfZeroFill
|
|
8
|
+
Characteristics
|
|
9
|
+
].freeze
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
:AddressOfCallBacks,
|
|
15
|
-
:SizeOfZeroFill,
|
|
16
|
-
:Characteristics
|
|
11
|
+
# 32-bit: all fields are 32-bit (V6)
|
|
12
|
+
# 64-bit: first 4 fields are 64-bit pointers (Q4), last 2 are 32-bit (V2)
|
|
13
|
+
IMAGE_TLS_DIRECTORY32 = IOStruct.new('V6', *TLS_DIRECTORY_FIELDS)
|
|
14
|
+
IMAGE_TLS_DIRECTORY64 = IOStruct.new('Q4V2', *TLS_DIRECTORY_FIELDS)
|
|
17
15
|
end
|
|
@@ -788,13 +788,13 @@ class PEdump::Unpacker::ASPack
|
|
|
788
788
|
###
|
|
789
789
|
|
|
790
790
|
rebuild_tls :step => 1
|
|
791
|
-
sorted_obj_tbl = @obj_tbl.sort_by{ |x| @ldr.pedump.
|
|
791
|
+
sorted_obj_tbl = @obj_tbl.sort_by{ |x| @ldr.pedump.rva2file(x.va) }
|
|
792
792
|
sorted_obj_tbl.each_with_index do |obj,idx|
|
|
793
793
|
# restore section flags, if any
|
|
794
794
|
@ldr.va2section(obj.va).flags = obj.flags if obj.flags
|
|
795
795
|
|
|
796
796
|
next if obj.size < 0 # empty section
|
|
797
|
-
#file_offset = @ldr.pedump.
|
|
797
|
+
#file_offset = @ldr.pedump.rva2file(obj.va)
|
|
798
798
|
#@io.seek file_offset
|
|
799
799
|
packed_size =
|
|
800
800
|
if idx == sorted_obj_tbl.size - 1
|
|
@@ -802,7 +802,7 @@ class PEdump::Unpacker::ASPack
|
|
|
802
802
|
obj.size
|
|
803
803
|
else
|
|
804
804
|
# subtract this file_offset from next object file_offset
|
|
805
|
-
@ldr.pedump.
|
|
805
|
+
@ldr.pedump.rva2file(sorted_obj_tbl[idx+1].va) - @ldr.pedump.rva2file(obj.va)
|
|
806
806
|
end
|
|
807
807
|
#packed_data = @io.read packed_size
|
|
808
808
|
packed_data = @ldr[obj.va, packed_size]
|
data/lib/pedump.rb
CHANGED
|
@@ -397,7 +397,7 @@ class PEdump
|
|
|
397
397
|
alias :rich_header :rich_hdr
|
|
398
398
|
alias :rich :rich_hdr
|
|
399
399
|
|
|
400
|
-
def
|
|
400
|
+
def rva2file va, h={}
|
|
401
401
|
return nil if va.nil?
|
|
402
402
|
|
|
403
403
|
va0 = va # save for log output of original addr
|
|
@@ -445,7 +445,11 @@ class PEdump
|
|
|
445
445
|
nil
|
|
446
446
|
end
|
|
447
447
|
|
|
448
|
-
def
|
|
448
|
+
def va2file va, h = {}
|
|
449
|
+
va && rva2file(va - @pe.ioh.ImageBase.to_i, h)
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
def file2rva offset, h = {}
|
|
449
453
|
return nil if offset.nil?
|
|
450
454
|
|
|
451
455
|
# a special case - PE without sections
|
|
@@ -453,7 +457,7 @@ class PEdump
|
|
|
453
457
|
|
|
454
458
|
sections.each do |s|
|
|
455
459
|
if (s.PointerToRawData...(s.PointerToRawData+s.SizeOfRawData)).include?(offset)
|
|
456
|
-
return s.VirtualAddress + s.PointerToRawData
|
|
460
|
+
return s.VirtualAddress + offset - s.PointerToRawData
|
|
457
461
|
end
|
|
458
462
|
end
|
|
459
463
|
|
|
@@ -465,6 +469,11 @@ class PEdump
|
|
|
465
469
|
nil
|
|
466
470
|
end
|
|
467
471
|
|
|
472
|
+
def file2va offset, h = {}
|
|
473
|
+
va = file2rva(offset, h)
|
|
474
|
+
va && (va + @pe.ioh.ImageBase.to_i)
|
|
475
|
+
end
|
|
476
|
+
|
|
468
477
|
# OPTIONAL: assigns @mz, @rich_hdr, @pe, etc
|
|
469
478
|
def dump f=@io
|
|
470
479
|
if f.is_a?(String)
|
|
@@ -601,7 +610,7 @@ class PEdump
|
|
|
601
610
|
return nil unless pe(f) && pe(f).ioh && f
|
|
602
611
|
|
|
603
612
|
imports = imports(f)
|
|
604
|
-
return nil if imports.empty?
|
|
613
|
+
return nil if imports.nil? || imports.empty?
|
|
605
614
|
|
|
606
615
|
a = []
|
|
607
616
|
imports.each do |iid|
|
|
@@ -628,7 +637,7 @@ class PEdump
|
|
|
628
637
|
dir = @pe.ioh.DataDirectory[IMAGE_DATA_DIRECTORY::IMPORT]
|
|
629
638
|
return [] if !dir || (dir.va == 0 && dir.size == 0)
|
|
630
639
|
|
|
631
|
-
file_offset =
|
|
640
|
+
file_offset = rva2file(dir.va)
|
|
632
641
|
return nil unless file_offset
|
|
633
642
|
|
|
634
643
|
# scan TLS first, to catch many fake imports trick from
|
|
@@ -636,7 +645,7 @@ class PEdump
|
|
|
636
645
|
tls_aoi = nil
|
|
637
646
|
if (tls = tls(f)) && tls.any?
|
|
638
647
|
tls_aoi = tls.first.AddressOfIndex.to_i - @pe.ioh.ImageBase.to_i
|
|
639
|
-
tls_aoi = tls_aoi > 0 ?
|
|
648
|
+
tls_aoi = tls_aoi > 0 ? rva2file(tls_aoi) : nil
|
|
640
649
|
end
|
|
641
650
|
|
|
642
651
|
r = []; t = nil
|
|
@@ -672,7 +681,7 @@ class PEdump
|
|
|
672
681
|
@imports = @imports[0,iidx]
|
|
673
682
|
break
|
|
674
683
|
end
|
|
675
|
-
if x.Name.to_i != 0 && (ofs =
|
|
684
|
+
if x.Name.to_i != 0 && (ofs = rva2file(x.Name))
|
|
676
685
|
begin
|
|
677
686
|
f.seek ofs
|
|
678
687
|
rescue
|
|
@@ -683,7 +692,7 @@ class PEdump
|
|
|
683
692
|
end
|
|
684
693
|
[:original_first_thunk, :first_thunk].each do |tbl|
|
|
685
694
|
camel = tbl.capitalize.to_s.gsub(/_./){ |char| char[1..-1].upcase}
|
|
686
|
-
if x[camel].to_i != 0 && (ofs =
|
|
695
|
+
if x[camel].to_i != 0 && (ofs = rva2file(x[camel])) && f.checked_seek(ofs)
|
|
687
696
|
x[tbl] ||= []
|
|
688
697
|
if pe.x64?
|
|
689
698
|
x[tbl] << t while (t = f.read(8).to_s.unpack('Q').first).to_i != 0
|
|
@@ -701,7 +710,7 @@ class PEdump
|
|
|
701
710
|
cache[t] ||=
|
|
702
711
|
if t & mask > 0 # 0x8000_0000(_0000_0000)
|
|
703
712
|
ImportedFunction.new(nil,nil,t & (mask-1),va) # 0x7fff_ffff(_ffff_ffff)
|
|
704
|
-
elsif ofs=
|
|
713
|
+
elsif ofs=rva2file(t, :quiet => true)
|
|
705
714
|
if !f.checked_seek(ofs) || f.eof?
|
|
706
715
|
logger.warn "[?] import ofs 0x#{ofs.to_s(16)} VA=0x#{t.to_s(16)} beyond EOF"
|
|
707
716
|
nil
|
|
@@ -788,7 +797,7 @@ class PEdump
|
|
|
788
797
|
dir = @pe.ioh.DataDirectory[IMAGE_DATA_DIRECTORY::EXPORT]
|
|
789
798
|
return nil if !dir || (dir.va == 0 && dir.size == 0)
|
|
790
799
|
va = @pe.ioh.DataDirectory[IMAGE_DATA_DIRECTORY::EXPORT].va
|
|
791
|
-
file_offset =
|
|
800
|
+
file_offset = rva2file(va)
|
|
792
801
|
return nil unless file_offset
|
|
793
802
|
if !f.checked_seek(file_offset) || f.eof?
|
|
794
803
|
logger.warn "[?] exports info beyond EOF"
|
|
@@ -798,7 +807,7 @@ class PEdump
|
|
|
798
807
|
x.entry_points = []
|
|
799
808
|
x.name_ordinals = []
|
|
800
809
|
x.names = []
|
|
801
|
-
if x.Name.to_i != 0 && (ofs =
|
|
810
|
+
if x.Name.to_i != 0 && (ofs = rva2file(x.Name))
|
|
802
811
|
f.seek ofs
|
|
803
812
|
if f.eof?
|
|
804
813
|
logger.warn "[?] export ofs 0x#{ofs.to_s(16)} beyond EOF"
|
|
@@ -808,7 +817,7 @@ class PEdump
|
|
|
808
817
|
end
|
|
809
818
|
end
|
|
810
819
|
if x.NumberOfFunctions.to_i > 0
|
|
811
|
-
if x.AddressOfFunctions.to_i !=0 && (ofs =
|
|
820
|
+
if x.AddressOfFunctions.to_i !=0 && (ofs = rva2file(x.AddressOfFunctions))
|
|
812
821
|
f.seek ofs
|
|
813
822
|
x.entry_points = []
|
|
814
823
|
x.NumberOfFunctions.times do
|
|
@@ -819,7 +828,7 @@ class PEdump
|
|
|
819
828
|
x.entry_points << f.read(4).unpack('V').first
|
|
820
829
|
end
|
|
821
830
|
end
|
|
822
|
-
if x.AddressOfNameOrdinals.to_i !=0 && (ofs =
|
|
831
|
+
if x.AddressOfNameOrdinals.to_i !=0 && (ofs = rva2file(x.AddressOfNameOrdinals))
|
|
823
832
|
f.seek ofs
|
|
824
833
|
x.name_ordinals = []
|
|
825
834
|
x.NumberOfNames.times do
|
|
@@ -831,7 +840,7 @@ class PEdump
|
|
|
831
840
|
end
|
|
832
841
|
end
|
|
833
842
|
end
|
|
834
|
-
if x.NumberOfNames.to_i > 0 && x.AddressOfNames.to_i !=0 && (ofs =
|
|
843
|
+
if x.NumberOfNames.to_i > 0 && x.AddressOfNames.to_i !=0 && (ofs = rva2file(x.AddressOfNames))
|
|
835
844
|
f.seek ofs
|
|
836
845
|
x.names = []
|
|
837
846
|
x.NumberOfNames.times do
|
|
@@ -844,7 +853,7 @@ class PEdump
|
|
|
844
853
|
nErrors = 0
|
|
845
854
|
x.names.size.times do |i|
|
|
846
855
|
begin
|
|
847
|
-
f.seek
|
|
856
|
+
f.seek rva2file(x.names[i])
|
|
848
857
|
x.names[i] = f.gets("\x00").to_s.chomp("\x00")
|
|
849
858
|
rescue
|
|
850
859
|
nErrors += 1
|
|
@@ -890,7 +899,7 @@ class PEdump
|
|
|
890
899
|
begin
|
|
891
900
|
dir = @pe.ioh.DataDirectory[IMAGE_DATA_DIRECTORY::TLS]
|
|
892
901
|
return nil if !dir || dir.va == 0
|
|
893
|
-
return nil unless file_offset =
|
|
902
|
+
return nil unless file_offset = rva2file(dir.va)
|
|
894
903
|
f.seek file_offset
|
|
895
904
|
if f.eof?
|
|
896
905
|
logger.info "[?] TLS info beyond EOF"
|
|
@@ -947,7 +956,10 @@ class PEdump
|
|
|
947
956
|
##############################################################################
|
|
948
957
|
|
|
949
958
|
def tail f=@io
|
|
950
|
-
|
|
959
|
+
secs = sections(f)
|
|
960
|
+
return nil if secs.nil? || secs.empty?
|
|
961
|
+
|
|
962
|
+
tail_start = secs.map{ |s| s.PointerToRawData + s.SizeOfRawData }.max
|
|
951
963
|
if tail_start && tail_start < f.size
|
|
952
964
|
f.seek tail_start
|
|
953
965
|
f
|
data/pedump.gemspec
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
|
-
# stub: pedump 0.7.
|
|
5
|
+
# stub: pedump 0.7.4 ruby lib
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
8
|
s.name = "pedump".freeze
|
|
9
|
-
s.version = "0.7.
|
|
9
|
+
s.version = "0.7.4".freeze
|
|
10
10
|
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
12
12
|
s.require_paths = ["lib".freeze]
|
|
@@ -83,7 +83,7 @@ Gem::Specification.new do |s|
|
|
|
83
83
|
|
|
84
84
|
s.add_runtime_dependency(%q<rainbow>.freeze, [">= 0".freeze])
|
|
85
85
|
s.add_runtime_dependency(%q<awesome_print>.freeze, [">= 0".freeze])
|
|
86
|
-
s.add_runtime_dependency(%q<iostruct>.freeze, [">= 0.
|
|
86
|
+
s.add_runtime_dependency(%q<iostruct>.freeze, [">= 0.7.0".freeze])
|
|
87
87
|
s.add_runtime_dependency(%q<multipart-post>.freeze, [">= 2.0.0".freeze])
|
|
88
88
|
s.add_runtime_dependency(%q<zhexdump>.freeze, [">= 0.0.2".freeze])
|
|
89
89
|
s.add_development_dependency(%q<rspec>.freeze, [">= 0".freeze])
|
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.7.
|
|
4
|
+
version: 0.7.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrey "Zed" Zaikin
|
|
@@ -43,14 +43,14 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 0.
|
|
46
|
+
version: 0.7.0
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 0.
|
|
53
|
+
version: 0.7.0
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: multipart-post
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|