pedump 0.5.0 → 0.6.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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.github/FUNDING.yml +2 -0
  3. data/.github/dependabot.yml +8 -0
  4. data/CODE_OF_CONDUCT.md +76 -0
  5. data/Gemfile +11 -16
  6. data/Gemfile.lock +73 -27
  7. data/README.md +15 -6
  8. data/Rakefile +5 -44
  9. data/VERSION +1 -1
  10. data/lib/pedump.rb +101 -29
  11. data/lib/pedump/cli.rb +29 -18
  12. data/lib/pedump/loader.rb +1 -1
  13. data/lib/pedump/loader/minidump.rb +195 -31
  14. data/lib/pedump/ne.rb +1 -1
  15. data/lib/pedump/pe.rb +63 -54
  16. data/lib/pedump/te.rb +51 -0
  17. data/lib/pedump/unpacker/aspack.rb +1 -1
  18. data/lib/pedump/version.rb +2 -5
  19. data/misc/aspack/aspack_unlzx.c +5 -3
  20. data/pedump.gemspec +47 -74
  21. metadata +50 -101
  22. data/.document +0 -5
  23. data/.rspec +0 -1
  24. data/.travis.yml +0 -4
  25. data/samples/bad/68.exe +0 -0
  26. data/samples/bad/data_dir_15_entries.exe +0 -0
  27. data/spec/65535sects_spec.rb +0 -8
  28. data/spec/bad_imports_spec.rb +0 -20
  29. data/spec/bad_samples_spec.rb +0 -13
  30. data/spec/composite_io_spec.rb +0 -122
  31. data/spec/data/calc.exe_sections.yml +0 -49
  32. data/spec/data/data_dir_15_entries.exe_sections.yml +0 -95
  33. data/spec/dllord_spec.rb +0 -21
  34. data/spec/foldedhdr_spec.rb +0 -28
  35. data/spec/imports_badterm_spec.rb +0 -52
  36. data/spec/imports_vterm_spec.rb +0 -52
  37. data/spec/loader/names_spec.rb +0 -24
  38. data/spec/loader/va_spec.rb +0 -44
  39. data/spec/manyimportsW7_spec.rb +0 -22
  40. data/spec/ne_spec.rb +0 -125
  41. data/spec/packer_spec.rb +0 -17
  42. data/spec/pe_spec.rb +0 -67
  43. data/spec/pedump_spec.rb +0 -19
  44. data/spec/resource_spec.rb +0 -13
  45. data/spec/sections_spec.rb +0 -11
  46. data/spec/sig_all_packers_spec.rb +0 -24
  47. data/spec/sig_spec.rb +0 -68
  48. data/spec/spec_helper.rb +0 -24
  49. data/spec/support/samples.rb +0 -24
  50. data/spec/unpackers/aspack_spec.rb +0 -69
  51. data/spec/unpackers/find_spec.rb +0 -21
  52. data/spec/virtsectblXP_spec.rb +0 -12
  53. data/tmp/.keep +0 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 73c28547719cedc77a48cbcd0b519283d09d061c358c24fd14fcff8e130072bf
4
+ data.tar.gz: 4444e01ee15c6920856ed30e63d118bc027758de0e696ea02d1c1bd3a6486bee
5
+ SHA512:
6
+ metadata.gz: d35bdf91d6081245a723b569837b7332baf0b61962747d6595a0afed6625fba3f15fa1e7ae5db9734ed7e08f03008031037254fc2df60f655c10b0e95db5d005
7
+ data.tar.gz: e9ac50ac19c5814f6364dde31dd0a16c0e263015e752c4a82b04e707c08a3e999255572c643da990ce9fabb4d3e624e85bdab53697e702044f941772fc96974e
@@ -0,0 +1,2 @@
1
+ #github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
2
+ ko_fi: zed_0xff
@@ -0,0 +1,8 @@
1
+ # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
2
+
3
+ version: 2
4
+ updates:
5
+ - package-ecosystem: bundler
6
+ directory: "/"
7
+ schedule:
8
+ interval: "weekly"
@@ -0,0 +1,76 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
9
+ level of experience, education, socio-economic status, nationality, personal
10
+ appearance, race, religion, or sexual identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at zed.0xff@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
+
73
+ [homepage]: https://www.contributor-covenant.org
74
+
75
+ For answers to common questions about this code of conduct, see
76
+ https://www.contributor-covenant.org/faq
data/Gemfile CHANGED
@@ -1,20 +1,15 @@
1
- source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
- gem "multipart-post", "~> 1.1.4"
6
- gem "progressbar"
1
+ source "https://rubygems.org"
2
+ #gemspec
3
+
4
+ gem 'rainbow'
7
5
  gem "awesome_print"
