1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
#!/usr/bin/env perl
my $quiet = 1;
unpack("L",pack("N",1))!=1 || die "only little-endian hosts are supported";
# first argument can specify custom suffix...
$suffix=(@ARGV[0]=~/^\$/) ? shift(@ARGV) : "\$m";
#################################################################
# rename segments in COFF modules according to %map table below #
%map=( ".text" => "fipstx$suffix", #
".text\$"=> "fipstx$suffix", #
".rdata"=> "fipsrd$suffix", #
".data" => "fipsda$suffix" ); #
#################################################################
# collect file list
foreach (@ARGV) {
if (/\*/) { push(@files,glob($_)); }
else { push(@files,$_); }
}
use Fcntl;
use Fcntl ":seek";
foreach (@files) {
$file=$_;
print "processing $file\n" unless $quiet;
sysopen(FD,$file,O_RDWR|O_BINARY) || die "sysopen($file): $!";
# read IMAGE_DOS_HEADER
sysread(FD,$mz,64)==64 || die "$file is too short";
@dos_header=unpack("a2C58I",$mz);
if (@dos_header[0] eq "MZ") {
$e_lfanew=pop(@dos_header);
sysseek(FD,$e_lfanew,SEEK_SET) || die "$file is too short";
sysread(FD,$Magic,4)==4 || die "$file is too short";
unpack("I",$Magic)==0x4550 || die "$file is not COFF image";
} elsif ($file =~ /\.obj$/i) {
# .obj files have no IMAGE_DOS_HEADER
sysseek(FD,0,SEEK_SET) || die "unable to rewind $file";
} else { next; }
# read IMAGE_FILE_HEADER
sysread(FD,$coff,20)==20 || die "$file is too short";
($Machine,$NumberOfSections,$TimeDateStamp,
$PointerToSymbolTable,$NumberOfSysmbols,
$SizeOfOptionalHeader,$Characteristics)=unpack("SSIIISS",$coff);
# skip over IMAGE_OPTIONAL_HEADER
sysseek(FD,$SizeOfOptionalHeader,SEEK_CUR) || die "$file is too short";
# traverse IMAGE_SECTION_HEADER table
for($i=0;$i<$NumberOfSections;$i++) {
sysread(FD,$SectionHeader,40)==40 || die "$file is too short";
($Name,@opaque)=unpack("Z8C*",$SectionHeader);
if ($map{$Name}) {
sysseek(FD,-40,SEEK_CUR) || die "unable to rewind $file";
syswrite(FD,pack("a8C*",$map{$Name},@opaque))==40 || die "syswrite failed: $!";
printf " %-8s -> %.8s\n",$Name,$map{$Name} unless $quiet;
}
}
close(FD);
}
|