ความเข้ากันได้ของแอป Windows ทำงานอย่างไร — โหมดความเข้ากันได้ ชิม และ Compatibility Administrator

· · Windows, โหมดความเข้ากันได้, ชิม, ความเข้ากันได้ของแอปพลิเคชัน, Compatibility Administrator, การใช้สินทรัพย์เดิม, การพัฒนา Windows, ระบบเดิม

«แอปธุรกิจอายุสิบปีที่ซอร์สโค้ดหายไปแล้ว ไม่เริ่มบนพีซี Windows 11 เครื่องใหม่ ผมติ๊ก “Windows XP” ที่แท็บความเข้ากันได้ของกล่องโต้ตอบคุณสมบัติ แล้วมันก็ทำงาน — นั่นทำอะไรจริง ๆ จะพึ่งสิ่งนี้ต่อไปได้ไหม» นั่นคือคำปรึกษาที่เราได้ยินบ่อย

เมื่อช่องติ๊กเดียวทำให้อะไรสักอย่างทำงาน ความไม่สบายใจเป็นเรื่องธรรมชาติ ตัวตนจริงของโหมดความเข้ากันได้ที่ดูเหมือนเวทมนตร์ คือชุดชิ้นโค้ดเล็ก ๆ ที่เรียกว่า ชิม ซึ่งนั่งระหว่างแอปกับ Windows API แล้วคืน «คำโกหก» Windows เองใช้ทางแก้ชั่วคราวนี้ในวงกว้างเพื่อให้แอปหลายรุ่นยังวิ่ง และเปิดกลไกบางส่วนให้ผู้ใช้กับผู้ดูแลระบบ

ใช้โดยไม่เข้าใจกลไก การยืดอายุกลายเป็น «ห้ามแตะเพราะไม่รู้ว่าทำไมมันวิ่ง» ที่ไม่เสถียร เข้าใจกลไกแล้วคุณจะตัดสินได้ด้วยเหตุผลว่า พึ่งได้อย่างปลอดภัยแค่ไหน อะไรจะทำให้พัง และเมื่อไรควรเขียนใหม่

การเข้าใจกลไกเปลี่ยนคุณภาพของการยืดอายุใช้โหมดความเข้ากันได้โดยไม่เข้าใจกลไกจะนำไปสู่การยืดอายุที่ไม่เสถียรและไม่กล้าแตะ เข้าใจกลไกแล้วจึงตัดสินด้วยเหตุผลว่าพึ่งได้แค่ไหน อะไรจะทำให้พัง และเมื่อไรควรเขียนใหม่ใช้โดยไม่เข้าใจกลไกยืดอายุไม่เสถียร ไม่กล้าแตะใช้หลังเข้าใจกลไกการตัดสินที่มีเหตุผลพึ่งได้แค่ไหนอะไรจะทำให้พังเมื่อไรควรเขียนใหม่

ภาพ 1: แม้เป็นการยืดอายุเดียวกัน คุณภาพต่างกันระหว่างความกังวลเพราะไม่รู้กลไกกับการตัดสินบนความเข้าใจ

มุ่งที่เจ้าหน้าที่ไอทีของธุรกิจขนาดกลางและเล็ก และนักพัฒนาแอป Windows ที่ดูแลแอปธุรกิจเก่า บทความนี้จัดจากแหล่งปฐมภูมิ Microsoft Learn กลไกชิมซึ่งเป็นตัวตนจริงของโหมดความเข้ากันได้ สิ่งที่ชิมตัวแทนทำได้ วิธีใส่ในองค์กรด้วย Compatibility Administrator ขีดจำกัดที่ชิมช่วยไม่ได้ และการตัดสินระหว่างยืดอายุกับย้ายระบบ

1. สรุปก่อน

  • ตัวตนจริงของโหมดความเข้ากันได้คือชิม (ชั้นความเข้ากันได้) การตั้งค่าจากแท็บความเข้ากันได้ถูกเขียนไปที่ HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers และมัดชิมถูกใส่ให้โพรเซสตอนเริ่ม12
  • ชิมคือฮุก API ในโหมดผู้ใช้ที่เขียนตารางที่อยู่นำเข้า (IAT) ใหม่ มันดักเส้นทางที่แอปเรียก Windows API แล้วคืนคำตอบเดียวกับที่ Windows เก่าเคยให้ ไม่ได้เปลี่ยนตัว OS3
  • สิ่งที่ชิมทำได้มีขอบเขตเดียวกับสิ่งที่การแก้โค้ดในแอปทำได้ มันเลี่ยงกลไกความปลอดภัยไม่ได้ และแก้ปัญหาโหมดเคอร์เนล (ไดรเวอร์อุปกรณ์) ไม่ได้3
  • Microsoft ส่งชิมสำเร็จรูปจำนวนมาก — โกหกเวอร์ชัน แมปพาธไฟล์ใหม่ ปลอมรีจิสทรี ปลอมการตรวจผู้ดูแล และอื่น ๆ คุณใส่ให้ EXE แต่ละตัวจาก Compatibility Administrator ได้4
  • Windows เองใช้ชิมเป็นค่าเริ่มต้น ฐานข้อมูลความเข้ากันได้มาตรฐานของ OS (.sdb) ถูกจับคู่ทุกครั้งที่เปิด และ PCA (Program Compatibility Assistant) อาจตรวจปัญหาแล้วใส่การตั้งค่าความเข้ากันได้อัตโนมัติ15
  • «ตอบราวกับว่าเป็น Windows ที่เก่ากว่า» ตอนนี้เป็นค่าเริ่มต้น ตั้งแต่ Windows 8.1 GetVersionEx ไม่คืนเวอร์ชัน OS ที่แอปไม่ได้ประกาศในแมนิเฟสต์ โหมดความเข้ากันได้คือส่วนขยายของกลไกนั้น67
  • ชิมใช้ไม่ได้กับแอป 16 บิต การพึ่งไดรเวอร์เคอร์เนล หรือการเข้าถึงฮาร์ดแวร์โดยตรง โดยเฉพาะแอป 16 บิตรันบน Windows 64 บิตไม่ได้เลย8
  • สำหรับแอปที่ «ขอผู้ดูแลแต่จริง ๆ ไม่ต้องการ» RunAsInvoker คือท่ามาตรฐาน __COMPAT_LAYER=RunAsInvoker กดคำขอสิทธิ์สูงแล้วให้แอปวิ่งใต้สิทธิ์มาตรฐาน9
  • วิ่งใต้ชิมแปลว่ายืดอายุได้ตอนนี้ แต่ทางจริงคือ «ทำให้วิ่งโดยไม่มีชิม» ถ้าตัดสินใจยืดอายุ จดว่าชิมใดทำให้วิ่ง และจัดการเป็นวัสดุตัดสินใจเขียนใหม่

2. ภาพรวมความเข้ากันได้ของแอป — ชั้นความเข้ากันได้ย้อนหลังที่ Windows มีอยู่แล้ว

ก่อนพูดถึงชิม นี่คือรายการกลไกที่ Windows มีอยู่แล้วสำหรับแอปเก่า แม้คนจะพูดว่า «เริ่มทำงานในโหมดความเข้ากันได้» สิ่งที่จริง ๆ ช่วยแอปคือชั้นใดชั้นหนึ่งเหล่านี้ หรือหลายชั้นรวมกัน

ชั้น สิ่งที่ทำ เป้าหมายทั่วไป
ชิม (โหมดความเข้ากันได้) ดักการเรียก API แล้วปลอมคำตอบเดียวกับที่ Windows เก่าเคยให้ แอปที่เขียนกับ OS เก่าโดยทั่วไป
การจำลอง UAC (ไฟล์ / รีจิสทรี) เปลี่ยนเส้นทางการเขียนไปที่ HKLM\Software หรือ Program Files ที่ไม่มีสิทธิ์ไปยัง VirtualStore ต่อผู้ใช้ แอป 32 บิตที่เขียนโดยสมมติสิทธิ์ผู้ดูแล
WOW64 รันแอป 32 บิตตามที่เป็นบน Windows 64 บิต (ให้มุมมอง 32 บิตของรีจิสทรีและระบบไฟล์) แอป 32 บิตโดยทั่วไป
การจำลอง DPI ให้แอปที่ไม่รู้ DPI วาดที่ 96 DPI แล้วแสดงโดยยืดบิตแมป แอปเก่าบนจอ DPI สูง

การจำลอง UAC เป็นมาตรการชั่วคราวสำหรับโพรเซสโต้ตอบ 32 บิตที่ไม่มีแมนิเฟสต์ และ Microsoft เองระบุว่าเป็น «เทคโนโลยีชั่วคราวที่เราตั้งใจจะถอดจาก Windows รุ่นอนาคต»10 ความเสียหายจริงจากการเปลี่ยนเส้นทาง Wow6432Node และ VirtualStore รวมถึงวิธีรับมือ อธิบายละเอียดใน «Registry 32-bit/64-bit Redirection and Virtualization Pitfalls» บทความนี้วางชิมเป็นศูนย์กลางและกล่าวถึงชั้นอื่นเท่าที่จำเป็น