8
- gem "iostruct", ">= 0.0.4"
9
- gem "zhexdump", ">= 0.0.2"
6
+ gem "iostruct", ">= 0.0.4"
7
+ gem "multipart-post", ">= 2.0.0"
8
+ gem "zhexdump", ">= 0.0.2"
10
9
 
11
- # Add dependencies to develop your gem here.
12
- # Include everything needed to run rake, tests, features, etc.
13
10
  group :development do
14
- gem "rspec"
15
- gem "bundler"
16
- gem "jeweler"
17
- # gem "rcov", ">= 0"
18
- gem "what_methods"
19
- # gem "looksee"
11
+ gem "rspec", "~> 3.9.0"
12
+ gem "rspec-its", "~> 1.3.0"
13
+ gem "bundler", "~> 2.1.4"
14
+ gem "jeweler", "~> 2.3.9"
20
15
  end
@@ -1,30 +1,73 @@
1
1
  GEM
2
- remote: http://rubygems.org/
2
+ remote: https://rubygems.org/
3
3
  specs:
4
- awesome_print (1.1.0)
5
- diff-lcs (1.1.3)
6
- git (1.2.5)
4
+ addressable (2.4.0)
5
+ awesome_print (1.8.0)
6
+ builder (3.2.4)
7
+ descendants_tracker (0.0.4)
8
+ thread_safe (~> 0.3, >= 0.3.1)
9
+ diff-lcs (1.3)
10
+ faraday (0.9.2)
11
+ multipart-post (>= 1.2, < 3)
12
+ git (1.5.0)
13
+ github_api (0.16.0)
14
+ addressable (~> 2.4.0)
15
+ descendants_tracker (~> 0.0.4)
16
+ faraday (~> 0.8, < 0.10)
17
+ hashie (>= 3.4)
18
+ mime-types (>= 1.16, < 3.0)
19
+ oauth2 (~> 1.0)
20
+ hashie (4.0.0)
21
+ highline (2.0.3)
7
22
  iostruct (0.0.4)
8
- jeweler (1.8.4)
9
- bundler (~> 1.0)
23
+ jeweler (2.3.9)
24
+ builder
25
+ bundler
10
26
  git (>= 1.2.5)
27
+ github_api (~> 0.16.0)
28
+ highline (>= 1.6.15)
29
+ nokogiri (>= 1.5.10)
30
+ psych
11
31
  rake
12
32
  rdoc
13
- json (1.7.5)
14
- multipart-post (1.1.5)
15
- progressbar (0.12.0)
16
- rake (10.0.4)
17
- rdoc (3.12)
18
- json (~> 1.4)
19
- rspec (2.12.0)
20
- rspec-core (~> 2.12.0)
21
- rspec-expectations (~> 2.12.0)
22
- rspec-mocks (~> 2.12.0)
23
- rspec-core (2.12.1)
24
- rspec-expectations (2.12.0)
25
- diff-lcs (~> 1.1.3)
26
- rspec-mocks (2.12.0)
27
- what_methods (1.0.1)
33
+ semver2
34
+ jwt (2.2.1)
35
+ mime-types (2.99.3)
36
+ mini_portile2 (2.4.0)
37
+ multi_json (1.14.1)
38
+ multi_xml (0.6.0)
39
+ multipart-post (2.1.1)
40
+ nokogiri (1.10.8)
41
+ mini_portile2 (~> 2.4.0)
42
+ oauth2 (1.4.2)
43
+ faraday (>= 0.8, < 2.0)
44
+ jwt (>= 1.0, < 3.0)
45
+ multi_json (~> 1.3)
46
+ multi_xml (~> 0.5)
47
+ rack (>= 1.2, < 3)
48
+ psych (3.1.0)
49
+ rack (2.2.3)
50
+ rainbow (3.0.0)
51
+ rake (13.0.1)
52
+ rdoc (6.2.1)
53
+ rspec (3.9.0)
54
+ rspec-core (~> 3.9.0)
55
+ rspec-expectations (~> 3.9.0)
56
+ rspec-mocks (~> 3.9.0)
57
+ rspec-core (3.9.1)
58
+ rspec-support (~> 3.9.1)
59
+ rspec-expectations (3.9.0)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.9.0)
62
+ rspec-its (1.3.0)
63
+ rspec-core (>= 3.0.0)
64
+ rspec-expectations (>= 3.0.0)
65
+ rspec-mocks (3.9.1)
66
+ diff-lcs (>= 1.2.0, < 2.0)
67
+ rspec-support (~> 3.9.0)
68
+ rspec-support (3.9.2)
69
+ semver2 (3.4.2)
70
+ thread_safe (0.3.6)
28
71
  zhexdump (0.0.2)
