line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package App::dumpbin 0.02 { |
2
|
3
|
|
|
3
|
|
133985
|
use 5.008001; |
|
3
|
|
|
|
|
34
|
|
3
|
3
|
|
|
3
|
|
16
|
use strict; |
|
3
|
|
|
|
|
4
|
|
|
3
|
|
|
|
|
63
|
|
4
|
3
|
|
|
3
|
|
14
|
use warnings; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
80
|
|
5
|
3
|
|
|
3
|
|
2296
|
use Path::Tiny; |
|
3
|
|
|
|
|
37922
|
|
|
3
|
|
|
|
|
1754
|
|
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
my %sections; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
sub exports { |
10
|
2
|
|
|
2
|
0
|
782
|
my $file = shift; |
11
|
2
|
|
|
|
|
6
|
my $raw = Path::Tiny->new($file)->slurp_raw; |
12
|
|
|
|
|
|
|
# |
13
|
2
|
50
|
|
|
|
522
|
exit 99 if 0x5A4D != unpack 'v', substr $raw, 0, 2; # check signature |
14
|
2
|
|
|
|
|
8
|
my $peo = unpack 'V', substr $raw, 0x3C, 4; |
15
|
2
|
50
|
|
|
|
9
|
exit 99 if "PE\0\0" ne substr $raw, $peo, 4; |
16
|
|
|
|
|
|
|
# |
17
|
2
|
|
|
|
|
10
|
my ( $sizeOfOptionalHeader, undef, $magic ) = unpack 'vvv', substr $raw, $peo + 20, 8; |
18
|
2
|
50
|
|
|
|
6
|
return if !$sizeOfOptionalHeader; # No optional COFF and thus no exports |
19
|
2
|
|
|
|
|
6
|
my $pe32plus = $magic == 0x20b; # 32bit: Ox10b 64bit: 0x20b ROM?: 0x107 |
20
|
2
|
|
|
|
|
7
|
my $opt_header = substr $raw, $peo + 24, $sizeOfOptionalHeader; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# COFF header |
23
|
2
|
|
|
|
|
7
|
my $numberOfSections = unpack 'v', substr $raw, $peo + 6, 2; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# Windows "optional" header |
26
|
2
|
100
|
|
|
|
11
|
my $imageBase = $pe32plus ? unpack 'Q', substr $opt_header, 24, 8 : unpack 'V', |
27
|
|
|
|
|
|
|
substr $opt_header, 28, 4; |
28
|
2
|
100
|
|
|
|
7
|
my $numberOfRVAandSizes = unpack 'V', substr $opt_header, ( $pe32plus ? 108 : 112 ), 4; |
29
|
|
|
|
|
|
|
{ |
30
|
2
|
|
|
|
|
4
|
%sections = (); |
|
2
|
|
|
|
|
5
|
|
31
|
2
|
|
|
|
|
6
|
my $sec_begin = $peo + 24 + $sizeOfOptionalHeader; |
32
|
2
|
|
|
|
|
6
|
my $sec_data = substr $raw, $sec_begin, $numberOfSections * 40; |
33
|
2
|
|
|
|
|
10
|
for my $x ( 0 .. $numberOfSections - 1 ) { |
34
|
13
|
|
|
|
|
22
|
my $sec_head = $sec_begin + ( $x * 40 ); |
35
|
13
|
|
|
|
|
29
|
my $sec_name = unpack 'Z*', substr $raw, $sec_head, 8; |
36
|
13
|
|
|
|
|
99
|
$sections{$sec_name} = [ unpack 'VV VVVV vv V', substr $raw, $sec_head + 8 ]; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# dig into directory |
41
|
2
|
100
|
|
|
|
10
|
my ( $edata_pos, $edata_len ) = unpack 'VV', substr $opt_header, $pe32plus ? 112 : 96, 8; |
42
|
2
|
|
|
|
|
10
|
my @fields = unpack 'V10', substr $raw, rva2offset($edata_pos), 40; |
43
|
2
|
|
|
|
|
8
|
my ( $ptr_func, $ptr_name, $ptr_ord ) = map { rva2offset( $fields[$_] ) } 7 .. 9; |
|
6
|
|
|
|
|
12
|
|
44
|
2
|
|
|
|
|
8
|
my %retval = ( name => unpack 'Z*', substr $raw, rva2offset( $fields[3] ), 256 ); |
45
|
2
|
|
|
|
|
14
|
my @ord = unpack 'V' x $fields[5], substr $raw, $ptr_func, 4 * $fields[5]; |
46
|
2
|
|
|
|
|
7
|
for my $idx ( 0 .. $fields[5] ) { |
47
|
6
|
|
|
|
|
16
|
my $ord_cur = unpack 'v', substr $raw, $ptr_ord + ( 2 * $idx ), 2; |
48
|
6
|
|
|
|
|
9
|
my $func_cur = $ord[$ord_cur]; # Match the ordinal to the function RVA |
49
|
6
|
100
|
|
|
|
16
|
next if $idx > ( $fields[6] - 1 ); |
50
|
4
|
|
|
|
|
10
|
my $name_cur = unpack 'V', substr $raw, $ptr_name + ( 4 * $idx ), 4; |
51
|
4
|
|
|
|
|
12
|
my $name_str = unpack 'Z*', substr $raw, rva2offset($name_cur), 512; |
52
|
4
|
|
|
|
|
9
|
$ord_cur += $fields[4]; # Add the ordinal base value |
53
|
4
|
|
|
|
|
15
|
$retval{exports}{$name_str} = [ $func_cur + $imageBase, $ord_cur ]; |
54
|
|
|
|
|
|
|
} |
55
|
2
|
|
|
|
|
15
|
%retval; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub rva2offset { |
59
|
14
|
|
|
14
|
0
|
63
|
my ($virtual) = @_; |
60
|
14
|
|
|
|
|
33
|
for my $section ( values %sections ) { |
61
|
63
|
100
|
100
|
|
|
165
|
if ( ( $virtual >= $section->[1] ) and ( $virtual < $section->[1] + $section->[0] ) ) { |
62
|
14
|
|
|
|
|
52
|
return $virtual - ( $section->[1] - $section->[3] ); |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
}; |
67
|
|
|
|
|
|
|
1; |
68
|
|
|
|
|
|
|
__END__ |