vspacer
 
vspacer
 

Self Deleting Executable by Gary Nebbett

 

The code below was written entirely by Gary Nebbett.

I have simply added documentation to make it more accessible.

The original article can be found here

John Findlay has an SelDelNT article which gives a very clear account of the stack unwind process.


// sde       : Self deleting executable
// OS        : Works on NT and 2000
// Author    : Gary Nebbett
//             STL, London Road, Harlow, Essex CM17 9NA, UK
//             Voice +44-279-29531
//             Email grn@stl.stc.co.uk | PSI%234237100122::GRN
// Reference : Deleting the Executable File of
//             the Running Process Gary Nebbett gary.nebbett@openlink.org
//             Windows Developer Magazine
//             http://www.windevnet.com/documents/s=7257/wdj0109g/0109g.htm
//             selfdel.cpp
//   ------------------       -------------------      ----------------
//   |                |       | Virtual Address |      | File Control |
//   | Process Object |------>| Descriptor      |      | Block        |
//   |                |       | (VAD)           |      | (FCB)        |
//   ------------------       -------------------      ----------------
//           :                         |                      ^
//    handle : to                      | ptr        reference | ptr
//           v                         v                      |
//   ------------------       -------------------       ---------------
//   |                |       |  Image Section  |       |             |
//   | Section Object |       |  Control Area   |       | File Object |
//   |                |       |                 |       |             |
//   ------------------       -------------------       ---------------
//           |                    ^        ^                  |
//           | ptr                | ptr    | ptr              | ptr
//           v                    |        |                  |
//   ------------------           |        |  -------------   |
//   |                |           |        |  |  Section  |   |
//   |   Segment      |<-----------        ---|  Object   |<---
//   |                |                       |  pointers |
//   ------------------                       -------------
//  DeleteFile() fails when used on it's own (running) executable
//  because there is a reference from the File Object to the File
//  Control Block that is incompatible with the deletion of the file.
//  The reference to the File Control Block persists until we eliminate:
//  - The section object from which the process was created.
//  - The VAD (Virtual Address descriptor recording that the file is
//    mapped into the virtual address space.
//#in clude windows.h
int main ( int argc, char * argv[]) {
    char buf[MAX_PATH];
    HMODULE module;
    // Remove the Process object's handle to the Section object.
    // Empirical observations indicate that the value of the handle
    // is always four, the lowest valid handle value.
    // The handle is the only reference to the section object,
    // and when the reference count goes to zero the section
    // object is deleted.
    CloseHandle( (HANDLE) 4 );
    // Get module handle to the running executable.
    // We will need this as an argument to UnmapViewOfFile()
    module = GetModuleHandle(0);
    // Get module name of the running executable
    // We will need this as an argument to ExitProcess()
    GetModuleFileName(module, buf, MAX_PATH);
    // Generate stack.
    // The return address specifies the address to which control will be transferred on exit from a function.
    //   --------------------------------------------------------------------------------
    //   ExitProcess()'s      argument 1     : (UINT uExitCode)
    //   stack frame          return address : transfer control on exit to 0 (Kernel32)
    //   --------------------------------------------------------------------------------
    //   DeleteFile()'s       argument 1     : (LPCTSTR lpFileName)
    //   stack frame          return address : transfer control on exit to ExitProcess()
    //   --------------------------------------------------------------------------------
    //   UnmapViewOfFile()'s  argument 1     : (HMODULE hModule)
    //   stack frame          return address : transfer control on exit to DeleteFile()
    //   --------------------------------------------------------------------------------
    __asm {
        push 0                ; ExitProcess() argument (UINT uExitCode)
        push                  ; ExitProcess() return address : transfer control to kernel32()
                              ; ExitProcess() stack frame
        lea  eax, buf         ; forward pass setup.
        push eax              ; DeleteFile() argument (LPCTSTR lpFileName)
        push ExitProcess      ; DeleteFile() return address : transfer control to ExitProcess()
                              ; DeleteFile() stack frame
        push module           ; UnmapViewOfFile() argument (HMODULE hModule)
        push DeleteFile       ; UnmapViewOfFile() return address : transfer control to DeleteFile()
        push UnmapViewOfFile  ; UnMapViewOfFile() stack frame
        ret                   ; Start unwinding the stack.
    }
    return 0;
}

download  sde.zip (12 KB)

   

Back to top | ZDS Home | This article updated August 6 2004.