-1

I want to delete an executable file while it is executing itself on Windows. I don't think that'll do any harm on the process as the same can be done by executing '.exe' from USB and then removing it - which doesn't affect the process in anyway.

I tried the most simple way without a luck:

extern wchar_t *pExePath;

DeleteFileW(pExePath);

Then I tried using native API:

UNICODE_STRING name;

static wchar_t strdrvPrefis [] {L"\\??\\"};

static wchar_t strObjectName[MAX_PATH];

name.Length = (name.MaximumLength = wcslen(pExePath) * sizeof(wchar_t) + (sizeof(strdrvPrefis) - sizeof(wchar_t)));

name.Buffer = strObjectName;

OBJECT_ATTRIBUTES objFile{};

objFile.Length = sizeof(OBJECT_ATTRIBUTES);

objFile.ObjectName = &name;

wcscat(strObjectName, strdrvPrefis);

wcscat(strObjectName, pExePath);

NtDeleteFile(&objFile);

Which fails with ACCES_DENIED if I rember corectly.

Then I tried 'NtFsControlFile' but without success too:

HANDLE hFile;

IO_STATUS_BLOCK info;

NTSTATUS RetNt = NtOpenFile(&hFile, FILE_READ_DATA | FILE_WRITE_DATA, &objFile, &info, 0, FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_OPEN_REPARSE_POINT | FILE_NO_INTERMEDIATE_BUFFERING);

RetNt = NtFsControlFile(hFile, nullptr, nullptr, nullptr, &info, 0x000900A0 /*FSCTL_DELETE_OBJECT_ID*/, nullptr, 0, nullptr, 0);

NtClose(hFile);

Right now the above snippet will fail at 'NtOpenFile'. If I remove 'FILE_WRITE_DATA' from it's second argument then 'NtFsControlFile' will fail with 'STATUS_ACCESS_DENIED'.

Any ideas how to achieve this?

I'm using VC++ 2013.

AnArrayOfFunctions
  • 3,452
  • 2
  • 29
  • 66
  • 3
    possible duplicate of [How can a program delete its own executable](http://stackoverflow.com/questions/1606140/how-can-a-program-delete-its-own-executable) – Alex K. Dec 29 '14 at 15:06
  • No it is not - I am asking how to dele the file and continue execution - this one want the executable to delete itself after execution. – AnArrayOfFunctions Dec 29 '14 at 15:35
  • You can't delete an executable or DLL while it is running or loaded. About all you could do is have it copy itself to %temp%, re-run from there, delete the original and then delete the %temp% copy when it exits. – Jonathan Potter Dec 29 '14 at 18:46

1 Answers1

2

Basically, you can't do that because when an EXE is running, the process has the file open. And you can't delete a file that a process has open.

As you've noticed, you can get away with running an executable from a USB memory stick and then pulling the memory stick from the USB port. The program continues to run. I doubt, though, that you can do the "Safely remove drive".

But that won't always be the case. An EXE is more than just code. It contains executable code and resources, and not everything is loaded into memory when the EXE runs. For example if the EXE contains a large bitmap resource, that resource won't be loaded until your program asks for it to be loaded. The process keeps a handle to the EXE so that it can load resources on an as-needed basis.

So if your program needs resources that are located in the EXE and haven't yet been loaded, then removing the USB stick would cause the program to fail if it subsequently tried to load one of those resources.

As far as I know, there is no way to delete a file that is currently open by another process. And as far as I know there's no way your program can close the handle that it's holding to the executable.

The article http://www.catch22.net/tuts/self-deleting-executables (linked in the duplicate answer) shows an example that creates a new file with the delete-on-close flag set. The executable is copied to that file and then that file is executed. You then delete the original executable and the one you're now executing will be deleted automatically when the process exits. That's the best way I know of to do what you're asking.

There is no direct way to delete a file that is currently being executed.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • `DeleteFile` can succeed if the file is opened with `FILE_SHARE_DELETE` share mode. The file persists until all handles to it are closed. OTOH, files that have mapped image/data sections can't be deleted even if the sharing mode would allow it. That's not a function of open handles. The filesystem queries the memory manager to see whether the file object has open views. If it does, the filesystem fails the request with the error `STATUS_CANNOT_DELETE`. – Eryk Sun Dec 31 '14 at 01:56