Newer
Older
AMI-Aptio-BIOS-Reversed / PurleyPlatPkg / BootGuard / ExtendBtGSupportToDxe / Pei / BootGuardPei / BootGuardPei.c
@Ajax Dong Ajax Dong 2 days ago 30 KB Restructure the repo
/*
 * BootGuardPei.c
 *
 * Combined decompiler listing for the BootGuardPei PEIM.  Addresses in
 * comments refer to offsets in the recovered IA32 image.  Names and types are
 * recovered artifacts and should be validated before reuse as source-level API.
 */

#include "BootGuardPei.h"

/* -------------------------------------------------------------------------
 * Memory primitives
 * ------------------------------------------------------------------------- */

// InternalCompareMem @ 0xffde2fa4 int InternalCompareMem(_BYTE *ZeroPool, _BYTE *a2, int n32)
{
 bool Buffer; // zf do /*0xffde2fb2*/
 {
 if ( !n32 ) /*0xffde2fb2*/
 break; /*0xffde2fb2*/
 Buffer = *ZeroPool++ == *a2++; /*0xffde2fb2*/
 --n32; /*0xffde2fb2*/
 }
 while ( Buffer ); /*0xffde2fb2*/
 return (unsigned __int8)*(ZeroPool - 1) - (unsigned __int8)*(a2 - 1); /*0xffde2fbe*/
}

// InternalCopyMem @ 0xffde2fc4 char *InternalCopyMem(char *dst, char *src, unsigned int n64)
{
 unsigned int n64_1; // edx char *dst_1; // edi char *src_1; // esi n64_1 = n64; /*0xffde2fce*/
 if ( src < dst && &src[n64 - 1] >= dst ) /*0xffde2fdc*/
 {
 src_1 = &src[n64 - 1]; /*0xffde2ff0*/
 dst_1 = &dst[n64 - 1]; /*0xffde2ff2*/
 }
 else
 {
 n64_1 = n64 & 3; /*0xffde2fe0*/
 qmemcpy(dst, src, 4 * (n64 >> 2)); /*0xffde2fe9*/
 src_1 = &src[4 * (n64 >> 2)]; /*0xffde2fe9*/
 dst_1 = &dst[4 * (n64 >> 2)]; /*0xffde2fe9*/
 }
 qmemcpy(dst_1, src_1, n64_1); /*0xffde2ff9*/
 return dst; /*0xffde3000*/
}

// SetMem @ 0xffde3004 void *SetMem(void *buf, unsigned int count, char value)
{
 memset(buf, value, count); /*0xffde3011*/
 return buf; /*0xffde3017*/
}

// SetMemZero @ 0xffde3024 void *SetMemZero(void *buf, unsigned int n80)
{
 memset(buf, 0, n80); /*0xffde303b*/
 return buf; /*0xffde3042*/
}

// SetMem32Loop @ 0xffde3044 int SetMem32Loop(int a1, int a2, int a3, int a4)
{
 do /*0xffde305d*/
 {
 *(_DWORD *)(a1 + 8 *a2 - 8) = a3; /*0xffde3055*/
 *(_DWORD *)(a1 + 8 *a2-- - 4) = a4; /*0xffde3059*/
 }
 while ( a2 ); /*0xffde305d*/
 return a1; /*0xffde3061*/
}

// SetMem32 @ 0xffde3064 void *SetMem32(void *buf, unsigned int count, int value)
{
 memset32(buf, value, count); /*0xffde3071*/
 return buf; /*0xffde3077*/
}

/* -------------------------------------------------------------------------
 * PEIM entry and Boot Guard verification
 * ------------------------------------------------------------------------- */

// _ModuleEntryPoint @ 0xffde307c EFI_STATUS ModuleEntryPoint(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
 int ConstructorStatus; // eax int DebugServices; // eax unsigned __int64 Ia32Msr; // rax EFI_STATUS BgEnabled; // esi unsigned __int64 MsrLow; // rax int PeiServices; // eax ConstructorStatus = PeiCryptLibConstructor((int)ImageHandle, (int)SystemTable); /*0xffde3089*/
 if ( ConstructorStatus < 0 ) /*0xffde3097*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", ConstructorStatus); /*0xffde30a0*/
 DebugServices = GetDebugPeiServicesPtr(); /*0xffde30a8*/
 if ( DebugServices ) /*0xffde30af*/
 (*(void ( **)(const char *, int, const char *))(DebugServices + 4))( /*0xffde30c0*/
 "e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\IA32\\PurleyPlatPkg\\BootGuard\\ExtendBtGSupportToDxe\\Pei\\BootGuardPei"
 "\\DEBUG\\AutoGen.c",
 168,
 "!EFI_ERROR (Status)");
 }
 Ia32Msr = __readmsr(0x13Au); /*0xffde30cb*/
 BgEnabled = 0; /*0xffde30cd*/
 if ( (Ia32Msr & 0x100000000LL) != 0 ) /*0xffde30d6*/
 {
 DebugPrint(64, "Processor supports Boot Guard.\n"); /*0xffde30df*/
 MsrLow = __readmsr(0x13Au); /*0xffde30eb*/
 if ( (_DWORD)MsrLow ) /*0xffde30ef*/
 {
 PeiServices = GetPeiServices(); /*0xffde30f8*/
 return (*(int ( **)(int, void *))(*(_DWORD *)PeiServices + 36))(PeiServices, &unk_FFDE4CAC); /*0xffde3108*/
 }
 else
 {
 DebugPrint( /*0xffde30f6*/
 0x80000000,
 "[BootGuardPei.c] Boot Guard is disabled by Boot Guard Profile Configuration in the Intel Fitc\n");
 }
 }
 else
 {
 DebugPrint(0x80000000, "Processor does not support Boot Guard.\n"); /*0xffde3112*/
 }
 return BgEnabled; /*0xffde3119*/
}

// LocateBootGuardHashKey @ 0xffde3121 int LocateBootGuardHashKey(void *HashKeyOut)
{
 int PeiServices; // ecx int PeiServices2; // esi int FvIdx; // edi int Status; // eax int Guid; // [esp+10h] [ebp-8h] BYREF int Handle; // [esp+14h] [ebp-4h] BYREF PeiServices2 = PeiServices; /*0xffde312c*/
 Guid = 0; /*0xffde3135*/
 FvIdx = 0; /*0xffde313c*/
 (*(void ( **)())(*(_DWORD *)PeiServices + 56))(); /*0xffde3140*/
 Status = (*(int ( **)(int, _DWORD, int *))(*(_DWORD *)PeiServices2 + 56))(PeiServices2, 0, &Handle); /*0xffde314f*/
 if ( Status >= 0 ) /*0xffde3157*/
 {
 while ( 2 ) /*0xffde315e*/
 {
 Guid = 0; /*0xffde315e*/
 while ( (*(int ( **)(int, int, int, int *))(*(_DWORD *)PeiServices2 + 60))(PeiServices2, 2, Handle, &Guid) != -2147483634 ) /*0xffde3188*/
 {
 if ( IsBootGuardHashGuid(Guid) ) /*0xffde3169*/
 {
 Status = (*(int ( **)(int, int, int, void *))(*(_DWORD *)PeiServices2 + 64))( /*0xffde31ac*/
 PeiServices2,
 25,
 Guid,
 HashKeyOut);
 if ( Status < 0 ) /*0xffde31b4*/
 return -2147483634; /*0xffde31b6*/
 return Status; /*0xffde31b6*/
 }
 }
 Status = (*(int ( **)(int, int, int *))(*(_DWORD *)PeiServices2 + 56))(PeiServices2, ++FvIdx, &Handle); /*0xffde3194*/
 if ( Status >= 0 ) /*0xffde319c*/
 continue; /*0xffde319c*/
 break;
 }
 }
 return Status; /*0xffde31b8*/
}

// BootGuardPeiEntry @ 0xffde31bf int BootGuardPeiEntry(void *PeiServices)
{
 int PeiServicePtr; // eax int Status; // esi int ContextSize; // eax void *ZeroPoolSize; // ecx int AllocStatus; // esi int BgStatus; // ebp int PeiServices2; // eax int PcdPei2; // eax int PcdPei3; // eax int HashData; // esi unsigned int Idx; // edi unsigned int i; // ebx unsigned int j; // ebx unsigned int k; // ebx int PeiServices3; // eax int PcdPei; // eax int PcdPei4; // eax int Sha256ContextRef; // [esp+4h] [ebp-50h] BYREF int HashDataPtr; // [esp+8h] [ebp-4Ch] BYREF int BootMode; // [esp+Ch] [ebp-48h] BYREF int Hash0[8]; // [esp+14h] [ebp-40h] BYREF int Hash1[8]; // [esp+34h] [ebp-20h] BYREF PeiServicePtr = GetPeiServices(); /*0xffde31c3*/
 Status = (*(int ( **)(int, int *))(*(_DWORD *)PeiServicePtr + 40))(PeiServicePtr, &BootMode); /*0xffde31d3*/
 if ( Status < 0 ) /*0xffde31d9*/
 {
 DebugPrint(0x80000000, "[BootGuardPei.c] Get Boot Mode is fail\n"); /*0xffde31e5*/
 return Status; /*0xffde31ee*/
 }
 if ( BootMode == 17 ) /*0xffde31f8*/
 {
 DebugPrint(64, "[BootGuardPei.c] In the BOOT_ON_S3_RESUME\n"); /*0xffde3201*/
 return Status; /*0xffde3201*/
 }
 ContextSize = Sha256ContextSize(); /*0xffde3204*/
 AllocStatus = (*(int ( **)(void *, int, int *))(*(_DWORD *)PeiServices + 76))( /*0xffde3219*/
 PeiServices,
 ContextSize,
 &Sha256ContextRef);
 if ( AllocStatus < 0 ) /*0xffde3220*/
 {
 DebugPrint(0x80000000, "[BootGuardPei.c] AllocatePool is fail for BootGuardSha256Context\n"); /*0xffde3227*/
 return AllocStatus; /*0xffde3249*/
 }
 HashDataPtr = AllocateZeroPool(ZeroPoolSize); /*0xffde322e*/
 if ( !HashDataPtr ) /*0xffde3234*/
 {
 DebugPrint(0x80000000, "[BootGuardPei.c] AllocateZeroPool is fail for RESERVE_BOOT_GUARD_FV_MAIN_HASH_KEY\n"); /*0xffde3240*/
 return AllocStatus; /*0xffde3240*/
 }
 BgStatus = LocateBootGuardHashKey((int)&HashDataPtr); /*0xffde325b*/
 if ( BgStatus >= 0 ) /*0xffde3260*/
 {
 HashData = HashDataPtr; /*0xffde32a9*/
 Idx = 0; /*0xffde32ad*/
 for ( i = 0; i < 0x20; ++i ) /*0xffde32b0*/
 DebugPrint(64, "[BootGuardPei.c] BootGuardFvMainHashKey0[%x]= %x.\n", i, *(unsigned __int8 *)(i + HashData)); /*0xffde32bf*/
 DebugPrint(64, "\n[BootGuardPei.c] BootGuardFvMainSegmentBase0= %x.\n", *(_DWORD *)(HashData + 32)); /*0xffde32d7*/
 DebugPrint(64, "\n[BootGuardPei.c] BootGuardFvMainSegmentSize0= %x.\n", *(_DWORD *)(HashData + 36)); /*0xffde32e6*/
 Sha256InitWrapper((_DWORD *)Sha256ContextRef); /*0xffde32ef*/
 Sha256UpdateWrapper(Sha256ContextRef, *(_DWORD *)(HashData + 32), *(_DWORD *)(HashData + 36)); /*0xffde32fe*/
 Sha256FinalWrapper((int *)Sha256ContextRef, (int)Hash0); /*0xffde330c*/
 for ( j = 0; j < 0x20; ++j ) /*0xffde3314*/
 DebugPrint(64, "[BootGuardPei.c] CurrentBootGuardFvMainHash256Val[%x]= %x.\n", j, *((unsigned __int8 *)Hash0 + j)); /*0xffde3324*/
 if ( CompareMem(HashData, (int)Hash0, 32) ) /*0xffde333a*/
 {
 DebugPrint(64, "[BootGuardPei.c] FvMainHashKey0 Verify Fail.\n"); /*0xffde334d*/
 }
 else
 {
 if ( !*(_DWORD *)(HashData + 72) ) /*0xffde3352*/
 return BgStatus; /*0xffde3352*/
 if ( !*(_DWORD *)(HashData + 76) ) /*0xffde335b*/
 return BgStatus; /*0xffde335b*/
 for ( k = 0; k < 0x20; ++k ) /*0xffde3364*/
 DebugPrint( /*0xffde3374*/
 64,
 "[BootGuardPei.c] BootGuardFvMainHashKey1[%x]= %x.\n",
 k,
 *(unsigned __int8 *)(k + HashData + 40));
 DebugPrint(64, "\n[BootGuardPei.c] BootGuardFvMainSegmentBase1= %x.\n", *(_DWORD *)(HashData + 72)); /*0xffde338e*/
 DebugPrint(64, "\n[BootGuardPei.c] BootGuardFvMainSegmentSize1= %x.\n", *(_DWORD *)(HashData + 76)); /*0xffde339c*/
 Sha256InitWrapper((_DWORD *)Sha256ContextRef); /*0xffde33a5*/
 Sha256UpdateWrapper(Sha256ContextRef, *(_DWORD *)(HashData + 72), *(_DWORD *)(HashData + 76)); /*0xffde33b4*/
 Sha256FinalWrapper((int *)Sha256ContextRef, (int)Hash1); /*0xffde33c2*/
 do /*0xffde33e3*/
 {
 DebugPrint( /*0xffde33d7*/
 64,
 "[BootGuardPei.c] CurrentBootGuardFvMainHash256Val2[%x]= %x.\n",
 Idx,
 *((unsigned __int8 *)Hash1 + Idx));
 ++Idx; /*0xffde33df*/
 }
 while ( Idx < 0x20 ); /*0xffde33e3*/
 if ( !CompareMem(HashData + 40, (int)Hash1, 32) ) /*0xffde33f0*/
 return BgStatus; /*0xffde343c*/
 DebugPrint(64, "[BootGuardPei.c] FvMainHashKey1 Verify Fail.\n"); /*0xffde3402*/
 }
 PeiServices3 = GetPeiServices(); /*0xffde3407*/
 (*(void ( **)(int, int))(*(_DWORD *)PeiServices3 + 44))(PeiServices3, 32); /*0xffde3411*/
 DebugClear(); /*0xffde3414*/
 PcdPei = GetPcdPei(); /*0xffde3419*/
 if ( !(*(unsigned __int8 ( **)(int))(PcdPei + 24))(9) ) /*0xffde3420*/
 {
 PcdPei4 = GetPcdPei(); /*0xffde342a*/
 (*(void ( **)(int, int))(PcdPei4 + 80))(9, 1); /*0xffde3433*/
 }
 return 0; /*0xffde3438*/
 }
 else
 {
 DebugPrint(0x80000000, "[BootGuardPei.c] LocateBootGuardHashKey is fail\n"); /*0xffde326c*/
 PeiServices2 = GetPeiServices(); /*0xffde3271*/
 (*(void ( **)(int, int))(*(_DWORD *)PeiServices2 + 44))(PeiServices2, 32); /*0xffde327b*/
 DebugClear(); /*0xffde327e*/
 PcdPei2 = GetPcdPei(); /*0xffde3283*/
 if ( !(*(unsigned __int8 ( **)(int))(PcdPei2 + 24))(9) ) /*0xffde328a*/
 {
 PcdPei3 = GetPcdPei(); /*0xffde3294*/
 (*(void ( **)(int, int))(PcdPei3 + 80))(9, 1); /*0xffde329d*/
 }
 return BgStatus; /*0xffde32a2*/
 }
}