29
72
 
30
73
  PLATFORMS
@@ -32,11 +75,14 @@ PLATFORMS
32
75
 
33
76
  DEPENDENCIES
34
77
  awesome_print
35
- bundler
78
+ bundler (~> 2.1.4)
36
79
  iostruct (>= 0.0.4)
37
- jeweler
38
- multipart-post (~> 1.1.4)
39
- progressbar
40
- rspec
41
- what_methods
80
+ jeweler (~> 2.3.9)
81
+ multipart-post (>= 2.0.0)
82
+ rainbow
83
+ rspec (~> 3.9.0)
84
+ rspec-its (~> 1.3.0)
42
85
  zhexdump (>= 0.0.2)
86
+
87
+ BUNDLED WITH
88
+ 2.1.4
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
- pedump [![Build Status](https://travis-ci.org/zed-0xff/pedump.png?branch=master)](https://travis-ci.org/zed-0xff/pedump) [![Dependency Status](https://gemnasium.com/zed-0xff/pedump.png)](https://gemnasium.com/zed-0xff/pedump)
1
+ pedump [![Build Status](https://travis-ci.org/zed-0xff/pedump.png?branch=master)](https://travis-ci.org/zed-0xff/pedump) [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/K3K81Z3W5)
2
2
  ======
3
3
 
4
+ News
5
+ ----
6
+ 2020.07.26 - now travis autotests run on ARM and OSX too!
7
+ 2020.07.25 - added EFI TE parsing; removed 'progressbar' gem dependency
8
+
4
9
  Description
5
10
  -----------
6
11
  A pure ruby implementation of win32 PE binary files dumper.
@@ -11,6 +16,7 @@ Supported formats:
11
16
  * win16 NE
12
17
  * win32 PE
13
18
  * win64 PE
19
+ * EFI TE
14
20
 
15
21
  Can dump:
16
22
 
@@ -43,13 +49,14 @@ Usage
43
49
  (can be used multiple times)
44
50
  -F, --force Try to dump by all means
45
51
  (can cause exceptions & heavy wounds)
46
- -f, --format FORMAT Output format: bin,c,dump,hex,inspect,table,yaml
52
+ -f, --format FORMAT Output format: bin,c,dump,hex,inspect,json,table,yaml
47
53
  (default: table)
48
54
  --mz
49
55
  --dos-stub
50
56
  --rich
51
57
  --pe
52
58
  --ne
59
+ --te
53
60
  --data-directory
54
61
  -S, --sections
55
62
  --tls
@@ -67,9 +74,11 @@ Usage
67
74
  -r, --recursive recurse dirs in packer detect
68
75
  --all Dump all but resource-directory (default)
69
76
  --va2file VA Convert RVA to file offset
77
+
70
78
  -W, --web Uploads files to a http://pedump.me
71
79
  for a nice HTML tables with image previews,
72
80
  candies & stuff
81
+ -C, --console opens IRB console with specified file loaded
73
82
 
74
83
  ### MZ Header
75
84
 
@@ -107,10 +116,10 @@ Usage
107
116
 
108
117
  === DOS STUB ===
109
118
 
110
- 00000000: 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 |........!..L.!Th|
111
- 00000010: 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f |is program canno|
112
- 00000020: 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 |t be run in DOS |
113
- 00000030: 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 |mode....$.......|
119
+ 00000000: 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 |........!..L.!Th|
120
+ 00000010: 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f |is program canno|
121
+ 00000020: 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 |t be run in DOS |
122
+ 00000030: 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 |mode....$.......|
114
123
 
115
124
  ### 'Rich' Header
116
125
 
data/Rakefile CHANGED
@@ -23,59 +23,20 @@ Jeweler::Tasks.new do |gem|
23
23
  gem.authors = ["Andrey \"Zed\" Zaikin"]
24
24
  gem.executables = %w'pedump'
25
25
  gem.files.include "lib/**/*.rb"
26
- gem.files.include "data/*.bin"
27
- gem.files.include "data/*.txt"
28
-
29
- gem.files.exclude "samples/*", "README.md.tpl"
30
- gem.extra_rdoc_files.exclude "README.md.tpl"
26
+ gem.files.exclude %w'samples/**/* spec/**/* tmp/**/* tmp/.keep .* README.md.tpl'
27
+ gem.extra_rdoc_files.exclude 'README.md.tpl'
28
+ # dependencies defined in Gemfile
31
29
  end
32
30
  Jeweler::RubygemsDotOrgTasks.new
33
31
 
34
32
  require 'rspec/core'
35
33
  require 'rspec/core/rake_task'
36
- RSpec::Core::RakeTask.new(:spec) do |spec|
37
- spec.pattern = FileList['spec/**/*_spec.rb']
38
- end
39
34
 
40
- RSpec::Core::RakeTask.new(:rcov) do |spec|
41
- spec.pattern = 'spec/**/*_spec.rb'
42
- spec.rcov = true
43
- end
35
+ desc "run specs"
36
+ RSpec::Core::RakeTask.new
44
37
 
45
38
  task :default => :spec
46
39
 
47
- #require 'rake/rdoctask'
48
- #Rake::RDocTask.new do |rdoc|
49
- # version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
- #
51
- # rdoc.rdoc_dir = 'rdoc'
52
- # rdoc.title = "pedump #{version}"
53
- # rdoc.rdoc_files.include('README*')
54
- # rdoc.rdoc_files.include('lib/**/*.rb')
55
- #end
56
-
57
- class Jeweler::Commands::Version::Base
58
- alias :commit_version_old :commit_version
59
- def commit_version
60
- code = <<-EOF
61
- class PEdump
62
- module Version
63
- MAJOR = #{version_helper.major}
64
- MINOR = #{version_helper.minor}
65
- PATCH = #{version_helper.patch}
66
- BUILD = nil
67
-
68
- STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
69
- end
70
- end
71
- EOF
72
- vfile = working_subdir.join("lib/pedump/version.rb")
73
- File.open(vfile,"w"){ |f| f << code }
74
- self.repo.add vfile if self.repo
75
- commit_version_old
76
- end
77
- end
78
-
79
40
  namespace :test do
80
41
  desc "test on all files in given path"
81
42
  task :all_files do
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
@@ -2,6 +2,7 @@
2
2
  require 'stringio'
3
3
  require 'iostruct'
4
4
  require 'zhexdump'
5
+ require 'set'
5
6
 
6
7
  unless Object.new.respond_to?(:try) && nil.respond_to?(:try)
7
8
  require 'pedump/core_ext/try'
@@ -16,6 +17,7 @@ require 'pedump/security'
16
17
  require 'pedump/packer'
17
18
  require 'pedump/ne'
18
19
  require 'pedump/ne/version_info'
20
+ require 'pedump/te'
19
21
 
20
22
  # pedump.rb by zed_0xff
21
23
  #
@@ -27,6 +29,10 @@ class PEdump
27
29
 
28
30
  VERSION = Version::STRING
29
31
  MAX_ERRORS = 100
32
+ MAX_IMAGE_IMPORT_DESCRIPTORS = 1000
33
+ MAX_EXPORT_NUMBER_OF_NAMES = 16384 # got 7977 in http://pedump.me/03ad7400080678c6b1984f995d36fd04
34
+ GOOD_FUNCTION_NAME_RE = /\A[\x21-\x7f]+\Z/
35
+ SUPPORTED_SIGNATURES = ['MZ', 'ZM', 'VZ']
30
36
 
31
37
  @@logger = nil
32
38
 
@@ -318,9 +324,9 @@ class PEdump
318
324
  @mz ||= f && MZ.read(f).tap do |mz|
319
325
  if mz.signature != 'MZ' && mz.signature != 'ZM'
320
326
  if @force
321
- logger.warn "[?] no MZ signature. want: 'MZ' or 'ZM', got: #{mz.signature.inspect}"
327
+ #logger.warn "[?] no MZ signature. want: 'MZ' or 'ZM', got: #{mz.signature.inspect}"
322
328
  else
323
- logger.error "[!] no MZ signature. want: 'MZ' or 'ZM', got: #{mz.signature.inspect}. (not forced)"
329
+ #logger.error "[!] no MZ signature. want: 'MZ' or 'ZM', got: #{mz.signature.inspect}. (not forced)"
324
330
  return nil
325
331
  end
326
332
  end
@@ -427,16 +433,22 @@ class PEdump
427
433
  end
428
434
 
429
435
  def _dump_handle h
430
- return unless pe(h) # also calls mz(h)
431
- rich_hdr h
432
- resources h
433
- imports h # also calls tls(h)
434
- exports h
435
- packer h
436
+ if pe(h) # also calls mz(h)
437
+ rich_hdr h
438
+ resources h
439
+ imports h # also calls tls(h)
440
+ exports h
441
+ packer h
442
+ elsif te(h)
443
+ end
436
444
  end
437
445
 
438
446
  def data_directory f=@io
439
- pe(f) && pe.ioh && pe.ioh.DataDirectory
447
+ if pe(f)
448
+ pe.ioh && pe.ioh.DataDirectory
449
+ elsif te(f)
450
+ te.DataDirectory
451
+ end
440
452
  end
441
453
 
442
454
  def sections f=@io
@@ -444,16 +456,52 @@ class PEdump
444
456
  pe.section_table
445
457
  elsif ne(f)
446
458
  ne.segments
459
+ elsif te(f)
460
+ te.sections
447
461
  end
448
462
  end
449
463
  alias :section_table :sections
450
464
 
451
- def ne?
452
- @pe ? false : (@ne ? true : (pe ? false : (ne ? true : false)))
465
+ def supported_file? f=@io
466
+ pos = f.tell
467
+ sig = f.read(2)
468
+ f.seek(pos)
469
+ if SUPPORTED_SIGNATURES.include?(sig)
470
+ true
471
+ else
472
+ unless @not_supported_sig_warned
473
+ msg = "no supported signature. want: #{SUPPORTED_SIGNATURES.join("/")}, got: #{sig.inspect}"
474
+ if @force
475
+ logger.warn "[?] #{msg}"
476
+ else
477
+ logger.error "[!] #{msg}. (not forced)"
478
+ end
479
+ @not_supported_sig_warned = true
480
+ end
481
+ false
482
+ end
483
+ end
484
+
485
+ def _detect_format
486
+ return :pe if @pe
487
+ return :ne if @ne
488
+ return :te if @te
489
+ return :pe if pe()
490
+ return :ne if ne()
491
+ return :te if te()
492
+ nil
453
493
  end
454
494
 
455
495
  def pe?
456
- @pe ? true : (@ne ? false : (pe ? true : false ))
496
+ _detect_format() == :pe
497
+ end
498
+
499
+ def ne?
500
+ _detect_format() == :ne
501
+ end
502
+
503
+ def te?
504
+ _detect_format() == :te
457
505
  end
458
506
 
459
507
  ##############################################################################
@@ -474,9 +522,10 @@ class PEdump
474
522
  :first_thunk
475
523
 
476
524
  class ImportedFunction < Struct.new(:hint, :name, :ordinal, :va, :module_name)
477
- # def == x
478
- # self.hint == x.hint && self.name == x.name && self.ordinal == x.ordinal
479
- # end
525
+ def == x
526
+ self.hint == x.hint && self.name == x.name && self.ordinal == x.ordinal &&
527
+ self.module_name == x.module_name
528
+ end
480
529
  # def <=> x
481
530
  # self.to_a[0..-2] <=> x.to_a[0..-2]
482
531
  # end
@@ -526,7 +575,11 @@ class PEdump
526
575
  # http://code.google.com/p/corkami/source/browse/trunk/asm/PE/manyimportsW7.asm
527
576
  break
528
577
  end
529
- t=IMAGE_IMPORT_DESCRIPTOR.read(f)
578
+ if r.size >= MAX_IMAGE_IMPORT_DESCRIPTORS
579
+ logger.warn "[!] too many IMAGE_IMPORT_DESCRIPTORs, not reading more than #{r.size}"
580
+ break
581
+ end
582
+ t = IMAGE_IMPORT_DESCRIPTOR.read(f)
530
583
  break if t.Name.to_i == 0 # also catches EOF
531
584
  r << t
532
585
  file_offset += IMAGE_IMPORT_DESCRIPTOR::SIZE
@@ -535,8 +588,16 @@ class PEdump
535
588
  logger.warn "[?] imports info beyond EOF"
536
589
  end
537
590
 
591
+ n_bad_names = 0
538
592
  logger.warn "[?] non-empty last IMAGE_IMPORT_DESCRIPTOR: #{t.inspect}" if t && !t.empty?
539
- @imports = r.each do |x|
593
+ @imports = r
594
+ r = nil
595
+ @imports.each_with_index do |x, iidx|
596
+ if n_bad_names > MAX_ERRORS
597
+ logger.warn "[!] too many bad imported function names. skipping further imports parsing"
598
+ @imports = @imports[0,iidx]
599
+ break
600
+ end
540
601
  if x.Name.to_i != 0 && (ofs = va2file(x.Name))
541
602
  begin
542
603
  f.seek ofs
@@ -571,12 +632,18 @@ class PEdump
571
632
  logger.warn "[?] import ofs 0x#{ofs.to_s(16)} VA=0x#{t.to_s(16)} beyond EOF"
572
633
  nil
573
634
  else
574
- ImportedFunction.new(
575
- f.read(2).unpack('v').first,
576
- f.gets("\x00").chomp("\x00"),
577
- nil,
578
- va
579
- )
635
+ hint = f.read(2).unpack('v').first
636
+ name = f.gets("\x00").chomp("\x00")
637
+ if !name.empty? && name !~ GOOD_FUNCTION_NAME_RE
638
+ n_bad_names += 1
639
+ if n_bad_names > MAX_ERRORS
640
+ nil
641
+ else
642
+ ImportedFunction.new(hint, name, nil, va)
643
+ end
644
+ else
645
+ ImportedFunction.new(hint, name, nil, va)
646
+ end
580
647
  end
581
648
  elsif tbl == :original_first_thunk
582
649
  # OriginalFirstThunk entries can not be invalid, show a warning msg
@@ -591,7 +658,7 @@ class PEdump
591
658
  end
592
659
  end
593
660
  x[tbl] && x[tbl].compact!
594
- end
661
+ end # [:original_first_thunk, :first_thunk].each
595
662
  if x.original_first_thunk && !x.first_thunk
596
663
  logger.warn "[?] import table: empty FirstThunk for #{x.module_name}"
597
664
  elsif !x.original_first_thunk && x.first_thunk
@@ -602,7 +669,8 @@ class PEdump
602
669
  logger.debug "[?] import table: OriginalFirstThunk != FirstThunk for #{x.module_name}"
603
670
  end
604
671
  end
605
- end
672
+ end # r.each
673
+ @imports
606
674
  end
607
675
 
608
676
  ##############################################################################
@@ -626,7 +694,11 @@ class PEdump
626
694
  :name, :entry_points, :names, :name_ordinals, :functions,
627
695
  :description # NE only
628
696
 
629
- ExportedFunction = Struct.new :name, :ord, :va, :file_offset
697
+ class ExportedFunction < Struct.new :name, :ord, :va, :file_offset
698
+ def ordinal
699
+ self.ord
700
+ end
701
+ end
630
702
 
631
703
  def exports f=@io
632
704
  if pe(f)
@@ -715,9 +787,9 @@ class PEdump
715
787
  ord2name = {}
716
788
  if x.names && x.names.any?
717
789
  n = x.NumberOfNames
718
- if n > 2048
719
- logger.warn "[?] NumberOfNames too big (#{x.NumberOfNames}), limiting to 2048"
720
- n = 2048
790
+ if n > MAX_EXPORT_NUMBER_OF_NAMES
791
+ logger.warn "[?] NumberOfNames too big (#{x.NumberOfNames}), limiting to #{MAX_EXPORT_NUMBER_OF_NAMES}"
792
+ n = MAX_EXPORT_NUMBER_OF_NAMES
721
793
  end
722
794
  n.times do |i|
723
795
  ord2name[x.name_ordinals[i]] ||= []