Creating a self deleting executable using .NET

P

PeterW

I am trying to create a GPS based warning system for speedcameras for the
Windows Mobile 5.0 (or higher) platform. One of the features of the
application is that it has an "erase" button that automatically closes down
the application and deletes the executable. This is because this type of
software is legally not allowed in all european countries (like switzerland)
and I want to give the user the option to remove the software before entering
such countries. It's essential that no trace of the software is left after
the erase.

I have been trying to find a technical solution for this feature but it has
proven to be much harder than I thought. The problem is that the physical
executable file is locked and can't be deleted as long as the executable is
running.

I found some quite interesting articles explaining the problem in more
detail and also explaining some possible solutions. An example of a very
usefull article on this subject can be found on:
http://www.catch22.net/tuts/selfdel

Unfortunately the solutions in the article require C++ and I am trying to
achieve a solution that will work in C#.NET. Is there anybody who
can help me a bit further with this problem ? Any help is appreciated.
 
P

Peter Duniho

PeterW said:
I am trying to create a GPS based warning system for speedcameras for the
Windows Mobile 5.0 (or higher) platform. One of the features of the
application is that it has an "erase" button that automatically closes down
the application and deletes the executable. This is because this type of
software is legally not allowed in all european countries (like switzerland)
and I want to give the user the option to remove the software before entering
such countries. It's essential that no trace of the software is left after
the erase.

Even ignoring the specific functionality of the application, that seems
like a needless feature to me. A regular uninstall should be able to
remove the program just as well. Just tell your users to use the normal
uninstall that's part of your program's setup.

Alternatively, just use the "RunOnce" registry key, and have the users
reboot as part of the deletion process (so that the command you add to
the "RunOnce" key can be executed...this presumes that "RunOnce" and
rebooting is supported on Windows Mobile, which I don't know much about).

Besides, the idea that the user will erase "all traces" of the software
also seems somewhat misplaced. A user using the software who just
happens to be traveling through some country where the software is
illegal isn't going to delete the software permanently. Presumably they
intend to reinstall at some later point, and they very well may keep a
copy on their person for that purpose (in case, for example, they
anticipate having trouble getting online).
I have been trying to find a technical solution for this feature but it has
proven to be much harder than I thought. The problem is that the physical
executable file is locked and can't be deleted as long as the executable is
running.

I found some quite interesting articles explaining the problem in more
detail and also explaining some possible solutions. An example of a very
usefull article on this subject can be found on:
http://www.catch22.net/tuts/selfdel

Unfortunately the solutions in the article require C++ and I am trying to
achieve a solution that will work in C#.NET. Is there anybody who
can help me a bit further with this problem ? Any help is appreciated.

It seems to me there are a number of "good" suggestions (inasmuch as the
idea is one needing solving, which is debatable :) ) in the article (and
some not-so-good...the "inject code into another process" idea is awful,
and probably won't work on any computer with DEP enabled).

In addition, generally anything you can do in C++, you can do in C#.
You may have to use p/invoke to access unmanaged Win32 features, but
otherwise it should work. I note that a number of the examples have an
asm block, but as near as I can tell for the most part that's just
obfuscation. You should be able to achieve the same results just by
calling the appropriate functions normally.

Of all those suggestions in the article, I would say that the
"DELETE_ON_CLOSE" method is probably the most convenient and reliable of
the various choices. It actually uses built-in, OS-supported API to do
the work rather than trying to hijack some other mechanism to do the
work. Best of all, there's nothing about it that requires you to be
running unmanaged code; you should be able to do the whole thing as
managed code.

Some modifications I'd make to the suggestion though:

-- Just write a stand-alone deletion application that you use to
create the temporary "DELETE_ON_CLOSE" file. Compile it, store it in
your main application's resource data, and then just write it out the
file at the appropriate time (it should be very small). (I see that
this is included as "an alternative method" at the very end of that
suggestion).

-- Don't mess around with the sleeping logic. Instead, use a
reliable inter-process mechanism for the main application and the
deletion application to communicate (e.g. named Mutex, sockets, pipe, etc.).

Of course, all this assumes this is actually a feature you should be
spending your time on. Honestly, it seems to me it's not. Just make
sure your uninstall works as it's supposed to and removes "all traces"
of the program. Then just tell your users to use that instead.

And tell your European governments that are putting up speed cameras to
do it the way other civilized governments do it: announce the locations
of cameras with signs. Then, the cameras serve more as an actual speed
control mechanism rather than a revenue-enhancement mechanism. That
way, you don't even need your application. :)

Pete
 
P

PeterW

The reason why I want to implement a self delete rather than letting the user
uninstall the application manually is that the last one is quite a cumbersome
process to do while you are driving. I want a big button on the touchscreen
that does the entire job automatically when pressed.

I have investigated if I can use the Delete_On_Close method but I got stuck
with that. I created a seperate helper executable that deletes my main
executable. This helper executable is loaded into the main executable as a
resourcefile. When I want to close down the main application and delete the
main executable, I write the contents of the helper executable to disk using
a filestream object. I specify the DeleteOnClose option so that the helper
executable is deleted as well.

So far everything works fine but..... When I close the filestream, the
helper executable is deleted right away (because of the DeleteOnClose
option). There is no chance starting the helper executable. If I try to start
the helper executable before closing the stream I get a message that the
process cannot be started because: "The process cannot access the file
because it is being used by another process"


Dim objWriteFileStream As New FileStream("F:\SelfDeleteFromResource.exe",
FileMode.CreateNew, FileAccess.Write, FileShare.Read, 1024,
FileOptions.DeleteOnClose)
objWriteFileStream.Write(My.Resources.SelfDelete, 0,
My.Resources.SelfDelete.Length)
objWriteFileStream.Flush()
System.Diagnostics.Process.Start("F:\SelfDeleteFromResource.exe") ==> this
line produces the error
objWriteFileStream.Close()

Aparently this works different in .NET than in the examples on
http://www.catch22.net/tuts/selfdel


I totally agree with your opinion about european governments. Unfortunately
it's not simple to do something about it. Cars (and everything associated
with them) have always been a revenue-enhancement mechanism. That's one of
the reasons why petrol costs 7,74 dollar/gallon over here. Cars are about
twice the price that the manufacturer asks due to the added taxes, and on
every corner there is a hidden speedcamera. :)
 
J

Jeff Gaines

The reason why I want to implement a self delete rather than letting the
user
uninstall the application manually is that the last one is quite a
cumbersome
process to do while you are driving. I want a big button on the touchscreen
that does the entire job automatically when pressed.

I don't know what sort of storage is in these devices but is deleting
enough anyway, or does the storage device need to be over-written several
times to prevent forensic recovery?
 
P

PeterW

Just a delete is sufficient.


Jeff Gaines said:
I don't know what sort of storage is in these devices but is deleting
enough anyway, or does the storage device need to be over-written several
times to prevent forensic recovery?
 
P

Peter Duniho

PeterW said:
The reason why I want to implement a self delete rather than letting the user
uninstall the application manually is that the last one is quite a cumbersome
process to do while you are driving. I want a big button on the touchscreen
that does the entire job automatically when pressed.

Admirable, but pointless IMHO. No, the user should not be messing
around with typing while driving. But frankly, that goes for a big
button on the touchscreen too. And it's not like they should be
surprised they are approaching a country where the application needs to
be deleted. They can either just wait until they are already stopped
for some other reason and uninstall, or they can pull over and perform
the necessary steps.
[...]
So far everything works fine but..... When I close the filestream, the
helper executable is deleted right away (because of the DeleteOnClose
option). There is no chance starting the helper executable. If I try to start
the helper executable before closing the stream I get a message that the
process cannot be started because: "The process cannot access the file
because it is being used by another process"

It sounds like you missed the part about keeping the file open using the
proper sharing flags, so that the new process can in fact open the file
for execution.

Pete
 
P

PeterW

I had hoped the "FileShare.Read" in the following line of code would do the
trick:

Dim objWriteFileStream As New FileStream("F:\SelfDeleteFromResource.exe",
FileMode.CreateNew, FileAccess.Write, FileShare.Read, 1024,
FileOptions.DeleteOnClose)

According to the documentation this flag controls if other filestreams can
access the file or not. FileShare.Read means that other filestreams can open
the file for read while the current process still has the file open.
Aparently this is limited to filestream objects only because it does not work
when you try to start an executable.

In the meantime I have been trying the use the unmanged code "CreateProcess"
as well but that does not work either. Probably the same problem because it
starts up notepad.exe fine but it does not start up the exe that was writen
to disk by the filestream object as described in my previous post.

Peter Duniho said:
PeterW said:
The reason why I want to implement a self delete rather than letting the user
uninstall the application manually is that the last one is quite a cumbersome
process to do while you are driving. I want a big button on the touchscreen
that does the entire job automatically when pressed.

Admirable, but pointless IMHO. No, the user should not be messing
around with typing while driving. But frankly, that goes for a big
button on the touchscreen too. And it's not like they should be
surprised they are approaching a country where the application needs to
be deleted. They can either just wait until they are already stopped
for some other reason and uninstall, or they can pull over and perform
the necessary steps.
[...]
So far everything works fine but..... When I close the filestream, the
helper executable is deleted right away (because of the DeleteOnClose
option). There is no chance starting the helper executable. If I try to start
the helper executable before closing the stream I get a message that the
process cannot be started because: "The process cannot access the file
because it is being used by another process"

