While this article uses the term "virus", the code demonstrated here is not a virus or any other form of malware. If you use this program to annoy your co-workers - you may have to deal with the repercussions!
Who said programming cannot be fun? Let's create a simple "memory eater" that executes itself an unlimited number of times - thus consuming all the Windows memory :)
The "Hello World VIRUS" we will build in this article is, of course, not a true virus. We'll create a totally useless application that executes itself when it gets executed. What a weird idea :)
Here are the topics you will learn by building your first (Hello World) Virus:
- Execute applications from Code,
- Send Parameters to applications being executed from code,
- Use Windows CallBack procedures,
- Get the Class Name and the Caption of a Window if you know its Handle,
- Send and Handle a Custom Message
"Hello World" VIRUS!
In the OnCreate event of the main (only form) form a ShellExecute method is called to execute another application from code - this time, the calling application - itself. When you run the virus for the first time, the Virus will execute itself and another instance will be created. The second instance, again, executes itself by creating the third instance, the third instance runs the fourth instance ... get the point?Ok, ok. Let's build a fair virus. The Virus will execute itself only a limited number of times. The last instance will clean up the system by terminating all the running instances.
procedure THelloWorldVirusForm.FormCreate(Sender: TObject) ;The MAXExecuteCount constant determines the maximum number of times the virus will execute itself. Another instance is started using the ShellExecute method - by passing the EXE name of the Virus itself and the current instance count. When the virus is run, the ParamCount is used to check if any parameters are passed to the program (execCount variable holds this number). If it is less then MAXExecuteCount the Virus executes itself again. A random number is used to position the window erratically on the screen (download full source).
//How many times to execute this application - "virus"?
const
MAXExecuteCount = 55;
var
execCount : integer;
begin
execCount := 0;
if ParamCount > 0 then execCount := StrToInt(ParamStr(1)) ;
if execCount < MAXExecuteCount then
begin
infoLabel.Caption := Format('Clone Nr: %d',[execCount]) ;
//run itself again
execCount := 1 + execCount;
ShellExecute(Application.Handle,'open',PChar(Application.ExeName),PChar(IntToStr(execCount)),'',SW_SHOW) ;
end
else
begin
//Let's be fair .. kill all clones...
Application.MessageBox('Hello, Scared?',PChar(Application.Title)) ;
Caption := 'I will close normally';
KillClones;
Application.MessageBox('System secured!',PChar(Application.Title)) ;
end; end;
When MAXExecuteCount is reached, since this is not a bad virus, the last instance ensures that all the running instances are terminated.
The KillClones function uses a Windows callback mechanism to enumerate all top-level windows and search for the Hello World Virus instances:
procedure THelloWorldVirusForm.KillClones;The EnumWindows fills a TStringList with the handles of the running Virus instances. A simple for loop is used to send a custom message to the Virus instance.
var
cloneHandle : THandle;
cloneHandles : TStringList;
sHandle : string;
begin
cloneHandles := TStringList.Create;
try
EnumWindows(@EnumWindowsFunc, LParam(cloneHandles)) ;
for sHandle in cloneHandles do
begin
cloneHandle := StrToInt(sHandle) ;
if cloneHandle <> self.Handle then SendMessage(cloneHandle, WM_CloneQuit, 0, 0) ;
end;
finally
cloneHandles.Free;
end;
end;
function EnumWindowsFunc(Handle: THandle; List: TStringList) : boolean ; stdcall;The Virus handles the custom message by calling Application.Terminate.
var
className: array[0..255] of Char;
caption: array[0..255] of Char;
begin
GetClassName(Handle, className, SizeOf(className)-1) ;
GetWindowText(Handle, caption, SizeOf(caption)-1) ;
if ((className = 'THelloWorldVirusForm') AND (caption = 'HelloWorldVirusForm')) then
List.Add(IntToStr(Handle)) ;
Result :=True;
end;
const
WM_CloneQuit = WM_USer + 2901; //"random" number
...
procedure Quit(var Msg : TMessage) ; message WM_CloneQuit;
...
procedureTHelloWorldVirusForm.Quit(var Msg: TMessage) ;
begin
Application.Terminate;
end;
Final WARNING: do NOT execute the Hello World Virus from the Delphi IDE, build the code and start the program from the Windows Explorer. If you run the application from the IDE - one instace will be left running. Use the Task Manager to terminate it.
Let's Get Nasty ;^)
Let's say we forget to include the "cleanup" code. Why not hide the TaskBar button, hide the Virus from Task Manager, produce a memory leak, etc ...


