pedump 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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]] ||= []