|
本帖最后由 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授权,即放弃版权,任意复制使用:
- #define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
- #include <stdio.h>
- #include <tchar.h>
- #define _WIN32_WINNT 0x0501
- #define WINVER 0x0501
- #include <windows.h>
- #include <ImageHlp.h>
- #pragma comment(lib,"imagehlp")
- #include <locale.h>
- #include <stdlib.h>
- void PrintError(DWORD dwError,TCHAR *tszEnv){
- HLOCAL hlocal = NULL;
- PCTSTR tszError;
- FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
- NULL, dwError, MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
- (PTSTR)&hlocal, 0, NULL);
- if (hlocal == NULL) tszError = _T("没有合适的错误消息。");
- else tszError=(LPCTSTR)LocalLock(hlocal);
- _tprintf(_T("%s,错误代码:0x%8X,提示:%s\n"),tszEnv,dwError,tszError);
- if (hlocal != NULL) LocalFree(hlocal);
- return;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- DWORD dwError;
- HANDLE hFileMapping =NULL;
- DWORD HeaderSum,CheckSum;
- LARGE_INTEGER size;
- TCHAR FileName[2048];
- setlocale(LC_ALL,"chs");
- if (argc<=1){
- _tprintf(_T("参数不足:请指定文件:"));
- _tscanf(_T("%[^\n]"),FileName);
- }else
- _tcscpy(FileName,argv[1]);
- if ((FileName[0]==_T('"'))&&(FileName[_tcslen(FileName)-1]==_T('"'))){
- memmove(FileName,FileName+1,(_tcslen(FileName)-2)*sizeof(TCHAR));
- FileName[_tcslen(FileName)-2]=0;
- }
- _tprintf(_T("将要修改:%s\n"),FileName);
- HANDLE hexeFile;
- hexeFile = CreateFile(FileName,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
- if (hexeFile==INVALID_HANDLE_VALUE){
- PrintError(GetLastError(),_T("打开文件出错"));
- return 2;
- }
- hFileMapping = CreateFileMapping(hexeFile,NULL,PAGE_READWRITE,0,0,0);
- if (hFileMapping==NULL){
- PrintError(GetLastError(),_T("创建文件映射出错"));
- CloseHandle(hexeFile);
- return 2;
- }
- LPVOID lpBase = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); //得到文件映射的初地址
- if (lpBase==NULL){
- PrintError(GetLastError(),_T("进行映射出错"));
- CloseHandle(hexeFile);
- CloseHandle(hFileMapping);
- return 2;
- }
- GetFileSizeEx(hexeFile,&size);//在这里我们强行假定exe小于4G(甚至小于2G!否则上面的Map就该出错了)
- //开始检查文件是32位还是64位
- bool flag_3264;
- IMAGE_DOS_HEADER *pDos = (IMAGE_DOS_HEADER*)lpBase;
- IMAGE_NT_HEADERS *pNt = (IMAGE_NT_HEADERS*)(pDos->e_lfanew + (char*)pDos);
- if (pNt->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 || pNt->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
- {
- flag_3264 = false;
- _tprintf(_T("检查发现你的文件是64位程序。\n"));
- }
- else
- {
- flag_3264 = true;
- _tprintf(_T("检查发现你的文件是32位程序。\n"));
- }
- if (flag_3264){
- PIMAGE_NT_HEADERS32 ntHeaders= (PIMAGE_NT_HEADERS32)CheckSumMappedFile(lpBase,size.LowPart, &HeaderSum, &CheckSum);
- ntHeaders->OptionalHeader.CheckSum=CheckSum;
- _tprintf(_T("你的文件旧校验和:0x%8X,新校验和:0x%8X,已经填写完成。\n"),HeaderSum,CheckSum);
- }else{
- PIMAGE_NT_HEADERS64 ntHeaders= (PIMAGE_NT_HEADERS64)CheckSumMappedFile(lpBase,size.LowPart, &HeaderSum, &CheckSum);
- ntHeaders->OptionalHeader.CheckSum=CheckSum;
- _tprintf(_T("你的文件旧校验和:0x%8X,新校验和:0x%8X,已经填写完成。\n"),HeaderSum,CheckSum);
- }
- UnmapViewOfFile(lpBase);
- CloseHandle(hFileMapping);
- CloseHandle(hexeFile);
-
- system("pause");
- return 0;
- }
复制代码 |
|