20

On windows 10 when we create a program named main.exe or rename a program to main.exe, the program will show a pop up as seen here :


some pop up in Notepad++ how wonderfull is that?


There is 2 different pop up than can be shown :

-the game bar one (French and English version):

Appuyer sur Win + G pour ouvrir la barre jeu

Press Win + G to open Game bar

-the screenshot one :

Appuyer sur Win + Alt +Impr.écran pour prendre une capture d'écran

(In English: Press Win + Alt + PrintScreen to take a screenshot)


I originally discovered the problem while using python and cx_freeze,

I have tested this on multiple programs, including (as seen above) renaming notepad++.exe to main.exe, and each time, one of the pop up was there,

We can also note that the pop up appears alternatively (one game pop up, then one sreenshot pop up, then one game pop up...)

I run windows10 via virtual box, but as described below, the problem also happend on physical machines.

Any idea on how this happend?

Note : BoltClock also tested it (on a physical machine) and found that, on his machine this behavior is only happening with "Main.exe" while, on my machine the behavior happened whatever may be the uppercase/lowercase distribution of the "main" (IE: it works with main.exe,Main.exe or even MaIN.exe)

Community
  • 1
  • 1
Ether Frog
  • 315
  • 1
  • 9
  • This is interesting.....i would really love to see your program so i can test it – danidee Apr 19 '16 at 13:03
  • Do you have Razer Game Booster or Cortex installed? – Ignacio Vazquez-Abrams Apr 21 '16 at 08:37
  • I don't have Razer Game Booster installed, as for Cortex, i'm not sure but at the least I can't find it. – Ether Frog Apr 21 '16 at 08:42
  • 3
    That's definitely a native Windows 10 popup related to the Xbox app. I see it when launching some of my games. I just reproduced this on my physical machine with some of my WinForms and WPF exes. But, peculiarly, it doesn't work for just any case combination - it only works for me with "Main.exe" and not "main.exe" for example. Still hilarious. – BoltClock Apr 21 '16 at 08:56
  • At a guess, you'll need a manifest specifying Windows 10 compatibility in order to suppress this behaviour. – Harry Johnston Apr 21 '16 at 22:53
  • @Harry Johnston: Assuming you're referring to the supportedOS element in app.manifest, I just tried that with 1) a fresh WPF project, and 2) an existing WPF project, but no dice. – BoltClock Apr 25 '16 at 12:58
  • @BoltClock could you, supposing you are on an english version of windows, provide us with the screen and/or the transcript of the pop up (so that people who run into the same problem can find this page when they google it)? – Ether Frog Apr 28 '16 at 12:04
  • Here you go: http://i.stack.imgur.com/U9kWY.png – BoltClock Apr 29 '16 at 08:59
  • 2
    I can't reproduce. I'm running a recent preview build, 14328.1000, perhaps the problem has been fixed? (Or perhaps it only affects some configurations.) – Harry Johnston Apr 29 '16 at 13:53
  • @BoltClock thanks. On a side note I am begining to wonder if this question would not be more fit for superuserSE since it's more about the OS than about any programming, any insight on this? – Ether Frog Apr 29 '16 at 14:32
  • @Harry Johnston: Interesting. Only a matter of time before the Anniversary Update hits I guess, but I'm definitely seeing this on the current 10586.x. – BoltClock Apr 29 '16 at 15:17
  • @EtherFrog: doesn't really significantly affect end-users though, it's only the programmer that is likely to be bothered by it, because it looks like a fault in the application. And any work-around is more likely IMO to be at the programmers end, even if it's just "don't name your executable main.exe". – Harry Johnston Apr 29 '16 at 23:18
  • @EtherFrog: since you've got a VM setup, perhaps you could try signing up a test VM to Windows Insider and see whether the latest build does actually resolve this for you? (You'd probably need to choose "fast ring".) – Harry Johnston Apr 29 '16 at 23:19
  • @Harry Well It's a VM I only use at work and I can't really go and apply to windows insider on my work VM – Ether Frog May 03 '16 at 10:00

1 Answers1

15

I've done some digging over the weekend and I have found over 2000 special exe names which will trigger the same behaviour, not just main.exe.

Explorer has a component called BroadcastDVR (located in the twinui dll) which, upon a process creation, will compare the executable properties against a "store" of games and will launch GameLauncher.exe if there is a match.

I've not managed to pinpoint where the comparison is done since it's hidden behind a RPC call, which is a PITA to reverse.

