从Python中的快捷方式(.lnk)读取目标路径时的文件路径工件?
问题描述:
当从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”
答
从问题的代码终止不符合MS-SHLLINK规范, 有许多固定的偏移值。
MS-SHLLINK: Shell Link (.LNK) Binary File Format
指定外壳链接二进制文件格式,其中包含可用于访问另一个数据对象的信息。 Shell链接二进制文件格式是扩展名为“LNK”的Windows文件的格式。
以下代码仅使用LinkFlags 0x14
和LinkTargetIDList 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