File Coverage

blib/lib/Metabrik/File/Readelf.pm
Criterion Covered Total %
statement 9 61 14.7
branch 0 26 0.0
condition 0 3 0.0
subroutine 3 6 50.0
pod 2 3 66.6
total 14 99 14.1


line stmt bran cond sub pod time code
1             #
2             # $Id$
3             #
4             # file::readelf Brik
5             #
6             package Metabrik::File::Readelf;
7 1     1   829 use strict;
  1         2  
  1         34  
8 1     1   11 use warnings;
  1         3  
  1         33  
9              
10 1     1   5 use base qw(Metabrik::Shell::Command Metabrik::System::Package);
  1         2  
  1         831  
11              
12             sub brik_properties {
13             return {
14 0     0 1   revision => '$Revision$',
15             tags => [ qw(unstable) ],
16             author => 'GomoR ',
17             license => 'http://opensource.org/licenses/BSD-3-Clause',
18             attributes => {
19             datadir => [ qw(datadir) ],
20             input => [ qw(file) ],
21             },
22             attributes_default => {
23             },
24             commands => {
25             install => [ ], # Inherited
26             program_headers => [ qw(file|OPTIONAL) ],
27             },
28             require_modules => {
29             'Metabrik::File::Type' => [ ],
30             },
31             require_binaries => {
32             readelf => [ ],
33             },
34             need_packages => {
35             ubuntu => [ qw(binutils) ],
36             debian => [ qw(binutils) ],
37             kali => [ qw(binutils) ],
38             },
39             };
40             }
41              
42             sub brik_use_properties {
43 0     0 1   my $self = shift;
44              
45             return {
46 0           attributes_default => {
47             },
48             };
49             }
50              
51             sub program_headers {
52 0     0 0   my $self = shift;
53 0           my ($file) = @_;
54              
55 0   0       $file ||= $self->input;
56 0 0         $self->brik_help_run_undef_arg('program_headers', $file) or return;
57              
58 0 0         my $ft = Metabrik::File::Type->new_from_brik_init($self) or return;
59 0 0         my $magic = $ft->get_magic_type($file) or return;
60              
61 0 0         if ($magic !~ /^ELF /) {
62 0           return $self->log->error("program_headers: file [$file] is not ELF: [$magic]");
63             }
64              
65 0           my $cmd = "readelf --program-headers \"$file\"";
66 0 0         my $r = $self->capture($cmd) or return;
67              
68 0           my $entry_point = 0;
69 0           my $starting_offset = 0;
70 0           my $start = 0;
71 0           my $first = 1;
72 0           my $section = {};
73 0           my @sections = ();
74 0           for my $line (@$r) {
75 0 0         next if $line =~ /^\s*$/;
76 0 0         next if $line =~ /^\s*Type\s+Offset/; # Skip header line
77 0 0         next if $line =~ /^\s*FileSiz\s+MemSiz/; # Skip header line
78 0           $line =~ s/^\s*//;
79 0           $line =~ s/\s*$//;
80 0 0         if ($line =~ /^\s*Entry point (\S+)/) {
81 0           $entry_point = $1;
82 0           next;
83             }
84 0 0         if ($line =~ /starting at offset (\d+)/) {
85 0           $starting_offset = $1;
86 0           next;
87             }
88              
89             # Skip until we find program headers section
90 0 0         if ($line =~ /^\s*Program Headers/) {
91 0           $start++;
92 0           next;
93             }
94              
95             # Parse the section
96             # LINE[ Type Offset VirtAddr PhysAddr]
97             # LINE[ FileSiz MemSiz Flags Align]
98             # LINE[ NOTE 0x0000000000000318 0x0000000000000000 0x0000000000000000]
99             # LINE[ 0x0000000000000480 0x0000000000000480 R 0]
100              
101 0 0         if ($start) {
102 0 0         if ($first) { # First line out of two, they are wrapped
103 0           my @toks = split(/\s+/, $line);
104 0           $section->{type} = $toks[0];
105 0           $section->{offset} = $toks[1];
106 0           $section->{virtaddr} = $toks[2];
107 0           $section->{physaddr} = $toks[3];
108 0           $first = 0; # Prepare for next round
109             }
110             else {
111 0           my @toks = split(/\s+/, $line);
112 0           $section->{filesiz} = $toks[0];
113 0           $section->{memsiz} = $toks[1];
114 0           $section->{flags} = $toks[2];
115 0           $section->{align} = $toks[3];
116 0           push @sections, $section;
117 0           $section = {};
118 0           $first = 1; # Prepare for next round
119             }
120             }
121             }
122              
123 0           my $headers = {
124             entry_point => $entry_point,
125             starting_offset => $starting_offset,
126             sections => \@sections,
127             };
128              
129 0           return $headers;
130             }
131              
132             1;
133              
134             __END__