ตำแหน่งของการจำลอง UACการจำลอง UAC เป็นมาตรการชั่วคราวสำหรับโพรเซสโต้ตอบ 32 บิตที่ไม่มีแมนิเฟสต์ มันเปลี่ยนเส้นทางการเขียนไปยัง VirtualStore ต่อผู้ใช้ แต่ Microsoft เองระบุว่าเป็นเทคโนโลยีชั่วคราวที่ตั้งใจจะถอดจาก Windows ในอนาคตโพรเซสโต้ตอบ 32 บิตที่ไม่มีแมนิเฟสต์การจำลอง UAC ถูกใส่ถูกเปลี่ยนเส้นทางไปยัง VirtualStore ต่อผู้ใช้เทคโนโลยีชั่วคราวที่ตั้งใจจะถอดภายหลัง

ภาพ 2: การจำลอง UAC เป็นมาตรการชั่วคราวสำหรับโพรเซส 32 บิตที่ไม่มีแมนิเฟสต์ และพึ่งถาวรไม่ได้

หมายเหตุข้างเรื่องการจำลอง DPI แอปที่ไม่ได้ประกาศการรับรู้ DPI ถูกถือว่าวาดที่ 96 DPI (100%) และ Windows ยืดบิตแมปเพื่อแสดง นั่นคือเหตุที่แอปเก่าดู «เบลอ» บนจอ DPI สูง และ «แทนที่พฤติกรรมการปรับสเกล DPI สูง» ของแท็บความเข้ากันได้คือสวิตช์ที่เปลี่ยนพฤติกรรมการจำลองนี้11

การจำลอง DPI ทำงานอย่างไรแอปที่ไม่ได้ประกาศการรับรู้ DPI ถูกถือว่าวาดที่ 96 DPI Windows ยืดบิตแมปจึงดูเบลอ และการแทนที่การตั้งค่า DPI สูงของแท็บความเข้ากันได้สลับพฤติกรรมการจำลองนี้สลับพฤติกรรมการจำลองแอปที่ไม่ประกาศการรับรู้ DPIถูกถือว่าวาดที่ 96 DPIบิตแมปถูกยืดเพื่อแสดงดูเบลอบนจอ DPI สูงแทนที่พฤติกรรมการปรับสเกล DPI สูง

ภาพ 3: แอปที่ไม่รู้ DPI ถูกถือเป็น 96 DPI และถูกยืด การแทนที่บนแท็บความเข้ากันได้คือสวิตช์ของการจำลองนี้

3. ชิมคืออะไรจริง ๆ — ดักระหว่าง API โดยเขียน IAT ใหม่

3.1. «ล่าม» ที่ยืนระหว่างแอปกับ OS

ไฟล์ปฏิบัติการ Windows (รูปแบบ PE) เรียก API ใน DLL ภายนอกผ่าน ตารางที่อยู่นำเข้า (IAT) เมื่อแอปเรียก GetVersionEx มันแค่กระโดดไปที่อยู่ที่เขียนใน IAT กลไกชิมใช้จุดนั้น ตอนโหลดมันเขียนรายการ IAT ของ API เป้าหมายไปที่อยู่ของโค้ดชิม แล้วแทรกตัวเองระหว่างแอปกับ Windows API ที่ได้แบบไดนามิกผ่าน GetProcAddress จัดการโดยฮุก GetProcAddress เอง3

เมื่อดักแล้ว ชิมอาจคืนหมายเลขเวอร์ชันเก่าให้ «เวอร์ชัน OS ปัจจุบันคืออะไร» หรือแมปการเข้าถึงไฟล์ไปยังตำแหน่งที่เขียนไม่ได้ไปที่อื่น แล้วเรียก API จริงถ้าจำเป็น จากมุมแอปดูเหมือน «วิ่งบน Windows เก่า» จากมุม OS ดูเหมือน «แอปที่ประพฤติดีกำลังวิ่ง» — ชิมคือล่ามระหว่างทั้งสอง

เส้นทางที่ชิมดักการเรียก APIการเรียก API ของแอปผ่าน IAT การเขียนรายการ IAT ไปยังชิมตอนโหลดให้ชิมดัก ปลอมคำตอบเดียวกับที่ Windows เก่าเคยให้ แล้วเรียก API จริงถ้าจำเป็นการเรียก APIเขียนใหม่ไปยังชิมตอนโหลดถ้าจำเป็นจัดการด้วยฮุกแอปรายการ IATชิม (ล่าม)Windows API จริงปลอมคำตอบเดียวกับที่ Windows เก่าเคยให้เรียกผ่าน GetProcAddress

ภาพ 4: ชิมดักระหว่างแอปกับ Windows API สิ่งที่ถูกเขียนใหม่คือ IAT ฝั่งแอป ตัว OS ไม่เปลี่ยน

คุณสมบัติสำคัญสามอย่างตามมาจากออกแบบนี้3

  1. ชิมรันเป็นโค้ดฝั่งแอป ไม่ใช่ส่วนของ OS จึงอยู่ภายใต้ข้อจำกัดความปลอดภัยเดียวกับแอป ชิมเลี่ยงกลไกความปลอดภัยของ OS ไม่ได้ และไม่ต้องคลายการตั้งค่าความปลอดภัยเพื่อใช้ชิม
  2. สิ่งที่ชิมแก้ได้ การแก้โค้ดฝั่งแอปก็แก้ได้ ชิมเป็นตัวแทนกรณี «ไม่มีซอร์ส / แก้ไม่ได้» ไม่ได้ทรงพลังกว่าการแก้โค้ด
  3. โหมดผู้ใช้เท่านั้น ปัญหาความเข้ากันได้ของไดรเวอร์อุปกรณ์ที่รันในโหมดเคอร์เนล ชิมแก้ไม่ได้

3.2. ฐานข้อมูลชิม (.sdb) และการจับคู่

ตารางคู่ «จะใส่ชิมใดให้ EXE ใด» คือ ฐานข้อมูลชิม ไฟล์ไบนารีสกุล .sdb ไฟล์ปฏิบัติการแอปเป้าหมายถูกลงทะเบียนในฐานด้วยแอตทริบิวต์อย่างชื่อไฟล์ ขนาด เช็กซัม และเวอร์ชัน (แอตทริบิวต์จับคู่) และถูกจับคู่ตอนโพรเซสเริ่ม ทางแก้รวม Appfix (ชิม) ซึ่งฉีดฮุก API และ Apphelp ซึ่งแสดงข้อความ «แอปนี้มีปัญหาความเข้ากันได้» มัดชิมและแฟล็กหลายตัวคือ ชั้นความเข้ากันได้ (โหมดความเข้ากันได้)1

พลาดง่าย การจับคู่นี้ไม่ใช่แค่แอปที่ตั้งโหมดความเข้ากันได้ แต่ ทุกครั้งที่โพรเซสเปิด Windows ส่งฐานมาตรฐานของ OS ที่มีการแก้สำหรับแอปที่รู้จักนับพัน (ไฟล์อยู่ใต้ %WINDIR%\AppPatch) และบนพีซีของคุณวันนี้เกือบแน่มีแอปเก่าเริ่มพร้อมชิมติดโดยไม่มีใครสังเกต การแก้ความเข้ากันได้ที่ Microsoft ให้มาถูกส่งเป็นส่วนหนึ่งของ Windows และอัปเดตผ่าน Windows Update3

การจับคู่ฐานข้อมูลชิมตอนโพรเซสเริ่มทุกครั้งที่โพรเซสเปิดจะถูกจับคู่กับฐานข้อมูลชิม ถ้าการลงทะเบียนตรงกับแอตทริบิวต์จับคู่ Appfix จะฉีดชิมหรือ Apphelp จะแสดงข้อความ มิฉะนั้นโพรเซสเริ่มตามเดิมใช่ใช่ไม่มัดชิมและแฟล็กโพรเซสเริ่มจับคู่กับ .sdbชื่อไฟล์ ขนาด ฯลฯมีการลงทะเบียน?Appfix: ฉีดชิมApphelp: ข้อความเริ่มตามเดิมชั้นความเข้ากันได้

ภาพ 5: การจับคู่รันทุกครั้งที่โพรเซสเปิด ไม่ใช่แค่แอปที่ตั้งโหมดความเข้ากันได้

3.3. PCA — กลไกที่ใส่ชิมอัตโนมัติ

อีกเส้นทางที่ชิมอาจถูกใส่โดยที่ผู้ดูแลไม่ได้ตั้งใจคือ PCA (Program Compatibility Assistant) PCA เฝ้าการทำงานของแอป และเมื่อตรวจสัญญาณปัญหาความเข้ากันได้ที่รู้จัก จะเสนอให้ผู้ใช้ใส่การแก้ หรือในบางกรณีใส่การตั้งค่าความเข้ากันได้อัตโนมัติ เช่น แอปที่แครชเพราะเรียกโค้ดใน DLL ที่ปล่อยแล้วถูกกำหนด PINDLL และแอปที่เขียนไฟล์ Windows ที่ถูกป้องกันไม่สำเร็จถูกกำหนด WRPMITIGATION5

วิธีที่ PCA ใส่การตั้งค่าความเข้ากันได้อัตโนมัติPCA เฝ้าการทำงานของแอป และเมื่อตรวจสัญญาณปัญหาความเข้ากันได้ที่รู้จัก จะเสนอให้ผู้ใช้ใส่การแก้ หรือในบางกรณีใส่การตั้งค่าความเข้ากันได้อัตโนมัติใช่จัดการด้วยข้อเสนอบางกรณีไม่การทำงานของแอปPCA เฝ้าสัญญาณปัญหาที่รู้จัก?กรณีใด?เสนอให้ใส่การแก้ใส่การตั้งค่าความเข้ากันได้อัตโนมัติรันตามเดิมตัวอย่าง: PINDLL หรือ WRPMITIGATION

ภาพ 6: PCA เฝ้าการทำงานของแอป และเมื่อตรวจสัญญาณปัญหาที่รู้จัก จะเสนอการแก้หรือใส่อัตโนมัติ

ตัวตนของ «ฉันไม่เคยตั้งอะไร แต่ถึงจุดหนึ่งช่องติ๊กโหมดความเข้ากันได้เปิดอยู่» ในหลายกรณีคือสิ่งนี้ ไม่ใช่ความผิดพลาดหรือคลิกพลาด Windows ประพฤติตามออกแบบ

4. สิ่งที่ชิมตัวแทนทำได้

จากชิมสำเร็จรูปที่ Microsoft เผยแพร่ นี่คือชุดที่จริง ๆ เจอบ่อยเมื่อยืดอายุแอปธุรกิจ4

ชิม สิ่งที่ทำได้ (สรุป)
WinXPSP3VersionLie และชิมตระกูล VersionLie อื่น คืนเวอร์ชันเก่าที่ระบุให้การถามเวอร์ชัน OS (ปลอมเวอร์ชัน)
CorrectFilePaths แมปการเข้าถึงพาธไฟล์ที่เขียนไม่ได้หรือไม่มี ไปยังตำแหน่งอื่น
VirtualRegistry เปลี่ยนเส้นทางหรือปลอมการอ่านเขียนรีจิสทรี (รวมปลอมเวอร์ชันและแกล้งคีย์ที่ไม่มี)
ForceAdminAccess คืน True ชั่วคราวให้การตรวจ «คุณเป็นสมาชิกกลุ่ม Administrators หรือไม่»
RunAsAdmin / RunAsHighest / RunAsInvoker ให้ระดับการรันจากภายนอกเทียบเท่า requireAdministrator / highestAvailable / asInvoker ในแมนิเฟสต์
WRPMitigation ปลอมความสำเร็จของการเขียนไปยังไฟล์ OS และคีย์รีจิสทรีที่ถูกป้องกัน เพื่อให้แอปไปต่อได้
EmulateGetDiskFreeSpace รายงานพื้นที่ดิสก์ว่างสูงสุด 2GB (สำหรับแอปที่ล้นบนดิสก์ใหญ่)
GlobalMemoryStatusLie ปลอมค่าสถานะหน่วยความจำที่รายงาน (สำหรับแอปที่สอบการตรวจหน่วยความจำตอนเริ่มไม่ผ่าน)
LoadLibraryRedirect โหลด DLL ปัจจุบันของ Windows แทน DLL ระบบเก่าที่แอปพกมา

ดูรายการแล้ว ชิมส่วนใหญ่คือ «คำโกหกที่คืนคำตอบที่แอปเก่าคาดหวัง» ดิสก์อย่างมาก 2GB OS คือ XP คุณคือผู้ดูแล — พวกมันสร้างโลกทัศน์ยุคที่แอปเกิด ภายในโพรเซสนั้นเท่านั้น

การปลอมเวอร์ชันกลายเป็น «พฤติกรรมเริ่มต้นอย่างเป็นทางการ»

การปลอมเวอร์ชันไม่ใช่แฮกพิเศษ ตั้งแต่ Windows 8.1 ค่าที่ GetVersionEx คืนขึ้นกับแมนิเฟสต์ของแอป แอปที่ไม่มีประกาศ <supportedOS> ในส่วน <compatibility> ของแมนิเฟสต์ได้รับเทียบเท่า Windows 8 (6.2) เสมอ ไม่ว่า OS จริงจะเป็นอะไร เมื่อมีประกาศ ค่าจนถึง OS สูงสุดในบรรดาที่ประกาศ จะถูกคืน (เช่น ถ้าประกาศถึง GUID ของ Windows 8.1 คุณได้ 6.3 แม้บน Windows 11)67

ดังนั้น «เวอร์ชัน Windows ที่แอปเห็น» ถูกตัดสินในขั้นที่ซ้อนกันเหล่านี้

  1. ค่าจนถึง OS ที่ประกาศในแมนิเฟสต์ถูกคืน (6.2 ถ้าไม่มีประกาศ)
  2. ถ้าโหมดความเข้ากันได้ (ชิมตระกูล VersionLie) ถูกใส่ เวอร์ชันของ OS ที่เลือกจะถูกคืน6
วิธีตัดสินเวอร์ชัน OS ที่แอปเห็นค่าที่ GetVersionEx คืนถูกตัดสินด้วยว่ามีประกาศ supportedOS ในแมนิเฟสต์หรือไม่ ไม่มีประกาศจะคืนเทียบเท่า Windows 8 6.2 มีประกาศจะคืนค่าจนถึง OS สูงสุดที่ประกาศ และถ้าชิมตระกูล VersionLie ถูกใส่ จะถูกทับด้วยเวอร์ชัน OS ที่เลือกไม่ใช่ใช่ไม่การถาม GetVersionExมีประกาศ supportedOS?คืนเทียบเท่า Windows 8 (6.2)ค่าจนถึง OS สูงสุดที่ประกาศชิมตระกูล VersionLie ถูกใส่?ค่า OS ที่เลือกในโหมดความเข้ากันได้ค่าถูกคืนตามเดิม

ภาพ 7: เวอร์ชัน Windows ที่แอปเห็นถูกตัดสินเป็นขั้นซ้อนโดยแมนิเฟสต์และโดยชิม

ถ้าแอปในบ้าน «แยกตามเวอร์ชัน OS แล้วถูกตัดสินเป็น 8 ทั้งที่เป็น Windows 11» ให้สงสัยประกาศ supportedOS ในแมนิเฟสต์ก่อน พูดกลับกัน แอปเก่าที่ปฏิเสธเริ่มเพราะตรวจเวอร์ชัน มีโอกาสสูงที่จะผ่านด้วยชิม VersionLie ในหลายกรณีมันดูแค่หมายเลขเวอร์ชัน และพฤติกรรมจริงบน OS ใหม่กว่าก็ใช้ได้

สองอาการจากเวอร์ชันและวิธีรับมือถ้าแอปในบ้านถูกตัดสินเป็น 8 ทั้งที่เป็น Windows 11 ให้สงสัยประกาศ supportedOS ในแมนิเฟสต์ แอปเก่าที่ปฏิเสธเริ่มเพราะตรวจเวอร์ชัน มีโอกาสสูงที่จะผ่านด้วยชิม VersionLieถูกตัดสินเป็น 8 ทั้งที่เป็น Windows 11สงสัยประกาศ supportedOSปฏิเสธเริ่มเพราะตรวจเวอร์ชันลองผ่านด้วย VersionLieพฤติกรรมจริงบน OS ใหม่กว่ามักใช้ได้

ภาพ 8: เมื่อการตัดสินเก่า ให้สงสัยแมนิเฟสต์ เมื่อปฏิเสธเริ่ม ให้สงสัย VersionLie

5. ช่องติ๊กโหมดความเข้ากันได้ทำอะไร

การตั้งค่าจากคุณสมบัติ → แท็บความเข้ากันได้ถูกเก็บในคีย์รีจิสทรี AppCompatFlags\Layers การตั้งค่าความเข้ากันได้ของแอป DXGI และคล้ายกันใช้คีย์เดียวกันเป็นที่ระบุชั้นความเข้ากันได้2 มาดูจริง

reg query "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"

สำหรับ EXE ที่คุณตั้ง «Windows XP (Service Pack 3)» «รันโปรแกรมนี้ในฐานะผู้ดูแลระบบ» และ «แทนที่พฤติกรรมการปรับสเกล DPI สูง» ที่แท็บความเข้ากันได้ คุณจะเห็นค่าประมาณดังนี้

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
    C:\LegacyApp\Gyomu.exe    REG_SZ    ~ WINXPSP3 RUNASADMIN HIGHDPIAWARE

คู่แทนระหว่างรายการช่องติ๊กกับค่า (ยืนยันบน Windows 11 ชื่อรายการและค่าอาจเปลี่ยนตามเวอร์ชัน OS)

รายการแท็บความเข้ากันได้ ค่าที่เขียน (ตัวอย่าง) สิ่งที่เป็นจริง
โหมดความเข้ากันได้: Windows XP (Service Pack 3) WINXPSP3 ชั้นความเข้ากันที่ได้มัดการปลอมเวอร์ชันกับชิมอื่นหลายตัว
โหมดสีลดลง (8 บิต / 256 สี) 256COLOR การผ่อนสำหรับโหมดสีเก่า
รันที่ความละเอียดหน้าจอ 640 × 480 640X480 รันที่ความละเอียดต่ำ
ปิดการเพิ่มประสิทธิภาพเต็มจอ DISABLEDXMAXIMIZEDWINDOWEDMODE ปิดการเพิ่มประสิทธิภาพการวาดตอนเต็มจอ
แทนที่พฤติกรรมการปรับสเกล DPI สูง (แอปพลิเคชัน) HIGHDPIAWARE หยุดการจำลอง DPI (การยืดบิตแมป)11
รันโปรแกรมนี้ในฐานะผู้ดูแลระบบ RUNASADMIN ขอสิทธิ์สูงตอนเริ่ม

