From dc83f2e3128822a518db721cc88f30723d465557 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 27 Mar 2007 00:04:55 +0000 Subject: [PATCH] Perl script to rename sections in MS COFF binaries. Submitted by: Andy Polyakov --- ms/segrenam.pl | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 ms/segrenam.pl diff --git a/ms/segrenam.pl b/ms/segrenam.pl new file mode 100644 index 0000000000..8be9888787 --- /dev/null +++ b/ms/segrenam.pl @@ -0,0 +1,64 @@ +#!/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", # + ".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); +}