pedump 0.5.1 → 0.6.1
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.
- checksums.yaml +5 -5
- data/.github/FUNDING.yml +2 -0
- data/.github/dependabot.yml +8 -0
- data/CODE_OF_CONDUCT.md +76 -0
- data/Gemfile +10 -9
- data/Gemfile.lock +72 -25
- data/README.md +15 -6
- data/Rakefile +69 -4
- data/VERSION +1 -1
- data/data/comp_id.txt +776 -0
- data/lib/pedump.rb +120 -29
- data/lib/pedump/cli.rb +35 -21
- data/lib/pedump/loader.rb +28 -6
- data/lib/pedump/loader/minidump.rb +130 -15
- data/lib/pedump/loader/section.rb +5 -3
- data/lib/pedump/ne.rb +1 -1
- data/lib/pedump/pe.rb +63 -54
- data/lib/pedump/rich.rb +562 -0
- data/lib/pedump/te.rb +62 -0
- data/lib/pedump/unpacker/aspack.rb +1 -1
- data/lib/pedump/version.rb +2 -5
- data/misc/aspack/aspack_unlzx.c +5 -3
- data/pedump.gemspec +108 -22
- data/rich.py +353 -0
- metadata +107 -15
data/lib/pedump.rb
CHANGED
@@ -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
|
|
@@ -255,7 +261,7 @@ class PEdump
|
|
255
261
|
|
256
262
|
# http://ntcore.com/files/richsign.htm
|
257
263
|
class RichHdr < String
|
258
|
-
attr_accessor :offset, :key # xor key
|
264
|
+
attr_accessor :offset, :skip, :key # xor key
|
259
265
|
|
260
266
|
class Entry < Struct.new(:version,:id,:times)
|
261
267
|
def inspect
|
@@ -264,8 +270,21 @@ class PEdump
|
|
264
270
|
end
|
265
271
|
|
266
272
|
def self.from_dos_stub stub
|
273
|
+
#stub.hexdump
|
267
274
|
key = stub[stub.index('Rich')+4,4]
|
268
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
|
269
288
|
end_idx = stub.index('Rich')+8
|
270
289
|
if stub[end_idx..-1].tr("\x00",'') != ''
|
271
290
|
t = stub[end_idx..-1]
|
@@ -273,14 +292,16 @@ class PEdump
|
|
273
292
|
PEdump.logger.error "[!] non-zero dos stub after rich_hdr: #{t.inspect}"
|
274
293
|
return nil
|
275
294
|
end
|
295
|
+
#stub[start_idx, end_idx-start_idx].hexdump
|
276
296
|
RichHdr.new(stub[start_idx, end_idx-start_idx]).tap do |x|
|
277
297
|
x.key = key
|
278
298
|
x.offset = stub.offset + start_idx
|
299
|
+
x.skip = skip
|
279
300
|
end
|
280
301
|
end
|
281
302
|
|
282
303
|
def dexor
|
283
|
-
self[
|
304
|
+
self[skip..-9].sub(/\A(#{Regexp::escape(key)}){3}/,'').xor(key)
|
284
305
|
end
|
285
306
|
|
286
307
|
def decode
|
@@ -318,9 +339,9 @@ class PEdump
|
|
318
339
|
@mz ||= f && MZ.read(f).tap do |mz|
|
319
340
|
if mz.signature != 'MZ' && mz.signature != 'ZM'
|
320
341
|
if @force
|
321
|
-
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}"
|
322
343
|
else
|
323
|
-
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)"
|
324
345
|
return nil
|
325
346
|
end
|
326
347
|
end
|
@@ -376,6 +397,13 @@ class PEdump
|
|
376
397
|
def va2file va, h={}
|
377
398
|
return nil if va.nil?
|
378
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
|
+
|
379
407
|
sections.each do |s|
|
380
408
|
if (s.VirtualAddress...(s.VirtualAddress+s.VirtualSize)).include?(va)
|
381
409
|
offset = va - s.VirtualAddress
|
@@ -407,9 +435,9 @@ class PEdump
|
|
407
435
|
# TODO: not all VirtualAdresses == 0 case
|
408
436
|
|
409
437
|
if h[:quiet]
|
410
|
-
logger.debug "[?] can't find file_offset of VA 0x#{
|
438
|
+
logger.debug "[?] can't find file_offset of VA 0x#{va0.to_i.to_s(16)} (quiet=true)"
|
411
439
|
else
|
412
|
-
logger.error "[?] can't find file_offset of VA 0x#{
|
440
|
+
logger.error "[?] can't find file_offset of VA 0x#{va0.to_i.to_s(16)}"
|
413
441
|
end
|
414
442
|
nil
|
415
443
|
end
|
@@ -427,16 +455,22 @@ class PEdump
|
|
427
455
|
end
|
428
456
|
|
429
457
|
def _dump_handle h
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
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
|
436
466
|
end
|
437
467
|
|
438
468
|
def data_directory f=@io
|
439
|
-
pe(f)
|
469
|
+
if pe(f)
|
470
|
+
pe.ioh && pe.ioh.DataDirectory
|
471
|
+
elsif te(f)
|
472
|
+
te.DataDirectory
|
473
|
+
end
|
440
474
|
end
|
441
475
|
|
442
476
|
def sections f=@io
|
@@ -444,16 +478,52 @@ class PEdump
|
|
444
478
|
pe.section_table
|
445
479
|
elsif ne(f)
|
446
480
|
ne.segments
|
481
|
+
elsif te(f)
|
482
|
+
te.sections
|
447
483
|
end
|
448
484
|
end
|
449
485
|
alias :section_table :sections
|
450
486
|
|
451
|
-
def
|
452
|
-
|
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
|
453
515
|
end
|
454
516
|
|
455
517
|
def pe?
|
456
|
-
|
518
|
+
_detect_format() == :pe
|
519
|
+
end
|
520
|
+
|
521
|
+
def ne?
|
522
|
+
_detect_format() == :ne
|
523
|
+
end
|
524
|
+
|
525
|
+
def te?
|
526
|
+
_detect_format() == :te
|
457
527
|
end
|
458
528
|
|
459
529
|
##############################################################################
|
@@ -498,6 +568,8 @@ class PEdump
|
|
498
568
|
pe_imports(f)
|
499
569
|
elsif ne(f)
|
500
570
|
ne(f).imports
|
571
|
+
else
|
572
|
+
[]
|
501
573
|
end
|
502
574
|
end
|
503
575
|
|
@@ -527,7 +599,11 @@ class PEdump
|
|
527
599
|
# http://code.google.com/p/corkami/source/browse/trunk/asm/PE/manyimportsW7.asm
|
528
600
|
break
|
529
601
|
end
|
530
|
-
|
602
|
+
if r.size >= MAX_IMAGE_IMPORT_DESCRIPTORS
|
603
|
+
logger.warn "[!] too many IMAGE_IMPORT_DESCRIPTORs, not reading more than #{r.size}"
|
604
|
+
break
|
605
|
+
end
|
606
|
+
t = IMAGE_IMPORT_DESCRIPTOR.read(f)
|
531
607
|
break if t.Name.to_i == 0 # also catches EOF
|
532
608
|
r << t
|
533
609
|
file_offset += IMAGE_IMPORT_DESCRIPTOR::SIZE
|
@@ -536,8 +612,16 @@ class PEdump
|
|
536
612
|
logger.warn "[?] imports info beyond EOF"
|
537
613
|
end
|
538
614
|
|
615
|
+
n_bad_names = 0
|
539
616
|
logger.warn "[?] non-empty last IMAGE_IMPORT_DESCRIPTOR: #{t.inspect}" if t && !t.empty?
|
540
|
-
@imports = r
|
617
|
+
@imports = r
|
618
|
+
r = nil
|
619
|
+
@imports.each_with_index do |x, iidx|
|
620
|
+
if n_bad_names > MAX_ERRORS
|
621
|
+
logger.warn "[!] too many bad imported function names. skipping further imports parsing"
|
622
|
+
@imports = @imports[0,iidx]
|
623
|
+
break
|
624
|
+
end
|
541
625
|
if x.Name.to_i != 0 && (ofs = va2file(x.Name))
|
542
626
|
begin
|
543
627
|
f.seek ofs
|
@@ -572,12 +656,18 @@ class PEdump
|
|
572
656
|
logger.warn "[?] import ofs 0x#{ofs.to_s(16)} VA=0x#{t.to_s(16)} beyond EOF"
|
573
657
|
nil
|
574
658
|
else
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
659
|
+
hint = f.read(2).unpack('v').first
|
660
|
+
name = f.gets("\x00").to_s.chomp("\x00")
|
661
|
+
if !name.empty? && name !~ GOOD_FUNCTION_NAME_RE
|
662
|
+
n_bad_names += 1
|
663
|
+
if n_bad_names > MAX_ERRORS
|
664
|
+
nil
|
665
|
+
else
|
666
|
+
ImportedFunction.new(hint, name, nil, va)
|
667
|
+
end
|
668
|
+
else
|
669
|
+
ImportedFunction.new(hint, name, nil, va)
|
670
|
+
end
|
581
671
|
end
|
582
672
|
elsif tbl == :original_first_thunk
|
583
673
|
# OriginalFirstThunk entries can not be invalid, show a warning msg
|
@@ -592,7 +682,7 @@ class PEdump
|
|
592
682
|
end
|
593
683
|
end
|
594
684
|
x[tbl] && x[tbl].compact!
|
595
|
-
end
|
685
|
+
end # [:original_first_thunk, :first_thunk].each
|
596
686
|
if x.original_first_thunk && !x.first_thunk
|
597
687
|
logger.warn "[?] import table: empty FirstThunk for #{x.module_name}"
|
598
688
|
elsif !x.original_first_thunk && x.first_thunk
|
@@ -603,7 +693,8 @@ class PEdump
|
|
603
693
|
logger.debug "[?] import table: OriginalFirstThunk != FirstThunk for #{x.module_name}"
|
604
694
|
end
|
605
695
|
end
|
606
|
-
end
|
696
|
+
end # r.each
|
697
|
+
@imports
|
607
698
|
end
|
608
699
|
|
609
700
|
##############################################################################
|
@@ -720,9 +811,9 @@ class PEdump
|
|
720
811
|
ord2name = {}
|
721
812
|
if x.names && x.names.any?
|
722
813
|
n = x.NumberOfNames
|
723
|
-
if n >
|
724
|
-
logger.warn "[?] NumberOfNames too big (#{x.NumberOfNames}), limiting to
|
725
|
-
n =
|
814
|
+
if n > MAX_EXPORT_NUMBER_OF_NAMES
|
815
|
+
logger.warn "[?] NumberOfNames too big (#{x.NumberOfNames}), limiting to #{MAX_EXPORT_NUMBER_OF_NAMES}"
|
816
|
+
n = MAX_EXPORT_NUMBER_OF_NAMES
|
726
817
|
end
|
727
818
|
n.times do |i|
|
728
819
|
ord2name[x.name_ordinals[i]] ||= []
|
data/lib/pedump/cli.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'pedump'
|
2
2
|
require 'pedump/packer'
|
3
|
+
require 'pedump/rich'
|
3
4
|
require 'pedump/version_info'
|
4
5
|
require 'optparse'
|
5
6
|
|
@@ -33,7 +34,7 @@ class PEdump::CLI
|
|
33
34
|
attr_accessor :data, :argv
|
34
35
|
|
35
36
|
KNOWN_ACTIONS = (
|
36
|
-
%w'mz dos_stub rich pe ne data_directory sections tls security' +
|
37
|
+
%w'mz dos_stub rich pe ne te data_directory sections tls security' +
|
37
38
|
%w'strings resources resource_directory imports exports version_info packer web console packer_only'
|
38
39
|
).map(&:to_sym)
|
39
40
|
|
@@ -65,8 +66,8 @@ class PEdump::CLI
|
|
65
66
|
@options[:force] ||= 0
|
66
67
|
@options[:force] += 1
|
67
68
|
end
|
68
|
-
opts.on "-f", "--format FORMAT", [:binary, :c, :dump, :hex, :inspect, :table, :yaml],
|
69
|
-
"Output format: bin,c,dump,hex,inspect,table,yaml","(default: table)" do |v|
|
69
|
+
opts.on "-f", "--format FORMAT", [:binary, :c, :dump, :hex, :inspect, :json, :table, :yaml],
|
70
|
+
"Output format: bin,c,dump,hex,inspect,json,table,yaml","(default: table)" do |v|
|
70
71
|
@options[:format] = v
|
71
72
|
end
|
72
73
|
KNOWN_ACTIONS.each do |t|
|
@@ -135,7 +136,7 @@ class PEdump::CLI
|
|
135
136
|
File.open(fname,'rb') do |f|
|
136
137
|
@pedump = create_pedump fname
|
137
138
|
|
138
|
-
next if !@options[:force] && !@pedump.
|
139
|
+
next if !@options[:force] && !@pedump.supported_file?(f)
|
139
140
|
|
140
141
|
@actions.each do |action|
|
141
142
|
case action
|
@@ -194,16 +195,14 @@ class PEdump::CLI
|
|
194
195
|
end
|
195
196
|
|
196
197
|
class ProgressProxy
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
@
|
201
|
-
@pbar = ProgressBar.new("[.] uploading", file.size, STDOUT)
|
202
|
-
@pbar.try(:file_transfer_mode)
|
203
|
-
@pbar.bar_mark = '='
|
198
|
+
def initialize file, prefix = "[.] uploading: ", io = STDOUT
|
199
|
+
@file = file
|
200
|
+
@io = io
|
201
|
+
@prefix = prefix
|
204
202
|
end
|
205
203
|
def read *args
|
206
|
-
@
|
204
|
+
@io.write("\r#{@prefix}#{@file.tell}/#{@file.size} ")
|
205
|
+
@io.flush
|
207
206
|
@file.read *args
|
208
207
|
end
|
209
208
|
def method_missing *args
|
@@ -212,6 +211,10 @@ class PEdump::CLI
|
|
212
211
|
def respond_to? *args
|
213
212
|
@file.respond_to?(args.first) || super(*args)
|
214
213
|
end
|
214
|
+
|
215
|
+
def finish!
|
216
|
+
@io.write("\r#{@prefix}#{@file.size}/#{@file.size} \n")
|
217
|
+
end
|
215
218
|
end
|
216
219
|
|
217
220
|
def upload f
|
@@ -224,7 +227,6 @@ class PEdump::CLI
|
|
224
227
|
require 'open-uri'
|
225
228
|
require 'net/http'
|
226
229
|
require 'net/http/post/multipart'
|
227
|
-
require 'progressbar'
|
228
230
|
|
229
231
|
stdout_sync = STDOUT.sync
|
230
232
|
STDOUT.sync = true
|
@@ -250,15 +252,15 @@ class PEdump::CLI
|
|
250
252
|
|
251
253
|
f.rewind
|
252
254
|
|
253
|
-
# upload with
|
255
|
+
# upload with progress
|
254
256
|
post_url = URI.parse(URL_BASE+'/')
|
257
|
+
# UploadIO is from multipart-post
|
255
258
|
uio = UploadIO.new(f, "application/octet-stream", File.basename(f.path))
|
256
259
|
ppx = ProgressProxy.new(uio)
|
257
260
|
req = Net::HTTP::Post::Multipart.new post_url.path, "file" => ppx
|
258
261
|
res = Net::HTTP.start(post_url.host, post_url.port){ |http| http.request(req) }
|
259
|
-
ppx.
|
262
|
+
ppx.finish!
|
260
263
|
|
261
|
-
puts
|
262
264
|
puts "[.] analyzing..."
|
263
265
|
|
264
266
|
if (r=open(File.join(URL_BASE,md5,'analyze')).read) != "OK"
|
@@ -326,7 +328,7 @@ class PEdump::CLI
|
|
326
328
|
|
327
329
|
puts action_title(action) unless @options[:format] == :binary
|
328
330
|
|
329
|
-
return dump(data) if [:inspect, :table, :yaml].include?(@options[:format])
|
331
|
+
return dump(data) if [:inspect, :table, :json, :yaml].include?(@options[:format])
|
330
332
|
|
331
333
|
dump_opts = {:name => action}
|
332
334
|
case action
|
@@ -376,6 +378,9 @@ class PEdump::CLI
|
|
376
378
|
when :yaml
|
377
379
|
require 'yaml'
|
378
380
|
puts data.to_yaml
|
381
|
+
when :json
|
382
|
+
require 'json'
|
383
|
+
puts data.to_json
|
379
384
|
end
|
380
385
|
end
|
381
386
|
|
@@ -454,6 +459,8 @@ class PEdump::CLI
|
|
454
459
|
case data.first
|
455
460
|
when PEdump::IMAGE_DATA_DIRECTORY
|
456
461
|
dump_data_dir data
|
462
|
+
when PEdump::EFI_IMAGE_DATA_DIRECTORY
|
463
|
+
dump_efi_data_dir data
|
457
464
|
when PEdump::IMAGE_SECTION_HEADER
|
458
465
|
dump_sections data
|
459
466
|
when PEdump::Resource
|
@@ -778,19 +785,26 @@ class PEdump::CLI
|
|
778
785
|
end
|
779
786
|
end
|
780
787
|
|
781
|
-
|
782
788
|
def dump_data_dir data
|
783
789
|
data.each do |row|
|
784
790
|
printf " %-12s rva:0x%8x size:0x %8x\n", row.type, row.va.to_i, row.size.to_i
|
785
791
|
end
|
786
792
|
end
|
787
793
|
|
794
|
+
def dump_efi_data_dir data
|
795
|
+
data.each_with_index do |row, idx|
|
796
|
+
printf " %-12s rva:0x%8x size:0x %8x\n", PEdump::EFI_IMAGE_DATA_DIRECTORY::TYPES[idx], row.va.to_i, row.size.to_i
|
797
|
+
end
|
798
|
+
end
|
799
|
+
|
788
800
|
def dump_rich_hdr data
|
789
801
|
if decoded = data.decode
|
790
|
-
puts "
|
802
|
+
puts " ID VER COUNT DESCRIPTION"
|
791
803
|
decoded.each do |row|
|
792
|
-
printf " %5d %
|
793
|
-
row.id, row.id, row.version, row.version, row.times, row.times
|
804
|
+
# printf " %5d %4x %7d %4x %12d %8x\n",
|
805
|
+
# row.id, row.id, row.version, row.version, row.times, row.times
|
806
|
+
printf " %4x %4x %12d %s\n",
|
807
|
+
row.id, row.version, row.times, ::PEdump::RICH_IDS[(row.id<<16) + row.version]
|
794
808
|
end
|
795
809
|
else
|
796
810
|
puts "# raw:"
|
data/lib/pedump/loader.rb
CHANGED
@@ -15,7 +15,15 @@ class PEdump::Loader
|
|
15
15
|
|
16
16
|
# shortcuts
|
17
17
|
alias :pe :pe_hdr
|
18
|
-
|
18
|
+
|
19
|
+
def ep
|
20
|
+
if @pe_hdr
|
21
|
+
@pe_hdr.try(:ioh).try(:AddressOfEntryPoint)
|
22
|
+
elsif @te_hdr
|
23
|
+
@te_hdr.AddressOfEntryPoint - @delta
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
19
27
|
def ep= v; @pe_hdr.ioh.AddressOfEntryPoint=v; end
|
20
28
|
|
21
29
|
########################################################################
|
@@ -23,12 +31,24 @@ class PEdump::Loader
|
|
23
31
|
########################################################################
|
24
32
|
|
25
33
|
def initialize io = nil, params = {}
|
34
|
+
# @delta is for EFI TE loading, based on https://github.com/gdbinit/TELoader/blob/master/teloader.cpp
|
35
|
+
@delta = 0
|
26
36
|
@pedump = PEdump.new(io, params)
|
27
37
|
if io
|
28
38
|
@mz_hdr = @pedump.mz
|
29
39
|
@dos_stub = @pedump.dos_stub
|
30
40
|
@pe_hdr = @pedump.pe
|
31
|
-
@
|
41
|
+
@te_hdr = @pedump.te
|
42
|
+
|
43
|
+
@image_base = params[:image_base]
|
44
|
+
if @pe_hdr
|
45
|
+
@image_base ||= @pe_hdr.try(:ioh).try(:ImageBase)
|
46
|
+
elsif @te_hdr
|
47
|
+
@image_base ||= @te_hdr.ImageBase
|
48
|
+
@delta = @pedump.te_shift
|
49
|
+
end
|
50
|
+
@image_base ||= 0
|
51
|
+
|
32
52
|
load_sections @pedump.sections, io
|
33
53
|
end
|
34
54
|
@find_limit = params[:find_limit] || DEFAULT_FIND_LIMIT
|
@@ -38,7 +58,7 @@ class PEdump::Loader
|
|
38
58
|
if section_hdrs.is_a?(Array)
|
39
59
|
@sections = section_hdrs.map do |x|
|
40
60
|
raise "unknown section hdr: #{x.inspect}" unless x.is_a?(PEdump::IMAGE_SECTION_HEADER)
|
41
|
-
Section.new(x, :deferred_load_io => f, :image_base => @image_base )
|
61
|
+
Section.new(x, :deferred_load_io => f, :image_base => @image_base, :delta => @delta )
|
42
62
|
end
|
43
63
|
if f.respond_to?(:seek) && f.respond_to?(:read)
|
44
64
|
#
|
@@ -249,10 +269,12 @@ class PEdump::Loader
|
|
249
269
|
def names
|
250
270
|
return @names if @names
|
251
271
|
@names = {}
|
252
|
-
|
253
|
-
|
254
|
-
|
272
|
+
|
273
|
+
oep = ep()
|
274
|
+
if oep
|
275
|
+
@names[oep + @image_base] = 'start'
|
255
276
|
end
|
277
|
+
|
256
278
|
_parse_imports
|
257
279
|
_parse_exports
|
258
280
|
#TODO: debug info
|