Вы находитесь на странице: 1из 17

#!

/usr/bin/perl
#
# Copyright (c) 2013 Nurlan Mukhanov (aka Falseclock) <nurike@gmail.com>
#
# Please inform me if you found error/mistakes or enhance this script.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
#
#
#
#
#
#

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

$| = 1;
use strict;
use warnings;
use utf8;
use Encode;
use Data::Dumper;
use vars qw($ROM $ROM_SIZE $IFR_PACKAGE_SIG @EFI_HII_PACKAGES %EFI_HII_PACKAGE_T
YPE %LANGUAGES @EFI_HII_PACKAGE_FORMS %EFI $DEFAULT_LANGUAGE @STRINGS @TABS %TYP
ES);
################### !!! IMPORTANT !!! ###################
$IFR_PACKAGE_SIG = '$IFRPKG!';
#########################################################
$DEFAULT_LANGUAGE = 'en-US';
my $file = $ARGV[0] || "Setup.rom";
&SPECIFICATION_LOAD();
#---------------------------- MAIN PROGRAMM ----------------------------#
open($ROM, "<$file ") or die "ERROR : Cannot open $file.\n";
{
binmode $ROM;
undef $/;
$ROM_SIZE = -s $file;
}
#-------------------------------------------------------------------# 1. Search IFR virtual package
my $header_offset = &IFR_PACKAGE_SIG();
print STDERR "IFR_PACKAGE_SIG not found!\nExiting programm...\n" and exit 1 if (
!$header_offset);
#--------------------------------------------------------------------

# 2. Search EFI_HII_PACKAGE_HEADERs
@EFI_HII_PACKAGES = &EFI_HII_PACKAGES($header_offset);
#print Dumper(\@EFI_HII_PACKAGES);
#=head
#-------------------------------------------------------------------# 3. Parse EFI_HII_PACKAGE_STRINGS
#print "Parsing language tables..\n";
%LANGUAGES = &EFI_HII_PACKAGE_STRINGS();
#printf "\tFound %d languages: %s\n", scalar keys %LANGUAGES, join ', ', sort ke
ys %LANGUAGES;
@STRINGS = @{$LANGUAGES{$DEFAULT_LANGUAGE}->{'strings'}};
#print Dumper(\@STRINGS);
#print Dumper(\%LANGUAGES);
=head
# 3.1. Check languages length
my %length;
$length{$_} = scalar @{$LANGUAGES{$_}->{'strings'}} foreach (keys %LANGUAGES);
my $warn = 0;
foreach (keys %length)
{
next if $_ eq 'en-US';
if ($length{$_} != $length{'en-US'})
{
if (!$warn)
{
printf STDERR "\tWARNING: languages array length is diff
erent, must be %d elements:\n", $length{'en-US'};
$warn = 1;
}
printf "\t\t%s: (%d)\n", $_, $length{$_} - $length{'en-US'};
}
}
=cut
#-------------------------------------------------------------------# 4. FORM packages parsing
@EFI_HII_PACKAGE_FORMS = &EFI_HII_PACKAGE_FORMS();
close($ROM);
#-----------------------------------------------------------------------#
#-----------------------------------------------------------------------#
sub str2hex {
return unpack ("H*", shift);
}
sub dec2bin {
return unpack("B32", pack("N", shift));
}
sub bin2dec {
return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}

