⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cryptstuff.asm

📁 yoda s Crypter 1.2 程序及源码 yoda PE加密保护,Win32ASM源码。
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	mov edi,offset TlsBackup
	mov ecx,sizeof IMAGE_TLS_DIRECTORY32
	rep movsb
	
	; fix the TLS DIRECTORY VA
	mov eax,CryptSectionVA
	add eax,IT_SIZE
	add eax,TLS_BACKUP_ADDR
	mov esi,pTlsDirAddr
	mov [esi],eax
  ExitTlsFixProc:
	ret
ProcessTlsTable ENDP

; This function encrypts the dll name strings, saves the ImageImportDescriptors to the loader data 
; and destroys them.
; return values:
; 1 - success
; 0 - too much IID's !
ProcessOrgIT PROC USES edi esi edx, pFileImage : LPVOID, pITBaseRO : LPVOID
	LOCAL dwIIDNum : DWORD

	; clear the IIDInfo array
	XOR EAX,EAX
	MOV EDI, OFFSET IIDInfo
	MOV ECX, SIZEOF IIDInfo
   ClearArrayLoop:
        STOSB
        LOOP ClearArrayLoop
	
	; get a random number
	INVOKE GetTickCount
	XOR EAX, ("yoda")
	MOV EDX,EAX							; EDX -> stupid number :)
	
	; start
	MOV  dwIIDNum, 0
	MOV  EDI,pITBaseRO
	ADD  EDI,pFileImage
	ASSUME EDI : PTR IMAGE_IMPORT_DESCRIPTOR			; EDI -> IID
	MOV ESI,OFFSET IIDInfo
	ASSUME ESI : PTR sItInfo					; ESI -> Loder IT data array
	.WHILE [EDI].Name1
	   ; too much IID's ?
	   INC  dwIIDNum
	   .IF dwIIDNum == (MAX_IID_NUM)
	       XOR  EAX, EAX
	       JMP  POIT_Exit
	   .ENDIF
	   
	   ; save IID Infos
	   PUPO <[EDI].Name1>, <[ESI].DllNameRVA>
	   PUPO <[EDI].OriginalFirstThunk>, <[ESI].OrgFirstThunk>
	   PUPO <[EDI].FirstThunk>, <[ESI].FirstThunk>
	   
	   ;-> get dll pointer
	   PUSH  [EDI].Name1
	   PUSH  pFileImage	
	   CALL  RVA2Offset
	   ADD   EAX, pFileImage
	   ;-> crypt string
	   CALL EnDeCryptString
  	   
  	   ;--- CRYPT API name strings ---
  	   PUSH ESI
  	   MOV  ESI, [EDI].OriginalFirstThunk
  	   .IF !ESI
  	      MOV ESI, [EDI].FirstThunk
  	   .ENDIF
  	   PUSH ESI
  	   PUSH pFileImage
  	   CALL RVA2Offset
  	   MOV  ESI, EAX
  	   ADD  ESI, pFileImage
  	   .WHILE DWORD PTR [ESI]	; ESI -> Thunk pointer
  	      MOV  EAX, [ESI]
  	      ; is it an Ordinal Import ?
	      TEST EAX,IMAGE_ORDINAL_FLAG32
	      JNZ  SkipApiString
  	      PUSH EAX
  	      PUSH pFileImage
  	      CALL RVA2Offset
  	      OR   EAX, EAX
  	      JZ   SkipApiString
  	      ADD  EAX, pFileImage
  	      ADD  EAX, 2		; skip the HINT
  	      CALL EnDeCryptString
   SkipApiString:  	      
  	      ADD  ESI, 4
  	   .ENDW
  	   POP ESI
  	   
  	   ; destroy Original IID
  	   MOV [EDI].Name1, EDX
  	   MOV [EDI].OriginalFirstThunk, EDX
  	   MOV [EDI].FirstThunk, EDX
  	   MOV [EDI].TimeDateStamp, EDX
  	   MOV [EDI].ForwarderChain, EDX
   	   
	   ; EDI -> point to next IID	   
	   ADD EDI,SIZEOF IMAGE_IMPORT_DESCRIPTOR
	   ADD ESI,SIZEOF sItInfo
	.ENDW
	ASSUME ESI : NOTHING
	ASSUME EDI : NOTHING
	XOR  EAX, EAX
	INC  EAX
   POIT_Exit:
	RET
ProcessOrgIT ENDP