/* -------------------------------------------------------------------------
 * PEI services, PCD, allocation, and debug support
 * ------------------------------------------------------------------------- */

// GetPcdPei @ 0xffde3446 int GetPcdPei()
{
 int PeiServices; // eax int Status; // eax int DebugPeiServicesPtr; // eax int Result; // [esp+0h] [ebp-4h] BYREF PeiServices = GetPeiServices(); /*0xffde344a*/
 Result = (int)&Result; /*0xffde3452*/
 Status = (*(int ( **)(int, void *, _DWORD, _DWORD))(*(_DWORD *)PeiServices + 32))(PeiServices, &unk_FFDE4C9C, 0, 0); /*0xffde345f*/
 if ( Status < 0 ) /*0xffde3467*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status); /*0xffde3474*/
 DebugPeiServicesPtr = GetDebugPeiServicesPtr(); /*0xffde347c*/
 if ( DebugPeiServicesPtr ) /*0xffde3483*/
 (*(void ( **)(const char *, int, const char *))(DebugPeiServicesPtr + 4))( /*0xffde3491*/
 "e:\\hs\\MdePkg\\Library\\PeiPcdLib\\PeiPcdLib.c",
 49,
 "!EFI_ERROR (Status)");
 }
 return Result; /*0xffde349c*/
}

// SetPcd @ 0xffde349e int SetPcd(int n15, int a2)
{
 int PcdPei; // eax PcdPei = GetPcdPei(); /*0xffde349e*/
 (*(void ( **)(int, int))(PcdPei + 68))(n15, a2); /*0xffde34ab*/
 return a2; /*0xffde34b4*/
}

// GetDebugPeiServicesPtr @ 0xffde34b5 int GetDebugPeiServicesPtr()
{
 int PeiServices; // eax _BYTE v2[4]; // [esp+0h] [ebp-8h] BYREF int Result; // [esp+4h] [ebp-4h] BYREF PeiServices = GetPeiServices(); /*0xffde34ba*/
 if ( (*(int ( **)(int, void *, _DWORD, _BYTE *, int *))(*(_DWORD *)PeiServices + 32))( /*0xffde34d9*/
 PeiServices,
 &unk_FFDE4C5C,
 0,
 v2,
 &Result) >= 0 )
 return Result; /*0xffde34df*/
 else return 0; /*0xffde34db*/
}

// DebugPrint @ 0xffde34e6 int DebugPrint(int a1, const char *a2, ...)
{
 int result; // eax int ( **v3)(int, const char *, char *); // esi va_list va; // [esp+10h] [ebp+Ch] BYREF va_start(va, a2);
 result = GetDebugPeiServicesPtr(); /*0xffde34e7*/
 v3 = (int ( **)(int, const char *, char *))result; /*0xffde34ec*/
 if ( result ) /*0xffde34f0*/
 {
 result = GetDebugLevel(); /*0xffde34f2*/
 if ( (result & a1) != 0 ) /*0xffde34fd*/
 return (*v3)(a1, a2, (char *)va); /*0xffde3509*/
 }
 return result; /*0xffde350e*/
}

// DebugAssert @ 0xffde3510 int DebugAssert(
 int e:__hs__MdePkg__Library__BaseLib__X86ReadIdtr.c,
 int n37,
 const char *PeiServices____((void__)_0))
{
 int result; // eax result = GetDebugPeiServicesPtr(); /*0xffde3516*/
 if ( result ) /*0xffde351d*/
 return (*(int ( **)(int, int, const char *))(result + 4))( /*0xffde3525*/
 e:__hs__MdePkg__Library__BaseLib__X86ReadIdtr.c,
 n37,
 PeiServices____((void__)_0));
 return result; /*0xffde352b*/
}

// DebugEnabled @ 0xffde352e char DebugEnabled()
{
 return 1; /*0xffde3530*/
}

// DebugLevelEnabled @ 0xffde3531 bool DebugLevelEnabled(int a1)
{
 return a1 != 0; /*0xffde3539*/
}

// AllocatePool @ 0xffde353a void *__thiscall AllocatePool(void *this)
{
 int PeiServices; // eax PeiServices = GetPeiServices(); /*0xffde353e*/
 if ( (*(int (__stdcall **)(int))(*(_DWORD *)PeiServices + 76))(PeiServices) >= 0 ) /*0xffde3554*/
 return this; /*0xffde355a*/
 else return 0; /*0xffde3556*/
}

// AllocateZeroPool @ 0xffde3561 int __thiscall AllocateZeroPool(void *this)
{
 int buf_1; // eax void *buf; // esi int DebugPeiServicesPtr; // eax buf_1 = (int)AllocatePool(this); /*0xffde3561*/
 if ( buf_1 ) /*0xffde3568*/
 {
 buf = (void *)buf_1; /*0xffde3715*/
 if ( (unsigned int)-buf_1 < 0x50 ) /*0xffde373f*/
 {
 DebugPeiServicesPtr = GetDebugPeiServicesPtr(); /*0xffde3741*/
 if ( DebugPeiServicesPtr ) /*0xffde3748*/
 (*(void ( **)(const char *, int, const char *))(DebugPeiServicesPtr + 4))( /*0xffde3752*/
 "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
 54,
 "Length <= (0xFFFFFFFF - (UINTN)Buffer + 1)");
 }
 return (int)SetMemZero(buf, 0x50u); /*0xffde375b*/
 }
 return buf_1; /*0xffde3571*/
}

// DebugClear @ 0xffde3572 int DebugClear()
{
 int PeiServices; // eax PeiServices = GetPeiServices(); /*0xffde3572*/
 return (*(int ( **)(int, void *))(*(_DWORD *)PeiServices + 24))(PeiServices, &unk_FFDE4CB8); /*0xffde3584*/
}

// CompareMem @ 0xffde3585 int CompareMem(void *Dst, void *Src, unsigned int Len)
{
 int DebugServices; // eax int DebugServices2; // eax int DebugServices3; // eax int DebugServices4; // eax if ( !Len || Dst == Src ) /*0xffde359e*/
 return 0; /*0xffde3637*/
 if ( !Dst ) /*0xffde35ac*/
 {
 DebugServices = GetDebugPeiServicesPtr(); /*0xffde35ae*/
 if ( DebugServices ) /*0xffde35b5*/
 (*(void ( **)(const char *, int, const char *))(DebugServices + 4))( /*0xffde35bf*/
 "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CompareMemWrapper.c",
 60,
 "DestinationBuffer != ((void *) 0)");
 }
 if ( !Src ) /*0xffde35c7*/
 {
 DebugServices2 = GetDebugPeiServicesPtr(); /*0xffde35c9*/
 if ( DebugServices2 ) /*0xffde35d0*/
 (*(void ( **)(const char *, int, const char *))(DebugServices2 + 4))( /*0xffde35da*/
 "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CompareMemWrapper.c",
 61,
 "SourceBuffer != ((void *) 0)");
 }
 if ( Len - 1 > ~(unsigned int)Dst ) /*0xffde35e9*/
 {
 DebugServices3 = GetDebugPeiServicesPtr(); /*0xffde35eb*/
 if ( DebugServices3 ) /*0xffde35f2*/
 (*(void ( **)(const char *, int, const char *))(DebugServices3 + 4))( /*0xffde3600*/
 "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CompareMemWrapper.c",
 62,
 "(Length - 1) <= (0xFFFFFFFF - (UINTN)DestinationBuffer)");
 }
 if ( Len - 1 > ~(unsigned int)Src ) /*0xffde360d*/
 {
 DebugServices4 = GetDebugPeiServicesPtr(); /*0xffde360f*/
 if ( DebugServices4 ) /*0xffde3616*/
 (*(void ( **)(const char *, int, const char *))(DebugServices4 + 4))( /*0xffde3624*/
 "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CompareMemWrapper.c",
 63,
 "(Length - 1) <= (0xFFFFFFFF - (UINTN)SourceBuffer)");
 }
 return InternalCompareMem(Dst, Src, Len); /*0xffde3639*/
}

