0

When testing the code from this answer, I do receive an output, however it seems to have some artifacts...

This is the code I tested:

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'))

The output is linked below, as for some reason, it does not copy completely.

Another problem I see is that it does not output the full file extension? It should be an .mp4, but it terminates at ".mp"

Image of output

chatbottest
  • 403
  • 1
  • 4
  • 9

1 Answers1

1

The Code from the Question does not follow the MS-SHLLINK specification, there are to many fixed Offset Values.

MS-SHLLINK: Shell Link (.LNK) Binary File Format
Specifies the Shell Link Binary File Format, which contains information that can be used to access another data object. The Shell Link Binary File Format is the format of Windows files with the extension "LNK".

The following code uses only LinkFlags 0x14 and LinkTargetIDList 0x4c as fixed Offsets.

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

Tested with Python: 3.4.2

stovfl
  • 14,998
  • 7
  • 24
  • 51