; returns aligned value
PEAlign PROC USES ecx edx, dwTarNum : DWORD, dwAlignTo : DWORD
	mov ecx,dwAlignTo
	mov eax,dwTarNum
	xor edx,edx
	div ecx
	cmp edx,0
	jz AlreadyAligned
	inc eax	
   AlreadyAligned:
   	mul ecx
	ret
PEAlign ENDP

; calulates the Offset from a RVA
; Base    - base of the MMF
; dwITRVA - the RVA to calculate
; returns 0 if an error occurred else the calculated Offset will be returned
RVA2Offset PROC USES ebx ecx edx, Base : DWORD,dwITRVA : DWORD
	; get the pointer to the NT header
	mov eax,Base
	add eax,[eax+03Ch]
	invoke ImageRvaToSection,eax,Base,dwITRVA
	test eax,eax
	jz @@ExitProc
	
	xchg eax,ebx
	assume ebx : ptr IMAGE_SECTION_HEADER
	mov eax,dwITRVA
	sub eax,[ebx].VirtualAddress
	add eax,[ebx].PointerToRawData		
	assume ebx : nothing
@@ExitProc:
	ret
RVA2Offset ENDP

; ------ START OF THE PE LOADER CODE -----
DepackerCode:
	pushad

	; get base ebp
	call CallMe
  CallMe:
	pop ebp
	sub ebp,offset CallMe
	
	;----- DECRYPT LOADER VARIABLES -----
	MOV ECX, CRYPT_LOADER_SIZE_DB
	LEA EDI, [EBP+OFFSET LOADER_CRYPT_START]
	MOV ESI, EDI
   VarDecryptionLoop:
        LODSB
	VarDecryptBuff DB VAR_PER_SIZE DUP (0)
        STOSB
        LOOP VarDecryptionLoop
        
LOADER_CRYPT_START:
	;------ DETECT WinNT ------
	MOV  EAX, [ESP+020h]
	INC  EAX
	JS   NoNT
	MOV  DWORD PTR [EBP+bNT], 1
   NoNT:	

        ;------ Get CRC OF LOADER CODE ------
        LEA  EAX, [EBP+OFFSET DepackerCode]
        MOV  ECX, LOADER_CRC_CHECK_SIZE
        CALL GetChecksum
        MOV  [EBP+dwLoaderCRC], EAX        
	
	;----- SI Check 1 -----
	MOV EAX, [ebp+PROTECTION_FLAGS]
	AND EAX, CHECK_SI_FLAG
	jz SkipSICheck
	
	; install SEH frame
	LEA  ESI,[EBP+SEH]
	ASSUME ESI : PTR sSEH
	LEA  EAX, [EBP+OFFSET SICheck1_SP]
	mov  [ESI].SaveEip, EAX
    	ASSUME ESI : NOTHING
	MOV  EDI, EBP
	LEA  EAX, [EBP+OFFSET SehHandler1]
	XOR  EBX, EBX
	push EAX
	push FS:[EBX]
	mov  FS:[EBX], ESP
	
	; 0 - SI not found
	; 1 - SI found
   	mov     ebp, 04243484Bh
    	mov     ax, 04h
    	JMP     SM1
    	DB 0FFh
  SM1:
      	INT  3
    	
   SICheck1_SP:
	MOV  EBP, EDI
	; uninstall SEH frame
	XOR  EBX, EBX
    	POP  FS:[EBX]
    	ADD  ESP, 4
    	
   	.IF AL != 4
    	   ; exit
    	   JMP SM2
           DB 0E9h
   SM2:    popad
	   ret
    	.ENDIF
  SkipSICheck:
	
	;----- GET BASE API ADDRESSES -----
	; find the ImageImportDescriptor and grab dll addresses
	mov eax,[ebp+dwImageBase]
	add eax,[eax+03Ch]
	add eax,080h
	mov ecx,[eax]                        		; ecx contains the VirtualAddress of the IT
	add ecx,[ebp+dwImageBase]
	add ecx,16                           		; ecx points to the FirstThunk address of the IID
	mov eax,dword ptr [ecx]
	add eax,[ebp+dwImageBase]
	mov ebx,dword ptr [eax]
	mov [ebp+_LoadLibrary],ebx
	add eax,4
	mov ebx,dword ptr [eax]
	mov [ebp+_GetProcAddress],ebx	
	
	;----- GET ALL OTHER API ADDRESSES -----
	; get kernel base
	lea eax,[ebp+offset szKernel32]
	push eax
	call [ebp+_LoadLibrary]
	mov esi,eax					; esi -> kernel base
	MOV [EBP+dwKernelBase], EAX

	;-> GetModuleHandle
	lea eax,[ebp+szGetModuleHandle]
	call DoGetProcAddr
	mov [ebp+_GetModuleHandle],eax	
	
	;-> VirtualProtect
	lea eax,[ebp+szVirtualProtect]
	call DoGetProcAddr
	mov [ebp+_VirtualProtect],eax	
	
	;-> GetModuleFileName
	lea eax,[ebp+szGetModuleFileName]
	call DoGetProcAddr
	mov [ebp+_GetModuleFileName],eax
	
	;-> CreateFile
	lea eax,[ebp+szCreateFile]
	call DoGetProcAddr
	mov [ebp+_CreateFile],eax
	
	;-> GlobalAlloc
	lea eax,[ebp+szGlobalAlloc]
	call DoGetProcAddr
	mov [ebp+_GlobalAlloc],eax
	
	;-> GlobalFree
	lea eax,[ebp+szGlobalFree]
	call DoGetProcAddr
	mov [ebp+_GlobalFree],eax
	
	;-> ReadFile
	lea eax,[ebp+szReadFile]
	call DoGetProcAddr
	mov [ebp+_ReadFile],eax
	
	;-> GetFileSize
	lea eax,[ebp+szGetFileSize]
	call DoGetProcAddr
	mov [ebp+_GetFileSize],eax
	
	;-> CloseHandle
	lea eax,[ebp+szCloseHandle]
	call DoGetProcAddr
	mov [ebp+_CloseHandle],eax
	
	; FUNNY JUMP :)
	LEA EAX, [EBP+OFFSET LoaderContinue1]
	PUSH EAX
	RET
	