// IsBootGuardHashGuid @ 0xffde363d bool __thiscall IsBootGuardHashGuid(int this)
{
 __int64 Unaligned64; // rax int Unaligned64_1; // ebx __int64 Unaligned64_3; // rax int Unaligned64_2; // edi __int64 v6; // kr00_8 __int64 v7; // rax int v9; // [esp+10h] [ebp-8h]
 int v10; // [esp+14h] [ebp-4h]

 Unaligned64 = ReadUnaligned64((void *)this); /*0xffde3645*/
 v10 = HIDWORD(Unaligned64); /*0xffde364f*/
 Unaligned64_1 = Unaligned64; /*0xffde3653*/
 Unaligned64_3 = ReadUnaligned64(&unk_FFDE4CC4); /*0xffde3655*/
 v9 = HIDWORD(Unaligned64_3); /*0xffde365d*/
 Unaligned64_2 = Unaligned64_3; /*0xffde3661*/
 v6 = ReadUnaligned64((void *)(this + 8)); /*0xffde366f*/
 v7 = ReadUnaligned64(&unk_FFDE4CCC); /*0xffde3671*/
 return Unaligned64_1 == Unaligned64_2 && v10 == v9 && v6 == v7; /*0xffde3692*/
}

// CopyMem @ 0xffde3699 int CopyMem(void *Dst, const void *Src, unsigned int Len)
{
 int DebugServices; // eax int DebugServices2; // eax if ( !Len ) /*0xffde36a0*/
 return (int)Dst; /*0xffde36a2*/
 if ( Len - 1 > ~(unsigned int)Dst ) /*0xffde36bd*/
 {
 DebugServices = GetDebugPeiServicesPtr(); /*0xffde36bf*/
 if ( DebugServices ) /*0xffde36c6*/
 (*(void ( **)(const char *, int, const char *))(DebugServices + 4))( /*0xffde36d0*/
 "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
 56,
 "(Length - 1) <= (0xFFFFFFFF - (UINTN)DestinationBuffer)");
 }
 if ( Len - 1 > ~(unsigned int)Src ) /*0xffde36de*/
 {
 DebugServices2 = GetDebugPeiServicesPtr(); /*0xffde36e0*/
 if ( DebugServices2 ) /*0xffde36e7*/
 (*(void ( **)(const char *, int, const char *))(DebugServices2 + 4))( /*0xffde36f1*/
 "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
 57,
 "(Length - 1) <= (0xFFFFFFFF - (UINTN)SourceBuffer)");
 }
 if ( Dst == Src ) /*0xffde36fb*/
 return (int)Dst; /*0xffde36fd*/
 else return (int)InternalCopyMem((char *)Dst, (char *)Src, Len); /*0xffde3707*/
}

/* -------------------------------------------------------------------------
 * Low-level platform helpers
 * ------------------------------------------------------------------------- */

// ReadUnaligned64 @ 0xffde3765 __int64 __thiscall ReadUnaligned64(void *this)
{
 int DebugPeiServicesPtr; // eax if ( !this ) /*0xffde376a*/
 {
 DebugPeiServicesPtr = GetDebugPeiServicesPtr(); /*0xffde376c*/
 if ( DebugPeiServicesPtr ) /*0xffde3773*/
 (*(void ( **)(const char *, int, const char *))(DebugPeiServicesPtr + 4))( /*0xffde3784*/
 "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
 192,
 "Buffer != ((void *) 0)");
 }
 return *(_QWORD *)this; /*0xffde378f*/
}

// GetDebugLevel @ 0xffde3791 int GetDebugLevel()
{
 unsigned __int8 v0; // al char Result; // al char n3_1; // cl v0 = __inbyte(0x70u); /*0xffde3797*/
 __outbyte(0x70u, v0 & 0x80 | 0x4A); /*0xffde379c*/
 Result = __inbyte(0x71u); /*0xffde37a3*/
 n3_1 = Result; /*0xffde37a4*/
 if ( (unsigned __int8)Result <= 3u ) /*0xffde37a9*/
 {
LABEL_4:
 if ( !n3_1 ) /*0xffde37c4*/
 return 0; /*0xffde37c4*/
 goto LABEL_5; /*0xffde37c4*/
 }
 n3_1 = Result; /*0xffde37ab*/
 if ( !Result ) /*0xffde37b3*/
 {
 n3_1 = MEMORY[0xFDAF0490] & 2 | 1; /*0xffde37bf*/
 goto LABEL_4; /*0xffde37bf*/
 }
LABEL_5:
 if ( n3_1 != -1 )
 return n3_1 != 1 ? -2147483578 : -2147483644;
 return 0; /*0xffde37dc*/
}

// GetPeiServices @ 0xffde37e0 int GetPeiServices()
{
 int Result; // esi _BYTE v2[2]; // [esp+4h] [ebp-8h] BYREF int v3; // [esp+6h] [ebp-6h]

 ReadIdtr(v2); /*0xffde37e9*/
 Result = *(_DWORD *)(v3 - 4); /*0xffde37f1*/
 if ( !Result ) /*0xffde37f6*/
 DebugAssert( /*0xffde3805*/
 (int)"e:\\hs\\MdePkg\\Library\\PeiServicesTablePointerLibIdt\\PeiServicesTablePointer.c",
 48,
 "PeiServices != ((void *) 0)");
 return Result; /*0xffde380d*/
}

// ReadIdtr @ 0xffde3812 void *__thiscall ReadIdtr(void *this)
{
 void *this_1; // eax if ( !this ) /*0xffde3818*/
 DebugAssert((int)"e:\\hs\\MdePkg\\Library\\BaseLib\\X86ReadIdtr.c", 37, "Idtr != ((void *) 0)"); /*0xffde3827*/
 this_1 = this; /*0xffde382d*/
 __sidt(this); /*0xffde3830*/
 return this_1; /*0xffde3834*/
}