สามจุดที่ต้องจำ

  • «รันโปรแกรมนี้ในฐานะผู้ดูแลระบบ» ถูกเขียนที่เดียวกัน โหมดความเข้ากันได้กับแฟล็กสิทธิ์สูงอยู่ด้วยกันในคีย์ Layers เดียวกัน และนั่นคือที่มาของความสับสน «ตั้งโหมดความเข้ากันได้แล้วสิทธิ์สูงตามมา / หายไป» การดูค่าตรง ๆ แยกทั้งสองออก
  • สิ่งที่เขียนใน HKCU คือ «การตั้งค่าของผู้ใช้นั้น» ถ้าตั้งจาก «เปลี่ยนการตั้งค่าสำหรับผู้ใช้ทั้งหมด» ของแท็บ จะถูกเขียนไปคีย์ชื่อเดียวกันฝั่ง HKLM และใช้กับผู้ใช้ทั้งหมด เมื่อแจกใน imaging ให้รู้ว่าเขียนฝั่งใด
  • ช่องติ๊กเป็นเพียงทางเข้าชั้นสำเร็จรูป แท็บให้เลือกได้แค่ชั้นตัวแทน คุณเลือกชิมทีละตัวแล้วรวมไม่ได้ นั่นคือสิ่งที่ Compatibility Administrator ในบทถัดไปทำ
เส้นทางจากการตั้งค่าแท็บความเข้ากันได้จนมีผลการตั้งค่าแท็บความเข้ากันได้ถูกเก็บเป็นพาธ EXE และค่าในคีย์ AppCompatFlags Layers ครั้งถัดไปที่ EXE นั้นเริ่ม ตัวโหลดอ่านค่าแล้วใส่ชั้นความเข้ากันได้ที่ตรงกันให้โพรเซสตั้งที่แท็บความเข้ากันได้เก็บพาธ EXE และค่าในคีย์ Layersการเริ่ม EXE ครั้งถัดไปตัวโหลดอ่านค่าใส่ชั้นความเข้ากันได้ให้โพรเซสHKCU เฉพาะผู้ใช้นั้นHKLM ใช้กับผู้ใช้ทั้งหมด

ภาพ 9: ช่องติ๊กในความเป็นจริงคือการเขียนคีย์ Layers และการใส่เกิดตอนเริ่มครั้งถัดไป

6. Compatibility Administrator ในทางปฏิบัติ — สร้างและแจก .sdb ที่กำหนดเอง

6.1. วิธีได้มา และข้อควรระวัง

Compatibility Administrator เป็นเครื่องมือใน Windows ADK (Windows Assessment and Deployment Kit)12 หลังติดตั้งมีทั้งรุ่น 32 บิตและ 64 บิต และ คุณต้องใช้รุ่น 32 บิตกับแอป 32 บิต และรุ่น 64 บิตกับแอป 64 บิต13

มีข้อควรระวังสำคัญอีกข้อ ถ้าเริ่ม Compatibility Administrator ในสถานะยกสิทธิ์ (ในฐานะผู้ดูแล) แล้วทดสอบ การจำลอง UAC และการเปลี่ยนเส้นทางจะไม่ประพฤติเหมือนผู้ใช้จริง และคุณอาจตัดสินผิดว่า «แก้แล้ว» ยืนยันผลของการแก้ด้วยบัญชีและสิทธิ์เดียวกับผู้ใช้จริงเสมอ4

สองข้อควรระวังเมื่อใช้ Compatibility Administratorใช้รุ่น 32 บิตกับแอป 32 บิต และรุ่น 64 บิตกับแอป 64 บิต และยืนยันผลของการแก้ด้วยบัญชีและสิทธิ์เดียวกับผู้ใช้จริง ไม่ใช่ในสถานะยกสิทธิ์แอป 32 บิตใช้รุ่น 32 บิตแอป 64 บิตใช้รุ่น 64 บิตทดสอบในสถานะยกสิทธิ์อาจตัดสินการแก้ผิดทดสอบด้วยสิทธิ์เดียวกับผู้ใช้จริงยืนยันผล

ภาพ 10: การเลือกรุ่น 32 หรือ 64 บิต และการยืนยันด้วยสิทธิ์เดียวกับผู้ใช้จริง คือข้อควรระวังที่ทางเข้า

6.2. ขั้นตอนสร้างฐานข้อมูลความเข้ากันได้ที่กำหนดเอง

โครงดังนี้14

  1. ในบานซ้ายของ Compatibility Administrator สร้างฐานใหม่ใต้ «Custom Databases» แล้วเลือก «Create New» → «Application Fix»
  2. ใส่ชื่อแอปและชื่อผู้ขาย แล้วระบุไฟล์ EXE เป้าหมาย
  3. เลือกโหมดความเข้ากันได้ (ชั้น) ที่จะใส่ — ลองมัดอย่าง «ความเข้ากันได้ Windows XP» ก่อนเป็นทางสั้น
  4. ถ้าจำเป็น เพิ่มการแก้ความเข้ากันได้ทีละตัว (ชิม) — คุณจำกัดเหลือชุดน้อยสุดอย่างแค่ VersionLie หรือแค่ CorrectFilePaths ได้
  5. ยืนยันเงื่อนไขจับคู่ (ขนาดไฟล์ เช็กซัม เวอร์ชัน และอื่น ๆ) แล้วบันทึก

เงื่อนไขจับคู่คือกุญแจของ «ใส่สิ่งนี้เฉพาะ EXE นี้» เงื่อนไขพื้นฐานเริ่มต้นมักพอ แต่เราแนะนำให้ เหลือเงื่อนไขที่ระบุเวอร์ชันแอปได้ นั่นกันอุบัติเหตุคำโกหกเก่าถูกใส่กับเวอร์ชันใหม่ต่อไปเมื่อผู้ขายส่งรุ่นที่แก้แล้วในภายหลัง1415

ขั้นตอนสร้างฐานข้อมูลความเข้ากันได้ที่กำหนดเองสร้าง Application Fix ในฐานใหม่ ระบุชื่อแอปและ EXE เป้าหมาย ลองมัดโหมดความเข้ากันได้ก่อน แล้วจำกัดเหลือชิมทีละตัวถ้าจำเป็น ยืนยันเงื่อนไขจับคู่แล้วบันทึกสร้างฐานใหม่เลือก Application Fixระบุชื่อแอปและ EXE เป้าหมายลองมัดโหมดความเข้ากันได้ถ้าจำเป็น จำกัดเหลือชิมทีละตัวยืนยันเงื่อนไขจับคู่แล้วบันทึกเหลือเงื่อนไขที่ระบุเวอร์ชัน

ภาพ 11: สำหรับ Application Fix ลองมัดโหมดความเข้ากันได้ก่อน จำกัดเหลือชุดน้อยสุด และจำกัดเป้าหมายด้วยเงื่อนไขจับคู่

ทดสอบ .sdb ที่สร้างบนเครื่องตรวจสอบก่อน เมื่อทำงานตามที่ตั้งใจ จึงกระจายสู่องค์กร

6.3. แจกด้วย sdbinst

คำสั่งที่ใส่ .sdb ที่กำหนดเองให้แต่ละพีซีคือ sdbinst.exe (ต้องมีสิทธิ์ผู้ดูแล)15

:: Install (-q is silent with no confirmation)
sdbinst -q "C:\Deploy\MyCorpFixes.sdb"

:: Uninstall (by file)
sdbinst -q -u "C:\Deploy\MyCorpFixes.sdb"

:: Uninstall (by database GUID)
sdbinst -q -u -g {database GUID}

ในฐานะกลยุทธ์การกระจายองค์กร Microsoft แนะนำให้ รวมเป็นฐานที่กำหนดเองหนึ่งชุดทั้งบริษัท (หรือต่อแผนก) แล้วจัดการจากศูนย์กลาง แทนการส่ง .sdb แยกกับตัวติดตั้งของแต่ละแอป ยิ่งมีการแก้มาก ยิ่งอัปเดตและแจกฐานเดียวง่ายกว่าแจกฐานบรรทัดเดียวจำนวนมาก ฐานที่กำหนดเองมี GUID ของตัวเอง และ การติดตั้งเวอร์ชันใหม่ด้วย GUID เดียวกันจะแทนเวอร์ชันเก่าอัตโนมัติ ดังนั้นงานอัปเดตก็เรียบง่าย วางการแจกเองบนเส้นทางที่มีอยู่ที่รันด้วยสิทธิ์ผู้ดูแลได้ เช่น แพ็กเป็น MSI หรือสคริปต์เริ่มต้น15

เส้นทางจากการสร้าง .sdb ที่กำหนดเองจนถึงการแจกสร้างฐานข้อมูลความเข้ากันได้ที่กำหนดเองใน Compatibility Administrator ทดสอบบนเครื่องตรวจสอบ ใส่ให้แต่ละพีซีด้วย sdbinst และตอนอัปเดตติดตั้งเวอร์ชันใหม่ด้วย GUID เดียวกันเพื่อให้เวอร์ชันเก่าถูกแทนอัตโนมัติสร้างใน Compatibility Administratorทดสอบบนเครื่องตรวจสอบใส่ให้แต่ละพีซีด้วย sdbinstติดตั้งเวอร์ชันใหม่ด้วย GUID เดียวกันเวอร์ชันเก่าถูกแทนอัตโนมัติลงทะเบียนใน Programs and Features

ภาพ 12: .sdb ที่กำหนดเองถูกกระจายผ่านสร้าง ตรวจ และแจกด้วย sdbinst และการอัปเดตจัดการด้วย GUID

ฐานที่กำหนดเองที่ติดตั้งแล้วถูกลงทะเบียนเป็นรายการใน «Programs and Features (แอปที่ติดตั้ง)» ดังนั้นคุณยืนยันสินค้าคงคลังและการถอดจากที่นั่นได้ พีซีใดมี .sdb ใดเป็นข้อมูลที่อยู่ในบัญชีจัดการสินทรัพย์

7. กรณีที่ใช้ไม่ได้ และขีดจำกัด

ชิมไม่ใช่กระสุนเงิน ตามออกแบบ พวกมันใช้ไม่ได้ในกรณีต่อไปนี้

  • ปัญหาโหมดเคอร์เนล ชิมรันในโพรเซสโหมดผู้ใช้ จึงแก้ความไม่เข้ากันของไดรเวอร์อุปกรณ์ไม่ได้ ถ้าไดรเวอร์ของเครื่องมือวัดเก่า ดองเกิล USB หรือเครื่องพิมพ์ไม่รองรับ Windows 11 สิ่งใดที่คุณใส่ฝั่งแอปก็ไม่แก้ โค้ดที่รันในเคอร์เนล เช่น ส่วนของซอฟต์แวร์แอนตี้ไวรัส ก็เช่นกัน3
  • แอป 16 บิต Windows 64 บิตไม่รองรับการรันแอป 16 บิต แฮนเดิลมีบิตที่ใช้ได้ 32 บิตบน Windows 64 บิต และตัดส่งให้แอป 16 บิตไม่ได้ จึงเริ่มล้มด้วย ERROR_BAD_EXE_FORMAT8 แม้แอปเองจะเป็น 32 บิต ก็มีแพ็กเกจยุคนั้นที่ สตับตัวติดตั้งเป็น 16 บิต และปรากฏเป็น «แอปจะวิ่ง แต่ติดตั้งไม่ได้»
  • การเข้าถึงฮาร์ดแวร์โดยตรง แอปอุตสาหกรรมที่สมมติว่าแตะพอร์ต I/O หรือหน่วยความจำกายภาพโดยตรงได้ ไม่ได้รับอนุญาตจากโหมดผู้ใช้บน Windows สมัยใหม่ และนั่นเกินขอบเขตที่ชิมปลอมได้
  • การเลี่ยงกลไกความปลอดภัย เพราะชิมรันใต้ข้อจำกัดความปลอดภัยเดียวกับแอป มันทำให้ «สิ่งที่ทำไม่ได้เพราะขาดสิทธิ์» เป็นไปไม่ได้ ForceAdminAccess และ WRPMitigation เพียง ปลอมความสำเร็จของการตรวจหรือการเขียนเพื่อให้แอปไปต่อ ไม่ได้เขียนทรัพยากรที่ถูกป้องกันจริง34
  • แอปที่ตรวจความสมบูรณ์ของตัวเอง แอปที่มีการป้องกันการคัดลอกเก่าหรือการตรวจการดัดแปลงอาจถือฮุก API เองว่าผิดปกติแล้วหยุดทำงาน
กรณีที่ชิมใช้ไม่ได้ชิมรันในโพรเซสโหมดผู้ใช้ จึงใช้ไม่ได้กับปัญหาไดรเวอร์โหมดเคอร์เนล แอป 16 บิต การเข้าถึงฮาร์ดแวร์โดยตรง หรือการเลี่ยงกลไกความปลอดภัยใช้ไม่ได้ใช้ไม่ได้ใช้ไม่ได้ใช้ไม่ได้ชิม (รันในโหมดผู้ใช้)ไดรเวอร์เคอร์เนลแอป 16 บิตการเข้าถึงฮาร์ดแวร์โดยตรงการเลี่ยงกลไกความปลอดภัยบน 64 บิต การเริ่มเองล้มปลอมแค่ความสำเร็จเพื่อให้แอปไปต่อ

ภาพ 13: ชิมเป็นโหมดผู้ใช้เท่านั้น และไม่ถึงเคอร์เนล แอป 16 บิต การเข้าถึงฮาร์ดแวร์โดยตรง หรือการเลี่ยงความปลอดภัย

และขีดจำกัดแกนร่วมของทุกชิมคือ มันเป็นทางแก้ชั่วคราว ชิมคือคำโกหกที่ตัดให้เข้ากับการใช้ API แบบหนึ่ง และถ้าการทำให้จริงฝั่ง OS เปลี่ยน สมมติฐานพัง ชิมที่ Microsoft ให้ถูกดูแลเป็นส่วนหนึ่งของ Windows ผ่าน Windows Update3 แต่การดูแลคำโกหกที่คุณใส่ด้วยฐานที่กำหนดเองคืองานขององค์กรคุณ กำหนดงบ เป็นต้นทุนการยืดอายุ สำหรับการปฏิบัติที่ตรวจ «รายการแอปที่ชิมพยุงชีวิต» ทุกครั้งที่มีอัปเดตฟีเจอร์

ชิมในฐานะทางแก้ชั่วคราว และใครรับผิดชอบดูแลชิมคือคำโกหกที่ตัดให้เข้ากับการใช้ API แบบหนึ่ง และสมมติฐานพังถ้าการทำให้จริงฝั่ง OS เปลี่ยน ชิมของ Microsoft ถูกดูแลผ่าน Windows Update แต่การดูแลคำโกหกที่ใส่ด้วยฐานที่กำหนดเองคืองานขององค์กร และการตรวจทุกอัปเดตฟีเจอร์คือต้นทุนการยืดอายุชิม = คำโกหกชั่วคราวการเปลี่ยน OS ทำให้พังชิมของ Microsoftผ่าน Windows Updateคำโกหกของฐานที่กำหนดเององค์กรดูแลตรวจทุกอัปเดตคือต้นทุนการยืดอายุ

ภาพ 14: ความรับผิดชอบดูแลคำโกหกของชิมแยกเป็นชุดที่ Microsoft ให้กับชุดที่องค์กรกำหนดเอง

8. คุณค่าเชิงปฏิบัติของ RunAsInvoker — ทำให้คำขอสิทธิ์สูงเงียบเท่านั้น

ในบรรดาชิม สิ่งที่โผล่บ่อยสุดในงานไอทีประจำวันคือ RunAsInvoker

แอปธุรกิจเก่าบางตัวประกาศ requireAdministrator ในแมนิเฟสต์ หรือถูกตรวจผิดเป็นตัวติดตั้งจากชื่อหรือเนื้อหา EXE แล้วขอสิทธิ์สูง UAC ทุกครั้งที่เริ่ม แต่หลายตัวขอผู้ดูแลเพียงเพราะแรงเฉื่อยยุค XP และไม่ได้ใช้สิทธิ์ผู้ดูแลจริง การใส่ชิม RunAsInvoker ทับทั้งการตรวจตัวติดตั้งและแมนิเฟสต์ และ แอปเริ่มด้วยโทเคนที่สืบทอดจากโพรเซสแม่ (= สิทธิ์ผู้ใช้มาตรฐาน)9

วิธีที่ RunAsInvoker กดคำขอสิทธิ์สูงประกาศ requireAdministrator ในแมนิเฟสต์หรือการตรวจผิดเป็นตัวติดตั้งทำให้เกิดคำขอสิทธิ์สูง UAC ตอนเริ่ม แต่การใส่ RunAsInvoker ทับทั้งสองและแอปเริ่มด้วยโทเคนที่สืบทอดจากแม่ไม่ใช่ประกาศ requireAdministratorใส่ RunAsInvoker แล้ว?ถูกตรวจผิดเป็นตัวติดตั้งคำขอสิทธิ์สูง UAC ทุกครั้งที่เริ่มเริ่มด้วยโทเคนของแม่งานที่ต้องการผู้ดูแลจริงล้มในแอป

ภาพ 15: RunAsInvoker ทับแค่สาเหตุของคำขอสิทธิ์สูง สิทธิ์ไม่เพิ่ม

แม้ไม่สร้าง .sdb ใน Compatibility Administrator คุณใส่ชั้นเดียวกันชั่วคราวด้วยตัวแปรสภาพแวดล้อม __COMPAT_LAYER ได้

:: Apply RunAsInvoker to child processes started from this command prompt
set __COMPAT_LAYER=RunAsInvoker
start "" "C:\LegacyApp\Gyomu.exe"
# In PowerShell
$env:__COMPAT_LAYER = 'RunAsInvoker'
Start-Process 'C:\LegacyApp\Gyomu.exe'

ถ้าคุณแปลงสองบรรทัดนั้นเป็นไฟล์แบตช์แล้วแจกเป็นทางลัด คุณเลี่ยงการมอบสิทธิ์ผู้ดูแลท้องถิ่นให้ผู้ใช้มาตรฐานได้ และไอทีไม่ถูกเรียกทุกครั้งเพราะรหัสผ่าน UAC นี่คือเทคนิคความเข้ากันได้ที่ทำให้แนวรับแข็ง ตามสิทธิ์น้อยสุด

