1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
#!/usr/bin/perl
sub sanehead {
my $blocktype = shift;
my $offset = shift;
my $dlen = shift;
my $count = shift;
if($blocktype > 0x300) { return 0 };
if($offset > 0x10000) { return 0 };
if($dlen > 20000) { return 0}
return 1;
}
if($#ARGV < 0) {
print "EM8300 microcode extractor\n";
print "Written by Henrik Johansson 2000-04-10\n\n";
print "Usage:\n\tmicrocode_extract.pl FILE [DESTDIR] [NAMEBASE]\n\n";
print "FILE refers to the VXD file which comes with the Windows drivers
and is found in the Windows\\System folder. The file is usually called
rmquasar.vxd (H+) or enc2dev.vxd (Creative Labs). \n\n";
print "DESTDIR is the dir where the microcode should be stored.\n\n";
print "NAMEBASE is the prefix of the saved microcode files.\n\n";
}
open(VXD,"<$ARGV[0]");
undef $/;
$vxd = <VXD>;
close(VXD);
$path=$ARGV[1];
$namebase=$ARGV[2];
if(length($namebase) == 0) { $namebase="microcode" };
$ucnt = 0;
for($i=0; $i < length($vxd); $i++)
{
if(unpack('v',substr($vxd,$i,2)) == 2) {
$savei = $i;
$ok = 1;
$blocktype = -1;
$count=0;
while($blocktype != 0) {
($blocktype, $offset, $dlen) = unpack('vVV',substr($vxd,$i,11));
if($blocktype == 0) { last; }
if(($blocktype == 2) && (($lastblocktype&0xf00) == 0x200)) { $i--; last; }
$dlen *= 2;
if(!sanehead($blocktype,$offset,$dlen,$count)) {
$ok = 0;
last;
}
$i+=10+$dlen;
$lastblocktype = $blocktype;
$count++;
}
$lastblocktype = -1;
if($ok && $count > 20) {
$ucodelen = $i - $savei;
$filename = "$path/$namebase$ucnt.bin";
open UCODE,">$filename" or die("Can't open microcode file");
print UCODE substr($vxd,$savei,$ucodelen);
print pack('SII',(0,0,0));
close UCODE;
print "Found microcode block (length=$ucodelen), ";
print "saving to $filename \n";
$ucnt++;
} else {
$i = $savei;
}
}
}
|