// HeapManagerInit @ 0xffde3835 int HeapManagerInit(int PeiServices)
{
 int HeapAddr; // esi if ( DebugEnabled() && DebugLevelEnabled(64) ) /*0xffde384d*/
 DebugPrint(64, "Ami PeiCryptLib Alloc Heap\n"); /*0xffde385e*/
 HeapAddr = (*(int (__stdcall **)(int, int))(*(_DWORD *)PeiServices + 72))(PeiServices, 4); /*0xffde3895*/
 if ( DebugEnabled() && DebugLevelEnabled(64) ) /*0xffde38a2*/
 DebugPrint(64, "PEI Heap alloc %r (addr=%X, size=%x)\n", HeapAddr, 0, 0x10000); /*0xffde38b8*/
 return 0; /*0xffde38e6*/
}

// PeiCryptLibConstructor @ 0xffde38ea int PeiCryptLibConstructor(int __return_address, int SystemTable)
{
 if ( DebugEnabled() && DebugLevelEnabled(64) ) /*0xffde38f9*/
 DebugPrint(64, "Ami PeiCryptLib Constructor\n"); /*0xffde390a*/
 if ( (*(int (__stdcall **)(int))(*(_DWORD *)SystemTable + 32))(SystemTable) < 0 ) /*0xffde392e*/
 (*(void ( **)(int, char *))(*(_DWORD *)SystemTable + 36))(SystemTable, asc_FFDE4BC4);// " " /*0xffde3938*/
 return HeapManagerInit(SystemTable); /*0xffde394c*/
}

/* -------------------------------------------------------------------------
 * SHA-256 implementation and wrappers
 * ------------------------------------------------------------------------- */

// Sha256FinalWrapper @ 0xffde394e BOOL Sha256FinalWrapper(int *Sha256ContextRef, int *ZeroPool)
{
 return Sha256Final(Sha256ContextRef, ZeroPool) == 0; /*0xffde3962*/
}

// Sha256ContextSize @ 0xffde3963 int Sha256ContextSize()
{
 return 112; /*0xffde3966*/
}

// Sha256InitWrapper @ 0xffde3967 char Sha256InitWrapper(_DWORD *Sha256ContextRef)
{
 Sha256Init(Sha256ContextRef); /*0xffde396b*/
 return 1; /*0xffde3973*/
}

// Sha256UpdateWrapper @ 0xffde3974 BOOL Sha256UpdateWrapper(int Sha256ContextRef, int src, unsigned int n0x40)
{
 return Sha256Update(Sha256ContextRef, src, n0x40) == 0; /*0xffde398d*/
}

// MemMgrInit @ 0xffde398e int MemMgrInit(_DWORD *HeapDesc, int HeapSize)
{
 int Result; // eax if ( HeapDesc ) /*0xffde3996*/
 {
 HeapDesc[2] = 0; /*0xffde39d2*/
 *HeapDesc = HeapDesc + 5; /*0xffde39d9*/
 HeapDesc[4] = HeapDesc + 5; /*0xffde39db*/
 HeapDesc[1] = HeapSize - 20; /*0xffde39e1*/
 HeapDesc[3] = (char *)HeapDesc + HeapSize - 8; /*0xffde39e6*/
 if ( DebugEnabled() && DebugLevelEnabled(64) ) /*0xffde39f6*/
 DebugPrint(64, "\n===>\nMem Mgr Init:\nHeap Start= %08X(sz %X)\n", *HeapDesc, HeapDesc[1] - 8); /*0xffde3a0f*/
 if ( DebugEnabled() && DebugLevelEnabled(64) ) /*0xffde3a21*/
 DebugPrint(64, "Heap End = %08X\n", HeapDesc[3]); /*0xffde3a34*/
 LOBYTE(Result) = DebugEnabled(); /*0xffde3a3c*/
 if ( (_BYTE)Result ) /*0xffde3a43*/
 {
 LOBYTE(Result) = DebugLevelEnabled(64); /*0xffde3a46*/
 if ( (_BYTE)Result ) /*0xffde3a4e*/
 return DebugPrint(64, "Desc Start= %08X(sz %X)\n<===\n", HeapDesc[3], 8); /*0xffde3a5b*/
 }
 }
 else
 {
 LOBYTE(Result) = DebugEnabled(); /*0xffde3998*/
 if ( (_BYTE)Result ) /*0xffde399f*/
 {
 LOBYTE(Result) = DebugLevelEnabled(64); /*0xffde39a9*/
 if ( (_BYTE)Result ) /*0xffde39b1*/
 return DebugPrint(64, "\n===>\n!!! Heap Addr %X !!!\n<===\n", 0); /*0xffde39be*/
 }
 }
 return Result; /*0xffde3a63*/
}

