pedump 0.5.4 → 0.6.3
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/CODE_OF_CONDUCT.md +76 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +25 -23
- data/README.md +104 -11
- data/Rakefile +41 -6
- data/VERSION +1 -1
- data/data/comp_id.txt +776 -0
- data/lib/pedump/cli.rb +144 -34
- data/lib/pedump/loader/section.rb +5 -3
- data/lib/pedump/loader.rb +28 -6
- data/lib/pedump/ne.rb +1 -1
- data/lib/pedump/pe.rb +63 -54
- data/lib/pedump/rich.rb +562 -0
- data/lib/pedump/te.rb +62 -0
- data/lib/pedump.rb +86 -18
- data/misc/aspack/aspack_unlzx.c +5 -3
- data/pedump.gemspec +20 -29
- metadata +12 -23
data/lib/pedump.rb
CHANGED
@@ -17,6 +17,7 @@ require 'pedump/security'
|
|
17
17
|
require 'pedump/packer'
|
18
18
|
require 'pedump/ne'
|
19
19
|
require 'pedump/ne/version_info'
|
20
|
+
require 'pedump/te'
|
20
21
|
|
21
22
|
# pedump.rb by zed_0xff
|
22
23
|
#
|
@@ -29,8 +30,9 @@ class PEdump
|
|
29
30
|
VERSION = Version::STRING
|
30
31
|
MAX_ERRORS = 100
|
31
32
|
MAX_IMAGE_IMPORT_DESCRIPTORS = 1000
|
32
|
-
MAX_EXPORT_NUMBER_OF_NAMES = 16384 # got 7977 in
|
33
|
+
MAX_EXPORT_NUMBER_OF_NAMES = 16384 # got 7977 in https://pedump.me/03ad7400080678c6b1984f995d36fd04
|
33
34
|
GOOD_FUNCTION_NAME_RE = /\A[\x21-\x7f]+\Z/
|
35
|
+
SUPPORTED_SIGNATURES = ['MZ', 'ZM', 'VZ']
|
34
36
|
|
35
37
|
@@logger = nil
|
36
38
|
|
@@ -259,7 +261,7 @@ class PEdump
|
|
259
261
|
|
260
262
|
# http://ntcore.com/files/richsign.htm
|
261
263
|
class RichHdr < String
|
262
|
-
attr_accessor :offset, :key # xor key
|
264
|
+
attr_accessor :offset, :skip, :key # xor key
|
263
265
|
|
264
266
|
class Entry < Struct.new(:version,:id,:times)
|
265
267
|
def inspect
|
@@ -268,8 +270,21 @@ class PEdump
|
|
268
270
|
end
|
269
271
|
|
270
272
|
def self.from_dos_stub stub
|
273
|
+
#stub.hexdump
|
271
274
|
key = stub[stub.index('Rich')+4,4]
|
272
275
|
start_idx = stub.index(key.xor('DanS'))
|
276
|
+
skip = 0
|
277
|
+
if start_idx
|
278
|
+
skip = 4
|
279
|
+
else
|
280
|
+
PEdump.logger.warn "[?] cannot find rich_hdr start_idx, using heuristics"
|
281
|
+
start_idx = stub.index("$\x00\x00\x00\x00\x00\x00\x00")
|
282
|
+
unless start_idx
|
283
|
+
PEdump.logger.warn "[?] heuristics failed :("
|
284
|
+
return nil
|
285
|
+
end
|
286
|
+
start_idx += 8
|
287
|
+
end
|
273
288
|
end_idx = stub.index('Rich')+8
|
274
289
|
if stub[end_idx..-1].tr("\x00",'') != ''
|
275
290
|
t = stub[end_idx..-1]
|
@@ -277,14 +292,16 @@ class PEdump
|
|
277
292
|
PEdump.logger.error "[!] non-zero dos stub after rich_hdr: #{t.inspect}"
|
278
293
|
return nil
|
279
294
|
end
|
295
|
+
#stub[start_idx, end_idx-start_idx].hexdump
|
280
296
|
RichHdr.new(stub[start_idx, end_idx-start_idx]).tap do |x|
|
281
297
|
x.key = key
|
282
298
|
x.offset = stub.offset + start_idx
|
299
|
+
x.skip = skip
|
283
300
|
end
|
284
301
|
end
|
285
302
|
|
286
303
|
def dexor
|
287
|
-
self[
|
304
|
+
self[skip..-9].sub(/\A(#{Regexp::escape(key)}){3}/,'').xor(key)
|
288
305
|
end
|
289
306
|
|
290
307
|
def decode
|
@@ -322,9 +339,9 @@ class PEdump
|
|
322
339
|
@mz ||= f && MZ.read(f).tap do |mz|
|
323
340
|
if mz.signature != 'MZ' && mz.signature != 'ZM'
|
324
341
|
if @force
|
325
|
-
logger.warn "[?] no MZ signature. want: 'MZ' or 'ZM', got: #{mz.signature.inspect}"
|
342
|
+
#logger.warn "[?] no MZ signature. want: 'MZ' or 'ZM', got: #{mz.signature.inspect}"
|
326
343
|
else
|
327
|
-
logger.error "[!] no MZ signature. want: 'MZ' or 'ZM', got: #{mz.signature.inspect}. (not forced)"
|
344
|
+
#logger.error "[!] no MZ signature. want: 'MZ' or 'ZM', got: #{mz.signature.inspect}. (not forced)"
|
328
345
|
return nil
|
329
346
|
end
|
330
347
|
end
|
@@ -380,6 +397,13 @@ class PEdump
|
|
380
397
|
def va2file va, h={}
|
381
398
|
return nil if va.nil?
|
382
399
|
|
400
|
+
va0 = va # save for log output of original addr
|
401
|
+
if pe?
|
402
|
+
# most common case, do nothing
|
403
|
+
elsif te?
|
404
|
+
va = va - te_shift()
|
405
|
+
end
|
406
|
+
|
383
407
|
sections.each do |s|
|
384
408
|
if (s.VirtualAddress...(s.VirtualAddress+s.VirtualSize)).include?(va)
|
385
409
|
offset = va - s.VirtualAddress
|
@@ -411,9 +435,9 @@ class PEdump
|
|
411
435
|
# TODO: not all VirtualAdresses == 0 case
|
412
436
|
|
413
437
|
if h[:quiet]
|
414
|
-
logger.debug "[?] can't find file_offset of VA 0x#{
|
438
|
+
logger.debug "[?] can't find file_offset of VA 0x#{va0.to_i.to_s(16)} (quiet=true)"
|
415
439
|
else
|
416
|
-
logger.error "[?] can't find file_offset of VA 0x#{
|
440
|
+
logger.error "[?] can't find file_offset of VA 0x#{va0.to_i.to_s(16)}"
|
417
441
|
end
|
418
442
|
nil
|
419
443
|
end
|
@@ -431,16 +455,22 @@ class PEdump
|
|
431
455
|
end
|
432
456
|
|
433
457
|
def _dump_handle h
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
458
|
+
if pe(h) # also calls mz(h)
|
459
|
+
rich_hdr h
|
460
|
+
resources h
|
461
|
+
imports h # also calls tls(h)
|
462
|
+
exports h
|
463
|
+
packer h
|
464
|
+
elsif te(h)
|
465
|
+
end
|
440
466
|
end
|
441
467
|
|
442
468
|
def data_directory f=@io
|
443
|
-
pe(f)
|
469
|
+
if pe(f)
|
470
|
+
pe.ioh && pe.ioh.DataDirectory
|
471
|
+
elsif te(f)
|
472
|
+
te.DataDirectory
|
473
|
+
end
|
444
474
|
end
|
445
475
|
|
446
476
|
def sections f=@io
|
@@ -448,16 +478,52 @@ class PEdump
|
|
448
478
|
pe.section_table
|
449
479
|
elsif ne(f)
|
450
480
|
ne.segments
|
481
|
+
elsif te(f)
|
482
|
+
te.sections
|
451
483
|
end
|
452
484
|
end
|
453
485
|
alias :section_table :sections
|
454
486
|
|
455
|
-
def
|
456
|
-
|
487
|
+
def supported_file? f=@io
|
488
|
+
pos = f.tell
|
489
|
+
sig = f.read(2)
|
490
|
+
f.seek(pos)
|
491
|
+
if SUPPORTED_SIGNATURES.include?(sig)
|
492
|
+
true
|
493
|
+
else
|
494
|
+
unless @not_supported_sig_warned
|
495
|
+
msg = "no supported signature. want: #{SUPPORTED_SIGNATURES.join("/")}, got: #{sig.inspect}"
|
496
|
+
if @force
|
497
|
+
logger.warn "[?] #{msg}"
|
498
|
+
else
|
499
|
+
logger.error "[!] #{msg}. (not forced)"
|
500
|
+
end
|
501
|
+
@not_supported_sig_warned = true
|
502
|
+
end
|
503
|
+
false
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
def _detect_format
|
508
|
+
return :pe if @pe
|
509
|
+
return :ne if @ne
|
510
|
+
return :te if @te
|
511
|
+
return :pe if pe()
|
512
|
+
return :ne if ne()
|
513
|
+
return :te if te()
|
514
|
+
nil
|
457
515
|
end
|
458
516
|
|
459
517
|
def pe?
|
460
|
-
|
518
|
+
_detect_format() == :pe
|
519
|
+
end
|
520
|
+
|
521
|
+
def ne?
|
522
|
+
_detect_format() == :ne
|
523
|
+
end
|
524
|
+
|
525
|
+
def te?
|
526
|
+
_detect_format() == :te
|
461
527
|
end
|
462
528
|
|
463
529
|
##############################################################################
|
@@ -502,6 +568,8 @@ class PEdump
|
|
502
568
|
pe_imports(f)
|
503
569
|
elsif ne(f)
|
504
570
|
ne(f).imports
|
571
|
+
else
|
572
|
+
[]
|
505
573
|
end
|
506
574
|
end
|
507
575
|
|
@@ -589,7 +657,7 @@ class PEdump
|
|
589
657
|
nil
|
590
658
|
else
|
591
659
|
hint = f.read(2).unpack('v').first
|
592
|
-
name = f.gets("\x00").chomp("\x00")
|
660
|
+
name = f.gets("\x00").to_s.chomp("\x00")
|
593
661
|
if !name.empty? && name !~ GOOD_FUNCTION_NAME_RE
|
594
662
|
n_bad_names += 1
|
595
663
|
if n_bad_names > MAX_ERRORS
|
data/misc/aspack/aspack_unlzx.c
CHANGED
@@ -30,6 +30,7 @@ int unpack(BYTE*packed_data, size_t packed_size, size_t unpacked_size){
|
|
30
30
|
LZX_CONTEXT LZX;
|
31
31
|
BYTE* unpacked_data = NULL;
|
32
32
|
size_t decoded_size;
|
33
|
+
int r;
|
33
34
|
|
34
35
|
bzero(&LZX, sizeof(LZX));
|
35
36
|
|
@@ -38,8 +39,9 @@ int unpack(BYTE*packed_data, size_t packed_size, size_t unpacked_size){
|
|
38
39
|
return(ERR_NO_MEM);
|
39
40
|
}
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
r = DecodeLZX(&LZX, packed_data, unpacked_data, packed_size, unpacked_size);
|
43
|
+
decoded_size = (size_t)r;
|
44
|
+
if ( r < 0 || decoded_size < unpacked_size ) {
|
43
45
|
free(unpacked_data);
|
44
46
|
fprintf(stderr,"ERR_UNPACK\n");
|
45
47
|
return(ERR_UNPACK);
|
@@ -58,7 +60,7 @@ int main(int argc, char*argv[]){
|
|
58
60
|
if(argc != 3){
|
59
61
|
fprintf(stderr, "ASPack unLZX\n");
|
60
62
|
fprintf(stderr, "usage: %s <packed_size> <unpacked_size>\n", argv[0]);
|
61
|
-
fprintf(stderr, "(data is read from stdin and written to stdout)\n"
|
63
|
+
fprintf(stderr, "(data is read from stdin and written to stdout)\n");
|
62
64
|
return 1;
|
63
65
|
}
|
64
66
|
|
data/pedump.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: pedump 0.
|
5
|
+
# stub: pedump 0.6.3 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "pedump".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.6.3"
|
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]
|
13
13
|
s.authors = ["Andrey \"Zed\" Zaikin".freeze]
|
14
|
-
s.date = "
|
14
|
+
s.date = "2021-12-07"
|
15
15
|
s.description = "dump headers, sections, extract resources of win32 PE exe,dll,etc".freeze
|
16
16
|
s.email = "zed.0xff@gmail.com".freeze
|
17
17
|
s.executables = ["pedump".freeze]
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
"README.md"
|
21
21
|
]
|
22
22
|
s.files = [
|
23
|
+
"CODE_OF_CONDUCT.md",
|
23
24
|
"Gemfile",
|
24
25
|
"Gemfile.lock",
|
25
26
|
"LICENSE.txt",
|
@@ -27,6 +28,7 @@ Gem::Specification.new do |s|
|
|
27
28
|
"Rakefile",
|
28
29
|
"VERSION",
|
29
30
|
"bin/pedump",
|
31
|
+
"data/comp_id.txt",
|
30
32
|
"data/fs.txt",
|
31
33
|
"data/jc-userdb.txt",
|
32
34
|
"data/sig.bin",
|
@@ -47,8 +49,10 @@ Gem::Specification.new do |s|
|
|
47
49
|
"lib/pedump/packer.rb",
|
48
50
|
"lib/pedump/pe.rb",
|
49
51
|
"lib/pedump/resources.rb",
|
52
|
+
"lib/pedump/rich.rb",
|
50
53
|
"lib/pedump/security.rb",
|
51
54
|
"lib/pedump/sig_parser.rb",
|
55
|
+
"lib/pedump/te.rb",
|
52
56
|
"lib/pedump/tls.rb",
|
53
57
|
"lib/pedump/unpacker.rb",
|
54
58
|
"lib/pedump/unpacker/aspack.rb",
|
@@ -64,45 +68,32 @@ Gem::Specification.new do |s|
|
|
64
68
|
]
|
65
69
|
s.homepage = "http://github.com/zed-0xff/pedump".freeze
|
66
70
|
s.licenses = ["MIT".freeze]
|
67
|
-
s.rubygems_version = "2.
|
71
|
+
s.rubygems_version = "3.2.22".freeze
|
68
72
|
s.summary = "dump win32 PE executable files with a pure ruby".freeze
|
69
73
|
|
70
74
|
if s.respond_to? :specification_version then
|
71
75
|
s.specification_version = 4
|
76
|
+
end
|
72
77
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.3.9"])
|
84
|
-
else
|
85
|
-
s.add_dependency(%q<rainbow>.freeze, [">= 0"])
|
86
|
-
s.add_dependency(%q<awesome_print>.freeze, [">= 0"])
|
87
|
-
s.add_dependency(%q<iostruct>.freeze, [">= 0.0.4"])
|
88
|
-
s.add_dependency(%q<multipart-post>.freeze, [">= 2.0.0"])
|
89
|
-
s.add_dependency(%q<progressbar>.freeze, [">= 0"])
|
90
|
-
s.add_dependency(%q<zhexdump>.freeze, [">= 0.0.2"])
|
91
|
-
s.add_dependency(%q<rspec>.freeze, ["~> 3.9.0"])
|
92
|
-
s.add_dependency(%q<rspec-its>.freeze, ["~> 1.3.0"])
|
93
|
-
s.add_dependency(%q<bundler>.freeze, ["~> 2.1.4"])
|
94
|
-
s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.9"])
|
95
|
-
end
|
78
|
+
if s.respond_to? :add_runtime_dependency then
|
79
|
+
s.add_runtime_dependency(%q<rainbow>.freeze, [">= 0"])
|
80
|
+
s.add_runtime_dependency(%q<awesome_print>.freeze, [">= 0"])
|
81
|
+
s.add_runtime_dependency(%q<iostruct>.freeze, [">= 0.0.4"])
|
82
|
+
s.add_runtime_dependency(%q<multipart-post>.freeze, [">= 2.0.0"])
|
83
|
+
s.add_runtime_dependency(%q<zhexdump>.freeze, [">= 0.0.2"])
|
84
|
+
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.9.0"])
|
85
|
+
s.add_development_dependency(%q<rspec-its>.freeze, ["~> 1.3.0"])
|
86
|
+
s.add_development_dependency(%q<bundler>.freeze, ["~> 2.2.3"])
|
87
|
+
s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.3.9"])
|
96
88
|
else
|
97
89
|
s.add_dependency(%q<rainbow>.freeze, [">= 0"])
|
98
90
|
s.add_dependency(%q<awesome_print>.freeze, [">= 0"])
|
99
91
|
s.add_dependency(%q<iostruct>.freeze, [">= 0.0.4"])
|
100
92
|
s.add_dependency(%q<multipart-post>.freeze, [">= 2.0.0"])
|
101
|
-
s.add_dependency(%q<progressbar>.freeze, [">= 0"])
|
102
93
|
s.add_dependency(%q<zhexdump>.freeze, [">= 0.0.2"])
|
103
94
|
s.add_dependency(%q<rspec>.freeze, ["~> 3.9.0"])
|
104
95
|
s.add_dependency(%q<rspec-its>.freeze, ["~> 1.3.0"])
|
105
|
-
s.add_dependency(%q<bundler>.freeze, ["~> 2.
|
96
|
+
s.add_dependency(%q<bundler>.freeze, ["~> 2.2.3"])
|
106
97
|
s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.9"])
|
107
98
|
end
|
108
99
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pedump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey "Zed" Zaikin
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rainbow
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 2.0.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: progressbar
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: zhexdump
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,14 +114,14 @@ dependencies:
|
|
128
114
|
requirements:
|
129
115
|
- - "~>"
|
130
116
|
- !ruby/object:Gem::Version
|
131
|
-
version: 2.
|
117
|
+
version: 2.2.3
|
132
118
|
type: :development
|
133
119
|
prerelease: false
|
134
120
|
version_requirements: !ruby/object:Gem::Requirement
|
135
121
|
requirements:
|
136
122
|
- - "~>"
|
137
123
|
- !ruby/object:Gem::Version
|
138
|
-
version: 2.
|
124
|
+
version: 2.2.3
|
139
125
|
- !ruby/object:Gem::Dependency
|
140
126
|
name: jeweler
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -159,6 +145,7 @@ extra_rdoc_files:
|
|
159
145
|
- LICENSE.txt
|
160
146
|
- README.md
|
161
147
|
files:
|
148
|
+
- CODE_OF_CONDUCT.md
|
162
149
|
- Gemfile
|
163
150
|
- Gemfile.lock
|
164
151
|
- LICENSE.txt
|
@@ -166,6 +153,7 @@ files:
|
|
166
153
|
- Rakefile
|
167
154
|
- VERSION
|
168
155
|
- bin/pedump
|
156
|
+
- data/comp_id.txt
|
169
157
|
- data/fs.txt
|
170
158
|
- data/jc-userdb.txt
|
171
159
|
- data/sig.bin
|
@@ -186,8 +174,10 @@ files:
|
|
186
174
|
- lib/pedump/packer.rb
|
187
175
|
- lib/pedump/pe.rb
|
188
176
|
- lib/pedump/resources.rb
|
177
|
+
- lib/pedump/rich.rb
|
189
178
|
- lib/pedump/security.rb
|
190
179
|
- lib/pedump/sig_parser.rb
|
180
|
+
- lib/pedump/te.rb
|
191
181
|
- lib/pedump/tls.rb
|
192
182
|
- lib/pedump/unpacker.rb
|
193
183
|
- lib/pedump/unpacker/aspack.rb
|
@@ -204,7 +194,7 @@ homepage: http://github.com/zed-0xff/pedump
|
|
204
194
|
licenses:
|
205
195
|
- MIT
|
206
196
|
metadata: {}
|
207
|
-
post_install_message:
|
197
|
+
post_install_message:
|
208
198
|
rdoc_options: []
|
209
199
|
require_paths:
|
210
200
|
- lib
|
@@ -219,9 +209,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
219
209
|
- !ruby/object:Gem::Version
|
220
210
|
version: '0'
|
221
211
|
requirements: []
|
222
|
-
|
223
|
-
|
224
|
-
signing_key:
|
212
|
+
rubygems_version: 3.2.22
|
213
|
+
signing_key:
|
225
214
|
specification_version: 4
|
226
215
|
summary: dump win32 PE executable files with a pure ruby
|
227
216
|
test_files: []
|