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
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
- require 'pedump/loader'
3
-
4
- describe PEdump::Loader do
5
- it "should read names from imports" do
6
- io = open("samples/calc.exe","rb")
7
- @ldr = PEdump::Loader.new io
8
-
9
- @ldr.names.should_not be_nil
10
- @ldr.names.should_not be_empty
11
- @ldr.names.size.should >= 343
12
- @ldr.names[0x10010d0].should == 'GetStartupInfoA'
13
- end
14
-
15
- it "should read names from exports" do
16
- io = open("samples/zlib.dll","rb")
17
- @ldr = PEdump::Loader.new io
18
-
19
- @ldr.names.should_not be_nil
20
- @ldr.names.should_not be_empty
21
- @ldr.names.size.should >= 69
22
- @ldr.names[0x1000e340].should == 'zlib_version'
23
- end
24
- end
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
- require 'pedump/loader'
3
-
4
- describe PEdump::Loader do
5
- describe "#valid_va?" do
6
- describe "samples/calc.exe" do
7
- before do
8
- io = open("samples/calc.exe","rb")
9
- @ldr = PEdump::Loader.new io
10
- end
11
-
12
- %w'1001000 1010000 104b999 104c000 1051000 109c000 10a01f5'.each do |x|
13
- it "returns true for 0x#{x}" do
14
- @ldr.valid_va?(x.to_i(16)).should be_true
15
- end
16
- end
17
-
18
- %w'0 1 1000 1000fff 104b99a 104bfff 1050fff 109bfff 10a01f6'.each do |x|
19
- it "returns false for 0x#{x}" do
20
- @ldr.valid_va?(x.to_i(16)).should be_false
21
- end
22
- end
23
- end
24
-
25
- describe "samples/upx.exe" do
26
- before do
27
- io = open("samples/upx.exe","rb")
28
- @ldr = PEdump::Loader.new io
29
- end
30
-
31
- %w'401000 541000 589000 589fff'.each do |x|
32
- it "returns true for 0x#{x}" do
33
- @ldr.valid_va?(x.to_i(16)).should be_true
34
- end
35
- end
36
-
37
- %w'0 1 1000 400000 58a000'.each do |x|
38
- it "returns false for 0x#{x}" do
39
- @ldr.valid_va?(x.to_i(16)).should be_false
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,22 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump')
3
-
4
- describe "corkami/manyimportsW7.exe" do
5
- before :all do
6
- @sample = sample
7
- end
8
-
9
- it "should have 2 imports" do
10
- @sample.imports.size.should == 2
11
- @sample.imports.map(&:module_name).should == %w'kernel32.dll msvcrt.dll'
12
- @sample.imports.map do |iid|
13
- (iid.original_first_thunk + iid.first_thunk).uniq.map(&:name)
14
- end.flatten.should == ["ExitProcess", "printf"]
15
- end
16
-
17
- it "should have 1 TLS" do
18
- @sample.tls.size.should == 1
19
- @sample.tls.first.AddressOfIndex.should == 0x401148
20
- @sample.tls.first.AddressOfCallBacks.should == 0x401100
21
- end
22
- end
@@ -1,125 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump')
3
-
4
- 5.times do |idx|
5
- fname = "ne#{idx}." + (idx==4 ? "dll" : "exe")
6
-
7
- modulenames = %w"_DELIS VISTA21P ISSET_SE HORSNCF MAPI"
8
- exports = []
9
-
10
- # ne0.exe
11
- exports << [
12
- PEdump::ExportedFunction.new("WNDPROC", 1, 0x10258)
13
- ]
14
-
15
- # ne1.exe
16
- exports << []
17
-
18
- # ne2.exe
19
- exports << [
20
- PEdump::ExportedFunction.new("LOGODLGPROC", 1, 0x13ACA),
21
- PEdump::ExportedFunction.new("BARWNDPROC", 2, 0x15FF0),
22
- PEdump::ExportedFunction.new("SETUPWNDPROC",3, 0x100B2),
23
- PEdump::ExportedFunction.new("LOGOBWNDPROC",4, 0x147B4),
24
- ]
25
-
26
- # ne3.exe
27
- exports << [
28
- PEdump::ExportedFunction.new("___EXPORTEDSTUB", 1, 0x63cf4),
29
- PEdump::ExportedFunction.new("_AFX_VERSION", 2, 0x4272c),
30
- ]
31
-
32
- # ne4.dll
33
- exports << [
34
- PEdump::ExportedFunction.new("WEP", 1, 0x10000),
35
- PEdump::ExportedFunction.new("BMAPIGETREADMAIL", 33, 0x7020A),
36
- PEdump::ExportedFunction.new("BMAPIRESOLVENAME", 38, 0x7077C),
37
- PEdump::ExportedFunction.new("BMAPIGETADDRESS", 36, 0x70692),
38
- PEdump::ExportedFunction.new("BMAPIFINDNEXT", 34, 0x70074),
39
- PEdump::ExportedFunction.new("BMAPIDETAILS", 37, 0x706F1),
40
- PEdump::ExportedFunction.new("MAPIFREEBUFFER", 18, 0xb0A71),
41
- PEdump::ExportedFunction.new("MAPIFINDNEXT", 16, 0xa0000),
42
- PEdump::ExportedFunction.new("MAPIDELETEMAIL", 17, 0x90000),
43
- PEdump::ExportedFunction.new("MAPIREADMAIL", 15, 0x100000),
44
- PEdump::ExportedFunction.new("BMAPIADDRESS", 35, 0x7051D),
45
- PEdump::ExportedFunction.new("MAPIADDRESS", 19, 0x60139),
46
- PEdump::ExportedFunction.new("MAPILOGON", 11, 0xc0000),
47
- PEdump::ExportedFunction.new("MAPISENDMAIL", 13, 0x130000),
48
- PEdump::ExportedFunction.new("MAPIRESOLVENAME", 21, 0x60A3F),
49
- PEdump::ExportedFunction.new("MAPIDETAILS", 20, 0x60752),
50
- PEdump::ExportedFunction.new("BMAPISAVEMAIL", 31, 0x70455),
51
- PEdump::ExportedFunction.new("MAPISAVEMAIL", 14, 0x1302BE),
52
- PEdump::ExportedFunction.new("BMAPIREADMAIL", 32, 0x70141),
53
- PEdump::ExportedFunction.new("MAPISENDDOCUMENTS", 10, 0x120703),
54
- PEdump::ExportedFunction.new("MAPILOGOFF", 12, 0xc00D2),
55
- PEdump::ExportedFunction.new("BMAPISENDMAIL", 30, 0x70000),
56
- ]
57
-
58
- imports = [
59
- ['KERNEL', 0x80],
60
- ['VBRUN300', 0x64],
61
- ['GDI', 0x15f],
62
- ['FINSTDLL', nil, 'FILECOPY'],
63
- ['DEMILAYR', 0x6f]
64
- ]
65
-
66
- versions = %w'2.20.900.0 - 3.0.111.0 1.0.0.1 3.2.0.4057'
67
-
68
- describe fname do
69
- it "should have NE header" do
70
- sample do |f|
71
- f.ne.should_not be_nil
72
- end
73
- end
74
-
75
- it "should not have PE header" do
76
- sample do |f|
77
- f.pe.should be_nil
78
- end
79
- end
80
-
81
- it "should have NE segments" do
82
- sample do |f|
83
- f.ne.segments.size.should == f.ne.ne_cseg
84
- end
85
- end
86
-
87
- it "should have NE resources" do
88
- sample do |f|
89
- f.ne.resources.should_not be_nil
90
- ver = f.ne.resources.find{ |res| res.type == 'VERSION' }
91
- expected = versions[idx]
92
- if expected == '-'
93
- ver.should be_nil
94
- else
95
- vi = ver.data.first
96
- [
97
- vi.Value.dwFileVersionMS.to_i >> 16,
98
- vi.Value.dwFileVersionMS.to_i & 0xffff,
99
- vi.Value.dwFileVersionLS.to_i >> 16,
100
- vi.Value.dwFileVersionLS.to_i & 0xffff
101
- ].join('.').should == expected
102
- end
103
- end
104
- end
105
-
106
- it "should have imports" do
107
- sample do |f|
108
- f.ne.imports.should_not be_nil
109
- func = PEdump::ImportedFunction.new
110
- func.module_name = imports[idx][0]
111
- func.ordinal = imports[idx][1]
112
- func.name = imports[idx][2]
113
-
114
- f.ne.imports.should include(func)
115
- end
116
- end
117
- it "should have exports" do
118
- sample do |f|
119
- f.ne.exports.should_not be_nil
120
- f.ne.exports.name.should == modulenames[idx]
121
- f.ne.exports.functions.should == exports[idx]
122
- end
123
- end
124
- end
125
- end
@@ -1,17 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump')
3
-
4
- %w'calc_upx.exe arm_upx.exe'.each do |fname|
5
- describe fname do
6
- before :all do
7
- File.open(File.join("samples",fname),"rb") do |f|
8
- @packer = PEdump.new(f).packer.first
9
- end
10
- end
11
-
12
- it "should detect UPX" do
13
- @packer.should_not be_nil
14
- @packer.name.should include 'UPX'
15
- end
16
- end
17
- end
@@ -1,67 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump')
3
-
4
- describe 'PE' do
5
- it "should assume TimeDateStamp is in UTC"
6
-
7
- KLASS = PEdump::ImportedFunction
8
-
9
- describe KLASS do
10
- it "should be equal" do
11
- pending "necessary?"
12
- a = []
13
- KLASS.new(*a).should == KLASS.new(*a)
14
- a = ['a']
15
- KLASS.new(*a).should == KLASS.new(*a)
16
- a = ['a','b']
17
- KLASS.new(*a).should == KLASS.new(*a)
18
- a = ['a','b','c']
19
- KLASS.new(*a).should == KLASS.new(*a)
20
- a = ['a','b','c','d']
21
- KLASS.new(*a).should == KLASS.new(*a)
22
- end
23
-
24
- it "should not be equal" do
25
- a = ['a']
26
- b = []
27
- KLASS.new(*a).should_not == KLASS.new(*b)
28
- a = ['a']
29
- b = ['b']
30
- KLASS.new(*a).should_not == KLASS.new(*b)
31
- a = ['a','B']
32
- b = ['a','b']
33
- KLASS.new(*a).should_not == KLASS.new(*b)
34
- a = ['a','b','c']
35
- b = ['a','b']
36
- KLASS.new(*a).should_not == KLASS.new(*b)
37
- a = ['a','b','c']
38
- b = ['a','b','X']
39
- KLASS.new(*a).should_not == KLASS.new(*b)
40
- end
41
-
42
- it "should be equal with different VA's" do
43
- pending "necessary?"
44
- a = ['a','b','c',nil]
45
- b = ['a','b','c','d']
46
- KLASS.new(*a).should == KLASS.new(*b)
47
- a = ['a','b','c',0x1000]
48
- b = ['a','b','c',0x2000]
49
- KLASS.new(*a).should == KLASS.new(*b)
50
- a = ['a','b','c',0x1000]
51
- b = ['a','b','c',0x1000]
52
- KLASS.new(*a).should == KLASS.new(*b)
53
- end
54
-
55
- it "should be equal in uniq() with different VA's" do
56
- a = ['a','b','c',nil]
57
- b = ['a','b','c','d']
58
- [KLASS.new(*a), KLASS.new(*b)].uniq.size.should == 1
59
- a = ['a','b','c',0x1000]
60
- b = ['a','b','c',0x2000]
61
- [KLASS.new(*a), KLASS.new(*b)].uniq.size.should == 1
62
- a = ['a','b','c',0x1000]
63
- b = ['a','b','c',0x1000]
64
- [KLASS.new(*a), KLASS.new(*b)].uniq.size.should == 1
65
- end
66
- end
67
- end
@@ -1,19 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe "PEdump#dump" do
4
- describe "should save packer" do
5
- it "when arg is a filename" do
6
- dump = PEdump.dump("samples/arm_upx.exe", :log_level => Logger::FATAL)
7
- dump.packers.size.should == 1
8
- dump.packers.first.name.should =~ /UPX/
9
- end
10
-
11
- it "when arg is an IO" do
12
- File.open("samples/arm_upx.exe", "rb") do |f|
13
- dump = PEdump.dump(f, :log_level => Logger::FATAL)
14
- dump.packers.size.should == 1
15
- dump.packers.first.name.should =~ /UPX/
16
- end
17
- end
18
- end
19
- end
@@ -1,13 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump')
3
-
4
- describe 'PEdump' do
5
- it "should get all resources" do
6
- fname = File.expand_path(File.dirname(__FILE__) + '/../samples/calc.exe')
7
- File.open(fname,"rb") do |f|
8
- @pedump = PEdump.new(fname)
9
- @resources = @pedump.resources(f)
10
- end
11
- @resources.size.should == 71
12
- end
13
- end
@@ -1,11 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump')
3
- require 'yaml'
4
-
5
- ['calc.exe', 'bad/data_dir_15_entries.exe'].each do |fname|
6
- describe fname do
7
- it "should match saved sections info" do
8
- sample.sections.should == YAML::load_file(File.join(DATA_DIR,"#{File.basename(fname)}_sections.yml"))
9
- end
10
- end
11
- end
@@ -1,24 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump/packer')
3
-
4
- describe "PEdump::Packer" do
5
- describe "matchers" do
6
- if ENV['SLOW']
7
- PEdump::SigParser.parse(:raw => true).each do |sig|
8
- data = sig.re.join
9
- next if data == "This program cannot be run in DOS mo"
10
- it "should find #{sig.name}" do
11
- a = PEdump::Packer.of(data).map(&:name)
12
- a.size.should > 0
13
-
14
- a = sig.name.split - a.join(' ').split - ['Exe','PE']
15
- a.delete_if{ |x| x[/[vV\.\/()\[\]]/] }
16
- p a if a.size > 1
17
- a.size.should < 2
18
- end
19
- end
20
- else
21
- pending "SLOW"
22
- end
23
- end
24
- end
@@ -1,68 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../lib/pedump/packer')
3
-
4
- describe "PEdump::Packer" do
5
- it "should have enough signatures" do
6
- PEdump::Packer.count.should > 1000
7
- end
8
-
9
- it "should not match" do
10
- maxlen = PEdump::Packer.map(&:size).max
11
- s = 'x'*maxlen
12
- PEdump::Packer.of_data(s).should be_nil
13
- end
14
-
15
- it "should parse" do
16
- a = PEdump::SigParser.parse
17
- a.should be_instance_of(Array)
18
- a.map(&:class).uniq.should == [PEdump::Packer]
19
- end
20
-
21
- it "should not react to DOS signature" do
22
- data = "This program cannot be run in DOS mode"
23
- PEdump::Packer.of(data).should be_nil
24
- end
25
-
26
- it "should match sigs" do
27
- n = 0
28
- File.open('data/signatures.txt', 'r:cp1252') do |f|
29
- while row = f.gets
30
- row.strip!
31
- next unless row =~ /^\[(.*)=(.*)\]$/
32
- s = ''
33
- title,hexstring = $1,$2
34
-
35
- # bad sigs
36
- next if hexstring == '909090909090909090909090909090909090909090909090909090909090909090909090'
37
- next if hexstring == 'E9::::0000000000000000'
38
-
39
- (hexstring.size/2).times do |i|
40
- c = hexstring[i*2,2]
41
- if c == '::'
42
- s << '.'
43
- else
44
- s << c.to_i(16).chr
45
- end
46
- end
47
- packers = PEdump::Packer.of(s)
48
- if packers
49
- names = packers.map(&:name)
50
- next if names.any? do |name|
51
- a = name.upcase.tr('V','')
52
- b = title.upcase.tr('V','')
53
- a[b] || b[a]
54
- end
55
- # puts "[.] #{title}"
56
- # names.each do |x|
57
- # puts "\t= #{x}"
58
- # end
59
- else
60
- puts "[?] #{title}: #{hexstring}"
61
- n += 1
62
- end
63
- end
64
- end
65
- #puts "[.] diff = #{n}"
66
- n.should == 0
67
- end
68
- end