Anyway, explorer.exe has a handle on the following file C:\Users\YOUR_USERNAME\AppData\Local\Microsoft\GamesDVR\KnownGameList.bin (there is a copy in C:\Windows\broadcastdvr) which list all the special executables which triggers the XBox recorder popup. You can see the main.exe entry here (entry #1007):

enter image description here

I've written a 010 template file to parse the entry list and it comes with 2089 entries on my computer. From what I've seen by reversing the binary file, there is three types of entry:

  • the "simple" one where there is only a match on the executable name. For example : main.exe or ai.exe

  • the more complex one where there is a match on the executable name and the path where the exe is stored must contains some strings. For example : acu.exe must be located in a subfolder of Assassin's Creed Unity.

  • Some entries have additionals strings to match, but I haven't found how to trigger the game DVR popup for them.

NB : the Win32 subsystem is case-insensitive so it makes sense that the executable name's case does not matter.

Here is the template (you can install 010 Editor from here, there is an evaluation period I think) :

typedef struct  {
   BYTE Reserved[0x300];
}HEADER;

typedef struct  {
    WORD ByteLen;
    BYTE RawString[ByteLen];
    //local string sName=ReadWString(RawString);
} GAME_WSTR <read=ReadGame>;

typedef struct {
    DWORD Reserved;
    DWORD ByteLen;
    BYTE RawString[ByteLen] <fgcolor=cLtRed>;
} OPTION_STR  <read=ReadOption>;

typedef struct  {
   local int StartAddr = FTell();
   DWORD EntrySize;

   // Executable game name
   GAME_WSTR GameName <fgcolor=cLtBlue>;

   // Optional magic
   if (ReadUShort() == 0xca54)
        WORD OptReserved;

   // Optional structs based on switch values
   WORD AdditionalNamesCount;
   WORD SwitchOption2;

   // Additional names (probably like a hint).
   local int i =0;
   for (i = 0; i <  AdditionalNamesCount; i++){
        OPTION_STR Option;
        if (ReadUShort() == 0xca54)
            WORD OptReserved;
   }

   // Look for a magic
   local int Find20h = 0;
   while(!Find20h){
        Find20h = (0x20 == ReadByte());
        BYTE Res;
   }

   GAME_WSTR GameId;
   WORD Reserved;

   // Sometimes there is an additionnal name
   // sometimes not. I check the current entry
   // is at less than the EntrySize declared.
   if (FTell()-StartAddr < EntrySize)
   {
       switch (SwitchOption2)
       {
       case 3:
            OPTION_STR Option3;
            break;
       case 2:

            OPTION_STR Option2;
       case 1:
            break;
       }
    }

} ENTRY <read=ReadGameName>;

string ReadOption(OPTION_STR &Game)
{
    local wstring GameName = L"";
    local int i ;
    for (i= 0; 2*i < Game.ByteLen; i++){
        WStrcat(GameName, Game.RawString[2*i]);
    }
    return WStringToString(GameName);
}

string ReadGame(GAME_WSTR &Game)
{
    local wstring GameName = L"";
    local int i ;
    for (i= 0; 2*i < Game.ByteLen; i++){
        WStrcat(GameName, Game.RawString[2*i]);
    }
    return WStringToString(GameName);
}

string ReadGameName(ENTRY &Entry)
{
    local string GameName = ReadGame(Entry.GameName);
    local string OptionGameName = "";
    if (Entry.AdditionalNamesCount)
        OptionGameName = " : "+ReadOption(Entry.Option);

    return GameName + OptionGameName;
}

//------------------------------------------
LittleEndian();
Printf("Parse KnownGameList.bin Begin.\n");
HEADER UnkwownHeader <bgcolor=cLtGray>;
while(1)
{
    ENTRY Entry <bgcolor=cLtPurple>;
    //Printf("Entry : %s -> %d.\n",ReadGameName(Entry) ,Entry.AdditionalNamesCount);
}
Printf("Parse KnownGameList.bin End.\n");

If that behavior annoy you, you can always globally disable it by setting the ShowStartup registry key to 0. It is located in HKEY_CURRENT_USER\Software\Microsoft\GameBar.

I haven't found how to disable specifically an executable from triggering it, but I might be possible just by looking at the machine code in twinui.

Security matter

We have a situation where we can launch a process just by changing the name of an executable. That might be dangerous.

The game launcher command line is located in HKEY_LOCAL_MACHINE\Software\Microsoft\GameOverlay which needs admin level to write into, so there is not UAC or Integrity level bypass possible here.

(I did not found an authorative link from the msdn, so here a SO answer confirming it : What registry access can you get without Administrator privleges?)

Community
  • 1
  • 1
lucasg
  • 10,734
  • 4
  • 35
  • 57
  • 3
    This... this is... they didn't even bother... I don't know what to say. Any application named "Runner.exe" or "Everything.exe" (so it affects the search tool) is affected by this popup you can't disable BTW. – Gabriel Morin Jun 21 '19 at 21:40