// Sha256Transform @ 0xffde3a66 int Sha256Transform(void *Ctx, void *Data)
{
 unsigned __int8 *BytePtr; // edx int Idx; // esi int TempByte; // eax int ShiftedVal; // ecx unsigned int *WPtr; // edi int n48; // ebp unsigned int W15; // ecx unsigned int W7; // edx int A; // edi int Round; // ecx _DWORD *StatePtr; // ebp int E; // ebx int T1; // esi int T2; // edx int B; // eax int StateIdx; // ebx int SavedD; // [esp+10h] [ebp-130h]
 int RoundOff; // [esp+14h] [ebp-12Ch]
 _DWORD State[8]; // [esp+18h] [ebp-128h] BYREF char *StateInit; // [esp+38h] [ebp-108h]
 int WIdx; // [esp+3Ch] [ebp-104h]
 _DWORD W[14]; // [esp+40h] [ebp-100h]
 char WBlock; // [esp+78h] [ebp-C8h] BYREF WIdx = 0; /*0xffde3a83*/
 StateInit = (char *)Ctx + 8; /*0xffde3a8c*/
 BytePtr = (unsigned __int8 *)Data + 2; /*0xffde3a94*/
 qmemcpy(State, (char *)Ctx + 8, sizeof(State)); /*0xffde3a97*/
 for ( Idx = 0; Idx < 16; ++Idx ) /*0xffde3a99*/
 {
 TempByte = *BytePtr; /*0xffde3aa8*/
 ShiftedVal = (*(BytePtr - 1) | (*(BytePtr - 2) << 8)) << 8; /*0xffde3aab*/
 BytePtr += 4; /*0xffde3aae*/
 W[Idx] = *(BytePtr - 3) | ((TempByte | ShiftedVal) << 8); /*0xffde3abc*/
 }
 WPtr = (unsigned int *)&WBlock; /*0xffde3ac8*/
 n48 = 48; /*0xffde3acc*/
 do /*0xffde3b05*/
 {
 W15 = *(WPtr - 13); /*0xffde3acd*/
 W7 = *WPtr++; /*0xffde3ad2*/
 WPtr[1] = *(WPtr - 6) /*0xffde3aff*/
 + *(WPtr - 15)
 + ((W7 >> 10) ^ __ROL4__(W7, 13) ^ __ROL4__(W7, 15))
 + ((W15 >> 3) ^ __ROR4__(W15, 7) ^ __ROL4__(W15, 14));
 --n48; /*0xffde3b02*/
 }
 while ( n48 ); /*0xffde3b05*/
 A = State[0]; /*0xffde3b07*/
 Round = 0; /*0xffde3b0b*/
 StatePtr = StateInit; /*0xffde3b11*/
 SavedD = State[3]; /*0xffde3b15*/
 E = State[4]; /*0xffde3b19*/
 RoundOff = 0; /*0xffde3b1d*/
 do /*0xffde3bc0*/
 {
 T1 = State[7] /*0xffde3b52*/
 + *(_DWORD *)((char *)W + Round)
 + *(int *)((char *)&dword_FFDE3F74 + Round)
 + (State[6] ^ E & (State[6] ^ State[5]))
 + (__ROR4__(E, 6) ^ __ROL4__(E, 7) ^ __ROR4__(E, 11));
 T2 = T1 + (__ROR4__(A, 2) ^ __ROL4__(A, 10) ^ __ROR4__(A, 13)) + (A & State[1] | State[2] & (A | State[1])); /*0xffde3b7f*/
 State[7] = State[6]; /*0xffde3b81*/
 State[6] = State[5]; /*0xffde3b8d*/
 Round = RoundOff + 4; /*0xffde3b91*/
 State[5] = E; /*0xffde3b98*/
 E = T1 + SavedD; /*0xffde3b9c*/
 SavedD = State[2]; /*0xffde3ba0*/
 State[3] = State[2]; /*0xffde3ba4*/
 B = State[1]; /*0xffde3ba8*/
 State[1] = A; /*0xffde3bac*/
 A = T2; /*0xffde3bb0*/
 State[2] = B; /*0xffde3bb2*/
 RoundOff = Round; /*0xffde3bb6*/
 }
 while ( Round < 256 ); /*0xffde3bc0*/
 State[4] = E; /*0xffde3bc6*/
 StateIdx = WIdx; /*0xffde3bca*/
 State[0] = T2; /*0xffde3bce*/
 do /*0xffde3be0*/
 *StatePtr++ += State[StateIdx++]; /*0xffde3bd6*/
 while ( StateIdx < 8 ); /*0xffde3be0*/
 return 0; /*0xffde3be2*/
}

// Sha256Final @ 0xffde3bef int Sha256Final(int *Ctx, int *OutHash)
{
 unsigned int DataLen; // ecx bool CarryFlag; // cf unsigned int BufPos; // eax int HiBits; // edx int LoBits; // ebx int LoBits2; // ecx _BYTE *OutPtr; // edx int *StatePtr; // esi int WordIdx; // edi int StateVal; // ecx unsigned int ByteVal; // eax DataLen = Ctx[10]; /*0xffde3bf4*/
 if ( DataLen >= 0x40 ) /*0xffde3bfa*/
 return -1; /*0xffde3bfc*/
 CarryFlag = __CFADD__(8 *DataLen, *Ctx); /*0xffde3c08*/
 *Ctx += 8 *DataLen; /*0xffde3c08*/
 Ctx[1] += CarryFlag; /*0xffde3c0d*/
 *((_BYTE *)Ctx + DataLen + 44) = 0x80; /*0xffde3c10*/
 BufPos = ++Ctx[10]; /*0xffde3c18*/
 if ( BufPos > 0x38 ) /*0xffde3c1e*/
 {
 while ( BufPos < 0x40 ) /*0xffde3c2f*/
 {
 *((_BYTE *)Ctx + BufPos + 44) = 0; /*0xffde3c22*/
 BufPos = ++Ctx[10]; /*0xffde3c29*/
 }
 Sha256Transform(Ctx, Ctx + 11); /*0xffde3c36*/
 Ctx[10] = 0; /*0xffde3c3d*/
 }
 while ( (unsigned int)Ctx[10] < 0x38 ) /*0xffde3c50*/
 *((_BYTE *)Ctx + Ctx[10]++ + 44) = 0; /*0xffde3c45*/
 HiBits = Ctx[1]; /*0xffde3c52*/
 LoBits = *Ctx; /*0xffde3c57*/
 LoBits2 = *Ctx; /*0xffde3c59*/
 *((_BYTE *)Ctx + 100) = HIBYTE(HiBits); /*0xffde3c5e*/
 *((_BYTE *)Ctx + 101) = BYTE2(HiBits); /*0xffde3c66*/
 *((_BYTE *)Ctx + 102) = BYTE1(HiBits); /*0xffde3c6e*/
 *((_BYTE *)Ctx + 103) = HiBits; /*0xffde3c77*/
 *((_BYTE *)Ctx + 104) = HIBYTE(LoBits2); /*0xffde3c7d*/
 *((_BYTE *)Ctx + 107) = LoBits; /*0xffde3c84*/
 *((_BYTE *)Ctx + 105) = BYTE2(LoBits); /*0xffde3c90*/
 *((_BYTE *)Ctx + 106) = BYTE1(LoBits); /*0xffde3c97*/
 Sha256Transform(Ctx, Ctx + 11); /*0xffde3ca2*/
 OutPtr = (char *)OutHash + 2; /*0xffde3caf*/
 StatePtr = Ctx + 2; /*0xffde3cb2*/
 WordIdx = 8; /*0xffde3cb5*/
 do /*0xffde3cdb*/
 {
 StateVal = *StatePtr; /*0xffde3cb6*/
 ByteVal = HIBYTE(*StatePtr++); /*0xffde3cba*/
 *(OutPtr - 2) = ByteVal; /*0xffde3cc0*/
 *(OutPtr - 1) = BYTE2(StateVal); /*0xffde3cc8*/
 *OutPtr = BYTE1(StateVal); /*0xffde3cd0*/
 OutPtr += 4; /*0xffde3cd2*/
 *(OutPtr - 3) = StateVal; /*0xffde3cd5*/
 --WordIdx; /*0xffde3cd8*/
 }
 while ( WordIdx ); /*0xffde3cdb*/
 return 0; /*0xffde3bff*/
}

