We are apologize for the inconvenience but you need to download
more modern browser in order to be able to browse our page

Download Safari
Download Safari
Download Chrome
Download Chrome
Download Firefox
Download Firefox
Download IE 10+
Download IE 10+

Reverse Engineering of newly introduced “IconLayouts” registry value

UPDATED 2019.08.07: Tested also working with 1903

Recently I’m trying to hide the desktop.ini and *.onetoc2 files from my desktop.
For software security engineers, especially windows malware researchers, it’s extremely crucial to enable “Show all files” and disable “Hide system files”. We do need these options to show all files constantly, because usually all malware will make themselves into super-hidden files.
And that’s why there will always be the annoying hidden files on my desktop.

Of course as a proud reverse engineer, I dug into our little explorer shell.

1. According to the answers from StackOverflow, before Windows 10 1703 the icons’ layout will be stored in https://superuser.com/questions/625854/where-does-windows-store-icon-positions

2. But after upgrading to 1703, everything changed. The ItemPosXXXxXXX reg value disappeared. Instead, the IconLayouts took its place, which is also a REG_BINARY value.

  •  I didn’t find any useful information for the internal structure of this binary data

3. Globally searching the string “IconLayouts” in every DLL and EXE file under System32 directory revealed that only shell32.dll used this value

4. Thanks to the symbols offered generously by Microsoft and easy-to-use IDA cross reference, I managed to have a quick peek on the 20Mb shell32.dll and to locate the target code with almost no effort.

5. Reverse engineering the IconLayout took sometime, with some guessing and heruistic techniques I got the 010 Editor Template.

//--- 010 Editor v8.0 Binary Template
//      File: IconLayouts.bt
//   Authors: Misty
//   Version: 0.0.1
//   Purpose: Parse the IconLayouts registry value
//  Category: 
// File Mask: IconLayouts.bin
//  ID Bytes: 
//   History: 
char unk[16];

struct StreamHelper_String{
    __int64 len;
    if (len > 0)
        wchar_t data[len];

struct tagPOINTF {
    float x;
    float y;

struct tagPOINT {
    int x;
    int y;

struct DesktopDictionary {
    int version; // 0x10003 on 1803
    struct IconNameTable{
        int version; // 0x10001 on 1803
        __int64 len;
        StreamHelper_String str[len]<optimize=false>;
    } iconNameTable;
    struct Desktops{
        __int64 desktopNum;
        struct DesktopData {
            int version; // 0x10002 on 1803
            StreamHelper_String linkedKey;
            __int64 workspaceNum;
            struct WorkspaceData {
                int version;
                int linkShiftX;
                int linkShiftY;
                struct GridWorkspaceWorker {
                    tagPOINT gridSize;
                    int infoFlags; // usually 0x1
                } gridWorkspace;
                __int64 iconsNum;
                typedef struct {
                    tagPOINTF iconLoc;
                    wchar_t index;
                } IconGridItemWorker <read=IconGridItemWorker_Read>;
                IconGridItemWorker iconGridItems[iconsNum]<optimize=false>;

            } workspaceData[workspaceNum]<optimize=false>;
        } desktops[desktopNum]<optimize=false>;
    } desktops;
} dic;

wstring IconGridItemWorker_Read(IconGridItemWorker &iiw){
    string ret;
    SPrintf(ret, "%d -> %s", iiw.index, dic.iconNameTable.str[iiw.index].data);
    return StringToWString(ret, CHARSET_UTF8);

Use it as you wish :0