2
0

segrenam.pl 2.1 KB

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