Wednesday, August 30, 2017

Policy Plus - Download ADMX Files for non-included languages

A couple weeks ago, an issue report was filed on Policy Plus stating that the Download ADMX Files feature was unable to move the ADMX files. Today I discovered that the user account this was happening on was set to en-GB (with pt-PT probably the system language). The ADMX package from Microsoft only includes a few common ADML languages, but Policy Plus always attempts to move the ADML subfolder named the same as the current culture. If the current culture's code isn't an included subfolder, that fails.

The solution was to first check that the ADML subfolder exists, and if it doesn't, just fall through to the English files. Language-related bugs are one of the perils of developing only on an English system.

The fix is live on GitHub.

Friday, August 25, 2017

Output of formatting cmdlets is not suitable for use as the represented object

New PowerShell users sometimes get confused between an object and its textual, formatted, on-screen representation. PowerShell provides a handful of formatting cmdlets (those with the Format verb), whose output can be much more informative than the default stringification. Of course, formatting an object still creates a string, which is not the same as the original object even if it prints identically. Even putting a string through a formatting cmdlet might get extra whitespace onto it that can confuse other cmdlets. Format-Wide with -Property does this, for instance.

Tuesday, August 22, 2017

Policy Plus - Antivirus false positives

I noticed yesterday while downloading Policy Plus in a VM for testing that Edge's (and/or Windows's) SmartScreen check marked the EXE as malicious. Surprised, I uploaded the file to VirusTotal, which informed me that one engine (SentinelOne) considered it bad. There was an automated comment from PayloadSecurity with a link to an an also probably automated analysis report.

The report listed a handful of "suspicious indicators", all of which are confusing to me. "Reads the active computer name" and "Reads the cryptographic machine GUID" are listed, but Policy Plus does neither, at least not directly; it's conceivable that the .NET Framework does them for some reason. The "Tries to sleep for a long time" section notes that it tried to sleep for 1566804069 milliseconds, but that's over 18 days, and Policy Plus doesn't intentionally delay at all except when waiting for some other relevant operation to complete, which should take at most a couple minutes, not days. "Reads information about the supported languages" makes more sense, since it does consider the current language for ADML management purposes.

More concerningly, the report alleges that Policy Plus contains the ability to listen for incoming connections, but in reality the program has no remote control or network server features whatsoever. The closest it has is the ability to download a setup package from Microsoft to get the newest ADMX files. The report says it contacts one host, but the IP given resolves to a handful of things under googlevideo.com and gvt1.com, both of which seem to be controlled by Google. I don't know why Policy Plus would ever contact a Google server, because there's nothing in the code to do anything like that.

All in all, the report is baffling to me - if it weren't for the screenshot, extracted strings, and assembly information I'd think they got the wrong file. I filed a SmartScreen false positive report with Microsoft and am waiting to hear back.

Monday, August 21, 2017

FMod - WPF surrender

After considering all the advantages and disadvantage of Abiathar's WPF transition adventures, I decided today to revert the Abiathar code base back to before any of the WPF changes. While it would be nice to get the speed boost from a complete conversion, a lot of the Abiathar internal structure is based (directly or indirectly) on graphics working in immediate mode, which is simply not the case with WPF. The current speed is good enough on modern machines, and there are much more interesting advancements to be made than rendering finagling. So for now, I'm sticking with Windows Forms and GDI+.

Sunday, August 20, 2017

Classic Windows Backup is interrupted by hibernation

A month or so ago, I looked into getting a full automated backup for my Windows 10 computer. The clearly recommended choice from the OS is the new Backup section in the modern Settings app, but it didn't seem to want to back up all the folders I specified. Some got backed up and I could see them on the target volume, but others just weren't copied. So I went for the classic Windows 7 Backup and Restore, accessible from the non-immersive Control Panel. That appeared to run as I wanted.

Since my machine has a lot of space used, backup takes quite a while, especially the system image phase. I don't like to leave my machine on overnight, and it's rare for me to stay up late enough for the whole image to finish. I regularly hibernate the machine, but I found once I brought it back into wakefulness that the backup was considered cancelled. That appears to be the major downfall of this strategy - the computer must remain on for the system image to be taken.

Saturday, August 19, 2017

Dangerous commands in Bash on Ubuntu on Windows can affect the host

One user wondered whether it was possible for dangerous commands run inside a Bash on Ubuntu on Windows prompt to affect the Windows system. It is possible, because there are mount points to the host file system. For example, /mnt/c goes to the Windows C volume.

I ran a little experiment to see how much a command inside WSL could damage the host. In a Windows 10 VM's Bash prompt, I ran the system-destroying sudo rm -rf / --no-preserve-root. After it finished, Linux was broken and all the test Windows user's personal files and folders were deleted, but the Windows system itself was still fine. Then I rolled the VM back to before the command and tried it again, but with Bash run as administrator. This time, more Windows files were deleted, and after a reboot, the VM bluescreened with CRITICAL_SERVICE_FAILED.

Clearly, dangerous commands inside WSL can damage the host Windows system. Untrusted code shouldn't be run inside the Bash prompt.

Friday, August 18, 2017

What does the SuperHidden Registry value control?

There is a value called SuperHidden under this Registry key on some versions of Windows:

HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced

It's reminiscent of Hidden (which controls whether the user sees hidden files in Explorer listings) and ShowSuperHidden (which controls whether the user sees system files in those listings). One might wonder what SuperHidden controls.

And the answer is... nothing! Using Process Monitor, I observed I/O to it and found that it only gets written when the View tab of Folder Options is shown. It's never read, even when Explorer is starting, so it can't control anything. So why is it there?

Investigating the stack provided by Process Monitor led me to shell32.dll, which issues a write to that value in CachedShellState::SaveAdvancedSettings. The corresponding function CachedShellState::_GetAdvancedSettings, however, issues a read from ShowSuperHidden, the value that actually does something. I also noticed that on Windows 10, the inert SuperHidden doesn't exist, and sure enough the Windows 10 version of shell32.dll writes to ShowSuperHidden.

Therefore, I strongly suspect that the existence of SuperHidden was a typo that was later corrected.

Based on my Super User answer.

Thursday, August 17, 2017

NTFS permissions to allow users to create their own home folders

In Active Directory environments, it's common to give each user a home folder where only the owner of the folder can work with the contents. The "Active Directory Users and Computers" tool can automatically set a user up with Full Control of their assigned home folder, but it's also possible to make a folder under which newly created folders will automatically be made home-like.

