Skip to content

Instantly share code, notes, and snippets.

@hyuunnn
Last active September 27, 2023 19:35
Show Gist options
  • Save hyuunnn/96fdeca437f6c62ef2a134662f39b64d to your computer and use it in GitHub Desktop.
Save hyuunnn/96fdeca437f6c62ef2a134662f39b64d to your computer and use it in GitHub Desktop.
lnk_parser

ex) python lnk.py "C:/lnkfile/"

ex) python lnk2.py "C:/lnkfile/" --> using pylnk

pylnk show_window_value is incorrect data

So I created the code to parse the ShowWindow.

# https://github.com/HarmJ0y/pylnker/blob/master/pylnker.py 참고
import struct
import binascii
import sys
import codecs
import time
import os
import datetime
class Lnk_parse:
def __init__(self):
self.Lnk_header_GUID_Number = "46000000000000c000000000000214010000004c"
self.DriveType_Value = {
"0":"DRIVE_UNKNOWN (0)",
"1":"DRIVE_NO_ROOT_DIR (1)",
"2":"DRIVE_REMOVABLE (2)",
"3":"DRIVE_FIXED (3)",
"4":"DRIVE_REMOTE (4)",
"5":"DRIVE_CDROM (5)",
"6":"DRIVE_RAMDISK (6)"
}
## https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-showwindow
self.ShowWindow_value = {
"0":"SW_HIDE (0)",
"1":"SW_SHOWNORMAL, SW_NORMAL (1)",
"2":"SW_SHOWMINIMIZED (2)",
"3":"SW_SHOWMAXIMIZED, SW_MAXIMIZE (3)",
"4":"SW_SHOWNOACTIVATE (4)",
"5":"SW_SHOW (5)",
"6":"SW_MINIMIZE (6)",
"7":"SW_SHOWMINNOACTIVE (7)",
"8":"SW_SHOWNA (8)",
"9":"SW_RESTORE (9)",
"10":"SW_SHOWDEFAULT (10)",
"11":"SW_FORCEMINIMIZE, SW_MAX (11)"
}
def lnk_unpack(self, seek_num, num):
result = []
self.f.seek(seek_num)
data = self.f.read(num)
bin_hex = binascii.hexlify(data).decode("utf-8")
for i in range(0,len(bin_hex),2):
result.append(bin_hex[i:i+2])
return ''.join(result[::-1])
def convert_unix_to_window(self, time):
return datetime.datetime.fromtimestamp(time / 10000000 - 11644473600).strftime('%Y:%m:%d %H:%M:%S')
def null_str(self, size):
result = b""
self.f.seek(size)
string = self.f.read(1)
while string != b"\x00":
result += (string)
string = self.f.read(1)
return result.decode("euc-kr")
def lnk_parse(self, filename):
check_GUID_number = ""
Creation_Time = ""
Last_Access_Time = ""
Last_Modification_Time = ""
FileSize = ""
IconIndex = ""
ShowWindow = ""
DriveType = ""
BasePath = ""
DriveSerialNumber = ""
self.f = open(filename,"rb")
# Last_access_time = str(datetime.datetime.fromtimestamp(os.stat(filename).st_atime).strftime('%Y:%m:%d %H:%M:%S.%f'))
check_lnk = self.lnk_unpack(0,20)
if check_lnk == self.Lnk_header_GUID_Number:
check_GUID_number = "O"
else:
check_GUID_number = "X"
try:
Creation_Time = self.convert_unix_to_window(int(self.lnk_unpack(0x1C,8),16))
except:
pass
try:
Last_Access_Time = self.convert_unix_to_window(int(self.lnk_unpack(0x24,8),16))
except:
pass
try:
Last_Modification_Time = self.convert_unix_to_window(int(self.lnk_unpack(0x2C,8),16))
except:
pass
try:
FileSize = int(self.lnk_unpack(0x34,4),16)
except:
pass
try:
IconIndex = int(self.lnk_unpack(0x38,4),16)
except:
pass
try:
ShowWindow = self.ShowWindow_value[str(int(self.lnk_unpack(0x3C,4),16))]
except:
pass
LnkFlags = self.lnk_unpack(20,4)
if LnkFlags[-1] in ("f","e","b","a","6","3","2","7"):
IDListSize = int(self.lnk_unpack(76,2),16)
LinkTargetIdentifier_end = IDListSize + 78
LinkInfo_start = LinkTargetIdentifier_end
VolumeID_offset = LinkInfo_start + 12
BasePath_offset = LinkInfo_start + 16
VolumeID_offset = int(self.lnk_unpack(VolumeID_offset,4),16)
BasePath_offset = int(self.lnk_unpack(BasePath_offset,4),16)
DriveType = int(self.lnk_unpack(LinkInfo_start + VolumeID_offset+4,4),16)
DriveSerialNumber = int(self.lnk_unpack(LinkInfo_start + VolumeID_offset+8,4),16)
BasePath = self.null_str(LinkInfo_start + BasePath_offset)
DriveType = self.DriveType_Value[str(DriveType)]
else:
pass
return filename, check_GUID_number, str(Creation_Time), str(Last_Access_Time), str(Last_Modification_Time), FileSize, IconIndex, ShowWindow, DriveType, DriveSerialNumber, BasePath
if __name__ == '__main__':
import csv
a = Lnk_parse()
f = open('output.csv', 'w', encoding='euc-kr', newline='')
wr = csv.writer(f)
wr.writerow(["filename", "check_GUID_number", "Creation_Time", "Last_Access_Time", "Last_Modification_Time", "FileSize", "IconIndex", "ShowWindow", "DriveType", "DriveSerialNumber", "BasePath"])
filenames = os.listdir(sys.argv[1])
for filename in filenames:
print(filename)
data = a.lnk_parse(sys.argv[1] + filename)
wr.writerow([data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10]])
f.close()
import pylnk
import os
import sys
import csv
import struct
def u32(x):
return struct.unpack("<L", x)[0]
DriveType_Value = {
"-1":"Error (-1)",
"0":"DRIVE_UNKNOWN (0)",
"1":"DRIVE_NO_ROOT_DIR (1)",
"2":"DRIVE_REMOVABLE (2)",
"3":"DRIVE_FIXED (3)",
"4":"DRIVE_REMOTE (4)",
"5":"DRIVE_CDROM (5)",
"6":"DRIVE_RAMDISK (6)"
}
## https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-showwindow
ShowWindow_value = {
"-1":"Error (-1)",
"0":"SW_HIDE (0)",
"1":"SW_SHOWNORMAL, SW_NORMAL (1)",
"2":"SW_SHOWMINIMIZED (2)",
"3":"SW_SHOWMAXIMIZED, SW_MAXIMIZE (3)",
"4":"SW_SHOWNOACTIVATE (4)",
"5":"SW_SHOW (5)",
"6":"SW_MINIMIZE (6)",
"7":"SW_SHOWMINNOACTIVE (7)",
"8":"SW_SHOWNA (8)",
"9":"SW_RESTORE (9)",
"10":"SW_SHOWDEFAULT (10)",
"11":"SW_FORCEMINIMIZE, SW_MAX (11)"
}
f = open('output2.csv', 'w', encoding='euc-kr', newline='')
wr = csv.writer(f)
wr.writerow(["filename", "Creation_Time", "Last_Access_Time", "Last_Modification_Time", "FileSize", "BasePath", "Command_Line_Arguments", "IconIndex", "ShowWindow", "DriveType", "DriveSerialNumber"])
filenames = os.listdir(sys.argv[1])
for filename in filenames:
print(filename)
try:
file_object = open(sys.argv[1] + filename, "rb")
lnk_file = pylnk.file()
lnk_file.open_file_object(file_object)
except OSError:
wr.writerow([filename, "OSError"])
continue
modification_time = lnk_file.file_modification_time.strftime('%Y:%m:%d %H:%M:%S')
creation_time = lnk_file.file_creation_time.strftime('%Y:%m:%d %H:%M:%S')
access_time = lnk_file.file_access_time.strftime('%Y:%m:%d %H:%M:%S')
file_size = lnk_file.file_size
local_path = lnk_file.local_path
command_line = lnk_file.command_line_arguments
icon_index = lnk_file.icon_index
drive_serial_number = lnk_file.drive_serial_number
if lnk_file.drive_type == None:
drive_type = -1
else:
drive_type = lnk_file.drive_type
ShowWindow = u32(open(sys.argv[1] + filename, "rb").read()[0x3C:0x3C+4]) ## pylnk show_window_value incorrect data
wr.writerow([filename, creation_time,
access_time, modification_time,
file_size, local_path, command_line,
icon_index, ShowWindow_value[str(ShowWindow)],
DriveType_Value[str(drive_type)], drive_serial_number])
lnk_file.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment