Some notes on Windows 11 Notepad

The new win11 version of Notepad accepts a few command line options that i have not seen documented anywhere (or only documented partially).

  • /A – forces Notepad to read the input file as ANSI
  • /W – forces Notepad to read the input file as WIDE (Unicode 16LE)
  • /.SETUP – tells Notepad it was launched by the Installer; AFAICT running Notepad with this option literally DoSes it
  • /.SETUP <filename> – same as above except we try to open the file <filename> — still DoS though
  • RestartByRestartManager:<GUID> – mentioned by @nas_bench here – used to restore some of the AutoSaved documents; the information is saved under HKCU\Software\Microsoft\Notepad\Autosave\GUID in a form of three coma-separated values f.ex.:

so analyzing this key and its children may have some DFIR value, potentially.

The first value is a code page (0,1=ANSI; 2,3=Unicode LE/BE; 4,5=UTF8 with or w/o BOM, 6=Chinese), second is probably a document path, and the third is a working directory. These all need to be confirmed as I am making quick&dirty assumptions here.

Launching c:\windows\notepad.exe under xdbg makes the old-fashioned Notepad window appear, with a banner encouraging the user to launch the new version of Notepad (Microsoft app):

This behavior is a bit unexpected and am wondering if it could be somehow abused.

The Launch button executes the so-called Centennial version of Notepad located here:

%LOCALAPPDATA%\Microsoft\WindowsApps\Microsoft.WindowsNotepad_8wekyb3d8bbwe\notepad.exe

In some circumstances a file probe.autosave may be created by new Notepad.

The info about currently opened tabs seems to be stored in this folder:

C:\Users\<USER>\AppData\Local\Packages\Microsoft.WindowsNotepad_8wekyb3d8bbwe\LocalState

and there (already) is a library for parsing these.

Launching notepad.exe leads to Windows App being executed, because of these new settings in the Registry:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe\0
AppExecutionAliasRedirect = 1
AppExecutionAliasRedirectPackages = *
FilterFullPath = C:\Windows\System32\notepad.exe

Changing the value of AppExecutionAliasRedirect from 1 to 0 will bring the old Notepad back. And lo and behold, there is a ‘legitimate’ way to disable new Notepad too – the Advanced App Settings allow us to disable the so-called Windows Apps aliases:

Once you disable the Notepad alias, the old Notepad will return. And if you want to disable that annoying banner showing up in this old Notepad you can add the following Registry entry:

HKCU\Software\Microsoft\Notepad
ShowStoreBanner (dword) = 0

And with that, we are back to the good ol’ Notepad version we all love 😉

The Windows 11 changes are very interesting from the DFIR perspective. Many old programs we took for granted (for decades!) are now exhibiting new behaviors that need an additional research effort. This is actually quite exciting because we all want to close cases in a conclusive way and knowing how to interpret the superset of all forensic artifacts is of a paramount importance…

Going reverse on reversing tools…

One of the oldest and most popular reversing tools is IDA Pro (usually bundled with its multiple decompilers&plug-ins). Over the years, the creators of this tool introduced a lot of substantial changes to this software, and in parallel, a lot of changes have been introduced to the programming frameworks newer IDA Pro versions rely on (namely, Python).

I bet some old OG IDA Pro users and reversers still remember the time they spent writing their first IDC scripts… and I bet some younger OGs reminisce similar memorable moments and feels about their early idapython scripts based on Python 2.x. Unfortunately, with many changes introduced to Python and IdaPython over the years we now live in a world where multiple parallel IDA Pro universes exist. The world in which many very useful plug-ins, scripts that just… used to ‘work’… today fail to work and they do so miserably…

Over the last 10 years or so, I’ve spent a substantial amount of time trying to port many of these older IDA Python-based plug-ins/scripts to that ‘latest, newest version’ of IDAPython du jour. It actually takes a lot of time, and it’s mainly because I am not the best person to be tasked with this upgrading task, plus the frequent changes on so many fronts are really hard to keep up with, so… in many of these past instances where I actually tried, I often did end up just throwing a towel in the end… It’s just not worth it, and I must say here that I have arrived at this sad conclusion on more than just one occasion…

