Creating a self deleting executable using .NET

  • Follow


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.
0
Reply Utf 11/21/2009 8:31:01 AM

PeterW wrote:
> 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
0
Reply Peter 11/21/2009 9:47:23 AM


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. :) 

"Peter Duniho" wrote:

> PeterW wrote:
> > 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
> .
> 
0
Reply Utf 11/21/2009 2:34:01 PM

On 21/11/2009 in message 
<4BE24CEB-E7D5-40E6-8E3C-B46C1426D70E@microsoft.com> PeterW wrote:

>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?

-- 
Jeff Gaines Dorset UK
This is as bad as it can get, but don't bet on it
0
Reply Jeff 11/21/2009 2:46:38 PM

Just a delete is sufficient. 


"Jeff Gaines" wrote:

> On 21/11/2009 in message 
> <4BE24CEB-E7D5-40E6-8E3C-B46C1426D70E@microsoft.com> PeterW wrote:
> 
> >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?
> 
> -- 
> Jeff Gaines Dorset UK
> This is as bad as it can get, but don't bet on it
> .
> 
0
Reply Utf 11/21/2009 4:36:01 PM

PeterW wrote:
> 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
0
Reply Peter 11/21/2009 7:17:17 PM

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" wrote:

> PeterW wrote:
> > 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
> .
> 
0
Reply Utf 11/22/2009 10:49:03 AM

PeterW wrote:
> 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
0
Reply Peter 11/22/2009 8:17:06 PM

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" wrote:

> PeterW wrote:
> > 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
> .
> 
0
Reply Utf 11/23/2009 10:06:06 PM

8 Replies
219 Views

(page loaded in 0.27 seconds)


Reply: