如何在Windows 7中更改休眠文件的位置?


Answers:


42

您不能,它必须位于启动驱动器(在您的情况下为C:驱动器)的根目录中。

Raymond Chen在此Windows机密文章:文件系统悖论中解释了原因。

休眠遵循类似的模式。休眠操作系统意味着将内存的全部内容转储到休眠文件中。从休眠状态恢复需要将文件吸回内存并假装什么也没有发生。再次,这是另一个麻烦的问题:要加载休眠文件,您需要文件系统驱动程序,但是文件系统驱动程序位于休眠文件中。如果将休眠文件保留在引导驱动器的根目录中,则可以改用微型文件系统驱动程序。


14
糟糕的窗户无法解决这个问题,我的SSD确实需要它。我希望他们修复它在未来,所以你可以选择把它放在哪里像在Mac OS X
Hultner

5
是的,在我看来,这是一个设计缺陷。即使系统需要从主驱动器启动,也没有理由将所有千兆字节的信息存储在同一驱动器上-休眠文件可以加载基本信息(例如驱动器访问权限),然后寻找另一个驱动器以获取更多信息数据。不幸的是,他们没有设计它来处理这种情况-这意味着他们要等到新的OS才能使用。
娜西2011年

1
@Namey:如果休眠文件可以加载基础知识,则也可以首先将其直接写入引导加载程序。然后,您打开了整个蠕虫罐。另一方面,我也不认为这是设计缺陷。它是在我认为Windows NT的时代写的,速度,内存限制和低CPU能力是主要因素,而不是小的SSD驱动器。哎呀,谁能预测SSD首先如此普遍?
surfasb

1
关于“鸡和鸡蛋”的说法很简单,没关系:如果引导加载程序知道如何将休眠文件从磁盘加载到内存中,则没有理由在引导加载程序中没有文件系统驱动程序。
Denis Barmenkov 2012年

3
那是微软的愚蠢借口。如果两个磁盘都在同一控制器上-使用相同的驱动程序怎么办?如果一个磁盘是ssd而您不想很快磨损该怎么办?
NickSoft

6

好的,移动hiberfil.sys有2件要解决的事情

  1. 告诉作为进程“系统”运行的“ ntoskrnl.exe”打开/保存休眠数据到D:\ hiberfil.sys而不是C:\->尚未解决!

  2. 要将这个机会也应用到启动配置数据文件(c:\ BOOT \ BCD)->使用VisualBCD https://www.boyans.net/DownloadVisualBCD.html- >之类的工具甚至使用regedit 相对容易。编辑HKLM \ BCD00000000 \ Objects {71575733-c376-11e4-80ea-806e6f6e6963} \ Elements \ 21000001,即ResumeLoader的HiberFileDrive或\ 22000002 HiberFilePath。也许您需要使用'File / Load hive'c:\ BOOT \ BCD来挂载'BCD00000000'分支。(光标必须位于HKLM上,否则菜单项显示为灰色) ->好像已经完成了由ntosknl.exe提供,因此无需更改它,因为ya更改将被覆盖。

但是,数字1更糟,更难更改。嗯,让我们将ntoskrnl.exe加载到IDA中,并找到处理/hiberfil.sys的函数并对其进行反编译,以查看到底发生了什么...

__int64 __fastcall PopCreateHiberFile(LARGE_INTEGER *a1)
{
...
 RtlInitUnicodeString(&Source, L"\\hiberfil.sys");
...
  RtlAppendUnicodeStringToString(&Destination, &IoArcBootDeviceName);
  RtlAppendUnicodeStringToString(&Destination, &Source);
...
  ObjectAttributes.RootDirectory = 0i64;
  ObjectAttributes.Attributes = 576;
  ObjectAttributes.ObjectName = &Destination;
  ObjectAttributes.SecurityDescriptor = v5;
  ObjectAttributes.SecurityQualityOfService = 0i64;
  ret_2 = IoCreateFile(
            &FileHandle,
            0x100003u,
            &ObjectAttributes,
...

好的,总的来说,路径是这样硬编码的: IoArcBootDeviceName +“ \ hiberfil.sys” 如果没有一些讨厌的二进制补丁,就无法更改它。除了触摸神圣的Windows grail修补“ ntoskernel”之外,还可能导致诸如更新,撤消补丁或防病毒程序可能变得疯狂等问题。但是,让我们看看IoArcBootDeviceName的引用是什么:

IopLoadCrashdumpDriver PopDeleteHiberFile PopCreateHiberFile PopBcdSetupResumeObject PopBcdSetDefaultResumeObjectElements PopBcdSetPendingResume PopBcdRegenerateResumeObject PopBcdCreateResumeObject PopAllocateHiberContext IopCreateArcNames PopBcdSetupResumeObject

哇,改变似乎很好(只有一点点改变是IopLoadCrashdumpDriver System32 \ Drivers \ crashdmp.sys但是谁需要崩溃转储-不管我们在那儿破坏了什么都没关系)

所以修补IopCreateArcNames创建ArcBootDeviceName将被罚款:

NTSTATUS INIT_FUNCTION NTAPI IopCreateArcNames  (   IN PLOADER_PARAMETER_BLOCK  LoaderBlock )   
...
   /* Create the global system partition name */
   63     sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
   64     RtlInitAnsiString(&ArcString, Buffer);
   65     RtlAnsiStringToUnicodeString(&IoArcBootDeviceName, &ArcString, TRUE);
   66 
   67     /* Allocate memory for the string */
   68     Length = strlen(LoaderBlock->ArcBootDeviceName) + sizeof(ANSI_NULL);
   69     IoLoaderArcBootDeviceName = ExAllocatePoolWithTag(PagedPool,
   70                                                       Length,
   71                                                       TAG_IO);
   72     if (IoLoaderArcBootDeviceName)
   73     {
   74         /* Copy the name */
   75         RtlCopyMemory(IoLoaderArcBootDeviceName,
   76                       LoaderBlock->ArcBootDeviceName,
   77                       Length);
   78     }

...

https://doxygen.reactos.org/d3/d82/ntoskrnl_2io_2iomgr_2arcname_8c.html 顺便说一句,我正在使用Win7 64位的ntkrnlmp.exe 6.1.7601.19045,并针对ReactOS检查了此代码。(但是,Reactos源代码中尚未实现休眠部分) 请注意,ArcBootDeviceName将类似于:\ Device \ Harddisk1 \ Partition0

嗯,让我们将ArcBootDeviceName(LoaderBlock + 0x78)修补到ArcHalDeviceName(LoaderBlock + 0x80)

因此,如果bootmgr加载器位于与Windows不同的分区上,则希望hibernate.sys是bootmgr创建的。

1405A9C15 4C 8B 4B 78                    mov     r9, [rbx+78h]
Patch #1           80

1405A9C19 4C 8D 05 30 06+                lea     r8, aArcnameS   ; "\\ArcName\\%s"
1405A9C20 48 8D 4C 24 40                 lea     rcx, [rsp+0D8h+pszDest] ; pszDest
1405A9C25 48 8B D7                       mov     rdx, rdi        ; cchDest
1405A9C28 E8 E3 AE B6 FF                 call    RtlStringCchPrintfA

...
1405A9C41 48 8D 0D C0 E7+                lea     rcx, IoArcBootDeviceName ; DestinationString
1405A9C48 41 B0 01                       mov     r8b, 1          ; AllocateDestinationString
1405A9C4B E8 60 13 DB FF                 call    RtlAnsiStringToUnicodeString
1405A9C50 48 8B 7B 78                    mov     rdi, [rbx+78h]
Patch #2           80

因此,在ntoskrnl.exe中,在两个位置用4C8B4B80替换4C8B4B78。不要忘了之后再修复PE-Checksum。


谈论一个很多人无法理解的神秘答案!
killjoy

是否有人尝试通过这种方式修补ntoskrnl.exe?此后是否奏效?
PF4Public,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.