Live data from Hacker News

Any sufficiently advanced uninstaller is indistinguishable from malware

devblogs.microsoft.com

511–520 of 556 posts

Re: Any sufficiently advanced uninstaller is indistinguishable from malware

#511
post #471

Earlier quoted context omitted.

The result of inspecting such a file is usually a series of disgusted shudders, "this will do WHAT do my machine"?

Sometimes a smile at the clarity and simplicity of the authors shell code, sometimes.

A rare delight but it does happen

Re: Any sufficiently advanced uninstaller is indistinguishable from malware

#512
post #151

Earlier quoted context omitted.

While a process still has an unlinked file open, /proc/ /fd can be used to obtain a handle to the file so that you can mess around with it.

You're suggesting opening every single FD of every single process (which might not even point to a file, let alone a file on that volume) and querying it just to do this? I mean, sure, I guess that's usually not physically impossible (unless e.g. /proc is unavailable/unmounted)... but it's clearly a hack. In fact, I think it's not just a (slow!) hack, but a buggy one too. Every time you open a an object that doesn't…

No I'm just saying it's possible. I can count on the fingers of 0 hands the number of times I've needed to do this to edit a deleted file out from under a process that has the only reference to an unlinked file open so at least in my experience it's merely acadamic knowledge!

Re: Any sufficiently advanced uninstaller is indistinguishable from malware

#513

Earlier quoted context omitted.

There are plenty of other solutions; that was merely one straightforward option that could be shown in a few lines of code and which doesn't require *injecting code into a binary you don't own*.

Sure, but there isn't even an offhand remark about how hacky this kind of polling is. It's presented as if it's a completely normal way to do things in reliable software.

No worse than the 10 minute delay rule in DllCanUnloadNow.

DllCanUnloadNow returns an indication that a DLL can be unloaded. A DLL cannot be unloaded if any threads are executing the code. But a DLL can only change to the unloadable state by executing some code, and that code has to return after it has set the indication. Only after it returns is the DLL is actually unloadable! So a delay is needed for that thread to vacate the DLL.

https://groups.google.com/g/microsoft.public.vc.atl/c/AQvHCW... [2001]

Re: Any sufficiently advanced uninstaller is indistinguishable from malware

#514

Earlier quoted context omitted.

Sure, but there isn't even an offhand remark about how hacky this kind of polling is. It's presented as if it's a completely normal way to do things in reliable software.

No worse than the 10 minute delay rule in DllCanUnloadNow. DllCanUnloadNow returns an indication that a DLL can be unloaded. A DLL cannot be unloaded if any threads are executing the code. But a DLL can only change to the unloadable state by executing some code, and that code has to return after it has set the indication. Only after it returns is the DLL is actually unloadable! So a delay is needed for that thread to…

So in the present example from Raymond Chen you need the loop for a similar reason.

The binary .exe program which the script is trying to delete is the one which created the script and launched it. So that means the .exe is still running at that point and cannot yet be deleted. Lauching the script indicates "I'm about to die", not "I'm already dead". The script cannot delete the .exe until the .exe terminates. Without some event to indicate that, you poll.

The script knows it can delete itself, so it tries that only once.

If a handle could be attached to the process, then the script could do a WaitForSingleObject on it; that would be the prim and proper way.

It doesn't seem worth doing; the chances are low that the process cannot terminate within 20 seconds of launching the reaper script.

Re: Any sufficiently advanced uninstaller is indistinguishable from malware

#515
post #9

I had never heard of detours before, but I guess it isn’t any different that a good old fashioned LD_PRELOAD

it's a little more general, I think, since one common use case for it is to use it on your own process in order to intercept calls to stdlib/OS code from libraries you don't control. For example, in the bad old days I used detours to virtualize the windows registry so that I could do "fake installs" of COM components inside of a VB6 app, allowing it to run without an install and without administrator permissions. Thi…

> it's a little more general, I think, since one common use case for it is to use it on your own process in order to intercept calls to stdlib/OS code from libraries you don't control.

This capability is intrinsic to how ELF linking works. The main application or even any library can interpose a libc function just by defining and exporting a function with the same name, and that definition will be preferentially linked in both the main application and all subsequently loaded dynamic libraries and modules. Your definition can then use dlsym(RTLD_NEXT, "foo") to obtain a function pointer to the next definition, which would normally be libc itself but may be from another library. A running application could actually have several implementations of a function, all proxying calls onward until the terminal (usually libc) implementation.

Basically, the way ELF linking works by default is that the first definition loaded is the preferred global symbol used to satisfy any symbol dependency with that name. It follows that there's normally a singular global symbol table. Though there are features and extensions that can be explicitly used to get different behaviors.

There's nothing magical about LD_PRELOAD within the context of ELF linking. LD_PRELOAD support in the linker (which is the first bit of code the kernel loads on exec(2)) is very simple; all the linker does is load the specified libraries first, even before the main application, so symbols exported therein become the initial and therefore default definition for satisfying subsequent symbol dependencies, including in the main application binary, and even if the main application binary also defines and exports those symbols.

All of this is basically the exact opposite behavior of how PE linking works on Windows, for better and worse--depending on your disposition and problems at hand.

