2 คะแนน โดย GN⁺ 2025-12-01 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ใน Windows สามารถใช้ สัญลักษณ์หรืออักขระที่ไม่ใช่ A~Z และไม่ใช่ ASCII เป็นอักษรไดรฟ์ได้
  • ภายในระบบ เส้นทาง Win32 (C:\foo) จะถูกแปลงเป็นและประมวลผลเป็น เส้นทาง NT namespace (\\??\\C:\foo)
  • โครงสร้างนี้ถูกจัดการโดย Object Manager โดยที่อักษรไดรฟ์เช่น C: มีตัวตนเป็น ออบเจกต์ symbolic link ธรรมดา เท่านั้น
  • การใช้คำสั่ง subst สามารถสร้าง อักษรไดรฟ์แบบไม่มาตรฐาน อย่าง +: หรือ €: ได้ แต่ Explorer และ PowerShell ไม่สามารถรับรู้ได้
  • พฤติกรรมเช่นนี้เป็นเบาะแสสำคัญในการเข้าใจโครงสร้างภายในและการเข้ารหัสของการประมวลผลเส้นทางใน Windows (เช่น WTF-16 ฯลฯ)

โครงสร้างภายในของอักษรไดรฟ์

  • เส้นทางทั่วไปของ Windows (C:\foo) เป็น เส้นทาง Win32 namespace และจะถูกแปลงเป็น เส้นทาง NT namespace เมื่อมีการเรียก API
    • ตัวอย่าง: เมื่อเรียก CreateFileW("C:\foo") ภายในระบบจะถูกแปลงเป็น NtCreateFile("\\??\\C:\foo")
  • \\?? เป็นโฟลเดอร์เสมือนของ Object Manager ซึ่งเป็นรูปแบบที่ผสมผสาน \\GLOBAL?? และโฟลเดอร์ DosDevices ของผู้ใช้แต่ละคน
  • วัตถุ C: มีอยู่เป็น symbolic link ภายใน \\GLOBAL?? และเชื่อมต่อไปยังเส้นทางอุปกรณ์จริง \\Device\\HarddiskVolume4
  • ดังนั้น C: จึงไม่ได้เป็นอักขระสำรองพิเศษ แต่เป็นการปฏิบัติเพียงเป็น ชื่อ symbolic link ทั่วไป

คำจำกัดความของอักษรไดรฟ์

  • อักษรไดรฟ์เป็นผลลัพธ์ของกระบวนการแปลงเส้นทาง Win32 เป็นเส้นทาง NT
    • ฟังก์ชันแปลง RtlDosPathNameToNtPathName_U จะเปลี่ยน C:\foo เป็น \\??\\C:\foo
  • ฟังก์ชันนี้จึงจัดการ +: ซึ่งเป็นอักขระที่ไม่เป็นมาตรฐานเช่นเดียวกัน จึงเมื่อมีวัตถุ +: อยู่ เส้นทาง +:\\ ก็ทำงานได้ตามปกติ
  • วัตถุ +: ที่สร้างด้วยคำสั่ง subst +: C:\foo จะถูกบันทึกไว้ในโฟลเดอร์ DosDevices ของแต่ละผู้ใช้

การทำงานของอักษรไดรฟ์ที่ไม่เป็นมาตรฐาน

  • เนื่องจาก Explorer.exe สำรวจเฉพาะขอบเขต A~Z จึงไม่แสดงไดรฟ์ +:
  • PowerShell ก็ไม่สามารถรับรู้ไดรฟ์ที่ไม่ใช่ ASCII และจะคืนข้อผิดพลาด
  • อย่างไรก็ตาม ใน cmd.exe ไดรฟ์อย่าง +: หรือ €: จะทำงานได้ตามปกติ