First, disable inheritance on the topmost folder and do not copy inherited entries. Then add these access control entries:

  • Allow SYSTEM full control over "this folder, subfolders, and files"
  • Allow Administrators full control over "this folder, subfolders, and files"
  • Allow Users "list folder contents", "read & execute", and "read" on "this folder only" (or "this folder, subfolders, and files" if you want everyone to have read access to each others' stuff)
  • Allow CREATOR OWNER full control over "subfolders and files only"
  • Allow Users "create folders / append data" on "this folder only"
The last entry is what allows users to create their own folders, while the second to last is what gives them full control over the contents.

Wednesday, August 16, 2017

Stopping an ASP.NET site with only FTP access

I recently needed to stop an ASP.NET web applications so that I could upload a new version of some pages. I only had FTP access, which couldn't overwrite the files because they were in use (by the web server process). Fortunately, there is a way to shut down dynamic ASP.NET requests with just FTP. Placing a file named App_Offline.htm in the site root will cause new requests to be blocked, while existing ones will continue. Once they all finish, it should be possible to update the ASP.NET page files. Removing App_Offline.htm will bring the site back to normal.

Tuesday, August 15, 2017

Policy Plus - Documentation adjusted

In the past couple months, I've introduced a handful of new code files to the Policy Plus repository, but had neglected to update the components list to include them. Today I scanned through the list of files and briefly explained each new one.

I also updated the main README file that gets shown to everyone who views the repository. It now includes a "Quick intro" page that explains how to get started. The most important part is the notice that Policy Plus does not save POL-backed sources automatically; the user has to use the Save Policies menu item (or press Ctrl+S).

Monday, August 14, 2017

Policy Plus - REG files from Edit Raw POL

I previously implemented the import and export of REG files in accordance with this feature request. That request also suggested that the import/export features be usable from the Edit Raw POL dialog, which makes sense because that dialog shows Registry paths while most other UI parts don't.

So today, I adjusted the Edit Raw POL window to include Import REG and Export REG buttons. If a key is selected, the export dialog defaults to exporting only that branch. The import button just offers the import dialog and refreshes the list view if the import happens.

These changes are live on GitHub: round 1 and round 2.

In other news, I figured out how Policy Plus suddenly got >50 stars - ghacks.net published a very nice article on it!

Sunday, August 13, 2017

Policy Plus - Import/export REG

Today I continued working on the REG import/export feature for Policy Plus. First I wrote the Save method for RegFile, which does its best to produce the exact same results as the Registry Editor. I haven't yet managed to make it linebreak hex strings identically, but that doesn't appear to be a problem.

Then I wrote the Apply method, which is very simple, but with one downfall. The REG format doesn't have a way to express "clear this key" without blowing away the entire subtree. Therefore, it's possible that Policy Plus and the Registry Editor will disagree about what a given REG does, but I'm not aware of any policies that delete a whole tree - key clearance is only used for lists, whose keys don't have subkeys.

To make use of all this new code, I added Import REG and Export REG menu items to the main form. They put up a respective dialog prompting for some settings before performing the import or export. Both ask for a filename and a prefix (so that hive-relative policy Registry entries can be exchanged with absolute Registry paths), but the exporter also allows the user to specify a branch to export. All this appears to work, but I'd like to put it through some more testing before publishing the changes.

The next step (aside from testing) is to add Import and Export buttons to the Edit Raw POL dialog.

Saturday, August 12, 2017

Policy Plus - REG loading

A Policy Plus user filed an issue requesting a new feature: the ability to import and export REG files. That sounds pretty useful to me - users might have created Registry files that they would like to import into a real policy object. (There are a bunch floating around the web, for example.)

So today I started implementing REG support. I created a RegFile class that can load REG files and that implements just enough of IPolicySource to be the target of a PolFile application. Since the user might not want to export the entire policy Registry, RegFile ignores set commands that do not apply to a previously specified branch.

Since I have not yet finished writing that class - saving is still a to-do - the changes are not yet pushed. I'll hopefully get that done tomorrow.

Viewing which users have a UWP app installed

Occasionally Sysprep will fail with an error indicating that an application package is installed for one user but not provisioned for all users. In some cases, this can be fixed by removing the app from those user profiles or by removing those users. To see which users have it, you can use PowerShell. Get-AppxPackage -AllUsers produces one record for each app, each of which has a PackageUserInformation property listing the package's status for each user (e.g. Installed or Staged).

Thursday, August 10, 2017

FMod - Some WPF repair

I spent some time cleaning up the WPF mess from the last tinkering. By resizing a Rectangle inside a Canvas when the level is changed, the horrible stretching/squishing is avoided. By applying render transforms to that Rectangle, zoom and panning works as before. That all applies to the tileset too, though for some reason there are faint undesired gridlines on the palette until it's refreshed. The speed isn't quite so bad as before, but it's still pretty bad - editing a tile takes several seconds, during which a CPU core is pegged. That's probably because I can't find a way to redraw just one tile using a DrawingGroup; the whole plane gets invalidated. The only thing that's faster is the movement of a paste preview plane, which works quite nicely here.

Nevertheless, it's obvious now that WPF isn't just a drop-in replacement for GDI+; it requires architecting and understanding that I do not currently have. It's very likely that I'll roll back to before the rendering rewrite.

Wednesday, August 9, 2017

Floating-point types in the P/Invoke tool

Even though I'm not aware of any standard Win32 API functions that take floating-point values, it would be good to support such data in my P/Invoke command-line tool. That turned out to be pretty simple: just adding single and double kinds mapped to the appropriate .NET types did the job. The .NET marshal already knew how to transfer those types, so such values can be serialized and recovered successfully.

Tuesday, August 8, 2017

Write to slot offsets in the P/Invoke tool

My P/Invoke command line tool's copyslot instruction already had a way to take one field or offset from a source slot, but there was no way to set just one field of a block. Today I added symmetry to that instruction by allowing the destination slot to also accept field or offset keywords. One field of one block can be copied to a field in a different block, or a non-block slot's value can be set into a field of a destination block.

Monday, August 7, 2017

More improvements to the P/Invoke tool

Though I can't bring to mind a specific Windows API task that requires it, it might occasionally be necessary to dereference a received pointer multiple times. The current slot functionality provides for one automatic wrapping and unwrapping, but there was previously no way to manually take a pointer stored in a slot and put the data there into another slot. So today, I extended the copyslot command to add a dereferenced mode that interprets the source slot's value as a pointer and returns the data there.

newslot block somePtr = blockptr(int 8); 
newslot int target; 
copyslot target = somePtr dereferenced; 
readslot target

As expected, that produces 8.

I also adjusted the parser a bit to not crash unnecessarily when a line is blank.

Sunday, August 6, 2017

FMod - WPF failure

I spent most of today moving Abiathar's rendering system from GDI+ to WPF. Mostly that involved changing uses of Bitmap to BitmapSource and uses of Graphics to DrawingContext, with appropriate adjustments to method calls. I changed the three main viewer panels to element hosts with a Rectangle inside to be the WPF display. Event handlers had to be manually wired up, and the event objects changed somewhat. There are still a few commented-out parts that are noncritical but really hard to migrate, but I did get it to build and run.

Currently, it's a mess. The image is always stretched to fill the whole viewport without scrolling, but I'm sure that can be corrected by nesting the Rectangle inside some other element. More importantly, it's super slow, at least 10x slower than previously, almost certainly even slower than Abiathar v1.0. This can probably be fixed too, but it's clear that WPF isn't as straightforward as I was hoping.

Saturday, August 5, 2017

FMod - WPF investigations

Abiathar's graphics performance is bottlenecked by GDI+, which is apparently implemented entirely in software. Rerendering all planes every time the viewport moved is horribly slow, so since the beginning Abiathar has kept each plane's image cached. More recently, the rendering of tile planes was rewritten to use raw byte manipulation rather than GDI+. Unfortunately, Abiathar still isn't as fast as I would like - it shouldn't take a big machine to comfortably navigate some simple 2D graphics.

Windows Presentation Foundation graphics are hardware-accelerated, unlike Windows Forms. Rewriting Abiathar in WPF would be a huge task, and probably not worth it, but it's possible to embed WPF controls in WinForms. There are just a couple controls that are problematic - the level and tileset viewer panels - so replacing those should improve performance. There is rather a lot of infrastructure dedicated to rendering that is tied to the GDI+ way of doing things, so while the changes wouldn't be a complete rewrite, they wouldn't be trivial either.

So today I started a feasibility investigation to see how doable it would be to move to WPF for rendering. Starting small, I changed the selected tile images to be rendered with WPF. That involved creating a drawing context and converting the GDI+ bitmap to a WPF bitmap source On my first attempt, the selected tiles showed up, but were fuzzy due to the 2x scaling. After much Googling, I discovered I needed to set the bitmap scaling mode on the drawing context. Then I noticed that no key-down events were seen by the main form anymore. Apparently ElementHost doesn't respect KeyPreview, so one of the new controls was eating all the key events. With help from Stack Overflow, I switched to a custom control derived from ElementHost. (That code needed to be slightly adjusted to always pass the arrow key presses on.) And then I saw that the mouse clicks were not delivered to the selected tile images, even though I wired up event handlers on the host controls. Handling the event on the WPF control hosted inside worked, though.

So far, it seems doable to change the graphics over to WPF. I will continue this effort for now. If for some reason it doesn't help performance, I'll just roll back to before I started messing with it.

Friday, August 4, 2017

Convenient inclusion of a block's size for the P/Invoke tool

Quite a few structures passed to Windows API functions have their own size as a field. I could just have the user of my P/Invoke command-line tool figure out the size in bytes and supply that manually, but that gets difficult for large structures. Besides, when there are pointer-sized fields in play, the lengths will be different between bitnesses. So today, I added a keyword that, in parameter lists, gets replaced with the size of the structure once all the rest of the parameters are processed.

While testing that, I realized that's it's really inconvenient to be required to specify in (units) before as (type) when expressing a length. So I adjusted the function responsible for parsing those to take them in either order and allow as to be supplied on its own.

newslot block withSize = blocksize as int, ulong 1, ulong 77; 
newslot int theSize = 0; 
copyslot theSize = withSize field 0; 
readslot theSize

That returns 24 (not 20, because of alignment requirements).

Problems passing arguments to programs from PowerShell? Use Start-Process

When running a program from PowerShell in the classic batch-like way - putting the program and its arguments plainly on a line - you might run in to trouble with characters that need escaping or quoting. PowerShell likes to interpret some characters as syntax directed at itself rather than as part of the command line for the new process. Attempting to quote problematic portions to stop PowerShell from parsing them may lead to undesirable quotes ending up in the command line.

A better solution is to use Start-Process, supplying one string with the command line to -ArgumentList. Since Start-Process is a cmdlet, it's very clear to PowerShell that it shouldn't mess with the syntax; the command is passed directly to the program.

Wednesday, August 2, 2017

There may be multiple layers of command-line processing

Most shells have some kind of escaping mechanism, so when they run programs, the command line to those programs is processed slightly from what the user typed at the original prompt. At least on Windows, the launched process just gets its command line as one big string and it's up to the application to parse it into individual arguments. When trying to figure out why a program isn't comprehending its arguments as intended, it's important to understand all the layers of processing.

On Windows, you can use PowerShell to test one layer. This command prints the command line given to powershell.exe without any extra processing; it reflects how the calling process adjusted the user input:

powershell -c [environment]::commandline # text to test here

Since the octothorpe comments out everything after it, PowerShell just runs the command that prints to the command line, which includes the text after the comment.

Tuesday, August 1, 2017

Predefined slots for the P/Invoke tool

I previously added a lasterror command to my P/Invoke command-line tool that prints the last Win32 error to the screen, but that's not very helpful if the last error needs to be used in a call. Since getting the last error is a very common thing to do when troubleshooting, I introduced an automatically defined slot for it, which is updated after every call.

It might be useful for some scripts to have the parent process's ID (say, a different program was invoking this tool to do something to itself). Getting that information is hugely inconvenient without WMI, which is hugely inconvenient to use in native code. So parentpid became a predefined slot as well. pid (the current process's ID) was added to match.

The addition of parentpid allows for scripts like this one, which enables SeRestorePrivilege on its calling process:

call kernel32.dll!OpenProcess /return native /into prochandle (int 0x400, int 0, slotdata parentpid); newslot native token;
call advapi32.dll!OpenProcessToken /return int (slotdata prochandle, int 0x20, slotptr token);
newslot block luid = int 0, int 0;
call advapi32.dll!LookupPrivilegeValueW /return int (nullptr, lpwstr "SeRestorePrivilege", slotptr luid);
newslot block privs = int 1, slotdata luid, int 2;
call advapi32.dll!AdjustTokenPrivileges /return int (slotdata token, int 0, slotptr privs, slotsize privs as int, nullptr, nullptr)