; it's in an own function to keep a the loader code small
; eax = address of API string
; esi = target dll base	
DoGetProcAddr:
	push eax
	push esi
	call [ebp+_GetProcAddress]
	ret

LoaderContinue1:
	;----- ANTI DUMP -----
	test [ebp+PROTECTION_FLAGS],ANTI_DUMP_FLAG
	jz LetDumpable
	
        push    fs:[30h]
        pop     eax
        TEST    EAX, EAX
        JS      fuapfdw_is9x     ; detected Win 9x
   fuapfdw_isNT:
        MOV     EAX, [EAX+0Ch]
        MOV     EAX, [EAX+0Ch]
        MOV     DWORD PTR [EAX+20h], 1000h ; increase size variable
        JMP     fuapfdw_finished
   fuapfdw_is9x:
        PUSH    0
        CALL    [ebp+_GetModuleHandle]
        TEST    EDX, EDX
        JNS     fuapfdw_finished      ; Most probably incompatible!!!
        CMP     DWORD PTR [EDX+8], -1
        JNE     fuapfdw_finished      ; Most probably incompatible!!!
        MOV     EDX, [EDX+4]          ; get address of internaly used
                                      ; PE header
        MOV     DWORD PTR [EDX+50h], 1000h ; increase size variable
   fuapfdw_finished:

   LetDumpable:
	
	;---- GET HEADER WRITE ACCESS -----
	mov edi,[ebp+dwImageBase]
	add edi,[edi+03Ch]
	assume edi : ptr IMAGE_NT_HEADERS			; edi -> pointer to PE header
	mov esi,[ebp+dwImageBase]
	mov ecx,[edi].OptionalHeader.SizeOfHeaders
	assume edi : nothing
		
	; fix page access
	lea eax,[ebp+Buff]
	push eax
	push PAGE_READWRITE
	push ecx
	push [ebp+dwImageBase]
	call [ebp+_VirtualProtect]
	
	
	;----- CALCULATE CRC -----
	test [ebp+PROTECTION_FLAGS],CHECK_HEADER_CRC
	jz DontCheckCRC

	; get the calling exe filename
	push MAX_PATH
	lea edi,[ebp+Buff]
	push edi			; edi -> filename
	push 0
	call [ebp+_GetModuleFileName]
	
	; map it...
	push 0
	push FILE_ATTRIBUTE_NORMAL
	push OPEN_EXISTING
	push NULL
	push FILE_SHARE_READ
	push GENERIC_READ
	push edi
	call [ebp+_CreateFile]
	.IF eax == INVALID_HANDLE_VALUE
	   xor eax,eax
	   jmp SkipChecksumCalc
	.ENDIF
	mov edi,eax			; edi -> file handle
	
	push NULL
	push edi
	call [ebp+_GetFileSize]
	sub eax,CHECKSUM_SKIP_SIZE
	xchg eax,esi			; esi -> filesize
	
	push esi
	push GMEM_FIXED+GMEM_ZEROINIT
	call [ebp+_GlobalAlloc]
	.IF eax == NULL
	   jmp SkipChecksumCalcAndCleanUp
	.ENDIF
	xchg eax,ebx			; ebx -> mem base
	
	push NULL
	lea eax,[ebp+Buff]
	push eax
	push esi
	push ebx
	push edi
	call [ebp+_ReadFile]
	
	; get the checksum
	mov eax,ebx
	mov ecx,esi
	PUSH EBX	; [ESP] -> hMem
	PUSH EDI        ; EDI = hFile
	
	CALL GetChecksum
	mov [ebp+dwCalcedCRC],eax
	
	POP  EDI
	POP  EBX
	; the calculated CRC will be compared at the start of the InitIT function >:-)
	LEA  EAX, [EBP+OFFSET AfterCRCCalcContinue]
	PUSH EAX
	RET

	;-> Start of GetChecksum
   GetChecksum:
	; eax = file image base
	; ecx = filesize	
	mov edi,eax						; edi -> data pointer
	xor eax,eax						; eax -> current bytes
	xor ebx,ebx						; ebx -> current checksum
	xor edx,edx						; edx -> Position (zero based)
	
	; start calculation
   CheckSumLoop:
        mov al,byte ptr [edi]
        mul edx
        add ebx,eax        
        inc edx
   	inc edi   	
   	loop CheckSumLoop
   	xchg eax,ebx		; eax -> checksum
   	RET
   	;-> End of GetChecksum

   AfterCRCCalcContinue:
	
	; clean up
	PUSH EBX
	call [ebp+_GlobalFree]
	xchg esi,eax

  SkipChecksumCalcAndCleanUp:	
	push eax
	push edi
	call [ebp+_CloseHandle]	
	pop eax
   SkipChecksumCalc:
   DontCheckCRC:

	;----- DECRYPTION -----
	mov eax,[ebp+dwImageBase]
	mov ebx,1
	CALL CryptPE
	LEA EAX, [EBP+OFFSET AfterDeCryptionContinue]
	PUSH EAX
	RET
	
	; eax = pointer to file memory
	; ebx: 0 - RawCrypt mode
	;      1 - VirtualCrypt mode
	CryptPE:
	mov edi,eax
	add edi,[edi+3Ch]
	assume edi : ptr IMAGE_NT_HEADERS		; edi -> PE header
	mov esi,edi
	add esi,0F8h
	assume esi : ptr IMAGE_SECTION_HEADER		; esi -> Section header
	xor edx,edx
	.REPEAT
	   
	   ; -> skip some special sections !
	   .IF dword ptr [esi].Name1 == ('crsr')
	      jmp @@LoopEnd
	   .ENDIF
	   .IF dword ptr [esi].Name1 == ('rsr.')
	      jmp @@LoopEnd
	   .ENDIF
	   .IF dword ptr [esi].Name1 == ('oler')
	      jmp @@LoopEnd
	   .ENDIF
	   .IF dword ptr [esi].Name1 == ('ler.')
	      jmp @@LoopEnd
	   .ENDIF
	   .IF dword ptr [esi].Name1 == ('Cy')
	      jmp @@LoopEnd
	   .ENDIF
	   .IF dword ptr [esi].Name1 == ('ade.')
	      jmp @@LoopEnd
	   .ENDIF
	   
	   ;-> skip also some other sections
	   .IF [esi].PointerToRawData == 0 || [esi].SizeOfRawData == 0
	      jmp @@LoopEnd
	   .ENDIF
   
	   ;-> en-/decrypt it
           pushad
	   mov ecx,[esi].SizeOfRawData
	   .IF ebx == 0				; (ebx is a parameter)
	      mov esi,[esi].PointerToRawData
	      ADD ESI, EAX
	      CALL EncryptSec
	   .ELSE
	      mov  esi,[esi].VirtualAddress
	      add  esi,eax
	      CALL DecryptSec
	   .ENDIF

	   JMP SecDecryptContinue1
	   
	; esi = CryptStart
	; ecx = CryptSize
	DecryptSec:
		mov edi,esi
	SecDecryptLoop:
		LODSB
		SecDecryptBuff DB SEC_PER_SIZE DUP (0)
		STOSB
		LOOP SecDecryptLoop
		RET
		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -