2 điểm bởi GN⁺ 2025-12-01 | 1 bình luận | Chia sẻ qua WhatsApp
  • Trên Windows, ký tự ổ đĩa có thể là các ký hiệu hoặc ký tự không phải ASCII ngoài A~Z
  • Về nội bộ, đường dẫn Win32 (C:\foo) được chuyển đổi và xử lý thành đường dẫn không gian tên NT (\??\C:\foo)
  • Cấu trúc này do Object Manager quản lý, và các ký tự ổ đĩa như C: chỉ tồn tại dưới dạng đối tượng liên kết tượng trưng đơn thuần
  • Dùng lệnh subst có thể tạo ký tự ổ đĩa phi tiêu chuẩn như +: hoặc €:, nhưng Explorer và PowerShell không nhận diện được chúng
  • Cách hoạt động này là manh mối quan trọng để hiểu cấu trúc nội bộ của cơ chế xử lý đường dẫn Windows và cách mã hóa (WTF-16, v.v.)

Cấu trúc nội bộ của ký tự ổ đĩa

  • Đường dẫn thông thường trên Windows (C:\foo) là đường dẫn không gian tên Win32, và khi gọi API sẽ được chuyển thành đường dẫn không gian tên NT
    • Ví dụ: khi gọi CreateFileW("C:\foo"), nội bộ sẽ được chuyển thành NtCreateFile("\??\C:\foo")
  • \?? là thư mục ảo của Object Manager, kết hợp \GLOBAL?? và thư mục DosDevices theo từng người dùng
  • Đối tượng C: tồn tại dưới dạng liên kết tượng trưng trong \GLOBAL??, và được nối tới đường dẫn thiết bị thực \Device\HarddiskVolume4
  • Vì vậy, C: không phải là ký tự dành riêng đặc biệt, mà được xử lý như tên liên kết tượng trưng thông thường

Định nghĩa của ký tự ổ đĩa

  • Ký tự ổ đĩa là sản phẩm của quá trình chuyển đổi đường dẫn Win32 sang đường dẫn NT
    • Hàm chuyển đổi RtlDosPathNameToNtPathName_U biến C:\foo thành \??\C:\foo
  • Hàm này cũng xử lý các ký tự phi tiêu chuẩn như +: theo cùng cách, nên nếu tồn tại đối tượng +: thì đường dẫn +:\ cũng hoạt động bình thường
  • Đối tượng +: được tạo bằng lệnh subst +: C:\foo sẽ được lưu trong thư mục DosDevices theo từng người dùng

Cách hoạt động của ký tự ổ đĩa phi tiêu chuẩn

  • Explorer.exe chỉ duyệt phạm vi A~Z nên ổ +: sẽ không được hiển thị
  • PowerShell cũng không nhận diện được ổ đĩa không phải ASCII và trả về lỗi
  • Tuy nhiên, trong cmd.exe, các ổ như +: hoặc €: vẫn hoạt động bình thường

Ký tự ổ đĩa không phải ASCII và Unicode

  • Có thể tạo ổ đĩa bằng ký hiệu euro (€) với lệnh subst €: C:\foo
    • Hoạt động không phân biệt chữ hoa chữ thường (Λ:λ: được nhận diện như nhau)
  • Ký tự ổ đĩa bị giới hạn ở một đơn vị mã WTF-16 duy nhất (U+FFFF trở xuống)
    • Các ký tự vượt quá U+FFFF như 𤭢: sẽ gây lỗi trong subst
    • Nếu gọi trực tiếp MountPointManager thì vẫn có thể tạo được, nhưng do chuyển đổi đường dẫn Win32 thất bại nên không thể truy cập
  • Điều này cho thấy Windows không hỗ trợ đầy đủ cặp surrogate của UTF-16

Phân biệt đường dẫn và vấn đề mã hóa

  • Cách triển khai xử lý đường dẫn theo từng ngôn ngữ có thể khác với RtlDosPathNameToNtPathName_U
    • Ví dụ: Rust chỉ nhận A-Z là đường dẫn tuyệt đối (C:\ là true, +:\ là false)
  • Tùy theo cách mã hóa (WTF-8 so với WTF-16), các chỉ số như path[0], path[1] có thể khác nhau, khiến kết quả phân biệt đường dẫn tuyệt đối cũng có thể khác
  • Thư viện chuẩn của Zig đã tính đến khác biệt này và được triển khai để nhận diện tới phạm vi <= U+FFFF

