; Program name: yoda's Crypter ; Version: 1.2 ; Author: C-ripper ; Target: Yoda's Crypter v.1.2 ; Greetings: yoda, r!sc, bane, Uknown One/TMG, everyone :) .586p .model flat,stdcall locals jumps include win32.inc EXTRN GetOpenFileNameA:PROC EXTRN MessageBoxA:PROC EXTRN GlobalAlloc:PROC EXTRN GlobalFree:PROC EXTRN VirtualAlloc:PROC EXTRN VirtualFree:PROC EXTRN ExitProcess:PROC EXTRN ReadFile:PROC EXTRN WriteFile:PROC EXTRN GetFileSize:PROC EXTRN CloseHandle:PROC EXTRN CreateFileA:PROC .data NULL equ 00h GMEM_FIXED equ 0000h ofn_struc OPENFILENAME <> ofn_struc_size equ 04ch ofn_filter db 'Executable file',00h,'*.exe',00h,00h ofn_title db 'Select file to unpack',00h f_name db 200h dup(?) f_handle dd ? f_size dd ? read_len dd ? write_len dd ? out_fhandle dd ? outfname db 'unpacked.exe',00h buffer dd ? temp_buf dd ? tls_table dd 0,0,0,0 pe_header_ptr dd ? section_start dd ? sections_num dd ? image_base dd ? import_start dd ? import_rva dd ? far_proc db ? min_size dd ? imp_align db ? correct_imp_loc dd ? garbage dd ? error_caption db 'Error!',00h cant_open_err db 'Cannot open input file!',00h no_mem_err db 'Cannot allocate memory!',00h not_mz_err db 'Not valid EXE file (''MZ'' signature does not present)!',00h not_pe_err db 'Not valid PE file (''PE'' signature does not present)!',00h import_err db 'Cannot rebuild import section (not found)!',00h success_msg db 'File successfully unpacked!',00h success_caption db 'Success',00h .code start proc ; Prepare the OpenFileName structure and get file name mov ofn_struc.lStructSize,ofn_struc_size mov ofn_struc.lpstrFilter,offset ofn_filter mov ofn_struc.lpstrFile,offset f_name mov ofn_struc.lpstrTitle,offset ofn_title mov ofn_struc.nMaxFile,0200h mov ofn_struc.Flags,OFN_FILEMUSTEXIST or \ OFN_PATHMUSTEXIST or OFN_LONGNAMES or\ OFN_EXPLORER or OFN_HIDEREADONLY call GetOpenFileNameA, offset ofn_struc or eax,eax ; Nothing selected? jz exit ; If so - exit call CreateFileA, offset f_name, GENERIC_READ+GENERIC_WRITE,\ NULL,NULL,\ OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL cmp eax,-1 ; ////Invalid_File_Handle? jne open_ok call MessageBoxA, NULL, offset cant_open_err, offset error_caption, NULL jmp exit ;------ File is opened OK open_ok: mov f_handle,eax ;------ Load file in memory call GetFileSize, f_handle, 00h mov f_size,eax call GlobalAlloc, GMEM_FIXED, f_size ; Allocate memory or eax,eax jnz mem_alloc_ok call CloseHandle, f_handle call MessageBoxA, NULL, offset no_mem_err, offset error_caption, NULL jmp exit ;------ Memory allocated OK mem_alloc_ok: mov buffer,eax ;buffer points to the beginning of the ;file in memory call ReadFile, f_handle, buffer, f_size, offset read_len, NULL call CloseHandle, f_handle ;------ Check for valid EXE file check_valid_exe: mov edx,buffer ; edx points to offset of the file_start cmp word ptr [edx],'ZM' jz exe_ok call MessageBoxA, NULL, offset not_mz_err, offset error_caption, NULL jmp free_mem_exit exe_ok: ;------ Check for valid PE file add edx,dword ptr [edx+003ch] ; PE header==>EDX cmp word ptr [edx],'EP' ; PE file? jz pe_ok call MessageBoxA, NULL, offset not_pe_err, offset error_caption, NULL jmp free_mem_exit pe_ok: mov pe_header_ptr,edx mov eax,dword ptr [edx+0034h] ; Get image base and save it for later use mov image_base,eax ; movzx eax,word ptr [edx+0006h] ;number of sections mov sections_num,eax ;###### UNPACKING START ############################################## mov eax,dword ptr [edx+0028h] ; EAX points to entry point of program call rva2fo or eax,eax jz free_mem_exit mov ebp,eax ; EBP is entry point offset ;--------------------Detect Yoda's v1.2 layer cmp dword ptr [ebp],0000e860h ; pushad jne free_mem_exit cmp dword ptr [ebp+0dh],00097bb9h ;mov ecx,97Bh jne free_mem_exit mov esi,pe_header_ptr mov edi,dword ptr [esi+10ch] ;get phys_offset of first section mov edx,dword ptr [esi+108h] ;phys_size mov esi,buffer add esi,edi mov edi,esi ;esi points to start of CODE section add edi,edx Call VirtualAlloc,NULL,37h,1000h,0004h ;alloc some memory for 1st ;decrypt routine mov temp_buf,eax mov esi,pe_header_ptr mov edx,sections_num imul edx,edx,28h sub edx,14h ;edx=(edx-28h)+14h -->Phys_Offset add edx,esi add edx,0f8h mov ebx,dword ptr [edx] mov edx,buffer add ebx,edx mov section_start,ebx ;fix the beginning off yC section mov edi,ebx add edi,0078h mov byte ptr [eax+36h],0c3h ;to return after it's done mov ecx,00000036h copy_: mov dl,byte ptr [edi] mov byte ptr [eax],dl inc edi inc eax loopnz copy_ mov edi,section_start cmp dword ptr [edi+0a29h],00 ;get first for bytes of needed .rdata(?) section jz no_tls_table mov ecx,dword ptr [edi+0a29h] mov dword ptr tls_table,ecx mov ecx,dword ptr [edi+0a2dh] mov dword ptr tls_table+4,ecx mov ecx,dword ptr [edi+0a31h] mov dword ptr tls_table+8,ecx mov ecx,dword ptr [edi+0a35h] mov dword ptr tls_table+0ch,ecx no_tls_table: add edi,0aeh mov ecx,97bh mov edx,temp_buf call edx Call VirtualFree,temp_buf,0000h,8000h mov edi,section_start add edi,3d2h ;2nd decrypt proc, reading it from Call VirtualAlloc,NULL,37h,1000h,0004h ;the decrypted part of the file mov temp_buf,eax mov edi,section_start add edi,03cfh mov byte ptr [eax+36h],0c3h mov ecx,00000036h copy__: mov dl,byte ptr [edi] ;again copy 3eh bytes to buffer mov byte ptr [eax],dl ;to run decrypt_sections proc inc edi inc eax loopnz copy__ mov eax,pe_header_ptr mov edi,eax mov esi,edi add esi,0f8h xor edx,edx decrypt_sections: cmp dword ptr [esi],63727372h jnz loc_1 jmp next_section loc_1: cmp dword ptr [esi],7273722eh jnz loc_2 jmp next_section loc_2: cmp dword ptr [esi],6f6c6572h jnz loc_3 jmp next_section loc_3: cmp dword ptr [esi],6c65722eh jnz loc_4 jmp next_section loc_4: cmp dword ptr [esi],00004379h jnz loc_5 jmp next_section loc_5: cmp dword ptr [esi],6164652eh jnz loc_6 jmp next_section loc_6: cmp dword ptr [esi+14h],00h jz next_section cmp dword ptr [esi+10h],00h jz next_section pushad mov ecx,[esi+10h] mov edi,[esi+14h] mov esi,buffer add esi,edi mov edx,temp_buf call edx popad next_section: add esi,28h inc edx cmp dx,[edi+06] jnz decrypt_sections Call VirtualFree,temp_buf,0000h,8000h ;^^^^^^^^^^^^^^^^^^^^^^Decrypt import table^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mov eax,section_start ;pointer to reserved import add eax,07efh ;info for later use xor edi,edi mov imp_align,00000001 cmp dword ptr [eax+08],00 jz pre_calc mov imp_align,00000002 pre_calc: mov edx,dword ptr [eax+10h] ;we may take this thunk for comparison calc_pointers: ;we'll better calc them cmp dword ptr [eax],00 ;to define later their place ;in original .exe jnz continue_ cmp dword ptr [eax+04],00 jz find_data_section continue_: add eax,04 inc edi jmp calc_pointers imul edi,edi,04 mov far_proc,00 find_data_section: mov ecx,sections_num ;looking for section were to put mov bl,01 ;important part of import mov esi,pe_header_ptr add esi,0f8h find_idata: cmp bl,cl jz proceed_ ;if yes then it's last section cmp edx,dword ptr [esi+0ch] jg move_on jmp chk_next_rva move_on: cmp edx,dword ptr [esi+0ch+28h] jg chk_next_rva cmp edx,[esi+34h] jnz proceed_ inc bl jmp proceed_ ;if (thunk>rva[i]) && (thunk