ผลของการแจกแบตช์ RunAsInvokerการแจกแบตช์สองบรรทัดที่ตั้ง RunAsInvoker เป็นทางลัดแปลว่าคุณเลี่ยงการมอบสิทธิ์ผู้ดูแลท้องถิ่นให้ผู้ใช้มาตรฐานได้ ไอทีไม่ถูกเรียกเพราะรหัสผ่าน UAC และการปฏิบัติตามสิทธิ์น้อยสุดแจกแบตช์สองบรรทัดเลี่ยงการมอบสิทธิ์ผู้ดูแลได้ไอทีไม่ถูกเรียกเพราะ UACการปฏิบัติที่ตามสิทธิ์น้อยสุด

ภาพ 16: การแจกแบตช์อย่างเดียวลดทั้งการมอบสิทธิ์ผู้ดูแลและการถูกเรียกเพราะ UAC ได้

ข้อควรระวังด้วย ให้ชัด

  • สิทธิ์ไม่เพิ่ม งานที่ต้องการสิทธิ์ผู้ดูแลจริง (เขียน HKLM อัปเดตใต้ Program Files เป็นต้น) จะผิดพลาดในแอป หรือถ้าเงื่อนไขครบ จะถูกการจำลอง UAC เปลี่ยนเส้นทางไป VirtualStore10 ถ้าการบันทึกการตั้งค่า «หยุดทำงาน» ทันที ให้สงสัยการจำลอง
  • วิธีตัวแปรสภาพแวดล้อมใช้กับโพรเซสลูกเท่านั้น สำหรับการใส่ถาวร การตั้งตรงในคีย์ Layers (RUNASINVOKER ไม่มีรายการบนแท็บ) หรือการแจกผ่าน .sdb เชื่อถือได้
  • การแก้ปลายทางการเขียนคือทางจริง ถ้าเปลี่ยนแอปได้ ให้ย้ายไฟล์ตั้งค่าไปใต้ %APPDATA% และประกาศ asInvoker ในแมนิเฟสต์ — นั่นคือรูปที่ถูกต้อง9
การใส่ชั่วคราวและถาวรของ RunAsInvokerการใส่ผ่านตัวแปรสภาพแวดล้อม COMPAT_LAYER ใช้กับโพรเซสลูกที่เริ่มจากที่นั่นเท่านั้น สำหรับการใส่ถาวรให้ตั้งตรงในคีย์ Layers หรือแจกผ่าน .sdbตั้งผ่านตัวแปรสภาพแวดล้อมใช้กับโพรเซสลูกเท่านั้นการใส่ชั่วคราวตั้งตรงในคีย์ Layersการใส่ถาวรแจกผ่าน sdb

ภาพ 17: วิธีตัวแปรสภาพแวดล้อมเป็นการใส่ชั่วคราวที่จำกัดที่โพรเซสลูก การทำให้ถาวรทำด้วยคีย์ Layers หรือ .sdb

9. การตัดสินระหว่างยืดอายุกับย้ายระบบ — คิดอะไรหลังวิ่งใต้ชิม

วินาทีที่วิ่งใต้ชิมคือความโล่ง แต่สำคัญคืออย่าหยุดคิดตรงนั้น การวิ่งใต้ชิมแปลแค่ว่าบังเอิญเข้ากับเบ้าที่ Windows เตรียมไว้ แกนการตัดสิน ในตาราง

แกนการตัดสิน เงื่อนไขที่เอนไปทางยืดอายุ (ชิม) เงื่อนไขที่เอนไปทางย้ายระบบ / เขียนใหม่
ระยะเวลาใช้งานที่เหลือ วางแผนเลิกพร้อมธุรกิจใน 1–2 ปี สมมติจะใช้ต่อ 5 ปีขึ้นไป
ซอร์สโค้ด ไม่มี (ผู้ขายหาย หรือสูญ) มี หรือสินทรัพย์กู้คืนได้
ความลึกของการพึ่ง ปัญหาความเข้ากันได้ของ API ในโหมดผู้ใช้เท่านั้น พึ่งไดรเวอร์ 16 บิต หรือฮาร์ดแวร์เฉพาะ
ทางเลือก ไม่มีผลิตภัณฑ์แพ็กเกจหรือเวอร์ชันใหม่ ผลิตภัณฑ์และเทคโนโลยีปลายทางชัด
ผลกระทบเมื่อล้ม ธุรกิจวิ่งด้วยขั้นตอนสำรองได้ ธุรกิจหลักถูกกระทบตรง
ขีดความสามารถในการตรวจ ยืนยันพฤติกรรมทุกอัปเดตฟีเจอร์ได้ ไม่มีทรัพยากรตรวจ และมักถูกแช่แข็ง

ถ้าตัดสินใจยืดอายุ ให้ใส่สามจุดต่อไปนี้ในการปฏิบัติเป็นชุด

  1. บันทึก EXE ใด ชิม/ชั้นใด และทำไม เหลือค่าคีย์ Layers และ GUID ของ .sdb ในบัญชี «ไม่มีใครรู้ว่าทำไมมันวิ่ง» คือหนี้ใหญ่สุดที่คุณทิ้งให้คนถัดไป นี่คือกรอบคิดการรักษาแบบเดียวกับ «When You Inherit a System With No Source Code and No Documentation»
  2. ตรวจ รวมการเริ่มและการทำงานหลักของแอปที่ชิมพยุงชีวิตไว้ในรายการตรวจของอัปเดตฟีเจอร์ Windows ผูกกับแผนเปลี่ยน OS ด้วย (Practical Options After Windows 10 End of Support)
  3. กำหนดเส้นตาย ตัดสินจุดจบของการยืดอายุ — «จนถึงการปรับระบบหลักครั้งถัดไป» «จนถึงมีนาคม 2028» — และพิจารณาการย้ายระบบคู่ขนาน
ชุดปฏิบัติสามจุดเมื่อตัดสินใจยืดอายุจดในบัญชีว่าชิมใดทำให้วิ่ง ตรวจพฤติกรรมของแอปที่ชิมพยุงชีวิตทุกอัปเดตฟีเจอร์ กำหนดเส้นตายจุดจบของการยืดอายุ และพิจารณาการย้ายระบบคู่ขนานตัดสินใจยืดอายุบันทึก: ชิมใดทำให้วิ่ง ใส่บัญชีตรวจ: ยืนยันพฤติกรรมทุกอัปเดตฟีเจอร์เส้นตาย: ตัดสินจุดจบของการยืดอายุพิจารณาการย้ายระบบคู่ขนาน

ภาพ 18: การยืดอายุถูกปฏิบัติเป็นชุดสามจุด บันทึก ตรวจ และเส้นตาย รวมการพิจารณาการย้ายระบบคู่ขนาน

ฝั่งย้ายระบบ ทางเลือกมาตรฐานเปลี่ยนตามเทคโนโลยีของแอป สำหรับ VB6 คือทางสามแพร่ง เขียนใหม่ทั้งก้อน แปลงอัตโนมัติ และย้ายเป็นขั้น ที่จัดใน «How Long Will VB6 Apps Keep Running?» สำหรับการพึ่ง ActiveX/OCX คือตารางตัดสิน คงไว้ / ห่อ / แทน ที่ «How to Handle ActiveX / OCX Today» วิธีวางชิมอย่างมีสุขภาพคือการซื้อเวลาให้ช่วงพิจารณาและเตรียมของโครงการย้ายระบบนั้นวิ่งอย่างปลอดภัย

ทางเลือกฝั่งย้ายระบบ และที่นั่งของชิมทางเลือกย้ายระบบมาตรฐานเปลี่ยนตามเทคโนโลยีของแอป สำหรับ VB6 ทางสามแพร่งคือเขียนใหม่ แปลงอัตโนมัติ และย้ายเป็นขั้น สำหรับการพึ่ง ActiveX ใช้ตารางคงไว้ / ห่อ / แทน และชิมถูกวางเป็นการซื้อเวลาให้การพิจารณาและเตรียมโครงการย้ายระบบVB6การพึ่ง ActiveXซื้อเวลาให้การพิจารณาและเตรียมเทคโนโลยีของแอปคืออะไร?เขียนใหม่ แปลงอัตโนมัติ หรือย้ายเป็นขั้นคงไว้ ห่อ หรือแทนยืดอายุผ่านชิม

ภาพ 19: ทางเลือกย้ายระบบมาตรฐานถูกตัดสินด้วยเทคโนโลยีของแอป และชิมถูกวางเป็นการซื้อเวลาให้การพิจารณานั้น

