1. Computing

How to Build your First "Hello World Virus"

Let's annoy fellow co-workers! Run a Hello World Virus on their computers...

By

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) ;
 //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;
 
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).

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;
 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; 
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.
 function EnumWindowsFunc(Handle: THandle; List: TStringList) : boolean ; stdcall;
 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; 
The Virus handles the custom message by calling Application.Terminate.
 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 ...

©2014 About.com. All rights reserved.