Giter VIP home page Giter VIP logo

golnk's Introduction

lnk - lnk Parser for Go

lnk is a package for parsing Windows Shell Link (.lnk) files.

It's based on version 5.0 of the [MS-SHLLINK] document:

If the lnk file does not adhere to this specification (either corrupted or from an earlier version), it might not be parsed.

Shell Link Structure

Each file has at least one header (SHELL_LINK_HEADER) and one or more optional sections.

SHELL_LINK = SHELL_LINK_HEADER [LINKTARGET_IDLIST] [LINKINFO]
              [STRING_DATA] *EXTRA_DATA

The existence of these sections are defined by the LinkFlags uint32 in the header (mapped to HEADER.LinkFlags). To see all flags, look at linkFlags in header.go.

Note about size fields: "Unless otherwise specified, the value contained by size fields includes the size of size field itself."

Currently lnk parses every section except EXTRA_DATA. Different data blocks are identified and stored but it does not parse any of them other than identifying the type (via their signature) and storing the content. Data blocks are defined in section 2.5 of the specification.

Setup

Package has only one dependency: https://github.com/olekukonko/tablewriter. It's used to create tables in section stringers.

Usage

Pass a filename to lnk.File or an io.Reader with its contents to lnk.Read. Both return LnkFile:

type LnkFile struct {
	Header     ShellLinkHeaderSection  // File header.
	IDList     LinkTargetIDListSection // LinkTargetIDList.
	LinkInfo   LinkInfoSection         // LinkInfo.
	StringData StringDataSection       // StringData.
	DataBlocks ExtraDataSection        // ExtraData blocks.
}

Each section is a struct that is populated. See their fields in their respective source files.

package main

import (
	"fmt"

	"github.com/parsiya/golnk"
)

func main() {

	Lnk, err := lnk.File("test.lnk")
	if err != nil {
		panic(err)
	}

	// Print header.
	fmt.Println(Lnk.Header)

	// Path to the target file is usually in LinkInfo.LocalBasePath.
	fmt.Println("BasePath", Lnk.LinkInfo.LocalBasePath)

	// fmt.Println(Lnk.LinkInfo)

	// fmt.Println(Lnk.StringData)

	// fmt.Println(Lnk.DataBlocks)
}

header printed

Each section has a Stringer that prints the fields in a table.

link info printed

Extra Data Blocks are not parsed but can be dumped or accessed manually.

extra data block dump

Parse the Windows start menu and extract the base path for all lnk files.

See test/parseStartMenu.go:

package main

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/parsiya/golnk"
)

// Sample program to parse all lnk files in the "All Users" start menu at
// C:\ProgramData\Microsoft\Windows\Start Menu\Programs.

func main() {
	startMenu := "C:/ProgramData/Microsoft/Windows/Start Menu/Programs"
	basePaths := []string{}
	err := filepath.Walk(startMenu, func(path string, info os.FileInfo, walkErr error) error {
		// Only look for lnk files.
		if filepath.Ext(info.Name()) == ".lnk" {
			f, lnkErr := lnk.File(path)
			// Print errors and move on to the next file.
			if lnkErr != nil {
				fmt.Println(lnkErr)
				return nil
			}
			var targetPath = ""
			if f.LinkInfo.LocalBasePath != "" {
				targetPath = f.LinkInfo.LocalBasePath
			}
			if f.LinkInfo.LocalBasePathUnicode != "" {
				targetPath = f.LinkInfo.LocalBasePathUnicode
			}
			if targetPath != "" {
				fmt.Println("Found", targetPath)
				basePaths = append(basePaths, targetPath)
			}
		}
		return nil
	})
	if err != nil {
		panic(err)
	}

	// Print everything.
	fmt.Println("------------------------")
	for _, p := range basePaths {
		fmt.Println(p)
	}
}

TODO

  1. Use dep?
  2. Identify ExtraDataBlocks.
  3. Clean up code.
  4. Write more unit tests.
  5. Test it on more lnk files.
  6. Add a Data field to each section and store raw bytes there. Then add a Dump method to each section and use hex.Dump to dump the raw bytes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.