10. สรุป

  • ตัวตนจริงของโหมดความเข้ากันได้คือชิม การตั้งค่าจากแท็บความเข้ากันได้ถูกเขียนไปที่คีย์ AppCompatFlags\Layers และถูกฉีดเข้าโพรเซสตอนเริ่มเป็นฮุก API ผ่านการเขียน IAT ใหม่
  • ชิมคือชุด «คำโกหกที่คืนคำตอบที่แอปเก่าคาดหวัง» มีชิมสำเร็จรูปสำหรับการปลอมเวอร์ชัน การแมปพาธใหม่ การปลอมรีจิสทรี การปลอมการตรวจผู้ดูแล และคล้ายกัน
  • Windows เองใช้ชิมจำนวนมากเป็นค่าเริ่มต้น และ PCA อาจใส่อัตโนมัติ การพึ่งโหมดความเข้ากันได้เองเป็นทางเลือกที่สมเหตุสมผลซึ่งขี่กลไกอย่างเป็นทางการของ OS
  • มีขีดจำกัดหลัก โหมดผู้ใช้เท่านั้น และไม่มีการเลี่ยงความปลอดภัย และไดรเวอร์เคอร์เนล แอป 16 บิต และการเข้าถึงฮาร์ดแวร์โดยตรงช่วยไม่ได้
  • การกระจายองค์กรคือการสร้าง .sdb ที่กำหนดเองใน Compatibility Administrator (Windows ADK) แล้วแจกด้วย sdbinst การเลือกรุ่น 32/64 บิต การทดสอบด้วยบัญชีผู้ใช้จริง และการจัดการอัปเดตด้วย GUID คือจุดปฏิบัติ
  • แอปที่ «ขอผู้ดูแลแต่จริง ๆ ไม่ต้องการ» ลดลงมาที่สิทธิ์มาตรฐานได้ด้วย __COMPAT_LAYER=RunAsInvoker นี่คือเทคนิคเชิงรับที่ทำให้คำขอสิทธิ์สูงเงียบ แทนการแจกสิทธิ์
  • การวิ่งใต้ชิมคือการยืดอายุ ไม่ใช่ทางแก้ การจดว่าอะไรทำให้วิ่ง การตรวจทุกอัปเดตฟีเจอร์ และการกำหนดเส้นตายให้การย้ายระบบวิ่งคู่ขนาน — ชุดสามจุดนั้นรวมอยู่ในการตัดสิน «พึ่งโหมดความเข้ากันได้»

ครั้งหน้าเมื่อแอปเก่าเริ่มทำงานหลังช่องติ๊กโหมดความเข้ากันได้ จงถามอีกครั้ง «แอปนี้วิ่งด้วยคำโกหกใด คำโกหกนั้นจะใช้ได้นานแค่ไหน» ถ้าตอบได้ การยืดอายุคือกลยุทธ์ที่น่าเคารพ

บทความที่เกี่ยวข้อง

ด้านให้คำปรึกษาที่เกี่ยวข้อง

KomuraSoft LLC รับการสืบสวนพฤติกรรมของแอปธุรกิจเก่าที่ไม่มีซอร์สโค้ด และการออกแบบการยืดอายุ (เลือกชิมและโหมดความเข้ากันได้ สร้างและกระจาย .sdb ที่กำหนดเอง) การตรวจความเข้ากันได้ของแอปที่มีอยู่สำหรับการย้ายไป Windows 11 และการวางแผนการเขียนใหม่หรือย้ายระบบที่วิ่งคู่กับการยืดอายุ การปรึกษาตั้งแต่ขั้น «เริ่มทำงานในโหมดความเข้ากันได้ แต่ปล่อยแบบนี้ได้ไหม» ก็ได้

ลิงก์อ้างอิง

  1. Microsoft Learn, Application Compatibility Database. โครงสร้างพื้นฐานความเข้ากันได้จัดการปัญหาและทางแก้ในฐานรูปแบบ .sdb การจับคู่ตามแอตทริบิวต์ไฟล์ปฏิบัติการ Apphelp (แสดงข้อความ) และ Appfix (ฮุก API ผ่านชิม) และชั้นความเข้ากันได้ (โหมด) ที่มัดชิมกับแฟล็กหลายตัว  2 3

  2. Microsoft Learn, DXGI overview. การตั้งค่าความเข้ากันได้ของแอปถูกเก็บในคีย์รีจิสทรี HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers (ใช้การตั้งค่าความเข้ากันได้ DXGI เป็นตัวอย่าง)  2

  3. Microsoft Learn, Understanding and Using Compatibility Fixes. การแก้ความเข้ากันได้ (ชิม) เปลี่ยนเส้นทางการเรียก API โดยเขียน IAT (ตารางที่อยู่นำเข้า) ใหม่ การลิงก์แบบไดนามิกจัดการด้วยการฮุก GetProcAddress ชิมอยู่ภายใต้ข้อจำกัดความปลอดภัยเดียวกับแอปและเลี่ยงกลไกความปลอดภัยของ OS ไม่ได้ เป็นโหมดผู้ใช้เท่านั้นและแก้ปัญหาไดรเวอร์ไม่ได้ การแก้ที่เป็นไปได้ด้วยชิมก็เป็นไปได้ด้วยการแก้โค้ด สถานการณ์ใช้อย่างแอปที่การสนับสนุนของผู้ขายสิ้นสุด และการแก้ความเข้ากันได้ที่ Microsoft ให้ถูกส่งเป็นส่วนหนึ่งของ Windows และอัปเดตผ่าน Windows Update  2 3 4 5 6 7 8

  4. Microsoft Learn, Compatibility Fixes for Windows 10, Windows 8, Windows 7, and Windows Vista. รายการและคำอธิบายการแก้ความเข้ากันได้ที่รู้จัก รวม CorrectFilePaths, VirtualRegistry, ForceAdminAccess, RunAsAdmin/RunAsHighest/RunAsInvoker, WRPMitigation, EmulateGetDiskFreeSpace, GlobalMemoryStatusLie, LoadLibraryRedirect และตระกูล VersionLie การเลือกรุ่น 32/64 บิตของ Compatibility Administrator และการทดสอบในสถานะยกสิทธิ์ทำให้การจำลองและการเปลี่ยนเส้นทางไม่ประพฤติตามที่คาด จึงควรตรวจด้วยบัญชีผู้ใช้จริง  2 3 4

  5. Microsoft Learn, Program Compatibility Assistant scenarios for Windows 8. PCA เฝ้าการทำงานของแอป ตรวจสัญญาณปัญหาความเข้ากันได้ที่รู้จัก และเสนอให้ใส่การแก้ที่แนะนำหรือใส่อัตโนมัติ (PINDLL, DISABLEUSERCALLBACKEXCEPTION, VIRTUALIZEDELETE, WRPMITIGATION และคล้ายกัน) และการใส่การแก้จากแท็บความเข้ากันได้กับ Program Compatibility Troubleshooter  2

  6. Microsoft Learn, GetVersionExW function. ตั้งแต่ Windows 8.1 ค่าที่ GetVersionEx คืนขึ้นกับแมนิเฟสต์ แอปที่ไม่ได้ทำแมนิเฟสต์สำหรับ Windows 8.1/10 ได้รับค่าเวอร์ชัน Windows 8 (6.2) และเมื่อเปิดโหมดความเข้ากันได้จะรายงานเวอร์ชันของ OS ที่เลือก  2 3

  7. Microsoft Learn, Targeting your application for Windows. วิธีประกาศ GUID ของ OS ที่รองรับด้วยองค์ประกอบ supportedOS ในส่วน compatibility ของแมนิเฟสต์แอป พฤติกรรมเมื่อไม่มีประกาศ และแอป x86 32 บิตแบบโต้ตอบที่ไม่มี trustInfo อยู่ภายใต้การจำลองไฟล์ UAC (เปลี่ยนเส้นทางการเขียนไป VirtualStore)  2

  8. Microsoft Learn, Running 32-bit Applications. WOW64 คือชั้นจำลองที่รันแอป 32 บิตบน Windows 64 บิตและแยกการชนกันของไฟล์กับรีจิสทรี และ Windows 64 บิตไม่รองรับการรันแอป 16 บิต การเริ่มล้มด้วย ERROR_BAD_EXE_FORMAT เพราะจำนวนบิตที่ใช้ได้ในแฮนเดิล  2

  9. Microsoft Learn, Using the RunAsInvoker Fix. การแก้ความเข้ากันได้ RunAsInvoker เริ่มแอปด้วยโทเคนที่สืบทอดจากโพรเซสแม่ ทับทั้งการตรวจตัวติดตั้งและการประมวลผลแมนิเฟสต์ ถูกใส่เป็นแฟล็กของตัวโหลดโดยไม่ดัก API และเมื่อแก้โค้ดได้ การแก้ที่ถูกคือประกาศ asInvoker ในแมนิเฟสต์  2 3

  10. Microsoft Learn, Registry Virtualization. การจำลองรีจิสทรีเป็นเทคโนโลยีความเข้ากันได้ที่เปลี่ยนเส้นทางการเขียนส่วนกลางไปที่ HKLM\Software ไปยัง VirtualStore ต่อผู้ใช้อย่างโปร่งใส มีเพียงโพรเซสโต้ตอบ 32 บิตที่อยู่ในขอบเขต และถูกปิดสำหรับโพรเซสที่ระบุ requestedExecutionLevel ในแมนิเฟสต์และโพรเซส 64 บิต และถูกวางเป็นเทคโนโลยีชั่วคราวที่ตั้งใจจะถอดจาก Windows ในอนาคต  2

  11. Microsoft Learn, High DPI Desktop Application Development on Windows. แอปที่ไม่รู้ DPI ถูกถือว่าวาดที่ 96 DPI คงที่ และบนจอ DPI สูง Windows ยืดบิตแมปจึงดูเบลอ รวมถึงความต่างระหว่างโหมดการรับรู้ DPI (Unaware/System/Per-Monitor)  2

  12. Microsoft Learn, Download and install the Windows ADK. Windows ADK รวม Compatibility Administrator และ Standard User Analyzer และวิธีคิดเรื่องการเลือกเวอร์ชัน ADK รวมถึงวิธีดาวน์โหลดและติดตั้ง 

  13. Microsoft Learn, Compatibility Administrator User’s Guide. Compatibility Administrator ให้การใส่การแก้ความเข้ากันได้ โหมดความเข้ากันได้ และข้อความ AppHelp และการสร้างฐานที่กำหนดเอง ทั้งรุ่น 32 บิตและ 64 บิตถูกติดตั้ง และคุณต้องใช้รุ่น 32 บิตกับแอป 32 บิต และรุ่น 64 บิตกับแอป 64 บิต 

  14. Microsoft Learn, Creating a Custom Compatibility Fix in Compatibility Administrator. การแก้ความเข้ากันได้ (เคยเรียกว่าชิม) คือชิ้นโค้ดเล็กที่ดักการเรียก API ขั้นตอนสร้าง Application Fix ในฐานที่กำหนดเอง (ระบุชื่อแอป ผู้ขาย และ EXE เป้าหมาย เลือกโหมดความเข้ากันได้ เลือกชิมเพิ่ม ตั้งเงื่อนไขจับคู่) และคุณควรเหลือเงื่อนไขที่ระบุแอปได้ถูกต้องขณะจำกัดข้อมูลจับคู่  2

  15. Microsoft Learn, Compatibility Fix Database Management Strategies and Deployment. ฐานที่จัดการจากศูนย์กลางถูกแนะนำเป็นกลยุทธ์จัดการฐานความเข้ากันได้ที่กำหนดเอง การแก้ความเข้ากันได้ควรรวมการตรวจเวอร์ชัน (เงื่อนไขจับคู่) เพื่อไม่ถูกใส่กับเวอร์ชันใหม่ การติดตั้งท้องถิ่นด้วย Sdbinst.exe (ตัวเลือก -q, -u, -g) การติดตั้งเวอร์ชันใหม่ด้วย GUID ฐานเดียวกันจะถอดเวอร์ชันเก่าอัตโนมัติ และวิธีแจกผ่าน MSI หรือสคริปต์  2 3