Also note that all of this is different than so-called "weak" symbols, which is a mechanism for achieving one of the same behaviors--overriding another definition--when statically linking. Otherwise, when statically linking, multiple definitions are either an error or it's difficult (i.e. confusing, especially in complex builds) to control when and where one definition is chosen over another.

[1] Though main application symbols aren't usually exported by default, so you need to explicitly mark a definition for export or build the entire main binary with a compiler flag like `-rdynamic`, which is the main binary analog to the `-shared` flag used for building shared libraries. The Python and Perl interpreters, for example, are built with -rdynamic as the interpreter binary itself exports all the implementation symbols required by binary modules, rather than defining them in a separate shared library against which modules explicitly link themselves against at compile time. (This is also why when building Perl, Python, and similar language modules you have to tell the compile-time linker to ignore unresolved symbols.)

Re: Any sufficiently advanced uninstaller is indistinguishable from malware

#517

Earlier quoted context omitted.

A VSCode extension would be installed and managed by the OS package manager. User created content would be not.

Really? Do you install Firefox extensions from apt-get?

Yes, there are a few that can be installed from the Debian packages.

Re: Any sufficiently advanced uninstaller is indistinguishable from malware

#518

Earlier quoted context omitted.

I see no reason not to allow this. That's why people at Microsoft made those decision and not you. The most obvious reason would be to use the executable itself to back the memory which the comment you replied to already hinted at. Instead of loading the entire executable into memory on application start, you just create some memory mapping entry. As the code executes and accesses different parts of the executable, t…

I think maybe you should familiarise yourself with how e.g. ext4 works. You can unlink a file and have a process still hold a reference to the inode. This allows you to continue reading (or executing) a file which may not have been fully mapped yet even after its last filesystem reference is gone. There really isn't that much of a good reason to disallow deleting the files (assuming NTFS is capable of supporting a si…

1. I know how Ext4 works in this case, and I don't care.

2. I already explained how I would like the system to respond. Ext4 or any other filesystem have nothing to do with it.

3. Processes don't hold references to inodes. That's nonsense (simply because there's no such thing as a "reference to inode" in any system interface). Process doesn't get a reference to the file from which its executable code is loaded at all (unless you count the first argument -- but that's the file's name, not the file). Who put this idea in your mind I don't know... and any filesystem, be it Ext4 or anything else has no role to play in this. Now, the loader may decide to store the inode of a file or not -- yeah, whatever. A filesystem may even decide to change the inode of an existing file, if it so wants -- since there's no system interface that relies on inodes, it's all a fair game. For example, Shell will usually read the text of a script it's executing a block or maybe even just a line at a time. If you modify the file during its execution, it's usually going to cause syntax errors, but, if you are lucky, you can even write self-modifying programs in Shell. Now, will Shell perform like this if inode changes? -- Knowing Linux tools, I'd say, probably not. Will probably fail in some spectacular way. But do I care? -- Nope. I want this power to delete the executable file as it's being executed. I see no reason not to have such power.

Re: Any sufficiently advanced uninstaller is indistinguishable from malware

#519

Earlier quoted context omitted.

I had a friend who worked for a company that specialized in Web browser bars and MSIs. In other words, they were a shop to put all kinds of malware into these things. It was a viable business model for a company of something like 50 people. The whole story and ideas put into Windows installing programs are a stupid joke. It's designed by project managers who have no idea what they are doing and no imagination and is…

A lot of weird things in windows are reflections of the gestalt in the 90's and early 2000. People went all in on all sort of OOP-derived weirdness, like CORBA, COM. "Plain-Text files for configuration? what do you think we are? savages? no, we need a hierarchical registry! every serious program must use some opaque binary format to store stuff!" seem to be the general animus at that time. Nowadays, even if you reall…

Agreed re: some of the Windows "strangeness". I think there was some amount of needlessly "Enterprise" architecting going on at MSFT back in the day.

There were also very practical solutions incorporated to accommodate the constraints of the hardware of the time that come off looking like needless complexity today, too. (There's also, arguably, some laziness in the old binary file formats that were nothing more than dumps of in-memory structures. That's a common story across a ton of old software-- not just MSFT.)

Rob Mensching, who worked at Microsoft on Windows Installer pre-release, has a nice blog post about internals of MSI.[0] He goes into some of the overwrought architecture in MSI, as well as quirks to overcome performance limitations in a world of floppy disk-based distribution and much smaller memory capacities. It's a good read.

[0] https://robmensching.com/blog/posts/2003/11/25/inside-the-ms...

Re: Any sufficiently advanced uninstaller is indistinguishable from malware

#520
post #332

Earlier quoted context omitted.

I have very little respect to people at Microsoft when it comes to technical side of things. Whenever I have to deal with their "creations" it's like they were motivated by malice, or part of their frontal cortex gone missing. > The most obvious reason would be to use the executable itself to back the memory which the comment you replied to already hinted at. Imagine that I've already read that, and I still see no re…

Most users do not want a running program to corrupt / crash on them - even if they deleted the backing exe.

So what? I want it, and I see no reason not to let me have it. Linux was designed with this main goal in mind: let people take ownership of their computers and do whatever the hell they want with them.

If your Linux doesn't do it -- I don't care. I'll make my Linux do it. Because that's how I want it to work.

Post reply on HN