Hi Folks !
This is a comment after reading the sticky thread http://www.asmcommunity.net/board/index.php?topic=4190
in the FAQ - about self-deleting progs. Namely I will add something about
self deleting .BATs under Win 9x.

In the above referenced thread it says like a simple batfile that deletes itself
will still leave its WinoldAp instance running after it exits. But there is a simple
way out which was maybe worth mentionning however ecvident (too evident ;=)

Create a .PIF file along with the bat with the property "close widow at exit".
From inside the BAT, DELete the .PIF before self DELeting the BAT !

Then running either of BAT or associated PIF will delete both files and exit properly...

I would easily believe there's a way to hack the "close (winoldapp) window on exit" property
without bothering to have a PIF setup, though there's no need to bother IMO.

Good day !

--
Czerno
Posted on 2004-04-09 05:46:44 by Czerno
I found a self-deleting program.


; uninstall.asm Possible use in an uninstaller - deletes itself when run
;
.386

.model flat, stdcall

option casemap:none

include \masm32\include\windows.inc
   include \masm32\include\user32.inc
   include \masm32\include\kernel32.inc
   include \masm32\include\advapi32.inc
   include \masm32\include\shlwapi.inc
   include \masm32\include\shell32.inc
   include \masm32\macros\macros.asm

   includelib  \masm32\lib\shell32.lib
   includelib  \masm32\lib\kernel32.lib
   includelib  \masm32\lib\user32.lib
   includelib  \masm32\lib\advapi32.lib
   includelib  \masm32\lib\shlwapi
   
.data

align 4
sinfo STARTUPINFO {sizeof STARTUPINFO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
szDelete db "/c del ",0
szNull db " >> NUL",0
szComSpec db "ComSpec",0
szPrefix db "Cln",0
szCmdLine db "%s %d %s",0

.data?

pinfo PROCESS_INFORMATION {?}
szExeName db             MAX_PATH dup (?)
szClone db            MAX_PATH dup (?)
szCmd db            512 dup (?)
hProcessOrig HANDLE            ?

.code

start:

;---------------------------------------------------------------
; Get the Commandline
;---------------------------------------------------------------

Invoke GetCommandLine
push esi
mov esi, eax

;---------------------------------------------------------------
; Load the application name
;---------------------------------------------------------------

; 22h = the " character ie. We have a long pathname
; that includes spaces
cmp byte ptr , 22h
jne BypassExeName
inc esi ; Bypass the "
lea ecx, szExeName

; While the byte pointed to by eax isn't a "...
BypassFullPath:
cmp byte ptr , 22h
je AddNullTerminator
mov dl,
mov byte ptr , dl
inc esi
inc ecx
jmp BypassFullPath

AddNullTerminator:
mov byte ptr , 0
jmp BypassWhitespace

; short pathname that doesn't include spaces
BypassExeName:
Invoke GetModuleFileName, NULL, addr szExeName, MAX_PATH
add esi, 9 ; the commandline must be at least 9 chars long

BypassExeNameLoop:
cmp byte ptr , 20h ; space character
je BypassWhitespace
cmp byte ptr , 0
je firstTimeExeRun
inc esi
jmp BypassExeNameLoop

BypassWhitespace:
inc esi
cmp byte ptr , 20h
je BypassWhitespace

; eax will point to the first argument (if there is one)
cmp byte ptr , 0
je firstTimeExeRun


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; This is the cloned version - do the uninstall
; and then delete self
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

;---------------------------------------------------------------
; Convert the second commandline parameter to a number
;---------------------------------------------------------------

xor eax, eax
mov ecx, 10

atoi:
add al,
inc esi
sub eax, 30h
cmp byte ptr , 20h ; space character
je MovProcessOrig
mul ecx
jmp atoi

MovProcessOrig:
mov hProcessOrig, eax

BypassWhitespace2:
inc esi
cmp byte ptr , 20h
je BypassWhitespace2

; Wait for the first instance to finish running
Invoke WaitForSingleObject, eax, INFINITE
Invoke CloseHandle, hProcessOrig
Invoke DeleteFile, esi
pop esi

; Remove the application file(s)

; Remove data files

; Remove directory - directory must be empty or RemoveDirectory will fail

; Remove registry entries

; Remove start menu links

; Uninstall complete and successful(!)

;---------------------------------------------------------------
; Attempt to quietly delete this file
;---------------------------------------------------------------

Invoke GetShortPathName, addr szExeName, addr szExeName, MAX_PATH
or eax, eax
jz ExitProc
Invoke lstrcpy, addr szCmd, addr szDelete
Invoke lstrcat, addr szCmd, addr szExeName
Invoke lstrcat, addr szCmd, addr szNull;

Invoke GetEnvironmentVariable, addr szComSpec, addr szExeName, MAX_PATH
or eax, eax
jz ExitProc
Invoke ShellExecute, 0, 0, addr szExeName, addr szCmd, 0, SW_HIDE
jmp ExitProc


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; This is the first time the .exe has run - spawn the clone
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

firstTimeExeRun:
Invoke GetTempPath, MAX_PATH, addr szClone
Invoke GetTempFileName, addr szClone, addr szPrefix, 0, addr szClone
Invoke CopyFile, addr szExeName, addr szClone, FALSE

; Create the clone process
Invoke GetCurrentProcessId
Invoke OpenProcess, SYNCHRONIZE, TRUE, eax
Invoke wsprintf, addr szCmd, addr szCmdLine, addr szClone, eax, addr szExeName
Invoke CreateProcess, NULL, addr szCmd, NULL, NULL, TRUE, 0, NULL, NULL, addr sinfo, addr pinfo
Invoke CloseHandle, pinfo.hProcess
Invoke CloseHandle, pinfo.hThread
; This original process can now terminate

ExitProc:
Invoke ExitProcess, 0

end start


edit: added code tag
Posted on 2009-11-11 19:48:06 by skywalker
system("killall APP_NAME; rm APP_PATH/APP_NAME");
Works on Linux.

Not sure if the MSVCRT.system() lets you execute more than 1 command.

In any case, you guys are trying too hard :D

4 KB files and Temp directories; why not throw in CreateRemoteThread
Posted on 2009-11-12 14:07:39 by r22
In any case, you guys are trying too hard :D

4 KB files and Temp directories;
Exactly - combined with a MoveFileEx() with MOVEFILE_DELAY_UNTIL_REBOOT set.

why not throw in CreateRemoteThread
Can't recommend that, as HIPS could very well see this as suspicious behavior.
Posted on 2009-11-13 01:09:56 by f0dder

system("killall APP_NAME; rm APP_PATH/APP_NAME");
Works on Linux.


Lol, it would even work without the killall :)
Linux doesn't really care if you pull the rug from under it :)
(or most other *nix flavours for that matter, including my own poison: FreeBSD).
Posted on 2009-11-13 04:07:31 by Scali