Trường Data trong cấu trúc LinkTargetIDList của file Shortcut (.lnk)

Standard

Mở bài

Theo tài liệu mà MS cung cấp, cấu trúc LinkTargetIDList được mô tả như sau:

18-1-2012 20-06-49

Với IDList:

18-1-2012 20-07-43

Và ItemID:

18-1-2012 20-08-19

Tất cả đều rất rõ ràng, chỉ trừ trường Data trong ItemID mà thôi.

Khi xử lý file .lnk với mục đích để lấy target mà file đó trỏ tới, ta thường có 2 hướng đi, đó là thông qua LinkTargetIDList hoặc LinkInfo. Trường hợp file không có cấu trúc LinkInfo, ta sẽ phải giải quyết cấu trúc LinkTargetIDList. Vậy, vấn đề là ta cần hiểu được trường Data nêu ở trên.

 

Thân bài

Qua việc “săm soi” một vài “đối tượng”, tôi thấy có thể định nghĩa trường Data một cách đơn giản bằng ví dụ sau:

18-1-2012 20-14-19

Chúng ta sẽ đi qua từng phần tử ItemID, chậm thôi, không cần vội Smile

1.

18-1-2012 20-16-35

Lưu ý rằng 2 byte đầu là kích thước của phần tử đang xét (bao gồm cả 2 byte này).

Phần tử đầu tiên, theo tài liệu của MS, thì đại diện cho My Computer.

2.

18-1-2012 20-18-49

Phần tử thứ hai này, dễ thấy, là ký tự của phân vùng chứa target. Bắt đầu bằng ký tự ‘/’ (0x2f). Lưu ý rằng giá trị 0x2f là không cố định, ta nên đặt biến count để xác định vị trí của phần tử này (đứng thứ 2).

3.

18-1-2012 20-21-26

Byte đầu tiên, là 0x31. Theo suy đoán, đây là byte đại diện cho kiểu của ItemID (folder hoặc file), mà cụ thể là 0x31 có nghĩa là folder.

11 byte kế tiếp, được giữ cố định trong nhiều trường hợp: “00 00 00 00 00 00 00 00 00 10 00”. Tiếp theo là tên thư mục trong mã ASCII, theo dạng null-terminated. Ở phía xa xa đằng sau, là tên thư mục trong mã Unicode, cũng theo dạng null-terminated.

18-1-2012 21-02-49

Do để đảm bảo tính chính xác, ta thường cần lấy đường dẫn ở mã unicode chứ không phải ascii, do đó điều cần thiết là phải xác định được những byte ở giữa chúng là gì. Trong hình trên, những byte ở giữa 2 chuỗi là: “54 00 08 00 04 00 EF BE 00 00 00 00 00 00 00 00 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00”. Cứ để đó đã.

4.

18-1-2012 21-14-38

Vẫn là 0x31, và vẫn là thư mục Devil Những byte ở giữa, là: “4C 00 08 00 04 00 EF BE 00 00 00 00 00 00 00 00 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00”. Lại cứ để đó đã Smile

5.

18-1-2012 21-15-37

Lần này là 0x32 – đây là file, và là phần tử ItemID cuối cùng. Những byte ở giữa, là: “68 00 08 00 04 00 EF BE 00 00 00 00 00 00 00 00 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00”.

Tổng hợp lại, ta được 3 dãy byte ngăn cách chuỗi ASCII và Unicode như sau:

18-1-2012 21-19-18

Có vẻ khá trơn tru Open-mouthed smile Cấu trúc dãy byte mà ta hiện có là (42 byte):

18-1-2012 21-20-32

Tiến hành tương tự với một file khác, ta được (tôi đã giãn cách các dãy byte để bạn dễ thấy được sự tương đồng giữa chúng):

18-1-2012 21-25-48

Cấu trúc dãy byte:

18-1-2012 21-27-38

So sánh với ở trên:

18-1-2012 21-20-32

Thôi thì, để an toàn và dịu dàng, ta quy ước về dãy byte này như sau:

Kể từ ký tự null-terminated của chuỗi ASCII:

  • Đọc đến byte đầu tiên khác 0x00.
  • Đọc 16 byte tiếp theo. // 00 xx 00 xx 00 xx xx 00 00 00 00 00 00 00 00 xx
  • Đọc đến byte đầu tiên khác 00. Byte này chính là ký tự đầu tiên của chuỗi Unicode. (Hoặc bạn có thể đọc 25 byte 0x00 cũng được). Việc đọc các chuỗi Unicode là không mấy khó khăn, xin phép không bàn ở đây.

Cập nhật 01h23 ngày 20/01/2012:

Dạo thêm qua một số file khác, nhận thấy rằng dãy byte ngăn cách khá “hỗn tạp”:

20-1-2012 01-22-13

Trong hình trên, tôi đã đánh dấu những gì mà tôi “đoán” được, cụ thể là 2 byte “EF BE”, được coi là byte nhận dạng, và byte thứ 9 đằng sau 2 byte nhận dạng đó, có giá trị là độ dài của dãy các byte “0x00” phía sau, và trừ đi 17. Với 0x14 (20) ta có 3 byte “0x00”; với 0x26 (38), ta có 21 byte “0x00”.

Tạm thời, thuật toán để giải quyết dãy byte ngăn cách này như sau:

Kể từ ký tự null-terminated của chuỗi ASCII:

  • Đọc đến 2 byte nhận dạng “EF BE”.
  • Đọc tiếp 8 byte.
  • Đọc 1 byte, lấy giá trị thu được trừ đi 17 (length).
  • Đọc length byte tiếp theo.
  • Đọc chuỗi Unicode.

Kết luận

Khi code và chạy thử nghiệm theo thuật toán ở trên, chương trình nhận dạng chính xác các phần tử ItemID. Dẫu vậy, do chỉ là suy đoán, và cũng không có nhiều file tương tự để kiểm tra, nên tính đúng đắn của thuật toán là không đảm bảo. Rất mong nhận được ý kiến phản hồi từ các bạn!

18-1-2012 21-44-05

Phụ lục

Các file shortcut minh họa cho bài viết:

http://www.mediafire.com/download.php?kscf1h9dx89nvdb

2 thoughts on “Trường Data trong cấu trúc LinkTargetIDList của file Shortcut (.lnk)

  1. tại sao đồng chí không tìm tài liệu về định dạng LNK mà lại tự mò thế này :p
    tự tìm hiểu là rất tốt nhưng sẽ tốn nhiều thời gian lắm đó :p

    • Mình đã tìm, và không thấy có tài liệu nào nói về trường Data này. Bài viết cũng có lưu ý rằng: “Tất cả đều rất rõ ràng, chỉ trừ trường Data trong ItemID mà thôi.”

      Rất vui nếu bạn có thể chia sẻ tài liệu liên quan đến vấn đề này, vì với kiến thức hiện tại của mình, vẫn chưa giải quyết được tất cả các trường hợp.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s