Assembler with LCC-Win32

The routine below deletes its own exe.

SelDel

#include <windows.h> // for API's used

int MAXPATH = MAX_PATH;
int stack_code_size = 9;

int __declspec(naked) stack_code(void)
{                      // bytes
    _asm("popl %eax"); // 1
    _asm("call %eax"); // 2 // call FreeLibrary()
    _asm("popl %eax"); // 1
    _asm("call %eax"); // 2 // call DeleteFileA()
    _asm("ret $265");  // 3 // MAXPATH + stack_code_size - 4
}

int main (void)
{
    _asm("subl $269,%esp");         // MAXPATH + stack_code_size
    _asm("movl %esp,%edi");         // alloc buffer in stack
    _asm("movl %edi,%ebx");

    _asm("movl %stack_code_size,%ecx"); // stack_code_size
    _asm("leal %stack_code,%esi");
    _asm("rep");
    _asm("movsb");                  // copy code to stack buffer

    _asm("pushl %MAXPATH");
    _asm("pushl %edi");             // copy EXE name to stack buffer (after code)
    _asm("pushl %ecx");             // 0
    _asm("call %GetModuleFileNameA");

    _asm("leal %ExitProcess,%eax"); // to push the real API address, we get
                                    // the offset of the JMP in end of .CODE
    _asm("movl 2(%eax),%eax");      // to the import table
    _asm("pushl (%eax)");           // and get the real address of the API

    _asm("pushl %edi");             // parameter to DeleteFileA()

    _asm("leal %DeleteFileA,%eax");
    _asm("movl 2(%eax),%eax");
    _asm("pushl (%eax)");

    _asm("pushl $0");
    _asm("call %GetModuleHandleA");

    _asm("pushl %eax");             // paramter to FreeLibrary()

    _asm("leal %FreeLibrary,%eax");
    _asm("movl 2(%eax),%eax");
    _asm("pushl (%eax)");

    _asm("jmp %ebx");               // jmp to code in stack

    return 0;

}

Back to main page