From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by mx.groups.io with SMTP id smtpd.web12.1380.1579054361225476239 for ; Tue, 14 Jan 2020 18:12:41 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.126, mailfrom: bob.c.feng@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Jan 2020 18:12:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,320,1574150400"; d="scan'208";a="372776830" Received: from fmsmsx106.amr.corp.intel.com ([10.18.124.204]) by orsmga004.jf.intel.com with ESMTP; 14 Jan 2020 18:12:40 -0800 Received: from shsmsx603.ccr.corp.intel.com (10.109.6.143) by FMSMSX106.amr.corp.intel.com (10.18.124.204) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 14 Jan 2020 18:12:39 -0800 Received: from shsmsx601.ccr.corp.intel.com (10.109.6.141) by SHSMSX603.ccr.corp.intel.com (10.109.6.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Wed, 15 Jan 2020 10:12:38 +0800 Received: from shsmsx601.ccr.corp.intel.com ([10.109.6.141]) by SHSMSX601.ccr.corp.intel.com ([10.109.6.141]) with mapi id 15.01.1713.004; Wed, 15 Jan 2020 10:12:38 +0800 From: "Bob Feng" To: "Li, Aaron" , "devel@edk2.groups.io" CC: "Gao, Liming" Subject: Re: [PATCH v1] BaseTools/Capsule: Add capsule dependency support Thread-Topic: [PATCH v1] BaseTools/Capsule: Add capsule dependency support Thread-Index: AQHVx1l+cXE5oNq/M0OSaXlAuy4mPKfrA66w Date: Wed, 15 Jan 2020 02:12:37 +0000 Message-ID: <155230f6e8124e8e997949cdfc2aa824@intel.com> References: <20200110015735.28076-1-aaron.li@intel.com> In-Reply-To: <20200110015735.28076-1-aaron.li@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.36] MIME-Version: 1.0 Return-Path: bob.c.feng@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Bob Feng -----Original Message----- From: Li, Aaron=20 Sent: Friday, January 10, 2020 9:58 AM To: devel@edk2.groups.io Cc: Feng, Bob C ; Gao, Liming Subject: [PATCH v1] BaseTools/Capsule: Add capsule dependency support REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2412 Capsule generate tool support encode capsule dependencies through '-j' command with a JSON file. To enable dependency feature, "Dependencies" field for each payload in JSON file is required. The value of "Dependencies" field is C style infix notation expression. For example: "Dependencies":"72E2945A-00DA-448E-9AA7-075AD840F9D4 > 0x00000001" The relation of Dependency Expression Opcode in UEFI2.8 chap 23.2 and infix= notation expression value is as follows: +-----------------------------+--------------------------+ | OPCODE | INFIX EXPRESSION VALUE | +-----------------------------+--------------------------+ | 0x00 (PUSH_GUID) | {GUID} | | 0x01 (PUSH_VERSION) | {UINT32} | | 0x02 (DECLEAR_VERSION_NAME} | DECLEAR "{VERSION_NAME}" | | 0x03 (AND) | && | | 0x04 (OR) | || | | 0x05 (NOT) | ~ | | 0x06 (TRUE) | TRUE | | 0x07 (FALSE) | FALSE | | 0x08 (EQ) | =3D=3D | | 0x09 (GT) | > | | 0x0A (GTE) | >=3D | | 0x0B (LT) | < | | 0x0C (LTE) | <=3D | +-----------------------------+--------------------------+ Cc: Bob Feng Cc: Liming Gao Signed-off-by: Aaron Li --- BaseTools/Source/Python/Capsule/GenerateCapsule.py | 62 ++- BaseTools/Source/Python/Common/Uefi/Capsule/CapsuleDependency.py | 409 +++= +++++++++++++++++ 2 files changed, 464 insertions(+), 7 deletions(-) diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools= /Source/Python/Capsule/GenerateCapsule.py index 6838beb682..a8de988253 100644 --- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py +++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py @@ -31,6 +31,7 @@ import json from Common.Uefi.Capsule.UefiCapsuleHeader import UefiCapsuleHeaderClass = from Common.Uefi.Capsule.FmpCapsuleHeader import FmpCapsuleHeaderClass from Common.Uefi.Capsule.FmpAuthHeader import FmpAuthHeaderClass +from Common.Uefi.Capsule.CapsuleDependency import=20 +CapsuleDependencyClass from Common.Edk2.Capsule.FmpPayloadHeader import FmpPayloadHeaderClass =20 # @@ -306,6 +307,7 @@ if __name__ =3D=3D '__main__': OpenSslOtherPublicCertFile =3D ConvertJsonValue (Config, 'Op= enSslOtherPublicCertFile', os.path.expandvars, Required =3D False, Default = =3D None, Open =3D True) OpenSslTrustedPublicCertFile =3D ConvertJsonValue (Config, 'Op= enSslTrustedPublicCertFile', os.path.expandvars, Required =3D False, Defaul= t =3D None, Open =3D True) SigningToolPath =3D ConvertJsonValue (Config, 'Si= gningToolPath', os.path.expandvars, Required =3D False, Default =3D None) + DepexExp =3D ConvertJsonValue (Config, 'De= pendencies', str, Required =3D False, Default =3D None) =20 # # Read binary input file @@ -330,7 +332,8 @@ if __name__ =3D=3D '__main__': OpenSslSignerPrivateCertFile, OpenSslOtherPublicCertFile, OpenSslTrustedPublicCertFile, - SigningToolPath + SigningToolPath, + DepexExp )) =20 def GenerateOutputJson (PayloadJsonDescriptorList): @@ -348,7 +351,8 @@ if __name__ =3D=3D '__main__': "OpenSslSignerPrivateCertFile": str(Payl= oadDescriptor.OpenSslSignerPrivateCertFile), "OpenSslOtherPublicCertFile": str(Payloa= dDescriptor.OpenSslOtherPublicCertFile), "OpenSslTrustedPublicCertFile": str(Payl= oadDescriptor.OpenSslTrustedPublicCertFile), - "SigningToolPath": str(PayloadDescriptor= .SigningToolPath) + "SigningToolPath": str(PayloadDescriptor= .SigningToolPath), + "Dependencies" :=20 + str(PayloadDescriptor.DepexExp) }for PayloadDescriptor in PayloadJsonDescrip= torList ] } @@ -424,7 +428,8 @@ if __name__ =3D=3D '__main__': OpenSslSignerPrivateCertFile =3D None, OpenSslOtherPublicCertFile =3D None, OpenSslTrustedPublicCertFile =3D None, - SigningToolPath =3D None + SigningToolPath =3D None, + DepexExp =3D None ): self.Payload =3D Payload self.Guid =3D Guid @@ -438,6 +443,7 @@ if __name__ =3D=3D '__main__': self.OpenSslOtherPublicCertFile =3D OpenSslOtherPublicCertFi= le self.OpenSslTrustedPublicCertFile =3D OpenSslTrustedPublicCert= File self.SigningToolPath =3D SigningToolPath + self.DepexExp =3D DepexExp =20 self.UseSignTool =3D self.SignToolPfxFile is not None self.UseOpenSsl =3D (self.OpenSslSignerPrivateCertFile is not= None and @@ -446,6 +452,7 @@ if __name__ =3D=3D '__main__': self.AnyOpenSsl =3D (self.OpenSslSignerPrivateCertFile is not= None or self.OpenSslOtherPublicCertFile is not Non= e or self.OpenSslTrustedPublicCertFile is not N= one) + self.UseDependency =3D self.DepexExp is not None =20 def Validate(self, args): if self.UseSignTool and self.AnyOpenSsl: @@ -544,7 +551,8 @@ if __name__ =3D=3D '__main__': args.OpenSslSignerPrivateCertF= ile, args.OpenSslOtherPublicCertFil= e, args.OpenSslTrustedPublicCertF= ile, - args.SigningToolPath + args.SigningToolPath, + None )) for SinglePayloadDescriptor in PayloadDescriptorList: try: @@ -564,6 +572,12 @@ if __name__ =3D=3D '__main__': except: print ('GenerateCapsule: error: can not encode FMP Payload= Header') sys.exit (1) + if SinglePayloadDescriptor.UseDependency: + CapsuleDependency.Payload =3D Result + CapsuleDependency.DepexExp =3D SinglePayloadDescriptor.Dep= exExp + Result =3D CapsuleDependency.Encode () + if args.Verbose: + CapsuleDependency.DumpInfo () if SinglePayloadDescriptor.UseOpenSsl or SinglePayloadDescript= or.UseSignTool: # # Sign image with 64-bit MonotonicCount appended to end of= image @@ -657,7 +671,8 @@ if __name__ =3D=3D '__main__': args.OpenSslSignerPrivateCertF= ile, args.OpenSslOtherPublicCertFil= e, args.OpenSslTrustedPublicCertF= ile, - args.SigningToolPath + args.SigningToolPath, + None )) # # Perform additional verification on payload descriptors @@ -700,7= +715,8 @@ if __name__ =3D=3D '__main__': PayloadDes= criptorList[Index].OpenSslSignerPrivateCertFile, PayloadDes= criptorList[Index].OpenSslOtherPublicCertFile, PayloadDes= criptorList[Index].OpenSslTrustedPublicCertFile, - PayloadDes= criptorList[Index].SigningToolPath + PayloadDes= criptorList[Index].SigningToolPath, + None )) else: PayloadDescriptorList[0].Payload =3D FmpCapsuleHeader.= GetFmpCapsuleImageHeader (0).Payload @@ -708,6 +724,7 @@ if __name__ =3D=3D= '__main__': if Index > 0: PayloadDecodeFile =3D FmpCapsuleHeader.GetFmpC= apsuleImageHeader (Index).Payload PayloadDescriptorList.append (PayloadDescripto= r (PayloadDecodeFile, + None, None, None, None, @@ -736,= 7 +753,8 @@ if __name__ =3D=3D '__main__': PayloadDescrip= torList[Index].OpenSslSignerPrivateCertFile, PayloadDescrip= torList[Index].OpenSslOtherPublicCertFile, PayloadDescrip= torList[Index].OpenSslTrustedPublicCertFile, - PayloadDescrip= torList[Index].SigningToolPath + PayloadDescrip= torList[Index].SigningToolPath, + None )) JsonIndex =3D 0 for SinglePayloadDescriptor in PayloadDescriptorList: @@ -782,6 +800,23 @@ if __name__ =3D=3D '__main__': if args.Verbose: print ('--------') print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION') + + PayloadSignature =3D struct.unpack (' #=20 +SPDX-License-Identifier: BSD-2-Clause-Patent # import struct import=20 +json import sys import uuid import re + +''' +CapsuleDependency +''' + +class OpConvert (object): + def __init__ (self): + # Opcode: (OperandSize, PackSize, PackFmt, EncodeConvert, DecodeCo= nvert) + self._DepexOperations =3D {0x00: (16, 16, 's', self.Str2Guid, s= elf.Guid2Str), + 0x01: (4, 1, 'I', self.Str2Uint, sel= f.Uint2Str), + 0x02: (1, 0, 's', self.Str2Utf8, sel= f.Byte2Str), + } + + def Str2Uint (self, Data): + try: + Value =3D int (Data, 16) + except: + Message =3D '{Data} is not a valid integer value.'.format (Dat= a =3D Data) + raise ValueError (Message) + if Value < 0 or Value > 0xFFFFFFFF: + Message =3D '{Data} is not an UINT32.'.format (Data =3D Data) + raise ValueError (Message) + return Value + + def Uint2Str (self, Data): + if Data < 0 or Data > 0xFFFFFFFF: + Message =3D '{Data} is not an UINT32.'.format (Data =3D Data) + raise ValueError (Message) + return "0x{Data:08x}".format (Data =3D Data) + + def Str2Guid (self, Data): + try: + Guid =3D uuid.UUID (Data) + except: + Message =3D '{Data} is not a valid registry format GUID value.= '.format (Data =3D Data) + raise ValueError (Message) + return Guid.bytes_le + + def Guid2Str (self, Data): + try: + Guid =3D uuid.UUID (bytes_le =3D Data) + except: + Message =3D '{Data} is not a valid binary format GUID value.'.= format (Data =3D Data) + raise ValueError (Message) + return str (Guid).upper () + + def Str2Utf8 (self, Data): + if isinstance (Data, str): + return Data.encode ('utf-8') + else: + Message =3D '{Data} is not a valid string.'.format (Data =3D D= ata) + raise ValueError (Message) + + def Byte2Str (self, Data): + if isinstance (Data, bytes): + if Data[-1:] =3D=3D b'\x00': + return str (Data[:-1], 'utf-8') + else: + return str (Data, 'utf-8') + else: + Message =3D '{Data} is not a valid binary string.'.format (Dat= a =3D Data) + raise ValueError (Message) + + def OpEncode (self, Opcode, Operand =3D None): + BinTemp =3D struct.pack ('': [4, 0x09, 2], + '>=3D': [4, 0x0A, 2], + '<': [4, 0x0B, 2], + '<=3D': [4, 0x0C, 2], + } + + def __init__ (self): + self.Payload =3D b'' + self._DepexExp =3D None + self._DepexList =3D [] + self._DepexDump =3D [] + self.Depex =3D b'' + self._Valid =3D False + self._DepexSize =3D 0 + self._opReferenceReverse =3D {v[1] : k for k, v in self._opRefere= nce.items ()} + self.OpConverter =3D OpConvert () + + @property + def DepexExp (self): + return self._DepexExp + + @DepexExp.setter + def DepexExp (self, DepexExp =3D ''): + if isinstance (DepexExp, str): + DepexExp =3D re.sub (r'\n',r' ',DepexExp) + DepexExp =3D re.sub (r'\(',r' ( ',DepexExp) + DepexExp =3D re.sub (r'\)',r' ) ',DepexExp) + DepexExp =3D re.sub (r'~',r' ~ ',DepexExp) + self._DepexList =3D re.findall(r"[^\s\"\']+|\"[^\"]*\"|\'[^\']= *\'",DepexExp) + self._DepexExp =3D " ".join(self._DepexList) + + else: + Msg =3D 'Input Depex Expression is not valid string.' + raise ValueError (Msg) + + def IsValidOperator (self, op): + return op in self._opReference.keys () + + def IsValidUnaryOperator (self, op): + return op in self._opReference.keys () and=20 + self._opReference[op][2] =3D=3D 1 + + def IsValidBinocularOperator (self, op): + return op in self._opReference.keys () and=20 + self._opReference[op][2] =3D=3D 2 + + def IsValidGuid (self, operand): + try: + uuid.UUID (operand) + except: + return False + return True + + def IsValidVersion (self, operand): + try: + Value =3D int (operand, 16) + if Value < 0 or Value > 0xFFFFFFFF: + return False + except: + return False + return True + + def IsValidBoolean (self, operand): + try: + return operand.upper () in ['TRUE', 'FALSE'] + except: + return False + + def IsValidOperand (self, operand): + return self.IsValidVersion (operand) or self.IsValidGuid=20 + (operand) or self.IsValidBoolean (operand) + + def IsValidString (self, operand): + return operand[0] =3D=3D "\"" and operand[-1] =3D=3D "\"" and=20 + len(operand) >=3D 2 + + # Check if priority of current operater is greater than pervious op + def PriorityNotGreater (self, prevOp, currOp): + return self._opReference[currOp][0] <=3D=20 + self._opReference[prevOp][0] + + def ValidateDepex (self): + OpList =3D self._DepexList + + i =3D 0 + while i < len (OpList): + Op =3D OpList[i] + + if Op =3D=3D 'DECLARE': + i +=3D 1 + if i >=3D len (OpList): + Msg =3D 'No more Operand after {Op}.'.format (Op =3D O= pList[i-1]) + raise IndexError (Msg) + # Check valid string + if not self.IsValidString(OpList[i]): + Msg =3D '{Operand} after {Op} is not a valid expressio= n input.'.format (Operand =3D OpList[i], Op =3D OpList[i-1]) + raise ValueError (Msg) + + elif Op =3D=3D '(': + # Expression cannot end with ( + if i =3D=3D len (OpList) - 1: + Msg =3D 'Expression cannot end with \'(\'' + raise ValueError (Msg) + # The previous op after '(' cannot be a binocular operator + if self.IsValidBinocularOperator (OpList[i+1]) : + Msg =3D '{Op} after \'(\' is not a valid expression in= put.'.format (Op =3D OpList[i+1]) + raise ValueError (Msg) + + elif Op =3D=3D ')': + # Expression cannot start with ) + if i =3D=3D 0: + Msg =3D 'Expression cannot start with \')\'' + raise ValueError (Msg) + # The previous op before ')' cannot be an operator + if self.IsValidOperator (OpList[i-1]): + Msg =3D '{Op} before \')\' is not a valid expression i= nput.'.format (Op =3D OpList[i-1]) + raise ValueError (Msg) + # The next op after ')' cannot be operand or unary operato= r + if (i + 1) < len (OpList) and (self.IsValidOperand (OpList= [i+1]) or self.IsValidUnaryOperator (OpList[i+1])): + Msg =3D '{Op} after \')\' is not a valid expression in= put.'.format (Op =3D OpList[i+1]) + raise ValueError (Msg) + + elif self.IsValidOperand (Op): + # The next expression of operand cannot be operand or unar= y operator + if (i + 1) < len (OpList) and (self.IsValidOperand (OpList= [i+1]) or self.IsValidUnaryOperator (OpList[i+1])): + Msg =3D '{Op} after {PrevOp} is not a valid expression= input.'.format (Op =3D OpList[i+1], PrevOp =3D Op) + raise ValueError (Msg) + + elif self.IsValidOperator (Op): + # The next op of operator cannot binocular operator + if (i + 1) < len (OpList) and self.IsValidBinocularOperato= r (OpList[i+1]): + Msg =3D '{Op} after {PrevOp} is not a valid expression= input.'.format (Op =3D OpList[i+1], PrevOp =3D Op) + raise ValueError (Msg) + # The first op can not be binocular operator + if i =3D=3D 0 and self.IsValidBinocularOperator (Op): + Msg =3D 'Expression cannot start with an operator {Op}= .'.format (Op =3D Op) + raise ValueError (Msg) + # The last op can not be operator + if i =3D=3D len (OpList) - 1: + Msg =3D 'Expression cannot ended with an operator {Op}= .'.format (Op =3D Op) + raise ValueError (Msg) + # The next op of unary operator cannot be guid / version + if self.IsValidUnaryOperator (Op) and (self.IsValidGuid (O= pList[i+1]) or self.IsValidVersion (OpList[i+1])): + Msg =3D '{Op} after {PrevOp} is not a valid expression= input.'.format (Op =3D OpList[i+1], PrevOp =3D Op) + raise ValueError (Msg) + + else: + Msg =3D '{Op} is not a valid expression input.'.format (Op= =3D Op) + raise ValueError (Msg) + i +=3D 1 + + def Encode (self): + # initialize + self.Depex =3D b'' + self._DepexDump =3D [] + OperandStack =3D [] + OpeartorStack =3D [] + OpList =3D self._DepexList + + self.ValidateDepex () + + # convert + i =3D 0 + while i < len (OpList): + Op =3D OpList[i] + if Op =3D=3D 'DECLARE': + # This declare next expression value is a VERSION_STRING + i +=3D 1 + self.Depex +=3D self.OpConverter.OpEncode (0x02,=20 + OpList[i][1:-1]) + + elif Op =3D=3D '(': + OpeartorStack.append (Op) + + elif Op =3D=3D ')': + while (OpeartorStack and OpeartorStack[-1] !=3D '('): + Operator =3D OpeartorStack.pop () + self.Depex +=3D self.OpConverter.OpEncode (self._opRef= erence[Operator][1]) + try: + OpeartorStack.pop () # pop out '(' + except: + Msg =3D 'Pop out \'(\' failed, too many \')\'' + raise ValueError (Msg) + + elif self.IsValidGuid (Op): + if not OperandStack: + OperandStack.append (self.OpConverter.OpEncode (0x00, = Op)) + else: + # accroding to uefi spec 2.8, the guid/version operand= s is a reversed order in firmware comparison. + self.Depex +=3D self.OpConverter.OpEncode (0x00, Op) + self.Depex +=3D OperandStack.pop () + + elif self.IsValidVersion (Op): + if not OperandStack: + OperandStack.append (self.OpConverter.OpEncode (0x01, = Op)) + else: + # accroding to uefi spec 2.8, the guid/version operand= s is a reversed order in firmware comparison. + self.Depex +=3D self.OpConverter.OpEncode (0x01, Op) + self.Depex +=3D OperandStack.pop () + + elif self.IsValidBoolean (Op): + if Op.upper () =3D=3D 'FALSE': + self.Depex +=3D self.OpConverter.OpEncode (0x07) + elif Op.upper () =3D=3D 'TRUE': + self.Depex +=3D self.OpConverter.OpEncode (0x06) + + elif self.IsValidOperator (Op): + while (OpeartorStack and OpeartorStack[-1] !=3D '(' and se= lf.PriorityNotGreater (OpeartorStack[-1], Op)): + Operator =3D OpeartorStack.pop () + self.Depex +=3D self.OpConverter.OpEncode (self._opRef= erence[Operator][1]) + OpeartorStack.append (Op) + + i +=3D 1 + + while OpeartorStack: + Operator =3D OpeartorStack.pop () + if Operator =3D=3D '(': + Msg =3D 'Too many \'(\'.' + raise ValueError (Msg) + self.Depex +=3D self.OpConverter.OpEncode (self._opReference[O= perator][1]) + self.Depex +=3D self.OpConverter.OpEncode (0x0D) + + self._Valid =3D True + self._DepexSize =3D len (self.Depex) + return self.Depex + self.Payload + + def Decode (self, Buffer): + # initialize + self.Depex =3D Buffer + OperandStack =3D [] + DepexLen =3D 0 + + while True: + Opcode, Operand, OperandSize =3D self.OpConverter.OpDecode (Bu= ffer[DepexLen:]) + DepexLen +=3D OperandSize + 1 + + if Opcode =3D=3D 0x0D: + break + + elif Opcode =3D=3D 0x02: + if not OperandStack: + OperandStack.append ('DECLARE \"{String}\"'.format (St= ring =3D Operand)) + else: + PrevOperand =3D OperandStack.pop () + OperandStack.append ('{Operand} DECLARE=20 + \"{String}\"'.format (Operand =3D PrevOperand, String =3D Operand)) + + elif Opcode in [0x00, 0x01]: + OperandStack.append (Operand) + + elif Opcode =3D=3D 0x06: + OperandStack.append ('TRUE') + + elif Opcode =3D=3D 0x07: + OperandStack.append ('FALSE') + + elif self.IsValidOperator (self._opReferenceReverse[Opcode]): + Operator =3D self._opReferenceReverse[Opcode] + if self.IsValidUnaryOperator (self._opReferenceReverse[Opc= ode]) and len (OperandStack) >=3D 1: + Oprand =3D OperandStack.pop () + OperandStack.append (' ( {Operator} {Oprand} )'.format= (Operator =3D Operator, Oprand =3D Oprand)) + elif self.IsValidBinocularOperator (self._opReferenceRever= se[Opcode]) and len (OperandStack) >=3D 2: + Oprand1 =3D OperandStack.pop () + Oprand2 =3D OperandStack.pop () + OperandStack.append (' ( {Oprand1} {Operator} {Oprand2= } )'.format (Operator =3D Operator, Oprand1 =3D Oprand1, Oprand2 =3D Oprand= 2)) + else: + Msg =3D 'No enough Operands for {Opcode:02X}.'.format = (Opcode =3D Opcode) + raise ValueError (Msg) + + else: + Msg =3D '{Opcode:02X} is not a valid OpCode.'.format (Opco= de =3D Opcode) + raise ValueError (Msg) + + self.DepexExp =3D OperandStack[0].strip (' ') + self.Payload =3D Buffer[DepexLen:] + self._Valid =3D True + self._DepexSize =3D DepexLen + return self.Payload + + + def DumpInfo (self): + DepexLen =3D 0 + Opcode =3D None + Buffer =3D self.Depex + + if self._Valid =3D=3D True: + print ('EFI_FIRMWARE_IMAGE_DEP.Dependencies =3D {') + while Opcode !=3D 0x0D: + Opcode, Operand, OperandSize =3D self.OpConverter.OpDecode= (Buffer[DepexLen:]) + DepexLen +=3D OperandSize + 1 + if Operand: + print (' {Opcode:02X}, {Operand},'.format (Opcode = =3D Opcode, Operand =3D Operand)) + else: + print (' {Opcode:02X},'.format (Opcode =3D Opcode)) + print ('}') + + print ('sizeof (EFI_FIRMWARE_IMAGE_DEP.Dependencies) =3D {S= ize:08X}'.format (Size =3D self._DepexSize)) + print ('sizeof (Payload) =3D {S= ize:08X}'.format (Size =3D len (self.Payload))) -- 2.18.0.windows.1