บทความล่าสุดที่มีแท็กเดียวกัน เพื่อเจาะลึกหัวข้อใกล้เคียง

Win32 Thread Pool API — คอนเคอร์เรนซีโดยไม่สร้างเธรดเอง ด้วย CreateThreadpoolWork

โค้ดเนทีฟของคุณกระจายการเรียก CreateThread ไปทั่วหรือไม่ บทความนี้อธิบาย Win32 thread pool API ที่ออกแบบใหม่ใน Vista — ออบเจ็กต์สี่ชนิด w...

Named Pipe ในทางปฏิบัติ — IPC มาตรฐานของ Windows ตั้งแต่การออกแบบถึงความปลอดภัย

คู่มือเชิงปฏิบัติเรื่อง named pipe ซึ่งเป็นการสื่อสารระหว่างโปรเซสมาตรฐานของ Windows บทความนี้จัดระเบียบจากแหล่งปฐมภูมิ ทั้งการเลือกระหว่...

แอปที่พังเมื่อรีซูมจากสลีป — อีเวนต์พลังงานของ Windows ทำงานอย่างไร และสร้างแอปธุรกิจที่รอดได้อย่างไร

เปิดแล็ปท็อปแล้วการเชื่อมต่อของแอปธุรกิจตาย — สาเหตุคือการออกแบบที่ไม่เคยคิดถึงสลีป บทความนี้ครอบคลุมลำดับการแจ้ง WM_POWERBROADCAST พฤติก...

DllMain และ Loader Lock — เหตุผลจริงที่ถูกบอกให้ "อย่าทำอะไรในการเริ่มต้น DLL"

ทำไมคุณต้องไม่เรียก LoadLibrary หรือซิงโครไนซ์กับเธรดอื่นจาก DllMain บทความนี้อธิบายจากแหล่งปฐมภูมิว่า loader lock ทำให้การแจ้ง DLL ทุกคร...

"ไม่ตอบสนอง" คืออะไรจริง ๆ — Windows ตัดสินว่าแอปแฮงอย่างไร และออกแบบอย่างไรให้ไม่แฮง

"ไม่ตอบสนอง" ของ Windows คือกลไกที่ OS ตัดสินว่าหน้าต่างไม่ได้ดึงข้อความเป็นเวลา 5 วินาทีแล้วแทนที่ด้วยหน้าต่างโกสต์ บทความนี้ครอบคลุมภาย...

หน้าเหล่านี้วางหัวข้อไว้ในบริบทที่กว้างขึ้นของบริการและการตัดสินใจ

บทความนี้เกี่ยวข้องโดยตรงกับบริการต่อไปนี้

คำถามที่พบบ่อย

คำถามที่มักพบในการปรึกษาเกี่ยวกับหัวข้อของบทความนี้

ถ้าแอปเริ่มทำงานหลังติ๊กโหมดความเข้ากันได้ จะใช้ต่อไปแบบนั้นได้ไหม
เพื่อให้ธุรกิจเดินต่อในระยะสั้น ได้ โหมดความเข้ากันได้คือฮุก API ในโหมดผู้ใช้ที่เรียกว่าชิม เป็นกลไกอย่างเป็นทางการที่ระบบปฏิบัติการจัดให้ แต่ชิมยังเป็นทางแก้ชั่วคราวเพื่อให้แอปวิ่งโดยไม่แก้ และอัปเดต OS อีกครั้งอาจเปลี่ยนสมมติฐานแล้วพังอีก จดข้อเท็จจริงว่ามันวิ่งใต้โหมดความเข้ากันได้ไว้ในบัญชี และถือบันทึกนั้นเป็นส่วนของการตัดสินใจว่าจะเขียนแอปใหม่หรือยืดอายุอย่างมีแผน
ช่องติ๊กโหมดความเข้ากันได้ทำอะไรจริง ๆ
เมื่อคุณบันทึกการตั้งค่าที่แท็บความเข้ากันได้ของกล่องโต้ตอบคุณสมบัติ Windows จะเขียนพาธของ EXE เป้าหมายและค่าอย่าง "WINXPSP3" หรือ "HIGHDPIAWARE" ใต้คีย์ HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers ครั้งถัดไปที่ EXE นั้นเริ่ม ตัวโหลด Windows อ่านค่าแล้วใส่ชั้นความเข้ากันได้ที่ตรงกัน (มัดชิม) ให้โพรเซส โหมดความเข้ากันได้ Windows XP เช่น สวมรอยเวอร์ชัน OS โดยคืนค่าเก่าจาก API ที่ถามเวอร์ชัน ตัว OS ไม่ได้ถูกเปลี่ยน มีเพียงโพรเซสนั้นที่ถูกแสดง Windows เก่าปลอม
แอปยุค 16 บิตจะรันใต้โหมดความเข้ากันได้บน Windows 64 บิตได้ไหม
ไม่ได้ Windows 64 บิตรันแอป 32 บิตผ่าน WOW64 แต่ไม่รองรับการรันแอป 16 บิต และการพยายามเริ่มจะล้มด้วย ERROR_BAD_EXE_FORMAT นั่นคือขีดจำกัดทางสถาปัตยกรรมที่ชิมเลี่ยงไม่ได้ แพ็กเกจเก่าที่สตับตัวติดตั้งเป็น 16 บิตก็ล้มด้วยเหตุเดียวกัน ถ้าจำเป็นจริงต้องมองนอกโหมดความเข้ากันได้ เช่น เครื่องเสมือนที่มี Windows 32 บิต
จะรันแอปที่ "ไม่เริ่มถ้าไม่รันในฐานะผู้ดูแลระบบ" ใต้บัญชีผู้ใช้มาตรฐานได้ไหม
RunAsInvoker น่าลอง ถ้าคุณรัน set __COMPAT_LAYER=RunAsInvoker ที่พรอมต์คำสั่งแล้วเริ่มแอป คำขอสิทธิ์สูงจากแมนิเฟสต์ requireAdministrator หรือจากการตรวจจับตัวติดตั้งจะถูกกด และแอปเริ่มด้วยสิทธิ์เดียวกัน (ผู้ใช้มาตรฐาน) กับผู้เรียก สำหรับแอปที่ขอสิทธิ์ผู้ดูแลอย่างเดียวและไม่เคยใช้จริง สิ่งนี้พอจะเอาสิทธิ์สูงออกจากงานประจำวัน สิทธิ์ไม่เพิ่ม ดังนั้นงานที่ต้องการสิทธิ์ผู้ดูแลจริงจะล้มในแอป รับมาใช้หลังตรวจพฤติกรรมแล้วเท่านั้น
หา Compatibility Administrator ได้ที่ไหน
อยู่ใน Windows ADK (Windows Assessment and Deployment Kit) ดาวน์โหลด ADK จากไซต์ Microsoft และตอนติดตั้งเลือกฟีเจอร์ Application Compatibility Tools ทั้งรุ่น 32 บิตและ 64 บิตถูกติดตั้ง คุณต้องใช้รุ่น 32 บิตกับแอป 32 บิต และรุ่น 64 บิตกับแอป 64 บิต ใส่ฐานข้อมูลความเข้ากันได้ที่สร้างเอง (.sdb) โดยรันคำสั่ง sdbinst บนแต่ละพีซี

โปรไฟล์ผู้เขียน

หน้าแนะนำผู้เขียนบทความ

Go Komura

ผู้แทนของ KomuraSoft LLC

เชี่ยวชาญด้านการพัฒนาซอฟต์แวร์ Windows ที่ปรึกษาเทคนิค และการตรวจสอบบั๊ก โดยเฉพาะโปรเจกต์ที่มีระบบเดิมและบั๊กที่ทำซ้ำได้ยาก

ลิงก์สาธารณะ

กลับไปยังบล็อก