Lỗi xử lý không phải ASCII trong SetVolumeMountPointW

  • Khi gọi SetVolumeMountPointW("€:\", volume), lệnh báo thành công nhưng liên kết thực tế được tạo lại xuất hiện dưới dạng ¬:
  • Điều này được cho là do 0x20AC (€) bị cắt cụt và lưu thành 0xAC
  • Đây là ví dụ cho thấy giới hạn của API trong việc xử lý ký tự ổ đĩa không phải ASCII

Kết luận

  • Về nội bộ, Windows không giới hạn ký tự ổ đĩa trong A~Z
  • Giới hạn xuất phát từ khác biệt triển khai của các công cụ tầng cao như Explorer, PowerShell
  • Nếu hiểu cấu trúc chuyển đổi giữa không gian tên Win32 và NT, cách xử lý mã hóa, cùng cơ chế hoạt động của Object Manager, ta có thể
    nắm sâu hơn cơ chế nội bộ của hệ thống tệp Windows

1 bình luận

 
GN⁺ 2025-12-01
Ý kiến trên Hacker News
  • Đường dẫn NT là cách Object Manager tham chiếu tài nguyên
    Ví dụ, HKEY_LOCAL_MACHINE là bí danh của \Registry\Machine
    NT tương tự Unix ở chỗ sử dụng không gian tên VFS toàn cục
    Các đường dẫn bắt đầu bằng ký tự ổ đĩa là “DOSPath” để tương thích với DOS, và ngay cả trong kernel mode một số subsystem vẫn còn dùng nó
    Trong PowerShell, nhiều loại tài nguyên được phơi bày dưới dạng “drive”, và ngoài các drive mặc định như hklm:\ còn có thể tạo drive tùy chỉnh
    Tài liệu liên quan: Mẫu quản lý PowerShell Drive
    Trên Linux/Bash không thể truy cập chứng chỉ bằng đường dẫn tệp, nhưng trên PowerShell/Windows thì có thể
    Khuyến nghị cài module PowerShell NtObjectManager rồi thử duyệt bằng ls NtObject:\
    Liên kết module

    • Thật ngạc nhiên là sau 30 năm Windows vẫn bị trói vào cấu trúc thư mục kiểu thập niên 80. Trong khi ổ đĩa mềm thì cũng chẳng còn
    • Dùng PSDrive provider của PnP PowerShell thì có thể duyệt cả SharePoint Online như một ổ đĩa
      Tài liệu Connect-PnPOnline
    • Trên Linux cũng có thể truy cập chứng chỉ như tệp qua /usr/share/ca-certificates hoặc /etc/ssl/certs
      Chỉ là nó không được tích hợp thống nhất như Windows Registry
    • ReactOS có trình duyệt NT Object nên có thể duyệt toàn bộ hệ phân cấp Registry bằng GUI
      Nó cũng chạy được trên Windows
      Ví dụ ReactOS NT Object Browser
    • Trên Linux, chứng chỉ cũng có thể được truy cập như các tệp thông thường
      Có thể xem trực tiếp các tệp PEM dưới /etc/ca-certificates/extracted/cadir
  • Windows có thể truy cập phân vùng mà không cần ký tự ổ đĩa
    Có thể mount dưới một thư mục như trên Linux, và có thể thiết lập bằng lệnh Add-PartitionAccessPath của PowerShell
    Sau khi khởi động lại vẫn được giữ nguyên

    • Tôi từng dùng tính năng này để lách đường dẫn cài game sang thẻ SD
      Trình cài đặt sẽ từ chối thẻ SD, nhưng có thể đánh lừa nó bằng NTFS mount point
      Tuy vậy một số trình cài đặt sẽ kiểm tra dung lượng trống của đĩa cha nên dễ bị rối
      Với mount lâu dài thì symbolic link còn hữu ích hơn
    • Ngay cả không dùng PowerShell cũng có thể thiết lập trong công cụ Disk Management qua menu “Change Drive Letter and Paths”
    • NTFS mount point hữu ích khi cần lách phần mềm không cho tùy chỉnh đường dẫn
      Có thể gộp các đĩa VM với chính sách hiệu năng khác nhau vào cùng một đường dẫn
    • Tuy nhiên chỉ dùng được giữa các phân vùng NTFS. exFAT hay ReFS không hỗ trợ
      Khi tạo phân vùng trong GUI có thể chọn “Mount in the following empty NTFS folder” thay vì “Assign drive letter”
    • Một số chương trình như Steam có thể kiểm tra dung lượng trống của đĩa cha rồi từ chối cài đặt
  • Ký tự ổ đĩa như “€:\” là ví dụ quái dị nhưng ngầu
    NT kernel linh hoạt hơn rất nhiều so với những gì lộ ra cho người dùng

    • Hầu hết mọi người chỉ biết đến lớp vỏ DOS của Windows NT
      Bên trong là một cấu trúc phức tạp dựa trên ánh xạ GUID
      Ví dụ, nếu tạo shortcut tên {GUID} thì đôi khi nó sẽ nối tới một tính năng ẩn
      Chính kiểu cấu trúc này cũng khiến Windows trở thành mảnh đất màu mỡ cho malware
    • Tùy codepage, những ký tự ổ đĩa như vậy thậm chí có thể không truy cập được
    • Muốn thật sự linh hoạt thì phải cho phép dùng emoji làm ký tự ổ đĩa
  • File Explorer không nhận diện ký tự ổ đĩa ngoài A~Z
    Vì vậy giấc mơ đổi toàn bộ ký tự ổ đĩa thành emoji là không thể

    • Phần lớn emoji không được biểu diễn bằng một code unit UTF-16 nên bị hạn chế
    • Một số emoji mặt cười có thể dùng được tùy theo codepage
      Nhưng thay vì vậy, đổi icon ổ đĩa thành emoji bằng autorun.inf sẽ hợp lý hơn, và cũng có thể chèn emoji vào nhãn ổ đĩa
    • Tên máy tính thì có thể dùng emoji
  • Thời Win9x có mẹo ALT + 255 để tạo thư mục mà Explorer không thể truy cập

    • Tôi từng dùng cách đó để giấu Duke Nukem trên máy tính ký túc xá
    • Cho đến gần đây vẫn có thể chặn truy cập Registry key theo cách tương tự
    • Giờ thì còn nghiêm trọng hơn. Ví dụ lỗ hổng bảo mật Windows 10/11
  • Trong môi trường phát triển Xbox 360, ký tự ổ đĩa là chuỗi ký tự
    Ví dụ: Game:\foo, Hdd0:\foo

    • Đúng vậy, nó thực sự tồn tại
      Trình giả lập Xenia xử lý nó như một hệ thống tệp ảo dựa trên symbolic link
      Ví dụ mã Xenia
  • Trên Linux có khái niệm tương tự là Abstract Domain Socket
    Đó là Unix domain socket có ký tự đầu tiên là NUL(\0), có thể lách các ràng buộc quyền hạn
    Hiện đang được dùng trong game server để tách biệt tài nguyên của từng người chơi mà vẫn duy trì liên lạc

    • Có thể tìm các socket này trong /proc/net/unix
  • Nghe như kiểu tính năng này rất hợp để làm malware
    Có vẻ có thể gây rối hệ thống bằng mount ẩn hoặc tên ổ đĩa kỳ quặc

    • Nhưng trên thực tế đường dẫn NT phải được ánh xạ tới volume thực nên rất khó ẩn hoàn toàn
    • Nếu biết đến Alternate Data Streams thì còn thấy sốc hơn
    • Cần quyền quản trị để thao tác ổ đĩa
  • Khi phải mount nhiều ảnh đĩa, ký tự ổ đĩa sẽ trở nên cực kỳ rối rắm
    Ví dụ mount 36 file ISO DVD thì sẽ nếm trải địa ngục dấu ngoặc kép trên dòng lệnh

  • Ở DOS đời cũ (có lẽ là bản 3.3), ký tự ổ đĩa sau Z là AA
    Tôi từng tạo nhiều RAM drive nhỏ để kiểm tra điều đó

    • Tôi nhớ là trong Netware cũng có thể ánh xạ ổ đĩa vượt quá Z