BUT I STILL LOVE SOME OF THESE OLD PLUG-INS!

Then one day it hit me.

The answer to all our IDA Plugin code incompatibility problems is… keeping multiple IDA Pro versions installed at the same time! And then, using an appropriate IDA Pro version for which these plug-ins or scripts were created for – run them, collect their output and… incorporate this output into our ‘working’ IDA database, typically created by ‘the latest and greatest’ version of IDA.

It may sound stupid, but it actually does work quite well!

Today I temporarily install older IDA Pro versions on my test malware box on regular basis — they are often a few years old, totally obsolete, but they offer one important feature to me – they still run that specific old plug-in/script code for me!

How does it work in practice?

In generic terms, you just install the old version of IDA, open the sample you are working on in that old IDA version, and then you run the actual code (plug-in or script) that this particular IDA Pro version supports. After that, you export the IDC script from the database (File -> Produce File -> Dump database to IDC file). Then you edit that exported IDC script to only call out to the functions or snippets of code that introduce changes you want… Then you import it into your ‘current’/’working’ IDA database….

And yeah, at first sight, this exported IDC script may look messy, but it’s easy to navigate, plus we can quickly notice that we can comment out all the unnecessary function calls inside its main function, and then we just focus on the functions we really want to execute – some of them adding structures, enums, naming locations, adding comments, etc.

The main function of a typical IDA-exported IDC script looks like this:

static main(void)
{
        // set 'loading idc file' mode
        set_inf_attr(INF_GENFLAGS, INFFL_LOADIDC|get_inf_attr(INF_GENFLAGS));
        GenInfo();            // various settings
        Segments();           // segmentation
        Enums();              // enumerations
        Structures();         // structure types
        ApplyStrucTInfos();   // structure type infos
        Patches();            // manual patches
        SegRegs();            // segment register values
        Bytes();              // individual bytes (code,data)
        Functions();          // function definitions
        // clear 'loading idc file' mode
        set_inf_attr(INF_GENFLAGS, ~INFFL_LOADIDC&get_inf_attr(INF_GENFLAGS));
}

Many of these high-level functions include call outs to similarly named, second-level functions – it’s actually really easy to follow and edit them. For example, if the main function calls out a Bytes function it’s most likely we will see it making call outs to multiple functions prefixed with the word Bytes:

static Bytes(void) {
	Bytes_0();
	Bytes_1();
	Bytes_2();
	Bytes_3();
	Bytes_4();
        end_type_updating(UTP_STRUCT);
}

You can quickly eyeball all of these functions’ bodies and decide which code/function call to comment out…

It usually takes less than 5-10 minutes to do so, and as a result you cherry-pick the exact metadata you want to import into your ‘working’ database (usually the one created with the latest available version of IDA Pro).

In the last few years I have used this approach many times, often during time-sensitive malware analysis engagements, and am happy to report that it does work quite well.

Aka: don’t fight the system, use it.

The other avenue to pursue here is to introduce subtle, cosmetic modifications to the old plug-ins’ code that you can modify to generate a code that is ‘compatible’ with the most up-to-date version of Ida and its IdaPython modules.

We can do it, because the output of many reversing IDA Python scrips is pretty predictable:

  • new names
  • new labels
  • new comments
  • list of offsets for code/data patching and actual patches
  • extracted / decrypted configs, strings
  • etc.

It’s actually very easy to add small code snippets to the old plug-ins that will generate a precise list of instructions encoded using the latest version of IdaPython, then save them into a temporary IdaPython script file that is compatible with the latest and greatest version of IDA Python. Such dynamically generated code can be then executed within a context of the database opened with the latest version of Ida Pro. Easy Peasy.

The bottom line is this:

  • make multiple versions of your reverse engineering tools work for you