sub oplength {
my $data = shift;
my $length = unpack("C", $data);
return bin2dec(substr &dec2bin($length), -7);
}
sub EFI_IFR {
my $data = shift;
my $length = length($data);
my @opcodes;
#printf "length: %d, hex: %s\n", length($data), join (' ', unpack("(H2)*
",substr($data,0,10)));
my $i = 0;
while ($i < $length)
{
my %op;
# Reading OPCODE
$op{'opcode'} = unpack("C", substr($data,$i,1));
$i++;
# Reading length
$op{'length'} = oplength(substr($data,$i,1));
$i++;
# Reading payload
$op{'payload'} = substr($data,$i,$op{'length'}-2);
$i += $op{'length'} -2;
# Setting indent
#$op{'indent'} = $INDENTS{$op{'opcode'}};
push @opcodes, \%op;
#
};
#

printf "Opcode: %02X, Length: %d\n",$op{'opcode'} , $op{'length'


my $www = <STDIN>;
}
return \@opcodes;

}
sub EFI_HII_PACKAGE_FORMS {
my @forms = ();
foreach (@EFI_HII_PACKAGES)
{
my %pkg = %{$_};
my %form;
if ($_->{type} == 0x02)
{
# printf "EFI_HII_PACKAGE_FORMS offset int : %d, hex: (0
x%08x)\n",$pkg{'int_offset'},$pkg{'int_offset'};

# Skeep first 4 bytes of FULLL_PACKAGE_LENGTH


my $FORM_PACKAGE_LENGTH = unpack('I', (data($pkg{int_off
set} + 4, 3).pack("H",0)) );
my $FORM_PACKAGE_TYPE = unpack('C', (data($pkg{int_offse
t} + 7, 1)) );
$form{'length'} = $FORM_PACKAGE_LENGTH;
$form{'type'} = $FORM_PACKAGE_TYPE;
#printf " Form length: %s, type: %s\n", $FORM_PACKAGE_L
ENGTH, $FORM_PACKAGE_TYPE;
my $op_offset = $pkg{int_offset} + 8;
my $op_length = ($FORM_PACKAGE_LENGTH - 4);
$form{'opcodes'} = &EFI_IFR(data($op_offset,$op_length))
;
$form{'package'} = $_;
push @forms, \%form;
}
}
&EFI_IFR_FORM_SET(\@forms);
#print Dumper(\@forms);
return @forms;
}
sub EFI_IFR_FORM_SET {
my $forms = shift;
my @forms = @{$forms};
#print Dumper(\@forms);
foreach my $form (@forms)
{
my %form = %{$form};
my @ops = @{$form{'opcodes'}};
foreach (@ops)
{
my %op = %{$_};
&EFI_IFR_PRINT(\%op,\%{$form{'package'}});
}
print "\n";
}
}
sub fguid {
my $guid = shift;
my ($a, $b, $c, $d, $e);
$a
$b
$c
$d
$e

=
=
=
=
=

unpack("H*",scalar reverse(substr($guid,0,4)));
unpack("H*",scalar reverse(substr($guid,4,2)));
unpack("H*",scalar reverse(substr($guid,6,2)));
unpack("H*",substr($guid,8,2));
unpack("H*",substr($guid,10,6));

return sprintf("%s-%s-%s-%s-%s",$a,$b,$c,$d,$e);
}
sub EFI_HII_PACKAGE_STRINGS {
my %pkg;
foreach (@EFI_HII_PACKAGES)
{
%pkg = %{$_} and last if ($_->{type} == 0x04);
}
my $reader= 4; # current reading offset
my %languages;
while ($reader < $pkg{size}) # read until we in package
{
my $LANG_PACKAGE_LENGTH = unpack('I', (data($pkg{int_offset} + $
reader, 3).pack("H",0)) );
my $LANG_PACKAGE_OFFSET = $pkg{int_offset} + $reader;
#print $LANG_PACKAGE_LENGTH,"\n";
if ($LANG_PACKAGE_LENGTH)
{
$reader += (3 + 1 + 42);
my $LANG_PACKAGE_NAME = (data($pkg{int_offset} + $reader
, 5)); # skip 00 - end of header
$languages{$LANG_PACKAGE_NAME} = {'offset' => $LANG_PACK
AGE_OFFSET, 'length' => $LANG_PACKAGE_LENGTH, 'name' => $LANG_PACKAGE_NAME };
}
$reader += $LANG_PACKAGE_LENGTH - (3 + 1 + 42);
}
foreach (keys %languages)
{
my %lang = %{$languages{$_}};
#print "Reading language from offset: ".$lang{'offset'}."\n";
#print "Language name is: ".$lang{'name'}."\n";
my $table = data($lang{'offset'}+46+6, $lang{'length'} - 46 - 6)
;
my @table = unpack('(H2)*',$table);
#
# ,
my
my
my
my
my
my
my

@strings;
$position=0;
$word = undef;
$eof = 0;
$last = undef;
$skip = 0;
$word_start = 0;

push @strings, undef;

# MEMEORY OFFSET CAN NOT BE 0

my %EFI_HII_STRING_BLOCK = map { $_ => 1 } ('10', '11', '12', '1


3', '15', '16', '17', '22', '30', '31', '32', '40');
for (my $l=0; $l < $#table; $l++)
{
my $byte = $table[$l];
if ( exists($EFI_HII_STRING_BLOCK{$byte}) && !$word && $
last ne '14')
{
print STDERR "Unexpected EFI_HII_STRING_BLOCK ->
BlockType = $byte found!\n";
printf STDERR "String offset: %d (0x%08x)\n", $l
ang{'offset'} + $l, $lang{'offset'} + $l;
exit 1;
}
'14');

$last = $byte and $word_start = 1 and next if ($byte eq


# EFI_HII_SIBT_STRING_UCS2
if ($byte eq '21' && !$word && !$word_start )

# EFI_HII_SIBT_SKIP2
{
#print "SKEEP FOUND\n";
$skip = hex($table[$l+1]);
# number of skips
$l += 2;
# pass reading @table for next 2 bytes
while ($skip)
{
push @strings, "EFI_HII_SIBT_SKIP2-$skip
";
$skip--;
}
next;
}
if ($byte eq '20' && !$word && !$word_start )
# EFI_HII_SIBT_DUPLICATE
{
push @strings, $strings[$#strings];
$l += 3;
next;
}
# If word end
if ($byte eq '00' && $table[$l+1] eq '00')
{
#print $word."\n";
push @strings, $word;
$word = undef;
$word_start = 0;
$l++;
next;

}
$word .= decode('utf-16le',pack("H*",$byte).pack("H*",$t
able[$l+1]));
$l++;
}
$languages{$_}->{'strings'} = \@strings;
}
return %languages;
#print Dumper(\%languages);
}
sub EFI_HII_PACKAGES {
my $offset = shift;
$offset += 8;
my @address = ();
while (1)
{
my $data = data($offset,8);
my $hex = unpack("H*",$data);
last if $hex !~ /^[ABCDEF0-9]{10}000000$/i;
if ($hex =~ /^[ABCDEF0-9]{6}8001000000$/i)
{
push @address, substr ((join '', (reverse ($hex =~ m/../
g))), 10);
#my $address = substr ((join '', (reverse ($hex =~ m/../
g))), 10);
#printf "$address - %s\n", hex($address);
}
$offset += 8;
}
my @pkg = ();
foreach (@address)
{
my %pkg;
$pkg{int_offset} = hex($_);
$pkg{hex_offset} = $_;
$pkg{size} = unpack("I*",data(hex($_),4));
$pkg{type} = unpack("C", data( hex($_)+7 , 1 ));
$pkg{type_name} = $EFI_HII_PACKAGE_TYPE{$pkg{type}}->{name};
$pkg{type_text} = $EFI_HII_PACKAGE_TYPE{$pkg{type}}->{text};
push @pkg, \%pkg;
}
return @pkg;
}
sub IFR_PACKAGE_SIG {
my $i = 0;
my $offset = 0;
my $seek = undef;
my @sig = split //, $IFR_PACKAGE_SIG;

while ($i <= $ROM_SIZE)


{
my $byte = data($i,1);
#last unless $byte;
# If we found start of header
if ($byte eq '$')
{
$offset = $i;
# Store current offset
$seek = $byte;
# Store begining of the signature
$i++;
next;
}
if ($offset)
# just to save CPU time
{
if (scalar grep $byte eq $_, @sig)
{
$seek .= $byte if ($IFR_PACKAGE_SIG =~ $seek.$by
te );
last if ($IFR_PACKAGE_SIG eq $seek );
}
else
{
$offset = 0;
$seek = undef;
}
}
$i++;
}
#printf "\nIFR_PACKAGE_SIG found at offset: %d (0x%08x)\n", ($offset, $o
ffset) if $offset;
return $offset;
}
sub data {
my $offset = shift;
my $length = shift;
my $data;
seek $ROM, $offset, 0;
sysread $ROM, $data, $length;
return $data;
};
sub TabSpace {
# Pushing
push @TABS, shift;
return '

' x (scalar @TABS - 1);

}
sub TabClose {
my $length = scalar @TABS;

my $return = "";
if ($length)
{
my $opcode = pop @TABS;
if ($opcode == $EFI{EFI_IFR_GRAY_OUT_IF_OP})
{
$return = sprintf "\xE2\x94\x94- END IF Grayout;\n";
}
elsif ($opcode == $EFI{EFI_IFR_SUPPRESS_IF_OP})
{
$return = sprintf "\xE2\x94\x94- END IF Suppress;\n";
}
else
{
$return = "What the fuck?";
}
}
return $return;
}
sub EFI_IFR_PRINT
{
my $op = shift;
my $package = shift;
my $TabSpace = '';
my %op = %{$op};
my %package = %{$package};
if ($op{'opcode'} != $EFI{EFI_IFR_FORM_SET_OP} and scalar @TABS) {
if ($op{'opcode'} == $EFI{EFI_IFR_SUPPRESS_IF_OP} or $op{'opcode
'} == $EFI{EFI_IFR_GRAY_OUT_IF_OP})
{
$TabSpace = sprintf "|";
}
elsif ( $op{'opcode'} == $EFI{EFI_IFR_END_OP} )
{
$TabSpace = sprintf "%s",'|
' x (scalar @TABS - 1 );
}
else
{
$TabSpace = sprintf "%s",'|
' x (scalar @TABS);
}
print $TabSpace;
}
{

if
($op{'opcode'} == $EFI{EFI_IFR_FORM_SET_OP})
# 0x0E
my $Guid = substr($op{'payload'},0,16);
my $FormSetTitle = unpack("S2",substr($op{'payload'},16,2));
my $Help = unpack("S2",substr($op{'payload'},18,2));
my $Flags = substr($op{'payload'},20,2);
my $ClassGuid = substr($op{'payload'},22,16);
printf "\n\xE2\x95\x94%s\xE2\x95\x97\n","\xE2\x95\x90"x116;
printf "\x{E2}\x{95}\x{91} FormSet: '%-62sGUID: %s \xE2\x95\x91\

n", ($STRINGS[$FormSetTitle]."'", fguid($Guid));


printf "\x{e2}\x{95}\x{9f}%s\x{e2}\x{95}\x{a2}\n","\x{e2}\x{94}\
x{80}"x116;
if ($STRINGS[$Help] and $STRINGS[$Help] ne ' ')
{
printf " \\Help text: '%s'\n", $STRINGS[$Help];
}
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_GUID_OP})
{
# 0x5F
my $Guid = substr($op{'payload'},0,16);
my $Data = unpack("H*", substr($op{'payload'},16));
#printf "\x{E2}\x{95}\x{91} Operation data: '%-55sGUID: %s \xE2\
x95\x91\n", $Data, &fguid($Guid);
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_DEFAULTSTORE_OP})
{
# 0x5C
my $DefaultId = unpack("S2", substr($op{'payload'},2,2));
my $DefaultName = unpack("S2", substr($op{'payload'},2,2));
#printf "EFI_IFR_DEFAULTSTORE_OP, length: %d, DefaultId: %s, Def
aultName: %s \n",length($op{'payload'}),$DefaultId,$DefaultName ;
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_VARSTORE_OP})
{
# 0x24
# typedef struct _EFI_IFR_VARSTORE {
# EFI_IFR_OP_HEADER
Header;
# EFI_GUID
Guid;
# EFI_VARSTORE_ID
VarStoreId;
# UINT16
Size;
# UINT8
Name[1];
# } EFI_IFR_VARSTORE;
#printf "EFI_IFR_VARSTORE_OP, length: %d \n",length($op{'payload
'});
my
my
my
my
: '%s'
&fguid($Guid);

$Guid = substr($op{'payload'},0,16);
$VarStoreId = unpack("S2", substr($op{'payload'},16,2));
$Size = unpack("S2", substr($op{'payload'},18,2));
$Name = substr($op{'payload'},20,12);

printf "\x{E2}\x{95}\x{91} VarStore Id: '0x%x', Size: '%s', Name


GUID: %s \x{E2}\x{95}\x{91}\n", $VarStoreId, $Size, $Name,
printf "\xE2\x95\x9A%s\xE2\x95\x9D\n","\xE2\x95\x90"x116;

}
elsif ($op{'opcode'} == $EFI{EFI_IFR_FORM_OP})
{
# 0x01
my $FormId = unpack("S2",substr($op{'payload'},0,2));
my $FormTitle = unpack("S2",substr($op{'payload'},2,2));
printf "\x{e2}\x{94}\x{8c}%s\x{e2}\x{94}\x{90}\n","\x{e2}\x{94}\
x{80}"x116;
printf "\x{e2}\x{94}\x{82} Form Name: '%-86s [ ID: '0x%04x' ]\x{
e2}\x{94}\x{82}\n", ($STRINGS[$FormTitle]."'", $FormId);
printf "\x{e2}\x{94}\x{94}%s\x{e2}\x{94}\x{98}\n","\x{e2}\x{94}\
x{80}"x116;
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_GRAY_OUT_IF_OP})
{
# 0x19

printf "%s\x{E2}\x{94}\x{8C}- Grayout IF:\n",TabSpace($op{'opcod


e'});
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_SUPPRESS_IF_OP})

# 0x0A

printf "%s\xE2\x94\x8C- Suppress IF:\n",TabSpace($op{'opcode'});


}
elsif ($op{'opcode'} == $EFI{EFI_IFR_END_OP})
# 0x29
printf "%s",&TabClose($op{'opcode'});
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_EQ_ID_VAL_OP})
# 0x12
my $QuestionId = unpack("S2",substr($op{'payload'},0,2));
my $Value = unpack("S2",substr($op{'payload'},2,2));
printf "Question [ ID: '0x%02x' ] == 0x%02x\n", $QuestionId, $Va

lue,;
{

}
elsif ($op{'opcode'} == $EFI{EFI_IFR_AND_OP})
# 0x15
printf "AND expression\n";
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_SUBTITLE_OP})
# 0x02
my $Prompt = unpack("S2",substr($op{'payload'},0,2));
my $Help = unpack("S2",substr($op{'payload'},2,2));

printf "Subtitle: '%s'\n", ($STRINGS[$Prompt]) if defined $STRIN


GS[$Prompt] and $STRINGS[$Prompt] ne ' ';
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_DEFAULT_OP})
{
# 0x5B
my $DefaultId = unpack("S2",substr($op{'payload'},0,2));
my $Type = unpack("C",substr($op{'payload'},2,1));
my $value;
if ($Type == 0) {
$value = unpack("C",substr($op{'payload'},3,1));
}
elsif ($Type == 1) {
$value = unpack("S2",substr($op{'payload'},3,2));
}
elsif ($Type == 2) {
$value = unpack("S2",substr($op{'payload'},3,2));
}
elsif ($Type == 5) {
$value = sprintf("%02d",unpack("C",substr($op{'payload'}
,3,1))).':'.sprintf("%02d",unpack("C",substr($op{'payload'},4,1))).':'.sprintf("
%02d",unpack("C",substr($op{'payload'},5,1)));
}
elsif ($Type == 6) {
$value = unpack("S2",substr($op{'payload'},3,2)).'/'.spr
intf("%02d",unpack("C",substr($op{'payload'},5,1))).'/'.sprintf("%02d",unpack("C
",substr($op{'payload'},6,1)));
}
else {
$value = unpack("S*",substr($op{'payload'},3,4));
}
printf " Default value: '%s', Type: 0x%02x\n",$value, $Type;
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_TRUE_OP})

# 0x46

printf "EQ == TRUE\n";


}
elsif ($op{'opcode'} == $EFI{EFI_IFR_TEXT_OP})
{
# 0x03
my $Prompt = unpack("S2",substr($op{'payload'},0,2));
my $Help = unpack("S2",substr($op{'payload'},2,2));
my $TextTwo = unpack("S2",substr($op{'payload'},4,2));
my $t2 = "";
$t2 = $STRINGS[$TextTwo] if (defined $STRINGS[$TextTwo]);
printf "Text: '%-32.32sDefault: '%-32.32sHelp: '%s'\n", $STRINGS
[$Prompt]."'", $t2."'", $STRINGS[$Help];
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_UINT64_OP})
{
# 0x45
my $Value = $op{'payload'};
printf "VALUE = %s\n", unpack("S*",$Value);

}
elsif ($op{'opcode'} == $EFI{EFI_IFR_EQUAL_OP})
# 0x2F
printf "EQUAL expression\n";
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_EQ_ID_LIST_OP})

