eltorito 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #!/home/joshua/.guix-profile/bin/perl
  2. use Getopt::Std;
  3. #
  4. # geteltorito.pl: a bootimage extractor
  5. # Script that will extract the first El Torito bootimage from a
  6. # bootable CD image
  7. # R. Krienke 08/2001
  8. # krienke@uni-koblenz.de
  9. # License: GPL
  10. #
  11. # Get latest version from:
  12. # http://userpages.uni-koblenz.de/~krienke/ftp/noarch/geteltorito
  13. #
  14. $utilVersion="0.6";
  15. #
  16. # Version 0.6
  17. # 2015/02/25
  18. # I included a patch by Daniel Kekez, daniel.kekez@utoronto.ca to make geteltorito
  19. # better compatible with windows:
  20. # "To run this Perl script using using Strawberry Perl under Windows, I
  21. # found it was necessary to explicitly open the files in binary mode since
  22. # Windows will default to text mode when open() is called."
  23. # Version 0.5
  24. # 2009/06/22
  25. # A patch for harddisk emulation images from <colimit@gmail.com>.
  26. # For BootMediaType=4 (harddisk emulation) SectorCount is always 1, and geteltorito.pl
  27. # returns just MBR. This patch guesses the correct bootimage size
  28. # from MBR (offset+size of the first partitition).
  29. # Version 0.4
  30. # 2007/02/01
  31. # A patch from Santiago Garcia <manty@debian.org> to use a virtual sector
  32. # size (vSecSize) of 512 bytes, as defined on "El Torito" specs and change
  33. # unpack of the sector count from n to v to get the correct sector count.
  34. # Version 0.3
  35. # 2006/02/21
  36. # A patch from Ben Collins <bcollins@ubuntu.com> to make the
  37. # utility work on PPC machines (change from 'L'-encoding in pack to 'V')
  38. # Version 0.2
  39. # Several patches included from Nathan Stratton Treadway(nathant@ontko.com)
  40. # to adjust the platform output as well as fixes for other minor bugs
  41. # Version 0.1
  42. # Initial release
  43. #
  44. # For information on El Torito see
  45. # http://en.wikipedia.org/wiki/El_torito
  46. $vSecSize=512;
  47. $secSize=2048;
  48. $ret=undef;$version=undef;$opt_h=undef;$loadSegment=undef;$systemType=undef;
  49. #
  50. # Read a particular sector from a file
  51. # sector counting starts at 0, not 1
  52. #
  53. sub getSector{
  54. my ($secNum, $secCount, $file)=@_;
  55. my ($sec, $count);
  56. open(FILE, "<:raw", $file) || die "Cannot open \"$file\" \n";
  57. seek(FILE, $secNum*$secSize, 0);
  58. $count=read(FILE, $sec, $vSecSize*$secCount, 0) ;
  59. if( $count != $vSecSize*$secCount ){
  60. warn "Error reading from file \"$file\"\n";
  61. }
  62. close(FILE);
  63. return($sec);
  64. }
  65. #
  66. # Write eltorito data into a file
  67. #
  68. sub writeOutputFile{
  69. my($name)=shift;
  70. my($value)=shift;
  71. open(OUT, ">:raw", $name)|| die "$0: Cannot open outputfile \"$name\" for writing. Stop.";
  72. print OUT $value;
  73. close(OUT);
  74. }
  75. #
  76. # Usage
  77. #
  78. sub usage{
  79. warn "\n$0 [-hv] [-o outputfilename] cd-image \n",
  80. "Script will try to extract an El Torito image from a \n",
  81. "bootable CD (or cd-image) given by <cd-image> and write \n",
  82. "the data extracted to STDOUT or to a file.\n",
  83. " -h: This help. \n",
  84. " -v: Print version of script and exit.\n",
  85. " -o <file>: Write extracted data to file <file> instead of STDOUT.\n",
  86. "\n\n";
  87. exit 0;
  88. }
  89. # ---------------------------------------------------------------------
  90. $ret=getopts('hvo:');
  91. if( defined($opt_v) ){
  92. warn "Version: $utilVersion \n";
  93. exit 0;
  94. }
  95. if( defined($opt_h) || $#ARGV <0 ){
  96. usage(0);
  97. }
  98. if( defined($opt_o) ){
  99. $outputFilename="$opt_o";
  100. }
  101. $imageFile=$ARGV[0];
  102. if( ! -r $imageFile ){
  103. die "Cannot read image/device \"$imageFile\". Aborting\n";
  104. }
  105. #
  106. # Read Sector 17 from CD which should contain a Boot Record Volume
  107. # descriptor. This descriptor contains at its start the text ($isoIdent)
  108. # CD001 and ($toritoSpec)
  109. # EL TORITO SPECIFICATION
  110. # see http://www.cdpage.com/Compact_Disc_Variations/eltoritoi.html
  111. # for details
  112. #
  113. $sector=getSector(17, 1, $imageFile );
  114. ($boot, $isoIdent, $version, $toritoSpec,
  115. $unUsed, $bootP)= unpack( "Ca5CA32A32V", $sector );
  116. if( $isoIdent ne "CD001" || $toritoSpec ne "EL TORITO SPECIFICATION" ){
  117. die "This data image does not seem to be a bootable CD-image\n";
  118. }
  119. #
  120. # Now fetch the sector of the booting catalog
  121. #
  122. $sector=getSector($bootP, 1, $imageFile );
  123. print STDERR "Booting catalog starts at sector: $bootP \n";
  124. # The first 32 bytes of this sector contains the validation entry for a
  125. # boot. The first byte has to be 01, the next byte determines the
  126. # architecture the image is designed for, where 00 is i86, 01 is PowerPC
  127. # and 02 is Mac. More data give info about manufacturer, etc. The
  128. # final two bytes must contain 0x55 and 0xAA respectively (as
  129. # defined by the El Torito standard).
  130. $validateEntry=substr($sector, 0, 32);
  131. ($header, $platform, $unUsed, $manufact, $unUsed, $five, $aa)=
  132. unpack( "CCvA24vCC", $validateEntry);
  133. if( $header != 1 || $five != 0x55 || $aa != 0xaa ){
  134. die "Invalid Validation Entry on image \n";
  135. }
  136. print STDERR "Manufacturer of CD: $manufact\n";
  137. print STDERR "Image architecture: ";
  138. print STDERR "x86" if( $platform == 0 );
  139. print STDERR "PowerPC" if( $platform == 1 );
  140. print STDERR "Mac" if( $platform == 2 );
  141. print STDERR "unknown ($platform)" if( $platform > 2 );
  142. print STDERR "\n";
  143. #
  144. # Now we examine the initial/defaultentry which follows the validate
  145. # entry and has a size of 32 bytes.
  146. $initialEntry=substr($sector, 32, 32);
  147. ($boot, $media, $loadSegment, $systemType, $unUsed,
  148. $sCount, $imgStart, $unUsed)=unpack( "CCvCCvVC", $initialEntry);
  149. if( $boot != 0x88 ){
  150. die "Boot indicator in Initial/Default-Entry is not 0x88. CD is not bootable. \n";
  151. }
  152. print STDERR "Boot media type is: ";
  153. if( $media == 0 ){
  154. print STDERR "no emulation";
  155. $count=0;
  156. }
  157. if( $media == 1 ){
  158. print STDERR "1.2meg floppy";
  159. $count=1200*1024/$vSecSize;
  160. }
  161. if( $media == 2 ){
  162. print STDERR "1.44meg floppy";
  163. $count=1440*1024/$vSecSize;
  164. }
  165. if( $media == 3 ){
  166. print STDERR "2.88meg floppy";
  167. $count=2880*1024/$vSecSize;
  168. }
  169. if( $media == 4 ){
  170. print STDERR "harddisk";
  171. $MBR=getSector($imgStart, 1, $imageFile );
  172. $partition1=substr($MBR, 446, 16);
  173. ($unUsed, $firstSector, $partitionSize) = unpack( "A8VV", $partition1);
  174. $count=$firstSector + $partitionSize;
  175. }
  176. print STDERR "\n";
  177. # Only use the internal sector counter if the real size is unknown
  178. # ($count==0)
  179. $cnt=$count==0?$sCount:$count;
  180. print STDERR "El Torito image starts at sector $imgStart and has $cnt sector(s) of $vSecSize Bytes\n";
  181. # We are there:
  182. # Now read the bootimage to stdout
  183. $image=getSector($imgStart, $cnt, $imageFile);
  184. if( length($outputFilename) ){
  185. writeOutputFile($outputFilename, $image);
  186. print STDERR "\nImage has been written to file \"$outputFilename\".\n";
  187. }else{
  188. print "$image";
  189. print STDERR "Image has been written to stdout ....\n";
  190. }