It sounds like you missed the part about keeping the file open using the
proper sharing flags, so that the new process can in fact open the file
for execution.

Pete
.
 
P

Peter Duniho

PeterW said:
I had hoped the "FileShare.Read" in the following line of code would do the
trick:

Dim objWriteFileStream As New FileStream("F:\SelfDeleteFromResource.exe",
FileMode.CreateNew, FileAccess.Write, FileShare.Read, 1024,
FileOptions.DeleteOnClose)

Why? The page you referenced specifically says the file you write "must
also have the FILE_SHARE_DELETE flag specified". Why would you think
that FileShare.Read would accomplish that, as opposed to (for example)
the FileShare.Delete flag?
According to the documentation this flag controls if other filestreams can
access the file or not.

Actually, the documentation is more specific: it says that flag "allows
subsequent opening of the file for reading". Not any access; it
specifically controls read sharing.

Also, the page you referenced clearly explains that you need the
FILE_SHARE_DELETE flag, because the file is originally opened with the
DELETE_ON_CLOSE flag (FileOptions.DeleteOnClose in .NET).

It seems to me you want (in addition to other sharing flags that may be
necessary) the equivalent of the FILE_SHARE_DELETE flag, which I believe
is the FileShare.Delete flag.
FileShare.Read means that other filestreams can open
the file for read while the current process still has the file open.
Aparently this is limited to filestream objects only because it does not work
when you try to start an executable. [...]

I disagree with your conclusion. It's likely your code would work fine
if you hadn't also specified the FileOptions.DeleteOnClose, and given
that you are, you need to specify the proper sharing flag to allow that
to happen.

Pete
 
P

PeterW

Hi Peter,

Thanks for your reply. You are indeed right. In the code that I posted only
the FILE_SHARE_READ is specified but I also tried it combined with
FILE_SHARE_DELETE which does not work either.

I found an article on the web explaining that the second process that
attempts to open the file also needs to open it with the FILE_SHARE_READ +
FILE_SHARE_DELETE flag set. If this is not the case then the second process
will exclusively open the file and effectively block the first process from
reading the file, this is not allowed and therefore attempting to do so
generates an error. I assume that this is the problem I'm dealing with.

If you open a filestream it's easy to specify the FILE_SHARE_READ +
FILE_SHARE_DELETE flags, but when you try to start up a new executable from
within the code you can't specify these flags. Starting an executable will by
default try to generate an exclusive lock. That's at least what I think is
happening. I need to find a way around this problem.

Yesterday I was doing some further research and I found this article on the
web: http://www.codeproject.com/KB/threads/HowToDeleteCurrentProcess.aspx
It explains a solution for the self delete problem that is very simple and
straightforward. Just add two lines of code:

Start("cmd.exe", "/C choice /C Y /N /D Y /T 3 & Del " +
System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0).FullyQualifiedName)
Application.Exit()

This works very well on my desktop. Unfortunately it does not work on a
Windows Mobile 5.0 device because windows mobile does not have a cmd.exe.

I will have to dig a bit further for a solution.






Peter Duniho said:
PeterW said:
I had hoped the "FileShare.Read" in the following line of code would do the
trick:

Dim objWriteFileStream As New FileStream("F:\SelfDeleteFromResource.exe",
FileMode.CreateNew, FileAccess.Write, FileShare.Read, 1024,
FileOptions.DeleteOnClose)

Why? The page you referenced specifically says the file you write "must
also have the FILE_SHARE_DELETE flag specified". Why would you think
that FileShare.Read would accomplish that, as opposed to (for example)
the FileShare.Delete flag?
According to the documentation this flag controls if other filestreams can
access the file or not.

Actually, the documentation is more specific: it says that flag "allows
subsequent opening of the file for reading". Not any access; it
specifically controls read sharing.

Also, the page you referenced clearly explains that you need the
FILE_SHARE_DELETE flag, because the file is originally opened with the
DELETE_ON_CLOSE flag (FileOptions.DeleteOnClose in .NET).

It seems to me you want (in addition to other sharing flags that may be
necessary) the equivalent of the FILE_SHARE_DELETE flag, which I believe
is the FileShare.Delete flag.
FileShare.Read means that other filestreams can open
the file for read while the current process still has the file open.
Aparently this is limited to filestream objects only because it does not work
when you try to start an executable. [...]

I disagree with your conclusion. It's likely your code would work fine
if you hadn't also specified the FileOptions.DeleteOnClose, and given
that you are, you need to specify the proper sharing flag to allow that
to happen.

Pete
.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top