Last active
October 26, 2018 21:49
-
-
Save bgrewell/3f4ed11737a24c1f7d7f0791c5b9be0e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import struct | |
import codecs | |
import binascii | |
sample_string = """ | |
4C 00 00 00 01 14 02 00 00 00 00 00 C0 00 00 00 | |
00 00 00 46 81 00 00 00 00 00 00 00 00 00 00 00 | |
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
00 00 00 00 00 00 00 00 00 00 00 00 80 00 14 00 | |
1F 00 E0 4F D0 20 EA 3A 69 10 A2 D8 08 00 2B 30 | |
30 9D 14 00 2E 1E 20 20 EC 21 EA 3A 69 10 A2 DD | |
08 00 2B 30 30 9D 56 00 00 00 00 00 00 00 00 00 | |
00 00 00 6A 00 00 00 00 00 00 00 00 00 00 5C 00 | |
5C 00 31 00 30 00 2E 00 31 00 30 00 30 00 2E 00 | |
32 00 2E 00 31 00 34 00 36 00 5C 00 65 00 70 00 | |
74 00 73 00 63 00 5C 00 71 00 61 00 77 00 68 00 | |
75 00 75 00 2E 00 64 00 6C 00 6C 00 00 00 00 00 | |
00 00 | |
""" | |
def convert_path_to_bytearray(path): | |
patharray = bytearray() | |
for idx, c in enumerate(path): | |
path_part = bytearray([ord(c), 0x00]) | |
patharray.extend(path_part) | |
return patharray | |
def convert_size_to_little_endian_bytearray(value): | |
value_bytes = bytearray(value.to_bytes((value.bit_length() + 7) // 8, byteorder='little')) | |
if len(value_bytes) % 2 != 0: | |
value_bytes.append(0x00) | |
return value_bytes | |
if __name__ == '__main__': | |
if len(sys.argv) < 2: | |
print("Usage: {} <output filename>".format(sys.argv[0])) | |
exit(1) | |
header = bytearray() | |
header_size = bytearray(b'\x4C\x00') # Set Header Size | |
link_clsid = bytearray(b'\x00\x00\x01\x14\x02\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00') # Set Link CLSID | |
link_flags = bytearray(b'\x00\x46\x81\x00') # Set Link Flags | |
file_attributes = bytearray(b'\x00\x00\x00\x00') # Set File Attributes | |
creation_time = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') # Set File Creation Time | |
access_time = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') # Set File Access Time | |
write_time = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') # Set File Write Time | |
file_size = bytearray(b'\x00\x00\x00\x00') # Set The Size Of The Link Target | |
icon_index = bytearray(b'\x00\x00\x00\x00') # Set the Index of an Icon | |
show_command = bytearray(b'\x00\x00\x00\x00') # Set the window state for the application | |
hotkey = bytearray(b'\x00\x00') # Set the HotKey Flags | |
res_1 = bytearray(b'\x00\x00') # Set Reserved 1 - Must be zero | |
res_2 = bytearray(b'\x00\x00\x00\x00') # Set Reserved 2 - Must be zero | |
res_3 = bytearray(b'\x00\x00\x00\x00') # Set Reserved 3 - Must be zero | |
# Build header | |
header.extend(header_size) | |
header.extend(link_clsid) | |
header.extend(link_flags) | |
header.extend(file_attributes) | |
header.extend(creation_time) | |
header.extend(access_time) | |
header.extend(write_time) | |
header.extend(file_size) | |
header.extend(icon_index) | |
header.extend(show_command) | |
header.extend(hotkey) | |
header.extend(res_1) | |
header.extend(res_2) | |
header.extend(res_3) | |
# Pad header to right size | |
header.append(0x00) | |
header.append(0x00) | |
# Setup LinkInfo | |
item_id_1_size = bytearray(b'\x14\x00') # My Computer CLSID size | |
print('item_id_1_size: ' + ' '.join('{:02X}'.format(x) for x in item_id_1_size)) | |
item_id_1 = bytearray(b'\x1F\x00\xE0\x4F\xD0\x20\xEA\x3A\x69\x10\xA2\xD8\x08\x00\x2B\x30\x30\x9D') # My Computer CLSID | |
print('item_id_1: ' + ' '.join('{:02X}'.format(x) for x in item_id_1)) | |
item_id_2_size = bytearray(b'\x14\x00') # Control Panel CLSID size | |
print('item_id_2_size: ' + ' '.join('{:02X}'.format(x) for x in item_id_2_size)) | |
item_id_2 = bytearray(b'\x2E\x1E\x20\x20\xEC\x21\xEA\x3A\x69\x10\xA2\xDD\x08\x00\x2B\x30\x30\x9D') # Control Panel CLSID | |
print('item_id_2: ' + ' '.join('{:02X}'.format(x) for x in item_id_2)) | |
item_id_3 = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') | |
item_id_3.extend(convert_path_to_bytearray(sys.argv[1])) # Path to file | |
item_id_3_size = convert_size_to_little_endian_bytearray(len(item_id_3) + 2) # Path to file size | |
print('item_id_3_size: ' + ' '.join('{:02X}'.format(x) for x in item_id_3_size)) | |
print('item_id_3: ' + ' '.join('{:02X}'.format(x) for x in item_id_3)) | |
total_payload_length = 8 + len(item_id_1) + len(item_id_2) + len(item_id_3) # Length of the LinkInfo Section | |
id_list_size = bytearray(convert_size_to_little_endian_bytearray(total_payload_length)) # Set to actual size later | |
term = bytearray(b'\x00\x00') # TerminalID | |
# Build LinkInfo | |
linkinfo = bytearray() | |
linkinfo.extend(id_list_size) | |
linkinfo.extend(item_id_1_size) | |
linkinfo.extend(item_id_1) | |
linkinfo.extend(item_id_2_size) | |
linkinfo.extend(item_id_2) | |
linkinfo.extend(item_id_3_size) | |
linkinfo.extend(item_id_3) | |
linkinfo.extend(term) | |
# Build file | |
file_contents = bytearray() | |
file_contents.extend(header) | |
file_contents.extend(linkinfo) | |
print(' '.join('{:02X}'.format(x) for x in file_contents)) | |
# Write File | |
output = open('output.lnk', 'wb') | |
output.write(file_contents) | |
output.flush() | |
output.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment