segrenam.pl 2.7 KB

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