# 0x14
my $QuestionId = unpack("S2", substr($op{'payload'},0,2));
my $ListLength = unpack("S2", substr($op{'payload'},2,2));
my @ValueList = unpack("(S4)*", substr($op{'payload'},4));
@ValueList = map {sprintf "'0x%02x'", $_ } @ValueList;
printf "LIST [ ID: '0x%02x' ] in (%s)\n",$QuestionId, join ",",
@ValueList;
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_OR_OP})
{
# 0x16
printf "OR expression\n";
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_NOT_OP})
{
# 0x17
printf "NOT expression \n";
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_TIME_OP})
{# 0x1b
my $Prompt = unpack("S2",substr($op{'payload'},0,2));
my $Help = unpack("S2",substr($op{'payload'},2,2));
my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
#my $VarName = unpack("S2",substr($op{'payload'},8,1));
#my $VarOffset = unpack("S2",substr($op{'payload'},9,1));
#my $Flags = unpack("S2",substr($op{'payload'},9,1));
printf "Time: '%s' [ QuestionId: '0x%02x', VarStore: '0x%02x', H
elp: '%s' ]\n", $STRINGS[$Prompt],$QuestionId,$VarStoreId,$STRINGS[$Help] ;
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_DATE_OP})
{# 0x1A
my $Prompt = unpack("S2",substr($op{'payload'},0,2));
my $Help = unpack("S2",substr($op{'payload'},2,2));

my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
#my $VarName = unpack("S2",substr($op{'payload'},8,1));
#my $VarOffset = unpack("S2",substr($op{'payload'},9,1));
#my $Flags = unpack("S2",substr($op{'payload'},9,1));
printf "Date: '%s' [ QuestionId: '0x%02x', VarStore: '0x%02x', H
elp: '%s' ]\n", $STRINGS[$Prompt],$QuestionId,$VarStoreId,$STRINGS[$Help] ;
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_NUMERIC_OP})
{# 0x07
my $Prompt = unpack("S2",substr($op{'payload'},0,2));
my $Help = unpack("S2",substr($op{'payload'},2,2));
my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
#my $VarStoreInfo = unpack("C",substr($op{'payload'},10,1));
my
my
my
my

$Type = unpack("C",substr($op{'payload'},11,1));
$MinValue = unpack("C",substr($op{'payload'},12,1));
$MaxValue = unpack("C",substr($op{'payload'},13,1));
$Step = unpack("C",substr($op{'payload'},14,1));

printf "Number question: Prompt: %s, Help: %s\n",($STRINGS[$Prom


pt], $STRINGS[$Help]) if $Prompt;
printf "%s \x{E2}\x{94}\x{94}- [ QuestionId: '0x%02x', VarStore:
'0x%02x' , Type: '%02x', MinValue: '%d', MaxValue: '%d', Step: '%d' ]\n",($TabS
pace,$QuestionId, $VarStoreId, $Type,$MinValue, $MaxValue, $Step) if $Prompt;;
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_REF_OP})
{# 0x0F
my $Prompt = unpack("S2",substr($op{'payload'},0,2));
my $Help = unpack("S2",substr($op{'payload'},2,2));
my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
my $FormId = unpack("S2>*!",substr($op{'payload'},11,4));
printf "Reference: '%s' [ FormID: '0x%04x', QuestionId: '0x%02x'
, VarStore: '0x%02x' ]\n", $STRINGS[$Prompt], $FormId, $QuestionId, $VarStoreId;
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_ACTION_OP})
{# 0x0C
my $Prompt = unpack("S2",substr($op{'payload'},0,2));
my $Help = unpack("S2",substr($op{'payload'},2,2));
my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
#my $VarStoreInfo = unpack("C",substr($op{'payload'},8,1));
printf "Action: '%-32.32s [ QuestionId: '0x%02x', VarStore: '0x%
02x', Help: %s ] \n", ($STRINGS[$Prompt]."'", $QuestionId,$VarStoreId, $STRINGS[
$Help]);
#printf "%s \x{E2}\x{94}\x{94}- \n", ($TabSpace if $STRINGS[$Pro
mpt];
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_PASSWORD_OP})
{# 0x08
my $Prompt = unpack("S2", substr($op{'payload'},0,2));
my $Help
= unpack("S2", substr($op{'payload'},2,2));
my $VarStoreId = unpack("S2", substr($op{'payload'},8,2));

printf "Password: %-32.32s [ VarStore: '0x%02x', Help: '%s']\n",


($STRINGS[$Prompt], $VarStoreId, $STRINGS[$Help]);
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_ONE_OF_OP}) {
# 0x05
my $Prompt = unpack("S2", substr($op{'payload'},0,2));
my $Help
= unpack("S2", substr($op{'payload'},2,2));
my $QuestionId = unpack("S2", substr($op{'payload'},4,2));
my $VarStoreId = unpack("S2", substr($op{'payload'},8,2));
#
my $VarOffset
= unpack("S2", substr($op{'payload'},4,2));
printf "Select option: '%-32.32s[ VarStore: '0x%02x', QuestionId
: '0x%02x', Help: '%s']\n", ($STRINGS[$Prompt]."'", $VarStoreId, $QuestionId,
(defined $STRINGS[$Help] ? $STRINGS[$Help] : '' ));
}
elsif ($op{'opcode'} == $EFI{EFI_IFR_ONE_OF_OPTION_OP}) {
# 0x09
my $Option
= unpack("S2", substr($op{'payload'},0,2));
my $Flags
= str2hex(substr($op{'payload'},2,1));
my $Type
= unpack("C", substr($op{'payload'},3,1));
my $Value
= unpack("C*", substr($op{'payload'},4,8));
#
load)
#
], value, flags, key)

