จะเปลี่ยนตำแหน่งของไฟล์ hibernation ใน Windows 7 ได้อย่างไร?


45

ฉันไม่สามารถเปิดใช้งานการไฮเบอร์เนตใน Windows 7 ได้เนื่องจากมีพื้นที่ไม่เพียงพอในไดรฟ์ C: เพื่อสร้างไฟล์ไฮเบอร์เนต ฉันจะทำให้ Windows วางไฟล์ไว้ที่อื่นได้อย่างไร



คุณทำไม่ได้ แต่คุณสามารถปิดการใช้งานการไฮเบอร์เนต ( powercfg.exe -h off) แล้วลบไฟล์
Ian Boyd

คำตอบ:


42

คุณทำไม่ได้มันต้องอยู่ในรูทของไดรฟ์สำหรับบู๊ต (ไดรฟ์ C: ในกรณีของคุณ)

เรย์มอนด์เฉินอธิบายเหตุผลที่ว่าทำไมในบทความที่เป็นความลับของ Windows นี้: ระบบแฟ้ม Paradox

การไฮเบอร์เนตมีรูปแบบคล้ายคลึงกัน การไฮเบอร์เนตระบบปฏิบัติการหมายถึงการทิ้งเนื้อหาทั้งหมดของหน่วยความจำลงในไฟล์ไฮเบอร์เนต การกู้คืนจากการจำศีลส่งผลให้ดูดไฟล์นั้นกลับเข้าสู่หน่วยความจำและทำท่าว่าไม่มีอะไรเกิดขึ้น อีกครั้งเป็นปัญหาไก่และไข่อีกครั้ง: หากต้องการโหลดไฟล์ไฮเบอร์เนตคุณจำเป็นต้องใช้ไดรเวอร์ระบบไฟล์ แต่ไดรเวอร์ระบบไฟล์อยู่ในไฟล์ไฮเบอร์เนต หากคุณเก็บไฟล์ hibernation ไว้ในไดเรกทอรีรากของบูตไดรฟ์ระบบไฟล์ขนาดเล็กสามารถใช้แทนได้


14
สำหรับหน้าต่างที่ไม่ดีไม่สามารถจัดการกับสิ่งนี้ได้ฉันต้องใช้ SSD จริงๆ ฉันหวังว่าพวกเขาจะแก้ไขได้ในอนาคตเพื่อให้คุณสามารถเลือกได้ว่าจะวางไว้ที่ใดใน Mac OS X
Hultner

5
ฉันคิดว่ามันเป็นข้อบกพร่องในการออกแบบเล็กน้อย แม้ว่าระบบจะต้องบูตจากไดรฟ์หลัก แต่ก็ไม่มีเหตุผลที่จะต้องเก็บข้อมูลกิกะไบต์ทั้งหมดไว้ในไดรฟ์เดียวกันไฟล์ hibernation สามารถโหลดข้อมูลพื้นฐาน (เช่นการเข้าถึงไดรฟ์) แล้วมองหาไดรฟ์อื่นเพิ่มเติม ข้อมูล. น่าเสียดายที่พวกเขาไม่ได้ออกแบบมาเพื่อจัดการกับกรณีนั้น - ซึ่งหมายความว่าพวกเขาจะไม่ทำจนกว่าระบบปฏิบัติการใหม่ ... ถ้าเคย
Namey

1
@Namey: หากไฟล์การจำศีลสามารถโหลดข้อมูลพื้นฐานได้มันอาจจะถูกเขียนลงใน boot loader ทันที จากนั้นคุณก็เปิดเวิร์มทั้งหมดของหนอนได้ ในอีกเรื่องหนึ่งฉันไม่คิดว่ามันเป็นข้อบกพร่องในการออกแบบเช่นกัน มันถูกเขียนย้อนกลับไปในสมัยของ Windows NT ฉันเข้าใจว่าความเร็วหน่วยความจำ จำกัด และพลังงาน CPU ต่ำเป็นปัจจัยสำคัญไม่ใช่ไดรฟ์ SSD ขนาดเล็ก Heck ใครที่คาดการณ์ว่า SSD จะเป็นเรื่องธรรมดาในตอนแรก
surfasb

1
เป็นเพียงคำศัพท์เกี่ยวกับ "ไก่และไข่" ซึ่งไม่สำคัญ: หากตัวโหลดการบูตรู้วิธีการโหลดไฟล์ไฮเบอร์เนตจากดิสก์ไปยังหน่วยความจำไม่มีเหตุผลที่จะไม่มีไดรเวอร์ระบบไฟล์ในตัวโหลดบูต
Denis Barmenkov

3
นั่นเป็นข้อแก้ตัวที่โง่ของ Microsoft จะเกิดอะไรขึ้นถ้าดิสก์ทั้งสองอยู่ในคอนโทรลเลอร์เดียวกัน - ใช้ไดรเวอร์เดียวกันหรือไม่ เกิดอะไรขึ้นถ้าดิสก์ตัวหนึ่งเป็น ssd และคุณไม่ต้องการที่จะสวมมันเร็ว?
NickSoft

6

โอเคมี 2 สิ่งที่ต้องแก้เพื่อย้าย hiberfil.sys

  1. บอก 'ntoskrnl.exe' ที่ทำงานเป็น 'ระบบ' ของกระบวนการเพื่อเปิด / บันทึกข้อมูลการจำศีลใน D: \ hiberfil.sys แทนที่จะเป็น C: \ -> ยังไม่ได้แก้ไข!

  2. เพื่อใช้โอกาสนี้กับไฟล์ข้อมูลการกำหนดค่าการบู๊ต (c: \ BOOT \ BCD) -> ซึ่งค่อนข้างง่ายด้วยเครื่องมืออย่าง VisualBCD https://www.boyans.net/DownloadVisualBCD.html -> หรือแม้แต่แค่ใช้ regedit การแก้ไข HKLM \ BCD00000000 \ วัตถุ {71575733-c376-11e4-80ea-806e6f6e6963} \ Elements \ 21000001 นั่นคือ HiberFileDrive ของ ResumeLoader หรือ \ 22000002 HiberFilePath บางทีคุณอาจต้องใช้ 'ไฟล์ / โหลดไฮฟ์' c: \ BOOT \ BCD เพื่อเมานต์สาขา 'BCD00000000' (เคอร์เซอร์ต้องอยู่ใน HKLM มิฉะนั้นรายการเมนูจะเป็นสีเทา) -> เนื่องจากดูเหมือนว่านี่เสร็จเรียบร้อยแล้ว โดย ntosknl.exe ดังนั้นจึงไม่จำเป็นต้องใช้ในการเปลี่ยนแปลงสิ่งนี้เนื่องจากการเปลี่ยนแปลงของยาจะถูกเขียนทับ

อย่างไรก็ตามหมายเลข 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,
...

ตกลงสั้น ๆ เส้นทางจะถูก hardcoded เช่นนี้: IoArcBootDeviceName + "\ hiberfil.sys" โดยไม่ต้องมีการแก้ไขไบนารีที่น่ารังเกียจบางอย่างไม่มีวิธีการเปลี่ยนแปลงนั้น นอกจากการสัมผัสจอกศักดิ์สิทธิ์ของ Windows แล้วการ "ntoskernel" อาจส่งผลให้เกิดปัญหาเช่นการอัปเดตการเลิกทำการติดตั้งโปรแกรมแก้ไขหรือโปรแกรมป้องกันไวรัสอาจจะบ้าไปแล้ว ...

IopLoadCrashdumpDriver PopDeleteHiberFile PopCreateHiberFile PopBcdSetupResumeObject PopBcdSetDefaultResumeObjectElements PopBcdSetPendingResumeObjectResumeProtocol

ว้าวการเปลี่ยนแปลงที่ดูเหมือนจะดี (สิ่งเดียวที่ออกไปเล็กน้อยคือ IopLoadCrashdumpDriver System32 \ Drivers \ crashdmp.sys อย่างไรก็ตามผู้ที่ต้องการ crashdump - ไม่สำคัญว่าเราจะทำลายบางสิ่งที่นั่น)

ดังนั้นการแก้ไข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 btw ฉันใช้ ntkrnlmp.exe 6.1.7601.19045 จาก Win7 64 บิตและตรวจสอบรหัสนี้กับ 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 ให้แทนที่ 4C8B4B78 ด้วย 4C8B4B80 ที่สองตำแหน่ง อย่าลืมแก้ไข PE-Checksum ในภายหลัง


พูดคุยเกี่ยวกับคำตอบที่คลุมเครือไม่มากที่จะเข้าใจ!
killjoy

ไม่มีใครพยายามที่จะแก้ไข ntoskrnl.exe ด้วยวิธีนี้? มันทำงานหลังจากนั้น
PF4Public
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.