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