Единственный способ, которым я смог заставить это работать, состоял в том, чтобы изменить сам файл ядра, чтобы иметь дополнительный заголовок / раздел программы, который содержал новые данные.
Теоретически, я считаю, что objcopy должен быть в состоянии сделать это, но после большого тестирования я не смог заставить его работать. Вместо этого я прибег к написанию Perl-скрипта, который модифицировал основной файл.
Вот сценарий для тех из вас, кто застрял в аналогичной ситуации (обратите внимание, что это для основных файлов ELF в арке i386):
#!/usr/bin/perl
my @elfHeader = (
[ident => 'A16'],
[e_type => 'v'],
[e_machine => 'v'],
[e_version => 'V'],
[e_entry => 'V'],
[e_phoff => 'V'],
[e_shoff => 'V'],
[e_flags => 'V'],
[e_ehsize => 'v'],
[e_phentsize => 'v'],
[e_phnum => 'v'],
[e_shentsize => 'v'],
[e_shnum => 'v'],
[e_shstrndx => 'v']
);
my @progHeader = (
[ptype => 'V'],
[poffset => 'V'],
[pvaddr => 'V'],
[ppaddr => 'V'],
[pfilesz => 'V'],
[pmemsz => 'V'],
[pflags => 'V'],
[palign => 'V'],
);
my ($core, $dataFile, $outFile) = @ARGV;
main();
sub main {
my @stat = stat($core);
my $coreSize = $stat[7];
@stat = stat($dataFile);
my $dfSize = $stat[7];
my ($in, $out, $df);
open($in, "", $outFile) || die("Couldn't open $outFile: $!");
my $buf;
my $bytes = sysread($in, $buf, 52);
my $hdr = unpackStruct(\@elfHeader, $buf);
# Fix the elf header to have an additional program header
my $phNum = $hdr->{e_phnum};
$hdr->{e_phnum}++;
# Fix the header to point to a new location for the program headers (at the end of the file)
my $phOff = $hdr->{e_phoff};
$hdr->{e_phoff} = $coreSize;
# Read in the full program header table
my $phTable;
sysseek($in, $phOff, 0);
my $readSize = $hdr->{e_phentsize} * $phNum;
$bytes = sysread($in, $phTable, $readSize);
# Add an additional entry to the end of the ph table
my $entry = packStruct(\@progHeader, {ptype => 1,
poffset => $coreSize + $hdr->{e_phentsize} * $hdr->{e_phnum},
pvaddr => 0x80f95000,
ppaddr => 0,
pfilesz => $dfSize,
pmemsz => $dfSize,
pflags => 7,
palign => 4096});
$phTable .= $entry;
# Form the new elf header
my $elf = packStruct(\@elfHeader, $hdr);
# Output the new header
syswrite($out, $elf, length($elf));
# Copy the full core file after the header
sysseek($in, 52, 0);
copyData($in, $out, $coreSize - 52);
# Output the new program table
syswrite($out, $phTable, length($phTable));
# Add the data on the end
copyData($df, $out, $dfSize);
}
sub copyData {
my ($in, $out, $numBytes) = @_;
my $buf;
while ($numBytes > 0) {
my $readBytes = sysread($in, $buf, 8192);
syswrite($out, $buf, $readBytes);
$numBytes -= $readBytes;
}
}
sub unpackStruct {
my ($fields, $data) = @_;
my $unpack;
map {$unpack .= $_->[1]} @{$fields};
my @vals = unpack($unpack, $data);
my %res;
foreach my $field (@{$fields}) {
$res{$field->[0]} = shift(@vals);
}
return \%res;
}
sub packStruct {
my ($fields, $data) = @_;
my $pack;
map {$pack .= $_->[1]} @{$fields};
my @vals;
foreach my $field (@{$fields}) {
push(@vals, $data->{$field->[0]})
}
my $res = pack($pack, @vals);
return $res;
}