อักขระไดรฟ์แบบไม่เป็น ASCII และยูนิโค้ด

  • สามารถสร้างไดรฟ์ ได้ด้วยคำสั่ง subst €: C:\foo
    • ทำงานโดยไม่คำนึงถึงตัวพิมพ์ใหญ่-เล็ก (Λ: และ λ: ถูกรู้จักเหมือนกัน)
  • อักขระไดรฟ์ถูกจำกัดอยู่ที่ WTF-16 code unit เดี่ยว (ไม่เกิน U+FFFF)
    • ตัวอักษรที่เกิน U+FFFF เช่น 𤭢: จะเกิดข้อผิดพลาดกับ subst
    • หากเรียก MountPointManager โดยตรงอาจสร้างได้ แต่การแปลงเส้นทาง Win32 จะล้มเหลวทำให้เข้าไม่ถึง
  • เหตุการณ์นี้แสดงให้เห็นว่า Windows ยังไม่รองรับ surrogate pair ของ UTF-16 อย่างครบถ้วน

ปัญหาการตรวจจับเส้นทางและการเข้ารหัส

  • การใช้งานการจัดการเส้นทางที่ต่างกันในแต่ละภาษาอาจแตกต่างจาก RtlDosPathNameToNtPathName_U
    • ตัวอย่างเช่น Rust รับรู้เส้นทาง absolute เฉพาะ A-Z (C:\ คืนค่า true, +:\\ คืนค่า false)
  • เนื่องจากวิธีการเข้ารหัส (WTF-8 เทียบกับ WTF-16) ทำให้ดัชนี path[0], path[1] ต่างกัน จึงอาจทำให้ผลการตรวจสอบเส้นทาง absolute ต่างกันได้
  • มาตรฐานไลบรารีของ Zig ถูกออกแบบให้รองรับจนถึงช่วง <= U+FFFF โดยคำนึงถึงความต่างนี้

ข้อบกพร่องในการประมวลผลอักขระไม่เป็น ASCII ของ SetVolumeMountPointW

  • การเรียก SetVolumeMountPointW("€:\\", volume) จะสำเร็จ แต่ลิงก์ที่ถูกสร้างจริงจะแสดงเป็น ¬:
  • คาดว่าเป็นผลจากการตัดทิ้งเป็น 0xAC เมื่อทำงานกับ 0x20AC (สัญลักษณ์ €)
  • เป็นตัวอย่างที่แสดงข้อจำกัดของ API ที่ไม่สามารถจัดการอักขระไดรฟ์ที่ไม่ใช่ ASCII ได้

สรุป

  • Windows โดยโครงสร้างภายใน ไม่จำกัดอักษรไดรฟ์เฉพาะ A~Z
  • การจำกัดนี้เกิดจากความแตกต่างในการนำไปใช้งานของเครื่องมือระดับสูง เช่น Explorer, PowerShell
  • หากเข้าใจโครงสร้างการแปลงระหว่าง Win32 และ NT namespace, การจัดการเข้ารหัส และพฤติกรรมของ Object Manager จะช่วยให้เข้าใจกลไกภายในของระบบไฟล์ Windows ได้ลึกขึ้น

