我能够让它工作的唯一方法是修改核心文件本身,使其具有包含新数据的附加程序头/节。
理论上,我相信 objcopy 应该可以做到这一点,但是经过大量测试后我无法让它工作。相反,我求助于编写修改核心文件的 perl 脚本。
这是为那些陷入类似情况的人准备的脚本(请注意,这是针对 i386 架构上的 ELF 核心文件):
#!/usr/bin/perl
我的@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']
);
我的@progHeader = (
[ptype => 'V'],
[poffset => 'V'],
[pvaddr => 'V'],
[ppaddr => 'V'],
[pfilesz => 'V'],
[pmemsz => 'V'],
[pflags => 'V'],
[palign => 'V'],
);
我的 ($core, $dataFile, $outFile) = @ARGV;
主要的();
子主{
我的@stat = stat($core);
我的 $coreSize = $stat[7];
@stat = stat($dataFile);
我的 $dfSize = $stat[7];
我的 ($in, $out, $df);
打开($in, "", $outFile) || die("无法打开 $outFile: $!");
我的 $buf;
我的 $bytes = sysread($in, $buf, 52);
我的 $hdr = unpackStruct(\@elfHeader, $buf);
# 修复 elf 头文件有一个额外的程序头文件
我的 $phNum = $hdr->{e_phnum};
$hdr->{e_phnum}++;
# 修复头文件以指向程序头文件的新位置(在文件末尾)
我的 $phOff = $hdr->{e_phoff};
$hdr->{e_phoff} = $coreSize;
# 读入完整的程序头表
我的 $phTable;
sysseek($in, $phOff, 0);
我的 $readSize = $hdr->{e_phentsize} * $phNum;
$bytes = sysread($in, $phTable, $readSize);
# 在 ph 表的末尾添加一个额外的条目
我的 $entry = packStruct(\@progHeader, {ptype => 1,
poffset => $coreSize + $hdr->{e_phentsize} * $hdr->{e_phnum},
pvaddr => 0x80f95000,
ppaddr => 0,
pfilesz => $dfSize,
pmemsz => $dfSize,
pflags => 7,
对齐 => 4096});
$phTable .= $entry;
# 形成新的精灵头
我的 $elf = packStruct(\@elfHeader, $hdr);
# 输出新的头文件
系统写入($out,$elf,长度($elf));
# 将完整的核心文件复制到文件头之后
sysseek($in, 52, 0);
复制数据($in,$out,$coreSize - 52);
# 输出新的节目表
syswrite($out, $phTable, 长度($phTable));
# 在末尾添加数据
复制数据($df,$out,$dfSize);
}
子副本数据 {
我的 ($in, $out, $numBytes) = @_;
我的 $buf;
而($numBytes > 0){
我的 $readBytes = sysread($in, $buf, 8192);
syswrite($out, $buf, $readBytes);
$numBytes -= $readBytes;
}
}
子解包结构{
我的 ($fields, $data) = @_;
我的 $unpack;
地图 {$unpack .= $_->[1]} @{$fields};
我的@vals = unpack($unpack, $data);
我的%res;
foreach 我的 $field (@{$fields}) {
$res{$field->[0]} = shift(@vals);
}
返回 \%res;
}
子包结构{
我的 ($fields, $data) = @_;
我的 $pack;
地图 {$pack .= $_->[1]} @{$fields};
我的@vals;
foreach 我的 $field (@{$fields}) {
推(@vals,$data->{$field->[0]})
}
我的 $res = pack($pack, @vals);
返回 $res;
}