Home | History | Annotate | Download | only in utils
      1 #!/usr/bin/perl
      2 ## -----------------------------------------------------------------------
      3 ##
      4 ##   Copyright 2002-2008 H. Peter Anvin - All Rights Reserved
      5 ##   Copyright 2009 Intel Corporation; author: H. Peter Anvin
      6 ##
      7 ##   This program is free software; you can redistribute it and/or modify
      8 ##   it under the terms of the GNU General Public License as published by
      9 ##   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
     10 ##   Boston MA 02111-1307, USA; either version 2 of the License, or
     11 ##   (at your option) any later version; incorporated herein by reference.
     12 ##
     13 ## -----------------------------------------------------------------------
     14 
     15 #
     16 # Post-process an ISO 9660 image generated with mkisofs/genisoimage
     17 # to allow "hybrid booting" as a CD-ROM or as a hard disk.
     18 #
     19 
     20 use bytes;
     21 use Fcntl;
     22 
     23 # User-specifyable options
     24 %opt = (
     25     # Fake geometry (zipdrive-style...)
     26     'h'      => 64,
     27     's'      => 32,
     28     # Partition number
     29     'entry'  => 1,
     30     # Partition offset
     31     'offset' => 0,
     32     # Partition type
     33     'type'   => 0x17,		# "Windows hidden IFS"
     34     # MBR ID
     35     'id'     => undef,
     36 );
     37 
     38 %valid_range = (
     39     'h'      => [1, 256],
     40     's'      => [1, 63],
     41     'entry'  => [1, 4],
     42     'offset' => [0, 64],
     43     'type'   => [0, 255],
     44     'id'     => [0, 0xffffffff],
     45     'hd0'    => [0, 2],
     46     'partok' => [0, 1],
     47 );
     48 
     49 # Boolean options just set other options
     50 %bool_opt = (
     51     'nohd0'    => ['hd0', 0],
     52     'forcehd0' => ['hd0', 1],
     53     'ctrlhd0'  => ['hd0', 2],
     54     'nopartok' => ['partok', 0],
     55     'partok'   => ['partok', 1],
     56 );
     57 
     58 sub usage() {
     59     print STDERR "Usage: $0 [options] filename.iso\n",
     60     "Options:\n",
     61     "  -h          Number of default geometry heads\n",
     62     "  -s          Number of default geometry sectors\n",
     63     "  -entry      Specify partition entry number (1-4)\n",
     64     "  -offset     Specify partition offset (default 0)\n",
     65     "  -type       Specify partition type (default 0x17)\n",
     66     "  -id         Specify MBR ID (default random)\n",
     67     "  -forcehd0   Always assume we are loaded as disk ID 0\n",
     68     "  -ctrlhd0    Assume disk ID 0 if the Ctrl key is pressed\n",
     69     "  -partok     Allow booting from within a partition\n";
     70     exit 1;
     71 }
     72 
     73 # Parse a C-style integer (decimal/octal/hex)
     74 sub doh($) {
     75     my($n) = @_;
     76     return ($n =~ /^0/) ? oct $n : $n+0;
     77 }
     78 
     79 sub get_random() {
     80     # Get a 32-bit random number
     81     my $rfd, $rnd;
     82     my $rid;
     83 
     84     if (open($rfd, "< /dev/urandom\0") && read($rfd, $rnd, 4) == 4) {
     85 	$rid = unpack("V", $rnd);
     86     }
     87 
     88     close($rfd) if (defined($rfd));
     89     return $rid if (defined($rid));
     90 
     91     # This sucks but is better than nothing...
     92     return ($$+time()) & 0xffffffff;
     93 }
     94 
     95 sub get_hex_data() {
     96     my $mbr = '';
     97     my $line, $byte;
     98     while ( $line = <DATA> ) {
     99 	chomp $line;
    100 	last if ($line eq '*');
    101 	foreach $byte ( split(/\s+/, $line) ) {
    102 	    $mbr .= chr(hex($byte));
    103 	}
    104     }
    105     return $mbr;
    106 }
    107 
    108 while ($ARGV[0] =~ /^\-(.*)$/) {
    109     $o = $1;
    110     shift @ARGV;
    111     if (defined($bool_opt{$o})) {
    112 	($o, $v) = @{$bool_opt{$o}};
    113 	$opt{$o} = $v;
    114     } elsif (exists($opt{$o})) {
    115 	$opt{$o} = doh(shift @ARGV);
    116 	if (defined($valid_range{$o})) {
    117 	    ($l, $h) = @{$valid_range{$o}};
    118 	    if ($opt{$o} < $l || $opt{$o} > $h) {
    119 		die "$0: valid values for the -$o parameter are $l to $h\n";
    120 	    }
    121 	}
    122     } else {
    123 	usage();
    124     }
    125 }
    126 
    127 ($file) = @ARGV;
    128 
    129 if (!defined($file)) {
    130     usage();
    131 }
    132 
    133 open(FILE, "+< $file\0") or die "$0: cannot open $file: $!\n";
    134 binmode FILE;
    135 
    136 #
    137 # First, actually figure out where mkisofs hid isolinux.bin
    138 #
    139 seek(FILE, 17*2048, SEEK_SET) or die "$0: $file: $!\n";
    140 read(FILE, $boot_record, 2048) == 2048 or die "$0: $file: read error\n";
    141 ($br_sign, $br_cat_offset) = unpack("a71V", $boot_record);
    142 if ($br_sign ne ("\0CD001\1EL TORITO SPECIFICATION" . ("\0" x 41))) {
    143     die "$0: $file: no boot record found\n";
    144 }
    145 seek(FILE, $br_cat_offset*2048, SEEK_SET) or die "$0: $file: $!\n";
    146 read(FILE, $boot_cat, 2048) == 2048 or die "$0: $file: read error\n";
    147 
    148 # We must have a Validation Entry followed by a Default Entry...
    149 # no fanciness allowed for the Hybrid mode [XXX: might relax this later]
    150 @ve = unpack("v16", $boot_cat);
    151 $cs = 0;
    152 for ($i = 0; $i < 16; $i++) {
    153     $cs += $ve[$i];
    154 }
    155 if ($ve[0] != 0x0001 || $ve[15] != 0xaa55 || $cs & 0xffff) {
    156     die "$0: $file: invalid boot catalog\n";
    157 }
    158 ($de_boot, $de_media, $de_seg, $de_sys, $de_mbz1, $de_count, 
    159  $de_lba, $de_mbz2) = unpack("CCvCCvVv", substr($boot_cat, 32, 32));
    160 if ($de_boot != 0x88 || $de_media != 0 ||
    161     ($de_segment != 0 && $de_segment != 0x7c0) || $de_count != 4) {
    162     die "$0: $file: unexpected boot catalog parameters\n";
    163 }
    164 
    165 # Now $de_lba should contain the CD sector number for isolinux.bin
    166 seek(FILE, $de_lba*2048+0x40, SEEK_SET) or die "$0: $file: $!\n";
    167 read(FILE, $ibsig, 4);
    168 if ($ibsig ne "\xfb\xc0\x78\x70") {
    169     die "$0: $file: bootloader does not have a isolinux.bin hybrid signature.".
    170         "Note that isolinux-debug.bin does not support hybrid booting.\n";
    171 }
    172 
    173 # Get the total size of the image
    174 (@imgstat = stat(FILE)) or die "$0: $file: $!\n";
    175 $imgsize = $imgstat[7];
    176 if (!$imgsize) {
    177     die "$0: $file: cannot determine length of file\n";
    178 }
    179 # Target image size: round up to a multiple of $h*$s*512
    180 $h = $opt{'h'};
    181 $s = $opt{'s'};
    182 $cylsize = $h*$s*512;
    183 $frac = $imgsize % $cylsize;
    184 $padding = ($frac > 0) ? $cylsize - $frac : 0;
    185 $imgsize += $padding;
    186 $c = int($imgsize/$cylsize);
    187 if ($c > 1024) {
    188     print STDERR "Warning: more than 1024 cylinders ($c).\n";
    189     print STDERR "Not all BIOSes will be able to boot this device.\n";
    190     $cc = 1024;
    191 } else {
    192     $cc = $c;
    193 }
    194 
    195 # Preserve id when run again
    196 if (defined($opt{'id'})) {
    197     $id = pack("V", doh($opt{'id'}));
    198 } else {
    199     seek(FILE, 440, SEEK_SET) or die "$0: $file: $!\n";
    200     read(FILE, $id, 4);
    201     if ($id eq "\x00\x00\x00\x00") {
    202 	$id = pack("V", get_random());
    203     }
    204 }
    205 
    206 # Print the MBR and partition table
    207 seek(FILE, 0, SEEK_SET) or die "$0: $file: $!\n";
    208 
    209 for ($i = 0; $i <= $opt{'hd0'}+3*$opt{'partok'}; $i++) {
    210     $mbr = get_hex_data();
    211 }
    212 if ( length($mbr) > 432 ) {
    213     die "$0: Bad MBR code\n";
    214 }
    215 
    216 $mbr .= "\0" x (432 - length($mbr));
    217 
    218 $mbr .= pack("VV", $de_lba*4, 0); 	# Offset 432: LBA of isolinux.bin
    219 $mbr .= $id;				# Offset 440: MBR ID
    220 $mbr .= "\0\0";				# Offset 446: actual partition table
    221 
    222 # Print partition table
    223 $offset  = $opt{'offset'};
    224 $psize   = $c*$h*$s - $offset;
    225 $bhead   = int($offset/$s) % $h;
    226 $bsect   = ($offset % $s) + 1;
    227 $bcyl    = int($offset/($h*$s));
    228 $bsect  += ($bcyl & 0x300) >> 2;
    229 $bcyl   &= 0xff;
    230 $ehead   = $h-1;
    231 $esect   = $s + ((($cc-1) & 0x300) >> 2);
    232 $ecyl    = ($cc-1) & 0xff;
    233 $fstype  = $opt{'type'};	# Partition type
    234 $pentry  = $opt{'entry'};	# Partition slot
    235 
    236 for ( $i = 1 ; $i <= 4 ; $i++ ) {
    237     if ( $i == $pentry ) {
    238 	$mbr .= pack("CCCCCCCCVV", 0x80, $bhead, $bsect, $bcyl, $fstype,
    239 		     $ehead, $esect, $ecyl, $offset, $psize);
    240     } else {
    241 	$mbr .= "\0" x 16;
    242     }
    243 }
    244 $mbr .= "\x55\xaa";
    245 
    246 print FILE $mbr;
    247 
    248 # Pad the image to a fake cylinder boundary
    249 seek(FILE, $imgstat[7], SEEK_SET) or die "$0: $file: $!\n";
    250 if ($padding) {
    251     print FILE "\0" x $padding;
    252 }
    253 
    254 # Done...
    255 close(FILE);
    256 
    257 exit 0;
    258 __END__
    259 33 ed 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
    260 90 90 90 90 90 90 90 33 ed fa 8e d5 bc 0 7c fb fc 66 31 db 66 31 c9 66 53
    261 66 51 6 57 8e dd 8e c5 52 be 0 7c bf 0 6 b9 0 1 f3 a5 ea 4b 6 0 0 52 b4 41
    262 bb aa 55 31 c9 30 f6 f9 cd 13 72 16 81 fb 55 aa 75 10 83 e1 1 74 b 66 c7 6
    263 f1 6 b4 42 eb 15 eb 0 5a 51 b4 8 cd 13 83 e1 3f 5b 51 f b6 c6 40 50 f7 e1
    264 53 52 50 bb 0 7c b9 4 0 66 a1 b0 7 e8 44 0 f 82 80 0 66 40 80 c7 2 e2 f2 66
    265 81 3e 40 7c fb c0 78 70 75 9 fa bc ec 7b ea 44 7c 0 0 e8 83 0 69 73 6f 6c
    266 69 6e 75 78 2e 62 69 6e 20 6d 69 73 73 69 6e 67 20 6f 72 20 63 6f 72 72 75
    267 70 74 2e d a 66 60 66 31 d2 66 3 6 f8 7b 66 13 16 fc 7b 66 52 66 50 6 53 6a
    268 1 6a 10 89 e6 66 f7 36 e8 7b c0 e4 6 88 e1 88 c5 92 f6 36 ee 7b 88 c6 8 e1
    269 41 b8 1 2 8a 16 f2 7b cd 13 8d 64 10 66 61 c3 e8 1e 0 4f 70 65 72 61 74 69
    270 6e 67 20 73 79 73 74 65 6d 20 6c 6f 61 64 20 65 72 72 6f 72 2e d a 5e ac b4
    271 e 8a 3e 62 4 b3 7 cd 10 3c a 75 f1 cd 18 f4 eb fd 0 0 0 0 0 0 0 0 0 0 0 0
    272 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    273 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    274 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    275 *
    276 33 ed 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
    277 90 90 90 90 90 90 90 33 ed fa 8e d5 bc 0 7c fb fc 66 31 db 66 31 c9 66 53
    278 66 51 6 57 8e dd 8e c5 b2 80 52 be 0 7c bf 0 6 b9 0 1 f3 a5 ea 4d 6 0 0 52
    279 b4 41 bb aa 55 31 c9 30 f6 f9 cd 13 72 16 81 fb 55 aa 75 10 83 e1 1 74 b 66
    280 c7 6 f3 6 b4 42 eb 15 eb 0 5a 51 b4 8 cd 13 83 e1 3f 5b 51 f b6 c6 40 50 f7
    281 e1 53 52 50 bb 0 7c b9 4 0 66 a1 b0 7 e8 44 0 f 82 80 0 66 40 80 c7 2 e2 f2
    282 66 81 3e 40 7c fb c0 78 70 75 9 fa bc ec 7b ea 44 7c 0 0 e8 83 0 69 73 6f
    283 6c 69 6e 75 78 2e 62 69 6e 20 6d 69 73 73 69 6e 67 20 6f 72 20 63 6f 72 72
    284 75 70 74 2e d a 66 60 66 31 d2 66 3 6 f8 7b 66 13 16 fc 7b 66 52 66 50 6 53
    285 6a 1 6a 10 89 e6 66 f7 36 e8 7b c0 e4 6 88 e1 88 c5 92 f6 36 ee 7b 88 c6 8
    286 e1 41 b8 1 2 8a 16 f2 7b cd 13 8d 64 10 66 61 c3 e8 1e 0 4f 70 65 72 61 74
    287 69 6e 67 20 73 79 73 74 65 6d 20 6c 6f 61 64 20 65 72 72 6f 72 2e d a 5e ac
    288 b4 e 8a 3e 62 4 b3 7 cd 10 3c a 75 f1 cd 18 f4 eb fd 0 0 0 0 0 0 0 0 0 0 0
    289 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    290 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    291 0 0 0 0 0 0 0 0 0 0 0 0 0 
    292 *
    293 33 ed 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
    294 90 90 90 90 90 90 90 33 ed fa 8e d5 bc 0 7c fb fc 66 31 db 66 31 c9 66 53
    295 66 51 6 57 8e dd 8e c5 60 b4 2 cd 16 a8 4 61 74 2 b2 80 52 be 0 7c bf 0 6
    296 b9 0 1 f3 a5 ea 57 6 0 0 52 b4 41 bb aa 55 31 c9 30 f6 f9 cd 13 72 16 81 fb
    297 55 aa 75 10 83 e1 1 74 b 66 c7 6 fd 6 b4 42 eb 15 eb 0 5a 51 b4 8 cd 13 83
    298 e1 3f 5b 51 f b6 c6 40 50 f7 e1 53 52 50 bb 0 7c b9 4 0 66 a1 b0 7 e8 44 0
    299 f 82 80 0 66 40 80 c7 2 e2 f2 66 81 3e 40 7c fb c0 78 70 75 9 fa bc ec 7b
    300 ea 44 7c 0 0 e8 83 0 69 73 6f 6c 69 6e 75 78 2e 62 69 6e 20 6d 69 73 73 69
    301 6e 67 20 6f 72 20 63 6f 72 72 75 70 74 2e d a 66 60 66 31 d2 66 3 6 f8 7b
    302 66 13 16 fc 7b 66 52 66 50 6 53 6a 1 6a 10 89 e6 66 f7 36 e8 7b c0 e4 6 88
    303 e1 88 c5 92 f6 36 ee 7b 88 c6 8 e1 41 b8 1 2 8a 16 f2 7b cd 13 8d 64 10 66
    304 61 c3 e8 1e 0 4f 70 65 72 61 74 69 6e 67 20 73 79 73 74 65 6d 20 6c 6f 61
    305 64 20 65 72 72 6f 72 2e d a 5e ac b4 e 8a 3e 62 4 b3 7 cd 10 3c a 75 f1 cd
    306 18 f4 eb fd 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    307 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    308 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    309 *
    310 33 ed 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
    311 90 90 90 90 90 90 90 33 ed fa 8e d5 bc 0 7c fb fc 66 31 db 66 31 c9 21 f6
    312 74 26 f6 4 7f 75 21 38 4c 4 74 1c 66 3d 21 47 50 58 75 10 80 7c 4 ed 75 a
    313 66 8b 4c 34 66 8b 5c 38 eb 4 66 8b 4c 8 66 53 66 51 6 57 8e dd 8e c5 52 be
    314 0 7c bf 0 6 b9 0 1 f3 a5 ea 75 6 0 0 52 b4 41 bb aa 55 31 c9 30 f6 f9 cd 13
    315 72 16 81 fb 55 aa 75 10 83 e1 1 74 b 66 c7 6 1b 7 b4 42 eb 15 eb 0 5a 51 b4
    316 8 cd 13 83 e1 3f 5b 51 f b6 c6 40 50 f7 e1 53 52 50 bb 0 7c b9 4 0 66 a1 b0
    317 7 e8 44 0 f 82 80 0 66 40 80 c7 2 e2 f2 66 81 3e 40 7c fb c0 78 70 75 9 fa
    318 bc ec 7b ea 44 7c 0 0 e8 83 0 69 73 6f 6c 69 6e 75 78 2e 62 69 6e 20 6d 69
    319 73 73 69 6e 67 20 6f 72 20 63 6f 72 72 75 70 74 2e d a 66 60 66 31 d2 66 3
    320 6 f8 7b 66 13 16 fc 7b 66 52 66 50 6 53 6a 1 6a 10 89 e6 66 f7 36 e8 7b c0
    321 e4 6 88 e1 88 c5 92 f6 36 ee 7b 88 c6 8 e1 41 b8 1 2 8a 16 f2 7b cd 13 8d
    322 64 10 66 61 c3 e8 1e 0 4f 70 65 72 61 74 69 6e 67 20 73 79 73 74 65 6d 20
    323 6c 6f 61 64 20 65 72 72 6f 72 2e d a 5e ac b4 e 8a 3e 62 4 b3 7 cd 10 3c a
    324 75 f1 cd 18 f4 eb fd 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    325 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    326 *
    327 33 ed 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
    328 90 90 90 90 90 90 90 33 ed fa 8e d5 bc 0 7c fb fc 66 31 db 66 31 c9 21 f6
    329 74 26 f6 4 7f 75 21 38 4c 4 74 1c 66 3d 21 47 50 58 75 10 80 7c 4 ed 75 a
    330 66 8b 4c 34 66 8b 5c 38 eb 4 66 8b 4c 8 66 53 66 51 6 57 8e dd 8e c5 b2 80
    331 52 be 0 7c bf 0 6 b9 0 1 f3 a5 ea 77 6 0 0 52 b4 41 bb aa 55 31 c9 30 f6 f9
    332 cd 13 72 16 81 fb 55 aa 75 10 83 e1 1 74 b 66 c7 6 1d 7 b4 42 eb 15 eb 0 5a
    333 51 b4 8 cd 13 83 e1 3f 5b 51 f b6 c6 40 50 f7 e1 53 52 50 bb 0 7c b9 4 0 66
    334 a1 b0 7 e8 44 0 f 82 80 0 66 40 80 c7 2 e2 f2 66 81 3e 40 7c fb c0 78 70 75
    335 9 fa bc ec 7b ea 44 7c 0 0 e8 83 0 69 73 6f 6c 69 6e 75 78 2e 62 69 6e 20
    336 6d 69 73 73 69 6e 67 20 6f 72 20 63 6f 72 72 75 70 74 2e d a 66 60 66 31 d2
    337 66 3 6 f8 7b 66 13 16 fc 7b 66 52 66 50 6 53 6a 1 6a 10 89 e6 66 f7 36 e8
    338 7b c0 e4 6 88 e1 88 c5 92 f6 36 ee 7b 88 c6 8 e1 41 b8 1 2 8a 16 f2 7b cd
    339 13 8d 64 10 66 61 c3 e8 1e 0 4f 70 65 72 61 74 69 6e 67 20 73 79 73 74 65
    340 6d 20 6c 6f 61 64 20 65 72 72 6f 72 2e d a 5e ac b4 e 8a 3e 62 4 b3 7 cd 10
    341 3c a 75 f1 cd 18 f4 eb fd 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    342 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    343 *
    344 33 ed 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
    345 90 90 90 90 90 90 90 33 ed fa 8e d5 bc 0 7c fb fc 66 31 db 66 31 c9 21 f6
    346 74 26 f6 4 7f 75 21 38 4c 4 74 1c 66 3d 21 47 50 58 75 10 80 7c 4 ed 75 a
    347 66 8b 4c 34 66 8b 5c 38 eb 4 66 8b 4c 8 66 53 66 51 6 57 8e dd 8e c5 60 b4
    348 2 cd 16 a8 4 61 74 2 b2 80 52 be 0 7c bf 0 6 b9 0 1 f3 a5 ea 81 6 0 0 52 b4
    349 41 bb aa 55 31 c9 30 f6 f9 cd 13 72 16 81 fb 55 aa 75 10 83 e1 1 74 b 66 c7
    350 6 27 7 b4 42 eb 15 eb 0 5a 51 b4 8 cd 13 83 e1 3f 5b 51 f b6 c6 40 50 f7 e1
    351 53 52 50 bb 0 7c b9 4 0 66 a1 b0 7 e8 44 0 f 82 80 0 66 40 80 c7 2 e2 f2 66
    352 81 3e 40 7c fb c0 78 70 75 9 fa bc ec 7b ea 44 7c 0 0 e8 83 0 69 73 6f 6c
    353 69 6e 75 78 2e 62 69 6e 20 6d 69 73 73 69 6e 67 20 6f 72 20 63 6f 72 72 75
    354 70 74 2e d a 66 60 66 31 d2 66 3 6 f8 7b 66 13 16 fc 7b 66 52 66 50 6 53 6a
    355 1 6a 10 89 e6 66 f7 36 e8 7b c0 e4 6 88 e1 88 c5 92 f6 36 ee 7b 88 c6 8 e1
    356 41 b8 1 2 8a 16 f2 7b cd 13 8d 64 10 66 61 c3 e8 1e 0 4f 70 65 72 61 74 69
    357 6e 67 20 73 79 73 74 65 6d 20 6c 6f 61 64 20 65 72 72 6f 72 2e d a 5e ac b4
    358 e 8a 3e 62 4 b3 7 cd 10 3c a 75 f1 cd 18 f4 eb fd 0 0 0 0 0 0 0 0 0 0 0 0
    359 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    360 *
    361