// Sha256Init @ 0xffde3ce3 _DWORD *Sha256Init(_DWORD *Sha256ContextRef)
{
 Sha256ContextRef[10] = 0; /*0xffde3ce9*/
 *Sha256ContextRef = 0; /*0xffde3cec*/
 Sha256ContextRef[1] = 0; /*0xffde3cee*/
 Sha256ContextRef[2] = 1779033703; /*0xffde3cf1*/
 Sha256ContextRef[3] = -1150833019; /*0xffde3cf8*/
 Sha256ContextRef[4] = 1013904242; /*0xffde3cff*/
 Sha256ContextRef[5] = -1521486534; /*0xffde3d06*/
 Sha256ContextRef[6] = 1359893119; /*0xffde3d0d*/
 Sha256ContextRef[7] = -1694144372; /*0xffde3d14*/
 Sha256ContextRef[8] = 528734635; /*0xffde3d1b*/
 Sha256ContextRef[9] = 1541459225; /*0xffde3d22*/
 return Sha256ContextRef; /*0xffde3d29*/
}

// Sha256Update @ 0xffde3d2a int Sha256Update(int Ctx, int Data, unsigned int Len)
{
 unsigned int Remaining; // ebx unsigned int CopyLen; // esi if ( *(_DWORD *)(Ctx + 40) >= 0x40u ) /*0xffde3d33*/
 return -1; /*0xffde3d39*/
 Remaining = Len; /*0xffde3d3b*/
 if ( !Len ) /*0xffde3d43*/
 return 0; /*0xffde3ddb*/
 while ( !*(_DWORD *)(Ctx + 40) && Remaining >= 0x40 ) /*0xffde3d56*/
 {
 CopyMem((void *)(Ctx + 44), (const void *)Data, 0x40u); /*0xffde3d5f*/
 if ( Sha256Transform((void *)Ctx, (void *)(Ctx + 44)) < 0 ) /*0xffde3d70*/
 return -1; /*0xffde3d70*/
 *(_QWORD *)Ctx += 512LL; /*0xffde3d72*/
 Data += 64; /*0xffde3d7c*/
 Remaining -= 64; /*0xffde3d7f*/
LABEL_13:
 if ( !Remaining ) /*0xffde3dcf*/
 return 0; /*0xffde3dcf*/
 }
 CopyLen = 64 - *(_DWORD *)(Ctx + 40); /*0xffde3d8a*/
 if ( Remaining < CopyLen ) /*0xffde3d8f*/
 CopyLen = Remaining; /*0xffde3d8f*/
 CopyMem((void *)(Ctx + *(_DWORD *)(Ctx + 40) + 44), (const void *)Data, CopyLen); /*0xffde3d9a*/
 *(_DWORD *)(Ctx + 40) += CopyLen; /*0xffde3d9f*/
 Data += CopyLen; /*0xffde3da5*/
 Remaining -= CopyLen; /*0xffde3da7*/
 if ( *(_DWORD *)(Ctx + 40) != 64 ) /*0xffde3dad*/
 goto LABEL_13; /*0xffde3dad*/
 if ( Sha256Transform((void *)Ctx, (void *)(Ctx + 44)) >= 0 ) /*0xffde3dbd*/
 {
 *(_QWORD *)Ctx += 512LL; /*0xffde3dbf*/
 *(_DWORD *)(Ctx + 40) = 0; /*0xffde3dc9*/
 goto LABEL_13; /*0xffde3dc9*/
 }
 return -1; /*0xffde3d38*/
}

// Udiv64 @ 0xffde3e04 unsigned int __stdcall Udiv64(unsigned __int64 a1, __int64 a2)
{
 unsigned int v2; // ecx unsigned __int64 v3; // rax unsigned int v4; // ebx unsigned int Result; // ebx unsigned __int64 v6; // rax unsigned __int64 Result; // rtt v2 = HIDWORD(a2); /*0xffde3e04*/
 if ( HIDWORD(a2) ) /*0xffde3e0a*/
 {
 v3 = a1; /*0xffde3e14*/
 v4 = a2; /*0xffde3e1c*/
 do /*0xffde3e2a*/
 {
 v3 >>= 1; /*0xffde3e20*/
 v4 = __PAIR64__(v2, v4) >> 1; /*0xffde3e24*/
 v2 >>= 1; /*0xffde3e28*/
 }
 while ( v2 ); /*0xffde3e2a*/
 Result = v3 / v4; /*0xffde3e2e*/
 v6 = (unsigned int)a2 * (unsigned __int64)Result; /*0xffde3e34*/
 if ( __CFADD__(Result *HIDWORD(a2), HIDWORD(v6)) || (HIDWORD(v6) = (a2 * (unsigned __int64)Result) >> 32, a1 < v6) ) /*0xffde3e47*/
 --Result; /*0xffde3e49*/
 return Result; /*0xffde3e58*/
 }
 else
 {
 LODWORD(Result) = a1; /*0xffde3e74*/
 HIDWORD(Result) = HIDWORD(a1) % (unsigned int)a2; /*0xffde3e74*/
 return Result / (unsigned int)a2; /*0xffde3e74*/
 }
}