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.
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 http://pedump.me/03ad7400080678c6b1984f995d36fd04
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[4..-9].sub(/\A(#{Regexp::escape(key)}){3}/,'').xor(key)
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#{va.to_i.to_s(16)} (quiet=true)"
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#{va.to_i.to_s(16)}"
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
- return unless pe(h) # also calls mz(h)
435
- rich_hdr h
436
- resources h
437
- imports h # also calls tls(h)
438
- exports h
439
- packer h
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) && pe.ioh && pe.ioh.DataDirectory
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 ne?
456
- @pe ? false : (@ne ? true : (pe ? false : (ne ? true : false)))
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
- @pe ? true : (@ne ? false : (pe ? true : false ))
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
@@ -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
- decoded_size = DecodeLZX(&LZX, packed_data, unpacked_data, packed_size, unpacked_size);
42
- if ( decoded_size < 0 || decoded_size < unpacked_size ) {
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", argv[0]);
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.4 ruby lib
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.5.4"
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 = "2020-01-25"
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.7.10".freeze
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
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
74
- s.add_runtime_dependency(%q<rainbow>.freeze, [">= 0"])
75
- s.add_runtime_dependency(%q<awesome_print>.freeze, [">= 0"])
76
- s.add_runtime_dependency(%q<iostruct>.freeze, [">= 0.0.4"])
77
- s.add_runtime_dependency(%q<multipart-post>.freeze, [">= 2.0.0"])
78
- s.add_runtime_dependency(%q<progressbar>.freeze, [">= 0"])
79
- s.add_runtime_dependency(%q<zhexdump>.freeze, [">= 0.0.2"])
80
- s.add_development_dependency(%q<rspec>.freeze, ["~> 3.9.0"])
81
- s.add_development_dependency(%q<rspec-its>.freeze, ["~> 1.3.0"])
82
- s.add_development_dependency(%q<bundler>.freeze, ["~> 2.1.4"])
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.1.4"])
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.5.4
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: 2020-01-25 00:00:00.000000000 Z
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.1.4
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.1.4
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
- rubyforge_project:
223
- rubygems_version: 2.7.10
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: []