2017-06-23 458 views
0

當從this answer測試代碼,我收到的輸出,但它似乎有一些文物......從Python中的快捷方式(.lnk)讀取目標路徑時的文件路徑工件?

這是我測試的代碼:

import locale 
import struct 

def __readLink(path): 
    target = '' 

    try: 
     with open(path, 'rb') as stream: 
      content = stream.read() 

      # skip first 20 bytes (HeaderSize and LinkCLSID) 
      # read the LinkFlags structure (4 bytes) 
      lflags = struct.unpack('I', content[0x14:0x18])[0] 
      position = 0x18 

      # if the HasLinkTargetIDList bit is set then skip the stored IDList 
      # structure and header 
      if (lflags & 0x01) == 1: 
       position = struct.unpack('H', content[0x4C:0x4E])[0] + 0x4E 

      last_pos = position 
      position += 0x04 

      # get how long the file information is (LinkInfoSize) 
      length = struct.unpack('I', content[last_pos:position])[0] 

      # skip 12 bytes (LinkInfoHeaderSize, LinkInfoFlags, and VolumeIDOffset) 
      position += 0x0C 

      # go to the LocalBasePath position 
      lbpos = struct.unpack('I', content[position:position+0x04])[0] 
      position = last_pos + lbpos 

      # read the string at the given position of the determined length 
      size= (length + last_pos) - position - 0x02 
      temp = struct.unpack('c' * size, content[position:position+size]) 
      target = ''.join([chr(ord(a)) for a in temp]) 
    except: 
     # could not read the file 
     pass 

    return target 

print(__readLink('test.lnk')) 

輸出鏈接如下出於某種原因,它不會完全複製。

我看到的另一個問題是,它不輸出完整的文件擴展名?它應該是一個約會專家,但在「.MP」

Image of output

回答

0

從問題的代碼終止不符合MS-SHLLINK規範, 有許多固定的偏移值。

MS-SHLLINK: Shell Link (.LNK) Binary File Format
指定外殼鏈接二進制文件格式,其中包含可用於訪問另一個數據對象的信息。 Shell鏈接二進制文件格式是擴展名爲「LNK」的Windows文件的格式。

以下代碼僅使用LinkFlags 0x14LinkTargetIDList 0x4c作爲固定偏移量。

def LocalBasePath(path): 
    def unpack(offset, size): 
     m = 'I' 
     if size == 2: m = 'H' 
     return struct.unpack(m, content[offset:offset+size])[0] 

    target = '' 
    try: 
     with open(path, 'rb') as fh: 
      content = fh.read() 

     # Read the LinkFlags 4 bytes 
     LinkFlags = unpack(0x14, 4) 

     position = 0x4c 
     # Skip LinkTargetIDList if HasLinkTargetIDList 
     if (LinkFlags & 0x01) == 1: 
      position += unpack(position, 2) 

     position += 0x02 # TerminalID 2 bytes 
     LinkInfo_offset = position 
     LinkInfoSize = unpack(position, 4) 

     # Skip 4 * 4 bytes in LinkInfo 
     LokalBasePathOffset = LinkInfo_offset + (4 * 4) 
     LocalBasePath = LinkInfo_offset + unpack(LokalBasePathOffset, 4) 

     # Read LocalBasePath String 
     size = ((LinkInfo_offset + LinkInfoSize) - LocalBasePath) -2 
     target = ''.join([chr(ord(a)) for a in struct.unpack('c' * size, content[LocalBasePath:LocalBasePath+size])]) 

    except Exception as exp: 
     print(exp) 

    return target 

測試使用Python 3.4.2

相關問題