pedump 0.2.1 → 0.3.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.
- data/Gemfile +2 -0
- data/Gemfile.lock +6 -0
- data/Rakefile +26 -0
- data/VERSION +1 -1
- data/lib/pedump.rb +92 -17
- data/lib/pedump/cli.rb +118 -18
- data/pedump.gemspec +8 -2
- metadata +33 -11
data/Gemfile
CHANGED
@@ -2,6 +2,8 @@ source "http://rubygems.org"
|
|
2
2
|
# Add dependencies required to use your gem here.
|
3
3
|
# Example:
|
4
4
|
# gem "activesupport", ">= 2.3.5"
|
5
|
+
gem "rest-client", "~> 1.6.7"
|
6
|
+
gem "progressbar", "~> 0.9.2"
|
5
7
|
|
6
8
|
# Add dependencies to develop your gem here.
|
7
9
|
# Include everything needed to run rake, tests, features, etc.
|
data/Gemfile.lock
CHANGED
@@ -7,8 +7,12 @@ GEM
|
|
7
7
|
bundler (~> 1.0)
|
8
8
|
git (>= 1.2.5)
|
9
9
|
rake
|
10
|
+
mime-types (1.16)
|
11
|
+
progressbar (0.9.2)
|
10
12
|
rake (0.9.2.2)
|
11
13
|
rcov (0.9.11)
|
14
|
+
rest-client (1.6.7)
|
15
|
+
mime-types (>= 1.16)
|
12
16
|
rspec (2.3.0)
|
13
17
|
rspec-core (~> 2.3.0)
|
14
18
|
rspec-expectations (~> 2.3.0)
|
@@ -24,5 +28,7 @@ PLATFORMS
|
|
24
28
|
DEPENDENCIES
|
25
29
|
bundler (~> 1.0.0)
|
26
30
|
jeweler (~> 1.6.4)
|
31
|
+
progressbar (~> 0.9.2)
|
27
32
|
rcov
|
33
|
+
rest-client (~> 1.6.7)
|
28
34
|
rspec (~> 2.3.0)
|
data/Rakefile
CHANGED
@@ -49,3 +49,29 @@ task :default => :spec
|
|
49
49
|
# rdoc.rdoc_files.include('README*')
|
50
50
|
# rdoc.rdoc_files.include('lib/**/*.rb')
|
51
51
|
#end
|
52
|
+
|
53
|
+
namespace :test do
|
54
|
+
desc "test on all files in given path"
|
55
|
+
task :all_files do
|
56
|
+
require './lib/pedump'
|
57
|
+
require './lib/pedump/cli'
|
58
|
+
path = ENV['path'] || raise("run me with path=...")
|
59
|
+
`find #{path} -type f`.split("\n").each do |fname|
|
60
|
+
puts "\n### #{fname}\n"
|
61
|
+
PEdump::CLI.new(fname).run
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
namespace :all_files do
|
66
|
+
desc "output file name to stderr, use with stdout redirection"
|
67
|
+
task :stderr do
|
68
|
+
require './lib/pedump'
|
69
|
+
require './lib/pedump/cli'
|
70
|
+
path = ENV['path'] || raise("run me with path=...")
|
71
|
+
`find #{path} -type f`.split("\n").each do |fname|
|
72
|
+
STDERR.puts "\n### #{fname}\n"
|
73
|
+
PEdump::CLI.new(fname).run
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/pedump.rb
CHANGED
@@ -303,13 +303,17 @@ class PEdump
|
|
303
303
|
end
|
304
304
|
|
305
305
|
def dexor
|
306
|
-
self[4..-9].sub(/\A(#{Regexp::escape(key)})
|
306
|
+
self[4..-9].sub(/\A(#{Regexp::escape(key)}){3}/,'').xor(key)
|
307
307
|
end
|
308
308
|
|
309
309
|
def decode
|
310
310
|
x = dexor
|
311
|
-
|
312
|
-
|
311
|
+
if x.size%8 == 0
|
312
|
+
x.unpack('vvV'*(x.size/8)).each_slice(3).map{ |slice| Entry.new(*slice)}
|
313
|
+
else
|
314
|
+
PEdump.logger.error "[?] #{self.class}: dexored size(#{x.size}) must be a multiple of 8"
|
315
|
+
nil
|
316
|
+
end
|
313
317
|
end
|
314
318
|
end
|
315
319
|
|
@@ -441,6 +445,8 @@ class PEdump
|
|
441
445
|
def _dump_handle h
|
442
446
|
rich_hdr(h) # includes mz(h)
|
443
447
|
resources(h) # includes pe(h)
|
448
|
+
imports h
|
449
|
+
exports h
|
444
450
|
end
|
445
451
|
|
446
452
|
def data_directory f=nil
|
@@ -472,16 +478,19 @@ class PEdump
|
|
472
478
|
ImportedFunction = Struct.new(:hint, :name, :ordinal)
|
473
479
|
|
474
480
|
def imports f=nil
|
481
|
+
return @imports if @imports
|
475
482
|
return nil unless pe(f) && pe(f).ioh && f
|
476
483
|
dir = @pe.ioh.DataDirectory[IMAGE_DATA_DIRECTORY::IMPORT]
|
477
484
|
return [] if !dir || (dir.va == 0 && dir.size == 0)
|
478
485
|
va = @pe.ioh.DataDirectory[IMAGE_DATA_DIRECTORY::IMPORT].va
|
479
|
-
|
486
|
+
file_offset = va2file(va)
|
487
|
+
return nil unless file_offset
|
488
|
+
f.seek file_offset
|
480
489
|
r = []
|
481
490
|
until (t=IMAGE_IMPORT_DESCRIPTOR.read(f)).empty?
|
482
491
|
r << t
|
483
492
|
end
|
484
|
-
r.each do |x|
|
493
|
+
@imports = r.each do |x|
|
485
494
|
if x.Name.to_i != 0 && (va = va2file(x.Name))
|
486
495
|
f.seek va
|
487
496
|
x.module_name = f.gets("\x00").chop
|
@@ -539,15 +548,21 @@ class PEdump
|
|
539
548
|
:AddressOfNames,
|
540
549
|
:AddressOfNameOrdinals,
|
541
550
|
# manual:
|
542
|
-
:name, :entry_points, :names, :
|
551
|
+
:name, :entry_points, :names, :name_ordinals
|
543
552
|
|
544
553
|
def exports f=nil
|
554
|
+
return @exports if @exports
|
545
555
|
return nil unless pe(f) && pe(f).ioh && f
|
546
556
|
dir = @pe.ioh.DataDirectory[IMAGE_DATA_DIRECTORY::EXPORT]
|
547
557
|
return [] if !dir || (dir.va == 0 && dir.size == 0)
|
548
558
|
va = @pe.ioh.DataDirectory[IMAGE_DATA_DIRECTORY::EXPORT].va
|
549
|
-
|
550
|
-
|
559
|
+
file_offset = va2file(va)
|
560
|
+
return nil unless file_offset
|
561
|
+
f.seek file_offset
|
562
|
+
@exports = IMAGE_EXPORT_DIRECTORY.read(f).tap do |x|
|
563
|
+
x.entry_points = []
|
564
|
+
x.name_ordinals = []
|
565
|
+
x.names = []
|
551
566
|
if x.Name.to_i != 0 && (va = va2file(x.Name))
|
552
567
|
f.seek va
|
553
568
|
x.name = f.gets("\x00").chop
|
@@ -559,7 +574,7 @@ class PEdump
|
|
559
574
|
end
|
560
575
|
if x.AddressOfNameOrdinals.to_i !=0 && (va = va2file(x.AddressOfNameOrdinals))
|
561
576
|
f.seek va
|
562
|
-
x.
|
577
|
+
x.name_ordinals = f.read(x.NumberOfNames*2).unpack('v*').map{ |o| o+x.Base }
|
563
578
|
end
|
564
579
|
end
|
565
580
|
if x.NumberOfNames.to_i != 0 && x.AddressOfNames.to_i !=0 && (va = va2file(x.AddressOfNames))
|
@@ -658,6 +673,13 @@ class PEdump
|
|
658
673
|
return va - s.VirtualAddress + s.PointerToRawData
|
659
674
|
end
|
660
675
|
end
|
676
|
+
# not found with regular search. assume any of VirtualSize was 0, and try with RawSize
|
677
|
+
sections.each do |s|
|
678
|
+
if (s.VirtualAddress...(s.VirtualAddress+s.SizeOfRawData)).include?(va)
|
679
|
+
return va - s.VirtualAddress + s.PointerToRawData
|
680
|
+
end
|
681
|
+
end
|
682
|
+
logger.error "[?] can't find file_offset of VA 0x#{va.to_i.to_s(16)}"
|
661
683
|
nil
|
662
684
|
end
|
663
685
|
|
@@ -673,11 +695,11 @@ class PEdump
|
|
673
695
|
end
|
674
696
|
f.seek res_section.PointerToRawData
|
675
697
|
IMAGE_RESOURCE_DIRECTORY.base = res_section.PointerToRawData
|
676
|
-
|
698
|
+
#@resource_data_base = res_section.PointerToRawData - res_section.VirtualAddress
|
677
699
|
IMAGE_RESOURCE_DIRECTORY.read(f)
|
678
700
|
end
|
679
701
|
|
680
|
-
class Resource < Struct.new(:type, :name, :id, :lang, :file_offset, :size, :cp, :reserved, :data)
|
702
|
+
class Resource < Struct.new(:type, :name, :id, :lang, :file_offset, :size, :cp, :reserved, :data, :valid)
|
681
703
|
def bitmap_hdr
|
682
704
|
bmp_info_hdr = data.find{ |x| x.is_a?(BITMAPINFOHEADER) }
|
683
705
|
raise "no BITMAPINFOHEADER for #{self.type} #{self.name}" unless bmp_info_hdr
|
@@ -765,23 +787,70 @@ class PEdump
|
|
765
787
|
when 'GROUP_CURSOR'
|
766
788
|
f.seek file_offset
|
767
789
|
data << CUR_ICO_HEADER.read(f)
|
790
|
+
nRead = CUR_ICO_HEADER::SIZE
|
768
791
|
data.last.wNumImages.times do
|
769
|
-
|
792
|
+
if nRead >= self.size
|
793
|
+
PEdump.logger.error "[!] refusing to read CURDIRENTRY beyond resource size"
|
794
|
+
break
|
795
|
+
end
|
796
|
+
data << CURDIRENTRY.read(f)
|
797
|
+
nRead += CURDIRENTRY::SIZE
|
770
798
|
end
|
771
799
|
when 'GROUP_ICON'
|
772
800
|
f.seek file_offset
|
773
801
|
data << CUR_ICO_HEADER.read(f)
|
802
|
+
nRead = CUR_ICO_HEADER::SIZE
|
774
803
|
data.last.wNumImages.times do
|
775
|
-
|
804
|
+
if nRead >= self.size
|
805
|
+
PEdump.logger.error "[!] refusing to read ICODIRENTRY beyond resource size"
|
806
|
+
break
|
807
|
+
end
|
808
|
+
data << ICODIRENTRY.read(f)
|
809
|
+
nRead += ICODIRENTRY::SIZE
|
776
810
|
end
|
777
811
|
when 'STRING'
|
778
812
|
f.seek file_offset
|
779
813
|
16.times do
|
780
|
-
|
781
|
-
|
814
|
+
break if f.tell >= file_offset+self.size
|
815
|
+
nChars = f.read(2).to_s.unpack('v').first.to_i
|
816
|
+
t =
|
817
|
+
if nChars*2 + 1 > self.size
|
818
|
+
# TODO: if it's not 1st string in table then truncated size must be less
|
819
|
+
PEdump.logger.error "[!] string size(#{nChars*2}) > stringtable size(#{self.size}). truncated to #{self.size-2}"
|
820
|
+
f.read(self.size-2)
|
821
|
+
else
|
822
|
+
f.read(nChars*2)
|
823
|
+
end
|
824
|
+
data <<
|
825
|
+
begin
|
826
|
+
t.force_encoding('UTF-16LE').encode!('UTF-8')
|
827
|
+
rescue
|
828
|
+
t.force_encoding('ASCII')
|
829
|
+
tt = t.size > 0x10 ? t[0,0x10].inspect+'...' : t.inspect
|
830
|
+
PEdump.logger.error "[!] cannot convert #{tt} to UTF-16"
|
831
|
+
[nChars,t].pack('va*')
|
832
|
+
end
|
782
833
|
end
|
783
834
|
# XXX: check if readed strings summary length is less than resource data length
|
784
835
|
end
|
836
|
+
|
837
|
+
data.delete_if do |x|
|
838
|
+
valid = !x.respond_to?(:valid?) || x.valid?
|
839
|
+
PEdump.logger.warn "[?] ignoring invalid #{x.class}" unless valid
|
840
|
+
!valid
|
841
|
+
end
|
842
|
+
ensure
|
843
|
+
validate
|
844
|
+
end
|
845
|
+
|
846
|
+
def validate
|
847
|
+
self.valid =
|
848
|
+
case type
|
849
|
+
when 'BITMAP','ICON','CURSOR'
|
850
|
+
data.any?{ |x| x.is_a?(BITMAPINFOHEADER) && x.valid? }
|
851
|
+
else
|
852
|
+
true
|
853
|
+
end
|
785
854
|
end
|
786
855
|
end
|
787
856
|
|
@@ -799,7 +868,7 @@ class PEdump
|
|
799
868
|
|
800
869
|
# see also http://www.informit.com/articles/article.aspx?p=1186882 about icons format
|
801
870
|
|
802
|
-
BITMAPINFOHEADER
|
871
|
+
class BITMAPINFOHEADER < create_struct 'V3v2V6',
|
803
872
|
:biSize, # BITMAPINFOHEADER::SIZE
|
804
873
|
:biWidth,
|
805
874
|
:biHeight,
|
@@ -812,6 +881,11 @@ class PEdump
|
|
812
881
|
:biClrUsed,
|
813
882
|
:biClrImportant
|
814
883
|
|
884
|
+
def valid?
|
885
|
+
self.biSize == 40
|
886
|
+
end
|
887
|
+
end
|
888
|
+
|
815
889
|
# http://www.devsource.com/c/a/Architecture/Resources-From-PE-I/2/
|
816
890
|
CUR_ICO_HEADER = create_struct('v3',
|
817
891
|
:wReserved, # always 0
|
@@ -878,7 +952,8 @@ class PEdump
|
|
878
952
|
entry.name,
|
879
953
|
nil, # id
|
880
954
|
entry.Name, # lang
|
881
|
-
entry.data.OffsetToData + @resource_data_base,
|
955
|
+
#entry.data.OffsetToData + @resource_data_base,
|
956
|
+
va2file(entry.data.OffsetToData),
|
882
957
|
entry.data.Size,
|
883
958
|
entry.data.CodePage,
|
884
959
|
entry.data.Reserved
|
data/lib/pedump/cli.rb
CHANGED
@@ -14,10 +14,12 @@ class PEdump::CLI
|
|
14
14
|
|
15
15
|
KNOWN_ACTIONS = (
|
16
16
|
%w'mz dos_stub rich pe data_directory sections' +
|
17
|
-
%w'strings resources resource_directory imports exports'
|
17
|
+
%w'strings resources resource_directory imports exports web'
|
18
18
|
).map(&:to_sym)
|
19
19
|
|
20
|
-
DEFAULT_ALL_ACTIONS = KNOWN_ACTIONS - %w'resource_directory'.map(&:to_sym)
|
20
|
+
DEFAULT_ALL_ACTIONS = KNOWN_ACTIONS - %w'resource_directory web'.map(&:to_sym)
|
21
|
+
|
22
|
+
URL_BASE = "http://pedump.me"
|
21
23
|
|
22
24
|
def initialize argv = ARGV
|
23
25
|
@argv = argv
|
@@ -41,7 +43,6 @@ class PEdump::CLI
|
|
41
43
|
"Output format: bin,c,dump,hex,inspect,table (default)" do |v|
|
42
44
|
@options[:format] = v
|
43
45
|
end
|
44
|
-
# TODO: imports, exports
|
45
46
|
KNOWN_ACTIONS.each do |t|
|
46
47
|
opts.on "--#{t.to_s.tr('_','-')}", eval("lambda{ |_| @actions << :#{t.to_s.tr('-','_')} }")
|
47
48
|
end
|
@@ -51,6 +52,9 @@ class PEdump::CLI
|
|
51
52
|
opts.on "--va2file VA", "Convert RVA to file offset" do |va|
|
52
53
|
@actions << [:va2file,va]
|
53
54
|
end
|
55
|
+
opts.on "-W", "--web", "Upload file to a #{URL_BASE} for a nice HTML tables with image previews, candies & stuff" do
|
56
|
+
@actions << :web
|
57
|
+
end
|
54
58
|
end
|
55
59
|
|
56
60
|
if (@argv = optparser.parse(@argv)).empty?
|
@@ -79,10 +83,14 @@ class PEdump::CLI
|
|
79
83
|
end
|
80
84
|
end
|
81
85
|
|
82
|
-
|
86
|
+
next if !@options[:force] && !@pedump.mz(f)
|
83
87
|
|
84
88
|
@actions.each do |action|
|
85
|
-
|
89
|
+
if action == :web
|
90
|
+
upload f
|
91
|
+
else
|
92
|
+
dump_action action,f
|
93
|
+
end
|
86
94
|
end
|
87
95
|
end
|
88
96
|
end
|
@@ -91,6 +99,71 @@ class PEdump::CLI
|
|
91
99
|
# prevents a 'Broken pipe - <STDOUT> (Errno::EPIPE)' message
|
92
100
|
end
|
93
101
|
|
102
|
+
class ProgressProxy
|
103
|
+
def initialize file
|
104
|
+
@file = file
|
105
|
+
@pbar = ProgressBar.new("[.] uploading", file.size, STDOUT)
|
106
|
+
@pbar.try(:file_transfer_mode)
|
107
|
+
@pbar.bar_mark = '='
|
108
|
+
end
|
109
|
+
def read *args
|
110
|
+
@pbar.inc args.first
|
111
|
+
@file.read *args
|
112
|
+
end
|
113
|
+
def method_missing *args
|
114
|
+
@file.send *args
|
115
|
+
end
|
116
|
+
def respond_to? *args
|
117
|
+
@file.respond_to?(*args) || super(*args)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def upload f
|
122
|
+
if @pedump.mz(f).signature != 'MZ'
|
123
|
+
@pedump.logger.error "[!] refusing to upload a non-MZ file"
|
124
|
+
return
|
125
|
+
end
|
126
|
+
|
127
|
+
require 'digest/md5'
|
128
|
+
require 'open-uri'
|
129
|
+
require 'rest-client'
|
130
|
+
require 'progressbar'
|
131
|
+
|
132
|
+
stdout_sync = STDOUT.sync
|
133
|
+
STDOUT.sync = true
|
134
|
+
|
135
|
+
md5 = Digest::MD5.file(f.path).hexdigest
|
136
|
+
@pedump.logger.info "[.] md5: #{md5}"
|
137
|
+
url = "#{URL_BASE}/#{md5}/"
|
138
|
+
|
139
|
+
@pedump.logger.info "[.] checking if file already uploaded.."
|
140
|
+
begin
|
141
|
+
if (r=open(url).read) == "OK"
|
142
|
+
@pedump.logger.warn "[.] file already uploaded: #{url}"
|
143
|
+
return
|
144
|
+
else
|
145
|
+
raise "invalid server response: #{r}"
|
146
|
+
end
|
147
|
+
rescue OpenURI::HTTPError
|
148
|
+
raise unless $!.to_s == "404 Not Found"
|
149
|
+
end
|
150
|
+
|
151
|
+
f.rewind
|
152
|
+
if (r=RestClient.post(URL_BASE, :file => ProgressProxy.new(f))) != "OK"
|
153
|
+
raise "invalid server response: #{r}"
|
154
|
+
end
|
155
|
+
puts
|
156
|
+
puts "[.] analyzing..."
|
157
|
+
|
158
|
+
if (r=open(File.join(URL_BASE,md5,'analyze')).read) != "OK"
|
159
|
+
raise "invalid server response: #{r}"
|
160
|
+
end
|
161
|
+
|
162
|
+
puts "[.] uploaded: #{url}"
|
163
|
+
ensure
|
164
|
+
STDOUT.sync = stdout_sync
|
165
|
+
end
|
166
|
+
|
94
167
|
def action_title action
|
95
168
|
s = action.to_s.upcase.tr('_',' ')
|
96
169
|
s += " Header" if [:mz, :pe, :rich].include?(action)
|
@@ -242,33 +315,52 @@ class PEdump::CLI
|
|
242
315
|
end
|
243
316
|
|
244
317
|
def dump_exports data
|
245
|
-
printf "#
|
318
|
+
printf "# module %s\n# flags=0x%x ts=%s version=%d.%d ord_base=%d\n",
|
246
319
|
data.name.inspect,
|
247
320
|
data.Characteristics,
|
248
321
|
Time.at(data.TimeDateStamp.to_i).strftime('"%Y-%m-%d %H:%M:%S"'),
|
249
|
-
data.MajorVersion, data.MinorVersion
|
322
|
+
data.MajorVersion, data.MinorVersion,
|
323
|
+
data.Base
|
324
|
+
|
325
|
+
if @options[:verbose]
|
326
|
+
printf "# Names rva=0x%08x file_offset=%8d\n",
|
327
|
+
data.AddressOfNames, @pedump.va2file(data.AddressOfNames)
|
328
|
+
printf "# EntryPoints rva=0x%08x file_offset=%8d\n",
|
329
|
+
data.AddressOfFunctions, @pedump.va2file(data.AddressOfFunctions)
|
330
|
+
printf "# Ordinals rva=0x%08x file_offset=%8d\n",
|
331
|
+
data.AddressOfNameOrdinals, @pedump.va2file(data.AddressOfNameOrdinals)
|
332
|
+
end
|
250
333
|
|
251
|
-
printf "#
|
334
|
+
printf "# nFuncs=%d nNames=%d\n",
|
252
335
|
data.NumberOfFunctions,
|
253
336
|
data.NumberOfNames
|
254
337
|
|
338
|
+
return unless data.name_ordinals.any? || data.entry_points.any? || data.names.any?
|
339
|
+
|
255
340
|
puts
|
256
341
|
|
342
|
+
ord2name = {}
|
343
|
+
data.NumberOfNames.times do |i|
|
344
|
+
ord2name[data.name_ordinals[i]] ||= []
|
345
|
+
ord2name[data.name_ordinals[i]] << data.names[i]
|
346
|
+
end
|
347
|
+
|
257
348
|
printf "%5s %8s %s\n", "ORD", "ENTRY_VA", "NAME"
|
258
349
|
data.NumberOfFunctions.times do |i|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
350
|
+
ep = data.entry_points[i]
|
351
|
+
names = ord2name[i+data.Base].try(:join,', ')
|
352
|
+
next if ep.to_i == 0 && names.nil?
|
353
|
+
printf "%5d %8x %s\n", i + data.Base, ep, names
|
263
354
|
end
|
264
355
|
end
|
265
356
|
|
266
357
|
def dump_imports data
|
267
|
-
fmt = "%-15s %5s %5s
|
358
|
+
fmt = "%-15s %5s %5s %s\n"
|
268
359
|
printf fmt, "MODULE_NAME", "HINT", "ORD", "FUNCTION_NAME"
|
269
360
|
data.each do |iid|
|
270
361
|
# image import descriptor
|
271
362
|
(Array(iid.original_first_thunk) + Array(iid.first_thunk)).uniq.each do |f|
|
363
|
+
next unless f
|
272
364
|
# imported function
|
273
365
|
printf fmt,
|
274
366
|
iid.module_name,
|
@@ -373,7 +465,7 @@ class PEdump::CLI
|
|
373
465
|
fmt.each_with_index do |f,i|
|
374
466
|
v = res.send(keys[i])
|
375
467
|
if f['x']
|
376
|
-
printf f.tr('x','s'), v < 10 ? v.to_s : "0x#{v.to_s(16)}"
|
468
|
+
printf f.tr('x','s'), v.to_i < 10 ? v.to_s : "0x#{v.to_s(16)}"
|
377
469
|
else
|
378
470
|
printf f, v
|
379
471
|
end
|
@@ -403,10 +495,18 @@ class PEdump::CLI
|
|
403
495
|
end
|
404
496
|
|
405
497
|
def dump_rich_hdr data
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
498
|
+
if decoded = data.decode
|
499
|
+
puts " LIB_ID VERSION TIMES_USED "
|
500
|
+
decoded.each do |row|
|
501
|
+
printf " %5d %2x %7d %4x %7d %3x\n",
|
502
|
+
row.id, row.id, row.version, row.version, row.times, row.times
|
503
|
+
end
|
504
|
+
else
|
505
|
+
puts "# raw:"
|
506
|
+
puts hexdump(data)
|
507
|
+
puts
|
508
|
+
puts "# dexored:"
|
509
|
+
puts hexdump(data.dexor)
|
410
510
|
end
|
411
511
|
end
|
412
512
|
|
data/pedump.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "pedump"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Andrey \"Zed\" Zaikin"]
|
12
|
-
s.date = "2011-12-
|
12
|
+
s.date = "2011-12-11"
|
13
13
|
s.description = "dump headers, sections, extract resources of win32 PE exe,dll,etc"
|
14
14
|
s.email = "zed.0xff@gmail.com"
|
15
15
|
s.executables = ["pedump"]
|
@@ -43,17 +43,23 @@ Gem::Specification.new do |s|
|
|
43
43
|
s.specification_version = 3
|
44
44
|
|
45
45
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_runtime_dependency(%q<rest-client>, ["~> 1.6.7"])
|
47
|
+
s.add_runtime_dependency(%q<progressbar>, ["~> 0.9.2"])
|
46
48
|
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
47
49
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
48
50
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
49
51
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
50
52
|
else
|
53
|
+
s.add_dependency(%q<rest-client>, ["~> 1.6.7"])
|
54
|
+
s.add_dependency(%q<progressbar>, ["~> 0.9.2"])
|
51
55
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
52
56
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
53
57
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
54
58
|
s.add_dependency(%q<rcov>, [">= 0"])
|
55
59
|
end
|
56
60
|
else
|
61
|
+
s.add_dependency(%q<rest-client>, ["~> 1.6.7"])
|
62
|
+
s.add_dependency(%q<progressbar>, ["~> 0.9.2"])
|
57
63
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
58
64
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
59
65
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pedump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,33 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-11 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: &70185231241440 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.6.7
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70185231241440
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: progressbar
|
27
|
+
requirement: &70185231240020 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.9.2
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70185231240020
|
14
36
|
- !ruby/object:Gem::Dependency
|
15
37
|
name: rspec
|
16
|
-
requirement: &
|
38
|
+
requirement: &70185231238140 !ruby/object:Gem::Requirement
|
17
39
|
none: false
|
18
40
|
requirements:
|
19
41
|
- - ~>
|
@@ -21,10 +43,10 @@ dependencies:
|
|
21
43
|
version: 2.3.0
|
22
44
|
type: :development
|
23
45
|
prerelease: false
|
24
|
-
version_requirements: *
|
46
|
+
version_requirements: *70185231238140
|
25
47
|
- !ruby/object:Gem::Dependency
|
26
48
|
name: bundler
|
27
|
-
requirement: &
|
49
|
+
requirement: &70185231228680 !ruby/object:Gem::Requirement
|
28
50
|
none: false
|
29
51
|
requirements:
|
30
52
|
- - ~>
|
@@ -32,10 +54,10 @@ dependencies:
|
|
32
54
|
version: 1.0.0
|
33
55
|
type: :development
|
34
56
|
prerelease: false
|
35
|
-
version_requirements: *
|
57
|
+
version_requirements: *70185231228680
|
36
58
|
- !ruby/object:Gem::Dependency
|
37
59
|
name: jeweler
|
38
|
-
requirement: &
|
60
|
+
requirement: &70185231227000 !ruby/object:Gem::Requirement
|
39
61
|
none: false
|
40
62
|
requirements:
|
41
63
|
- - ~>
|
@@ -43,10 +65,10 @@ dependencies:
|
|
43
65
|
version: 1.6.4
|
44
66
|
type: :development
|
45
67
|
prerelease: false
|
46
|
-
version_requirements: *
|
68
|
+
version_requirements: *70185231227000
|
47
69
|
- !ruby/object:Gem::Dependency
|
48
70
|
name: rcov
|
49
|
-
requirement: &
|
71
|
+
requirement: &70185231225760 !ruby/object:Gem::Requirement
|
50
72
|
none: false
|
51
73
|
requirements:
|
52
74
|
- - ! '>='
|
@@ -54,7 +76,7 @@ dependencies:
|
|
54
76
|
version: '0'
|
55
77
|
type: :development
|
56
78
|
prerelease: false
|
57
|
-
version_requirements: *
|
79
|
+
version_requirements: *70185231225760
|
58
80
|
description: dump headers, sections, extract resources of win32 PE exe,dll,etc
|
59
81
|
email: zed.0xff@gmail.com
|
60
82
|
executables:
|
@@ -93,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
93
115
|
version: '0'
|
94
116
|
segments:
|
95
117
|
- 0
|
96
|
-
hash:
|
118
|
+
hash: 2723794485104812379
|
97
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
120
|
none: false
|
99
121
|
requirements:
|