无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 6200|回复: 9
打印 上一主题 下一主题

[求助] bootmgfw.efi能引导不同路径的BCD文件吗?

[复制链接]
跳转到指定楼层
1#
发表于 2020-2-7 13:36:13 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
bootmgfw.efi 引导的是MICROSOFT\BOOT路径下的BCD文件,如何让bootmgfw.efi引导别外路径下的BCD。
2#
发表于 2020-2-7 14:11:59 | 只看该作者
可以做两个目录,Win7只支持默认路径,Win10可以另外建立目录,用bootice加boot项,别的你可以试试。可以用Clover,Xboot等3方引导工具
回复

使用道具 举报

3#
发表于 2020-2-7 15:57:16 | 只看该作者
需要前置 grub2
回复

使用道具 举报

4#
发表于 2020-2-7 18:27:56 | 只看该作者
要引导任意路径下的bcd,可以在同路径下放一个bootmgfw.efi,然后使用其他引导器如grub2等来引导这个路径下的bootmgfw.efi

点评

不管引导什么路径的bootmgfw.efi,bootmgfw.efi都指向MICROSOFT\BOOT\BCD,不会指向是别的路径,也不会指向bootmgfw.efi同路径,这是问题所在?要是bootmgfw.efi能指向自己目录,问题就解决了。  详情 回复 发表于 2020-2-7 19:38
回复

使用道具 举报

5#
发表于 2020-2-7 20:42:50 | 只看该作者
理论上可以通过 WinHEX 修改,不过一但修改,数字签名失效,会导致过不了 Secure Boot
回复

使用道具 举报

6#
发表于 2020-2-7 20:50:58 | 只看该作者
本帖最后由 2011cwj6958 于 2020-2-7 21:13 编辑

已经确定原版bootmgfw.ef会引导相同路径下的bcd。

















回复

使用道具 举报

7#
发表于 2020-2-7 21:16:54 | 只看该作者
其实有过一阵子搞不同路径的bcd的,bios下的有破解版,efi下的还是跟原版一样吧。弄几个菜单项自己选择呗,还非得一家一个直接进桌面啊:)
回复

使用道具 举报

8#
发表于 2020-2-7 21:25:04 | 只看该作者
本帖最后由 hilsonma 于 2020-2-7 21:30 编辑
不管引导什么路径的bootmgfw.efi,bootmgfw.efi都指向MICROSOFT\BOOT\BCD,不会指向是别的路径,也不会指向bootmgfw.efi同路径,这是问题所在?要是bootmgfw.efi能指向自己目录,问题就解决了。

我的使用经验已证实,bootmgfw.efi会优先使用同目录下的bcd文件,同目录下找不到bcd文件,再使用同分区下的\efi\microsoft\boot\bcd.

而bootmgr则只能是使用同分区下的\boot\bcd.

以上是指原版默认情况,经过winhex等修改的除外。
回复

使用道具 举报

9#
发表于 2020-2-7 21:35:11 | 只看该作者
本帖最后由 sunsea 于 2020-2-7 21:59 编辑

操作其实挺简单的。

不过我没研究出来换BCD名字的办法,换掉\EFI\Microsoft\Boot的办法倒是有。

首先有个非常令人高兴的事实:到目前为止(Win10 1809 LTSC)微软的EFI的引导程序还没有压缩。
所以直接用WinHex打开bootmgfw.efi,在Unicode模式下(如图)替换所有\EFI\Microsoft\Boot这个字串本体为你想要的,比如我这里换成了\EF1\Microsoft\Boot(注意是1不是I!)注意字符串总长度维持不变!


然后重写校验和,记住:efi本质也是个类似于exe的遵守PE文件格式的可执行程序!目前网上没有多少程序能够重写64位exe的efi,在这里献丑写了一个,VC2005编译通过:
给程序填写Checksum.rar (41.18 KB, 下载次数: 20)
用法,将修改好的efi文件作为这个程序的唯一参数运行即可,可以再cmd中运行来查看运行结果。

然后在bcd里关掉数字签名验证:

这就行了,然后在启动盘上把EF1和等等启动文件目录造出来就行。另外所有资源(比如说中文字体)和bcd也记得要放进去。这样做的主要问题是过不了Secure Boot,不过本论坛目前已经有很多此方面的研究,可以到UEFI启动区搜索。

另外开源上面那个程序的代码,Public Domain授权,即放弃版权,任意复制使用:
  1. #define WIN32_LEAN_AND_MEAN                // 从 Windows 头中排除极少使用的资料
  2. #include <stdio.h>
  3. #include <tchar.h>
  4. #define _WIN32_WINNT 0x0501
  5. #define WINVER 0x0501
  6. #include <windows.h>
  7. #include <ImageHlp.h>
  8. #pragma comment(lib,"imagehlp")
  9. #include <locale.h>
  10. #include <stdlib.h>

  11. void PrintError(DWORD dwError,TCHAR *tszEnv){
  12.         HLOCAL hlocal = NULL;
  13.         PCTSTR tszError;
  14.         FormatMessage(
  15.                 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  16.                 NULL, dwError, MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
  17.                 (PTSTR)&hlocal, 0, NULL);
  18.         if (hlocal == NULL) tszError = _T("没有合适的错误消息。");
  19.         else tszError=(LPCTSTR)LocalLock(hlocal);
  20.         _tprintf(_T("%s,错误代码:0x%8X,提示:%s\n"),tszEnv,dwError,tszError);
  21.         if (hlocal != NULL) LocalFree(hlocal);
  22.         return;
  23. }

  24. int _tmain(int argc, _TCHAR* argv[])
  25. {
  26.         DWORD dwError;


  27.         HANDLE hFileMapping =NULL;
  28.         DWORD HeaderSum,CheckSum;
  29.         LARGE_INTEGER size;
  30.         TCHAR FileName[2048];

  31.         setlocale(LC_ALL,"chs");

  32.         if (argc<=1){
  33.                 _tprintf(_T("参数不足:请指定文件:"));
  34.                 _tscanf(_T("%[^\n]"),FileName);

  35.         }else
  36.                 _tcscpy(FileName,argv[1]);
  37.         if ((FileName[0]==_T('"'))&&(FileName[_tcslen(FileName)-1]==_T('"'))){
  38.                 memmove(FileName,FileName+1,(_tcslen(FileName)-2)*sizeof(TCHAR));
  39.                 FileName[_tcslen(FileName)-2]=0;
  40.         }
  41.         _tprintf(_T("将要修改:%s\n"),FileName);

  42.         HANDLE hexeFile;
  43.         hexeFile = CreateFile(FileName,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  44.         if (hexeFile==INVALID_HANDLE_VALUE){
  45.                 PrintError(GetLastError(),_T("打开文件出错"));
  46.                 return 2;
  47.         }

  48.         hFileMapping = CreateFileMapping(hexeFile,NULL,PAGE_READWRITE,0,0,0);

  49.         if (hFileMapping==NULL){
  50.                 PrintError(GetLastError(),_T("创建文件映射出错"));
  51.                 CloseHandle(hexeFile);
  52.                 return 2;
  53.         }

  54.         LPVOID lpBase = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); //得到文件映射的初地址

  55.         if (lpBase==NULL){
  56.                 PrintError(GetLastError(),_T("进行映射出错"));
  57.                 CloseHandle(hexeFile);
  58.                 CloseHandle(hFileMapping);
  59.                 return 2;
  60.         }
  61.         GetFileSizeEx(hexeFile,&size);//在这里我们强行假定exe小于4G(甚至小于2G!否则上面的Map就该出错了)

  62.         //开始检查文件是32位还是64位
  63.         bool flag_3264;
  64.         IMAGE_DOS_HEADER *pDos = (IMAGE_DOS_HEADER*)lpBase;
  65.         IMAGE_NT_HEADERS *pNt = (IMAGE_NT_HEADERS*)(pDos->e_lfanew + (char*)pDos);

  66.         if (pNt->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 || pNt->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
  67.         {               
  68.                 flag_3264 = false;
  69.                 _tprintf(_T("检查发现你的文件是64位程序。\n"));
  70.         }
  71.         else
  72.         {               
  73.                 flag_3264 = true;
  74.                 _tprintf(_T("检查发现你的文件是32位程序。\n"));
  75.         }

  76.         if (flag_3264){
  77.                 PIMAGE_NT_HEADERS32 ntHeaders= (PIMAGE_NT_HEADERS32)CheckSumMappedFile(lpBase,size.LowPart, &HeaderSum, &CheckSum);
  78.                 ntHeaders->OptionalHeader.CheckSum=CheckSum;
  79.                 _tprintf(_T("你的文件旧校验和:0x%8X,新校验和:0x%8X,已经填写完成。\n"),HeaderSum,CheckSum);


  80.         }else{
  81.                 PIMAGE_NT_HEADERS64 ntHeaders= (PIMAGE_NT_HEADERS64)CheckSumMappedFile(lpBase,size.LowPart, &HeaderSum, &CheckSum);
  82.                 ntHeaders->OptionalHeader.CheckSum=CheckSum;
  83.                 _tprintf(_T("你的文件旧校验和:0x%8X,新校验和:0x%8X,已经填写完成。\n"),HeaderSum,CheckSum);
  84.         }
  85.         UnmapViewOfFile(lpBase);
  86.         CloseHandle(hFileMapping);
  87.         CloseHandle(hexeFile);
  88.         


  89.         system("pause");



  90.         return 0;
  91. }
复制代码
回复

使用道具 举报

10#
发表于 2020-5-29 08:01:51 | 只看该作者
试试bootmgfw.efi优先使用同目录下的bcd文件
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2025-8-27 01:11

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表