1 ความคิดเห็น

 
GN⁺ 2025-12-01
ความเห็นจาก Hacker News
  • พาธของ NT คือวิธีที่ Object Manager ใช้อ้างอิงรีซอร์ส
    ตัวอย่างเช่น HKEY_LOCAL_MACHINE เป็น alias ของ \\Registry\\Machine
    NT คล้ายกับ Unix ตรงที่ใช้ VFS namespace แบบโกลบอล
    พาธที่ขึ้นต้นด้วยอักษรไดรฟ์คือ “DOSPath” เพื่อความเข้ากันได้กับ DOS และแม้ใน kernel mode ก็ยังมีบาง subsystem ที่ใช้อยู่
    ใน PowerShell สามารถเปิดเผยรีซอร์สหลายแบบเป็น “ไดรฟ์” ได้ และนอกจากไดรฟ์พื้นฐานอย่าง hklm:\ แล้วก็ยังสร้างไดรฟ์แบบกำหนดเองได้ด้วย
    เอกสารที่เกี่ยวข้อง: ตัวอย่างการจัดการ PowerShell Drive
    บน Linux/Bash ไม่สามารถเข้าถึงใบรับรองผ่านพาธไฟล์ได้ แต่บน PowerShell/Windows ทำได้
    แนะนำให้ติดตั้งโมดูล PowerShell NtObjectManager แล้วลองสำรวจด้วย ls NtObject:\
    ลิงก์โมดูล

    • น่าทึ่งที่ผ่านไป 30 ปีแล้ว Windows ก็ยังติดอยู่กับ โครงสร้างไดเรกทอรีแบบยุค 80s ทั้งที่ไม่มีฟลอปปีดิสก์แล้ว
    • ถ้าใช้ PSDrive provider ของ PnP PowerShell ก็สามารถสำรวจ SharePoint Online ได้เหมือนไดรฟ์
      เอกสาร Connect-PnPOnline
    • บน Linux ก็เข้าถึงใบรับรองเป็นไฟล์ได้ผ่าน /usr/share/ca-certificates หรือ /etc/ssl/certs
      เพียงแต่ไม่ได้รวมศูนย์เท่ากับ Windows Registry
    • ใน ReactOS มี NT Object browser ที่สามารถสำรวจลำดับชั้น Registry ทั้งหมดผ่าน GUI ได้
      และใช้งานบน Windows ได้ด้วย
      ตัวอย่าง ReactOS NT Object Browser
    • บน Linux ใบรับรองก็เข้าถึงได้ในรูปแบบไฟล์ธรรมดา
      สามารถดูไฟล์ PEM ได้โดยตรงใต้ /etc/ca-certificates/extracted/cadir
  • Windows สามารถเข้าถึงพาร์ทิชันได้โดยไม่ต้องมีอักษรไดรฟ์
    สามารถเมานต์ไว้ใต้ไดเรกทอรีเหมือน Linux ได้ และตั้งค่าผ่านคำสั่ง Add-PartitionAccessPath ของ PowerShell
    โดยจะคงอยู่หลังรีบูตด้วย

    • เคยใช้ฟีเจอร์นี้เพื่อเบี่ยง พาธติดตั้งเกมไปยังการ์ด SD
      ตัวติดตั้งปฏิเสธการ์ด SD แต่ถ้าใช้ NTFS mount point ก็หลอกมันได้
      แต่ตัวติดตั้งบางตัวจะตรวจสอบพื้นที่ว่างของดิสก์แม่เลยทำให้สับสน
      สำหรับการเมานต์ถาวร symbolic link มีประโยชน์กว่า
    • แม้ไม่ใช้ PowerShell ก็สามารถตั้งค่าได้จาก เครื่องมือจัดการดิสก์ ผ่านเมนู “เปลี่ยนอักษรและพาธของไดรฟ์”
    • NTFS mount point มีประโยชน์เวลาต้องเลี่ยงซอฟต์แวร์ที่ปรับแต่งพาธไม่ได้
      สามารถรวมดิสก์ VM ที่มีนโยบายประสิทธิภาพต่างกันไว้ใต้พาธเดียวได้
    • แต่ทำได้ เฉพาะระหว่าง NTFS เท่านั้น exFAT และ ReFS ไม่รองรับ
      ตอนสร้างพาร์ทิชันใน GUI สามารถเลือก “เมานต์เป็นพาธ” แทน “กำหนดอักษรไดรฟ์” ได้
    • บางโปรแกรม เช่น Steam อาจตรวจสอบพื้นที่ว่างของดิสก์แม่แล้วปฏิเสธการติดตั้ง
  • อักษรไดรฟ์แบบ “€:\” เป็นตัวอย่างที่ ทั้งต้องสาปและเจ๋ง
    เคอร์เนล NT ยืดหยุ่นกว่าที่เปิดเผยให้ผู้ใช้เห็นมาก

    • คนส่วนใหญ่รู้จักแค่ เปลือก DOS ของ Windows NT
      แต่ข้างในซ่อนโครงสร้างซับซ้อนที่อิงกับการแมป GUID เอาไว้
      เช่น ถ้าสร้าง shortcut ชื่อ {GUID} ก็อาจเชื่อมไปยังฟังก์ชันที่ซ่อนอยู่
      โครงสร้างแบบนี้เองที่ทำให้ Windows กลายเป็น แหล่งเพาะมัลแวร์ ได้ด้วย
    • แล้วแต่ code page อักษรไดรฟ์แบบนี้อาจเข้าใช้งานไม่ได้เลย
    • ถ้าจะให้ยืดหยุ่นจริง อักษรไดรฟ์ก็ควรใช้ อีโมจิ ได้
  • File Explorer ไม่รู้จักอักษรไดรฟ์นอกเหนือจาก A~Z
    ดังนั้นความฝันที่จะเปลี่ยนอักษรไดรฟ์ทั้งหมดเป็น อีโมจิ จึงเป็นไปไม่ได้

    • อีโมจิส่วนใหญ่ไม่ได้แสดงด้วย UTF-16 หนึ่ง code unit จึงมีข้อจำกัด
    • อีโมจิหน้ายิ้ม บางตัวอาจใช้ได้ขึ้นอยู่กับ code page
      แต่เปลี่ยนไอคอนไดรฟ์ด้วย autorun.inf จะดีกว่า และยังใส่อีโมจิใน label ได้ด้วย
    • ชื่อคอมพิวเตอร์สามารถใช้อีโมจิได้
  • ในยุค Win9x มีทริก ALT + 255 ที่ใช้สร้าง โฟลเดอร์ที่ Explorer เข้าไม่ได้

    • เคยใช้วิธีนั้นซ่อน Duke Nukem ไว้ในคอมของหอพัก
    • จนไม่นานมานี้ก็ยังใช้วิธีเดียวกันป้องกันการเข้าถึง Registry key ได้
    • ตอนนี้ยิ่งหนักกว่าเดิม กรณีช่องโหว่ความปลอดภัยใน Windows 10/11
  • ในสภาพแวดล้อมพัฒนา Xbox 360 อักษรไดรฟ์อยู่ในรูปแบบสตริง
    ตัวอย่างเช่น Game:\foo, Hdd0:\foo

    • ใช่ มันมีอยู่จริง
      Xenia emulator จัดการสิ่งนี้เป็น virtual file system ที่อิง symbolic link
      ตัวอย่างโค้ด Xenia
  • บน Linux มีแนวคิดคล้ายกันคือ Abstract Domain Socket
    เป็น Unix domain socket ที่ตัวอักษรตัวแรกเป็น NUL(\0) ซึ่งสามารถหลบข้อจำกัดด้านสิทธิ์ได้
    กำลังใช้อยู่ในเกมเซิร์ฟเวอร์เพื่อแยกรีซอร์สของผู้เล่นแต่ละคนออกจากกัน แต่ยังคงสื่อสารกันได้

    • และยังหา socket เหล่านี้ได้จาก /proc/net/unix
  • ฟีเจอร์แบบนี้ฟังดูเหมือนเป็นสภาพแวดล้อมที่เหมาะกับการสร้าง มัลแวร์
    น่าจะใช้ mount ที่ซ่อนอยู่หรือชื่อไดรฟ์แปลก ๆ เพื่อก่อกวนระบบได้

    • แต่ในทางปฏิบัติ พาธ NT ต้องถูกแมปเข้ากับโวลุมจริง จึงซ่อนแบบสมบูรณ์ได้ยาก
    • ถ้ารู้จัก Alternate Data Streams จะยิ่งทึ่งกว่าเดิม
    • การจัดการไดรฟ์ต้องใช้สิทธิ์ผู้ดูแลระบบ
  • หากต้องเมานต์ดิสก์อิมเมจหลายไฟล์ อักษรไดรฟ์จะทำให้สับสนมาก
    เช่น ถ้าเมานต์ DVD ISO 36 ไฟล์ คุณจะได้เจอกับ นรกแห่งเครื่องหมายอัญประกาศในบรรทัดคำสั่ง

  • ใน DOS รุ่นเก่า ๆ (น่าจะเวอร์ชัน 3.3) อักษรไดรฟ์ถัดจาก Z คือ AA
    เคยลองสร้าง RAM drive เล็ก ๆ หลายตัวเพื่อยืนยันเรื่องนี้

    • จำได้ว่าใน Netware ก็สามารถ แมปไดรฟ์ เกิน Z ได้เหมือนกัน