oid, value, flags, key = struct.unpack("<HHBH", self.pay


print ts+"Option '%s' = 0x%x Flags 0x%x Key 0x%x"%(s[oid

printf " Option: '%-37.37s[ Value: '%s' Default: '%-6s


Typ
e: '%-6.6s ]\n", ($STRINGS[$Option]."'", $Value, ($Flags eq '10' ? 'true' : 'fal
se')."'", $TYPES{$Type}."'");
}
else {
printf "--> UNKNOWN OPCODE: %02X, length: %d\n", $op{'opcode'},
$op{'length'};
exit 1;
}
}
sub SPECIFICATION_LOAD
{
$EFI{EFI_IFR_FORM_OP}
$EFI{EFI_IFR_SUBTITLE_OP}
$EFI{EFI_IFR_TEXT_OP}
$EFI{EFI_IFR_IMAGE_OP}
$EFI{EFI_IFR_ONE_OF_OP}
$EFI{EFI_IFR_CHECKBOX_OP}
$EFI{EFI_IFR_NUMERIC_OP}
$EFI{EFI_IFR_PASSWORD_OP}
$EFI{EFI_IFR_ONE_OF_OPTION_OP}
$EFI{EFI_IFR_SUPPRESS_IF_OP}
$EFI{EFI_IFR_LOCKED_OP}
$EFI{EFI_IFR_ACTION_OP}
$EFI{EFI_IFR_RESET_BUTTON_OP}
$EFI{EFI_IFR_FORM_SET_OP}
$EFI{EFI_IFR_REF_OP}
$EFI{EFI_IFR_NO_SUBMIT_IF_OP}
$EFI{EFI_IFR_INCONSISTENT_IF_OP}
$EFI{EFI_IFR_EQ_ID_VAL_OP}
$EFI{EFI_IFR_EQ_ID_ID_OP}
$EFI{EFI_IFR_EQ_ID_LIST_OP}

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

0x01;
0x02;
0x03;
0x04;
0x05;
0x06;
0x07;
0x08;
0x09;
0x0A;
0x0B;
0x0C;
0x0D;
0x0E;
0x0F;
0x10;
0x11;
0x12;
0x13;
0x14;

$EFI{EFI_IFR_AND_OP}
$EFI{EFI_IFR_OR_OP}
$EFI{EFI_IFR_NOT_OP}
$EFI{EFI_IFR_RULE_OP}
$EFI{EFI_IFR_GRAY_OUT_IF_OP}
$EFI{EFI_IFR_DATE_OP}
$EFI{EFI_IFR_TIME_OP}
$EFI{EFI_IFR_STRING_OP}
$EFI{EFI_IFR_REFRESH_OP}
$EFI{EFI_IFR_DISABLE_IF_OP}
$EFI{EFI_IFR_ANIMATION_OP}
$EFI{EFI_IFR_TO_LOWER_OP}
$EFI{EFI_IFR_TO_UPPER_OP}
$EFI{EFI_IFR_MAP_OP}
$EFI{EFI_IFR_ORDERED_LIST_OP}
$EFI{EFI_IFR_VARSTORE_OP}
$EFI{EFI_IFR_VARSTORE_NAME_VALUE_OP}
$EFI{EFI_IFR_VARSTORE_EFI_OP}
$EFI{EFI_IFR_VARSTORE_DEVICE_OP}
$EFI{EFI_IFR_VERSION_OP}
$EFI{EFI_IFR_END_OP}
$EFI{EFI_IFR_MATCH_OP}
$EFI{EFI_IFR_GET_OP}
$EFI{EFI_IFR_SET_OP}
$EFI{EFI_IFR_READ_OP}
$EFI{EFI_IFR_WRITE_OP}
$EFI{EFI_IFR_EQUAL_OP}
$EFI{EFI_IFR_NOT_EQUAL_OP}
$EFI{EFI_IFR_GREATER_THAN_OP}
$EFI{EFI_IFR_GREATER_EQUAL_OP}
$EFI{EFI_IFR_LESS_THAN_OP}
$EFI{EFI_IFR_LESS_EQUAL_OP}
$EFI{EFI_IFR_BITWISE_AND_OP}
$EFI{EFI_IFR_BITWISE_OR_OP}
$EFI{EFI_IFR_BITWISE_NOT_OP}
$EFI{EFI_IFR_SHIFT_LEFT_OP}
$EFI{EFI_IFR_SHIFT_RIGHT_OP}
$EFI{EFI_IFR_ADD_OP}
$EFI{EFI_IFR_SUBTRACT_OP}
$EFI{EFI_IFR_MULTIPLY_OP}
$EFI{EFI_IFR_DIVIDE_OP}
$EFI{EFI_IFR_MODULO_OP}
$EFI{EFI_IFR_RULE_REF_OP}
$EFI{EFI_IFR_QUESTION_REF1_OP}
$EFI{EFI_IFR_QUESTION_REF2_OP}
$EFI{EFI_IFR_UINT8_OP}
$EFI{EFI_IFR_UINT16_OP}
$EFI{EFI_IFR_UINT32_OP}
$EFI{EFI_IFR_UINT64_OP}
$EFI{EFI_IFR_TRUE_OP}
$EFI{EFI_IFR_FALSE_OP}
$EFI{EFI_IFR_TO_UINT_OP}
$EFI{EFI_IFR_TO_STRING_OP}
$EFI{EFI_IFR_TO_BOOLEAN_OP}
$EFI{EFI_IFR_MID_OP}
$EFI{EFI_IFR_FIND_OP}
$EFI{EFI_IFR_TOKEN_OP}
$EFI{EFI_IFR_STRING_REF1_OP}
$EFI{EFI_IFR_STRING_REF2_OP}
$EFI{EFI_IFR_CONDITIONAL_OP}

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

0x15;
0x16;
0x17;
0x18;
0x19;
0x1A;
0x1B;
0x1C;
0x1D;
0x1E;
0x1F;
0x20;
0x21;
0x22;
0x23;
0x24;
0x25;
0x26;
0x27;
0x28;
0x29;
0x2A;
0x2B;
0x2C;
0x2D;
0x2E;
0x2F;
0x30;
0x31;
0x32;
0x33;
0x34;
0x35;
0x36;
0x37;
0x38;
0x39;
0x3A;
0x3B;
0x3C;
0x3D;
0x3E;
0x3F;
0x40;
0x41;
0x42;
0x43;
0x44;
0x45;
0x46;
0x47;
0x48;
0x49;
0x4A;
0x4B;
0x4C;
0x4D;
0x4E;
0x4F;
0x50;

$EFI{EFI_IFR_QUESTION_REF3_OP}
$EFI{EFI_IFR_ZERO_OP}
$EFI{EFI_IFR_ONE_OP}
$EFI{EFI_IFR_ONES_OP}
$EFI{EFI_IFR_UNDEFINED_OP}
$EFI{EFI_IFR_LENGTH_OP}
$EFI{EFI_IFR_DUP_OP}
$EFI{EFI_IFR_THIS_OP}
$EFI{EFI_IFR_SPAN_OP}
$EFI{EFI_IFR_VALUE_OP}
$EFI{EFI_IFR_DEFAULT_OP}
$EFI{EFI_IFR_DEFAULTSTORE_OP}
$EFI{EFI_IFR_FORM_MAP_OP}
$EFI{EFI_IFR_CATENATE_OP}
$EFI{EFI_IFR_GUID_OP}
$EFI{EFI_IFR_SECURITY_OP}

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

0x51;
0x52;
0x53;
0x54;
0x55;
0x56;
0x57;
0x58;
0x59;
0x5A;
0x5B;
0x5C;
0x5D;
0x5E;
0x5F;
0x60;

%EFI_HII_PACKAGE_TYPE =
(
0x00
=> { name => 'EFI_HII_PACKAGE_TYPE_ALL'
, text => 'Pseudo-package type' },
0x01
=> { name => 'EFI_HII_PACKAGE_TYPE_GUID'
, text => 'Package type where the format of the data is specified using a GUID i
mmediately following the package header' },
0x02
=> { name => 'EFI_HII_PACKAGE_FORMS'
, text => 'Forms package' },
0x04
=> { name => 'EFI_HII_PACKAGE_STRINGS'
, text => 'Strings package' },
0x05
=> { name => 'EFI_HII_PACKAGE_FONTS'
, text => 'Fonts package' },
0x06
=> { name => 'EFI_HII_PACKAGE_IMAGES'
, text => 'Images package' },
0x07
=> { name => 'EFI_HII_PACKAGE_SIMPLE_FONTS'
, text => 'Simplified (8x19, 16x19) Fonts package' },
0x08
=> { name => 'EFI_HII_PACKAGE_DEVICE_PATH'
, text => 'Binary-encoded device path' },
0x09
=> { name => 'EFI_HII_PACKAGE_KEYBOARD_LAYOUT'
, text => 'Used to mark the end of a package list' },
0x0A
=> { name => 'EFI_HII_PACKAGE_ANIMATIONS'
, text => 'Animations package' },
0xDF
=> { name => 'EFI_HII_PACKAGE_END'
, text => 'Package types reserved for use by platform firmware implementations'
},
0xE0
=> { name => 'EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN'
, text => 'Package types reserved for use by platform firmware implementations'
},
);
%TYPES =
(
0x00 => 'int8',
0x01 => 'int16',
0x02 => 'int32',
0x03 => 'int64',
0x04 => 'bool',
0x05 => 'time',
0x06 => 'date',
0x07 => 'string',
0x08 => 'other',
);

Вам также может понравиться