Question: I want to make a program that gets the positions of the icons on the screen. And with some research I found out that the values I needed were in a registry binary file called IconLayouts (Located in HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Bags\1\Desktop) I used python to get the positions using the winreg module. And succeeded on getting the values. from winreg import * aReg = ConnectRegistry(None, HKEY_CURRENT_USER) aKey = OpenKey(aReg, r"Software\Microsoft\Windows\Shell\Bags\1\Desktop", REG_BINARY) name, value, type_ = EnumValue(aKey, 9) value = value.replace(b'\x00', b'')  This is the code I have. But the problem is I don't know what to do with these values. The program returns something like: b'\x03\x01\x01\x01\x04,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}> ,::{645FF040-5081-101B-9F08-00AA002F954E}> \x13Timetables.jpeg> \nfolder>\\ \x01\x02\x01\x01\x02\x01\x0c\x04\x01\x04\x80?\x01@\x020A\x03'  I would appreciate if you would help me decipher this output and get the positions from it.

Answer: The following code snippet could help. It's very, very simplified code combined from Windows Shellbag Forensics article and shellbags.py script (the latter is written in Python 2.7 hence unserviceable for me). import struct from winreg import * aReg = ConnectRegistry(None, HKEY_CURRENT_USER) aKey = OpenKey(aReg, r"Software\Microsoft\Windows\Shell\Bags\1\Desktop", REG_BINARY) name, value, type_ = EnumValue(aKey, 9) offset = 0x10 head = [struct.unpack_from("<H", value[offset:],0)[0], struct.unpack_from("<H", value[offset:],2)[0], struct.unpack_from("<H", value[offset:],4)[0], struct.unpack_from("<H", value[offset:],6)[0]] number_of_items = struct.unpack_from("<I", value[offset:],8)[0] # 4 bytes (dword) offset += 12 for x in range( number_of_items): uint16_size = struct.unpack_from("<H", value[offset:],0)[0]; uint16_flags = struct.unpack_from("<H", value[offset:],2)[0]; uint32_filesize = struct.unpack_from("<I", value[offset:],4)[0]; dosdate_date = struct.unpack_from("<H", value[offset:],8)[0]; dostime_time = struct.unpack_from("<H", value[offset:],10)[0]; fileattr16_ = struct.unpack_from("<H", value[offset:],12)[0]; offset += 12 entry_name = value[offset:(offset + (2 * uint32_filesize - 8))].decode('utf-16-le') offset += (2 * uint32_filesize - 4 ) if offset % 2: offset += 1 print( x, uint32_filesize, entry_name) print( '\nThere is', (len(value) - offset), 'bytes left' )  Output (truncated): .\SO\70039190.py 0 44 ::{59031A47-3F72-44A7-89C5-5595FE6B30EE} 1 44 ::{20D04FE0-3AEA-1069-A2D8-08002B30309D} 2 44 ::{5399E694-6CE5-4D6C-8FCE-1D8870FDCBA0} 3 31 Software602 Form Filler.lnk 4 8 test 5 32 Virtual Russian Keyboard.lnk … 49 22 WTerminalAdmin.lnk 50 22 AVG Secure VPN.lnk 51 44 ::{645FF040-5081-101B-9F08-00AA002F954E} 52 29 powershell - Shortcut.lnk There is 1176 bytes left  Honestly, I don't fully comprehend offset around entry_name… Edit I have found (partial) structure for the rest of value. There are two tables containing row and column along with an index to desktop_items list for each desktop icon. Current row and column assignment is in the second table (see the picture below). The first table supposedly contains default assignments for automatic sort by (from desktop context menu). Unfortunately, I have no clue for interpretation of row and column values (e.g. 16256, 16384) to icon indexes (3rd row, 2nd column). import struct import winreg import pprint aReg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) aKey = winreg.OpenKey(aReg, r"Software\Microsoft\Windows\Shell\Bags\1\Desktop", winreg.REG_BINARY) name, value, type_ = winreg.EnumValue(aKey, 9) aKey.Close() aReg.Close() offset = 0x10 head = [struct.unpack_from("<H", value[offset:],0)[0], # 2 bytes (word) struct.unpack_from("<H", value[offset:],2)[0], struct.unpack_from("<H", value[offset:],4)[0], struct.unpack_from("<H", value[offset:],6)[0], struct.unpack_from("<I", value[offset:],8)[0] # 4 bytes (dword) ] number_of_items = head[-1] offset += 12 desktop_items = [] for x in range( number_of_items): uint16_size = struct.unpack_from("<H", value[offset:],0)[0]; uint16_flags = struct.unpack_from("<H", value[offset:],2)[0]; uint32_filesize = struct.unpack_from("<I", value[offset:],4)[0]; dosdate_date = struct.unpack_from("<H", value[offset:],8)[0]; dostime_time = struct.unpack_from("<H", value[offset:],10)[0]; fileattr16_ = struct.unpack_from("<H", value[offset:],12)[0]; offset += 12 entry_name = value[offset:(offset + (2 * uint32_filesize - 8))].decode('utf-16-le') offset += (2 * uint32_filesize - 4 ) # uint16_size = location # 0x20 = %PUBLIC%\Desktop # 0x7c = %USERPROFILE%\Desktop desktop_items.append([x, '{:04x}'.format(uint16_size), 0, 0, '{:04x}'.format(fileattr16_), entry_name]) print('{:2}'.format(x), '{:04x}'.format(uint16_size), # '{:04x}'.format(uint16_flags), # always zero # '{:04x}'.format(dosdate_date), # always zero # '{:04x}'.format(dostime_time), # always zero '{:04x}'.format(fileattr16_), entry_name) print( '\nThere is', (len(value) - offset), 'bytes left' ) print('head (12 bytes):', head) offs = offset head2 = [] for x in range( 32): head2.append(struct.unpack_from("<H", value[offs:],2*x)[0]) offs += 64 print( 'head2 (64 bytes):', head2) for x in range( number_of_items): item_list = [ struct.unpack_from("<H", value[offs:],0)[0], # 0 struct.unpack_from("<H", value[offs:],2)[0], # column struct.unpack_from("<H", value[offs:],4)[0], # 0 struct.unpack_from("<H", value[offs:],6)[0], # row struct.unpack_from("<H", value[offs:],8)[0] ] # index to desktop_items # print( x, item_list) desktop_items[item_list[-1]][2] = int( item_list[1]) desktop_items[item_list[-1]][3] = int( item_list[3]) offs += 10 print(len(value), offset, offs, (offs - offset), '1st table, from start:') table_1st = desktop_items table_1st.sort(key=lambda k: (k[2], k[3])) pprint.pprint(table_1st) #pprint.pprint(desktop_items) # 2nd table from behind offs = len(value) for x in range( number_of_items): offs -= 10 item_list = [ struct.unpack_from("<H", value[offs:],0)[0], # 0 struct.unpack_from("<H", value[offs:],2)[0], # column struct.unpack_from("<H", value[offs:],4)[0], # 0 struct.unpack_from("<H", value[offs:],6)[0], # row struct.unpack_from("<H", value[offs:],8)[0] ] # index to desktop_items # print(item_list) desktop_items[item_list[-1]][2] = int( item_list[1]) desktop_items[item_list[-1]][3] = int( item_list[3]) print(len(value), offset, offs, (offs - offset), '2nd table, from behind:') table_2nd = desktop_items table_2nd.sort(key=lambda k: (k[2], k[3])) pprint.pprint(table_2nd) # pprint.pprint(desktop_items)  Result (an illustrative picture):