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

📄 unopix.asm

📁 The final version of UPX scrambler and PE sources in Delphi and flat assembler.
💻 ASM
📖 第 1 页 / 共 3 页
字号:
			jmp @_import_next
@@:			pop edx
			sub edx,[eax+IMAGE_SECTION_HEADER.VirtualAddress]
			add edx,[eax+IMAGE_SECTION_HEADER.PointerToRawData]
			add edx,edi
			push edx
			invoke lstrlenA,edx
			pop edx
			invoke CharUpperBuffA,edx,eax ; set upper case for dll name :)
@_import_next:		pop eax
			add eax,sizeof.IMAGE_IMPORT_DIRECTORY_ENTRY
		 .endw
	     .endif
	 .endif

	 mov eax,[dwOriginalEP]
	 sub eax,[esi+IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
	 mov edx,[ebx+IMAGE_SECTION_HEADER.VirtualAddress]
	 .if eax >= edx
	     add edx,[ebx+IMAGE_SECTION_HEADER.VirtualSize]
	     .if eax < edx
		 sub eax,[ebx+IMAGE_SECTION_HEADER.VirtualAddress]
		 add eax,[ebx+IMAGE_SECTION_HEADER.PointerToRawData]
		 add eax,edi
		 mov [dwOepAddress],eax
		 invoke RtlMoveMemory,ebx,SECTION_NAME_TEXT,IMAGE_SIZEOF_SHORT_NAME ; set name '.text'

		 mov eax,[dwOriginalEP]
		 sub eax,[esi+IMAGE_NT_HEADERS.OptionalHeader.ImageBase] ; begin
		 mov edx,[ebx+IMAGE_SECTION_HEADER.VirtualSize]
		 .if edx > [ebx+IMAGE_SECTION_HEADER.SizeOfRawData]
		     mov edx,[ebx+IMAGE_SECTION_HEADER.SizeOfRawData]
		 .endif
		 add edx,[ebx+IMAGE_SECTION_HEADER.VirtualAddress] ; end
		 push eax ebx
		 mov ebx,eax
		 lea eax,[esi+IMAGE_NT_HEADERS.OptionalHeader.DataDirectoryExport] ; first IMAGE_DATA_DIRECTORY
		 mov ecx,IMAGE_NUMBEROF_DIRECTORY_ENTRIES ; IMAGE_DATA_DIRECTORY count
@@:		 .if [eax+IMAGE_DATA_DIRECTORY.VirtualAddress] >= ebx
		     .if [eax+IMAGE_DATA_DIRECTORY.VirtualAddress] < edx
			 mov edx,[eax+IMAGE_DATA_DIRECTORY.VirtualAddress]
		     .endif
		 .endif
		 add eax,sizeof.IMAGE_DATA_DIRECTORY
		 loop @b
		 pop ebx eax
		 mov ecx,edx
		 sub ecx,eax
		 ; ecx = max count of bytes from oep to encrypt
		 mov [loader_ecx_oep],ecx
		 mov [loader_ecx_dll_oep],ecx

		 mov eax,[dwOepAddress]
		 .if [dwIsDllFile] = 0 ; if is not dll
		     cmp word [eax],$E860
		     je @_upx_set_nop
		     cmp word [eax],$BE60
		     jne @_skip_upx_mod
		     ; --- find UPX jmp to oep and fix it
@_upx_set_nop:	     pushad
		     sub ecx,5
		     add eax,ecx
		     inc ecx
@@:		     .if byte [eax] = $E9 ; jmp
			 mov edx,[eax+1] ; jmp address
			 add edx,5
			 add edx,eax
			 sub edx,edi
			 add edx,[ebx+IMAGE_SECTION_HEADER.VirtualAddress]
			 sub edx,[ebx+IMAGE_SECTION_HEADER.PointerToRawData] ; edx= jmp RVA
			 push eax edx ecx
			 stdcall IsBadImageRva,edx,[esi+IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage] ; stdcall ImageRvaToSection,esi,edi,edx
			 .if eax = 0 ; <> 0
			     pop ecx edx eax
			     add edx,[esi+IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
			     mov [loader_jmp_oep_unp_addr],edx
			     mov ecx,[dwLoaderRVA]
			     add ecx,loader_jmp_oep_unp-loader_proc-5
			     sub ecx,eax
			     add ecx,edi
			     sub ecx,[ebx+IMAGE_SECTION_HEADER.VirtualAddress]
			     add ecx,[ebx+IMAGE_SECTION_HEADER.PointerToRawData]
			     mov [eax+1],ecx
			 .else
			     pop ecx edx eax
			 .endif
			 xor ecx,ecx
			 inc ecx
		     .endif
		     dec eax
		     loop @b
		     popad
@_skip_upx_mod:
		     ; --- common
		     .if byte [eax] = $55 ; push ebp
			 mov byte [eax],$90 ; nop
		     .endif
		     .if byte [eax] = $60 ; pushad
			 mov byte [eax],$90 ; nop
		     .endif
		 .endif

		 ; generate key & encrypt oep data
		 stdcall Random,$FFFFFFFF
		 mov [loader_code_key_data2],eax
		 stdcall Random,$FFFFFFFF
		 mov [loader_code_key_data3],eax
		 stdcall Random,$FFFFFFFF
		 mov [loader_code_key_data4],eax

		 push ecx
		 mov [dwAdler32Val],1
		 lea eax,[loader_crypt_start]
		 lea edx,[dwAdler32Val]
		 mov ecx,loader_crypt_end_adler-loader_crypt_start
		 call Adler32_Update
		 mov eax,[dwAdler32Val]
		 xor eax,[loader_code_key_data3]
		 mov [loader_code_key_data1],eax
		 pop ecx
		 mov eax,[dwOepAddress]
		 lea edx,[loader_code_key_data1]
		 call TEA_EncryptECB
		 stdcall Random,$FFFFFFFF
		 mov [loader_code_key_data1],eax
	     .endif
	 .endif

	 mov edx,[ebx+IMAGE_SECTION_HEADER.VirtualAddress]
	 .if [esi+IMAGE_NT_HEADERS.OptionalHeader.DataDirectoryResource.VirtualAddress] >= edx
	     add edx,[ebx+IMAGE_SECTION_HEADER.VirtualSize]
	     .if [esi+IMAGE_NT_HEADERS.OptionalHeader.DataDirectoryResource.VirtualAddress] < edx
		 invoke RtlMoveMemory,ebx,SECTION_NAME_RSRC,IMAGE_SIZEOF_SHORT_NAME ; set name '.rsrc'
	     .endif
	 .endif
     .endif
     pop ecx
     add ebx,IMAGE_SIZEOF_SECTION_HEADER
     dec ecx
     jne @_loop

     xor eax,eax
     mov [esi+IMAGE_NT_HEADERS.OptionalHeader.DataDirectoryBaseReloc.VirtualAddress],eax
     mov [esi+IMAGE_NT_HEADERS.OptionalHeader.DataDirectoryBaseReloc.Size],eax

     ; generate key for loader decrypt
     stdcall Random,$FFFFFFFF
     mov [loader_decrypt_key_data1],eax
     stdcall Random,$FFFFFFFF
     mov [loader_decrypt_key_data3],eax
     stdcall Random,$FFFFFFFF
     mov [loader_decrypt_key_data4],eax

     mov [dwAdler32Val],1
     lea eax,[loader_proc]
     lea edx,[dwAdler32Val]
     mov ecx,loader_crypt_start-loader_proc
     call Adler32_Update_2
     mov eax,[dwAdler32Val]
     xor eax,[loader_decrypt_key_data4]
     mov [loader_decrypt_key_data2],eax

     lea eax,[loader_crypt_start]
     lea edx,[loader_decrypt_key_data1]
     mov ecx,loader_crypt_end-loader_crypt_start
     call TEA_EncryptECB
     stdcall Random,$FFFFFFFF
     mov [loader_decrypt_key_data2],eax

     mov eax,[dwFlags]
     and eax,PROTECTION_FLAG_SAVEOVERLAY
     .if eax
	 ; save overlay
	 invoke VirtualAlloc,0,[dwExtraSize],MEM_COMMIT,PAGE_READWRITE
	 .if eax
	     mov ebx,eax ; temp overlay buffer
	     mov eax,[dwFileSize]
	     sub eax,[dwExtraSize]
	     lea eax,[edi+eax]
	     push eax
	     invoke RtlMoveMemory,ebx,eax,[dwExtraSize] ; copy overlay to the buffer
	     mov eax,[esp]
	     invoke RtlMoveMemory,eax,loader_proc,loader_size ; copy loader to end of the image
	     pop eax
	     add eax,loader_size
	     invoke RtlMoveMemory,eax,ebx,[dwExtraSize] ; restore overlay
	     invoke VirtualFree,ebx,[dwExtraSize],MEM_DECOMMIT
	 .else
	     jmp @f
	 .endif
     .else
	 @@:
	 ; strip overlay
	 mov eax,[dwFileSize]
	 sub eax,[dwExtraSize]
	 lea eax,[edi+eax]
	 invoke RtlMoveMemory,eax,loader_proc,loader_size ; copy loader to end of the image
	 ; and reduce size of file
	 mov eax,[dwExtraSize]
	 sub [dwFileSize],eax
     .endif

     ;===========================================

     add [dwFileSize],loader_size
     push ERROR_SUCCESS ; return code

     stdcall GotoXY,[xyCoord]
     stdcall Filln,#32,40
     stdcall GotoXY,[xyCoord]
     call @f
     db 'Done.',0
     @@:
     stdcall Writeln,
@err:
     invoke UnmapViewOfFile,[ptrMap]
     invoke CloseHandle,[hMap]
     invoke SetFilePointer,[hFile],[dwFileSize],0,FILE_BEGIN
     .if eax <> -1
	 .if [dwFileSize] <> 0
	     invoke SetEndOfFile,[hFile]
	 .endif
     .endif
     invoke CloseHandle,[hFile]
@ret:
     pop eax ; return code
     pop esi edi ebx
     ret
endp

proc ImageRvaToSection,NtHeaders:DWORD,ImageBase:DWORD,RVA:DWORD
     mov eax,[NtHeaders]
     movzx ecx,[eax+IMAGE_NT_HEADERS.FileHeader.NumberOfSections]
     lea eax,[eax+4+IMAGE_SIZEOF_FILE_HEADER+IMAGE_SIZEOF_NT_OPTIONAL_HEADER]
@@:  mov edx,[eax+IMAGE_SECTION_HEADER.VirtualAddress]
     .if [RVA] >= edx
	 add edx,[eax+IMAGE_SECTION_HEADER.VirtualSize]
	 .if [RVA] < edx
	     ret
	 .endif
     .endif
     add eax,IMAGE_SIZEOF_SECTION_HEADER
     loop @b
     xor eax,eax
     ret
endp

proc IsBadImageRva,RVA:DWORD,ImageSize:DWORD
     mov eax,[RVA]
     or eax,eax
     setz al
     .if eax >= $1000
	 mov edx,[ImageSize]
	 sub edx,$1000
	 .if eax < edx
	     xor eax,eax
	 .endif
     .endif
     ret
endp

TEA_EncryptECB:
; ->EAX - address of data buffer
; ->ECX - buffer size
; ->EDX - address of 128-bits key
     shr ecx,3
     jecxz @_ecb_encrypt_end
@_ecb_encrypt_loop:
     call TEA_EncryptBlock
     add eax,8
     loop @_ecb_encrypt_loop
@_ecb_encrypt_end:
     retn

TEA_EncryptBlock:
; ->EAX - address of 64-bits block to encrypt
; ->EDX - address of 128-bits key
     push ebx ecx edx edi esi eax
     mov ebx,edx
     mov edx,[eax]
     bswap edx
     mov edi,edx
     mov edx,[eax+4]
     bswap edx
     mov esi,edx
     xor edx,edx
     mov ecx,16
@@:  add edx,$9E3779B9
     mov eax,esi
     shl eax,4
     add edi,eax
     mov eax,esi
     xor eax,[ebx]
     add edi,eax
     mov eax,esi
     shr eax,5
     xor eax,edx
     add edi,eax
     add edi,[ebx+4]
     mov eax,edi
     shl eax,4
     add esi,eax
     mov eax,edi
     xor eax,[ebx+8]
     add esi,eax
     mov eax,edi
     shr eax,5
     xor eax,edx
     add esi,eax
     add esi,[ebx+12]
     loop @b
     pop eax
     mov edx,edi
     bswap edx
     mov [eax],edx
     mov edx,esi
     bswap edx
     mov [eax+4],edx
     pop esi edi edx ecx ebx
     retn

SECTION_NAME_TEXT  db '.text',0,0,0 ; 8 bytes
SECTION_NAME_DATA  db '.data',0,0,0
SECTION_NAME_IDATA db '.idata',0,0
SECTION_NAME_EDATA db '.edata',0,0
SECTION_NAME_RDATA db '.rdata',0,0
SECTION_NAME_BSS   db '.bss',0,0,0,0
SECTION_NAME_TLS   db '.tls',0,0,0,0
SECTION_NAME_RSRC  db '.rsrc',0,0,0
SECTION_NAME_RELOC db '.reloc',0,0

DosStub:
  db $4D,$5A,$80,$00,$01,$00,$00,$00,$04,$00,$10,$00,$FF,$FF,$00,$00
  db $40,$01,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$00
  db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
  db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$00,$00,$00
  db $0E,$1F,$BA,$0E,$00,$B4,$09,$CD,$21,$B8,$01,$4C,$CD,$21,$54,$68
  db $69,$73,$20,$70,$72,$6F,$67,$72,$61,$6D,$20,$63,$61,$6E,$6E,$6F
  db $74,$20,$62,$65,$20,$72,$75,$6E,$20,$69,$6E,$20,$44,$4F,$53,$20
  db $6D,$6F,$64,$65,$2E,$0D,$0A,$24,$00,$00,$00,$00,$00,$00,$00,$00
@@: SizeOfDosStub = @b - DosStub

;far_jump:
;    db $68 ; push xxxxxxxx
;far_jump_address:
;    dd ?   ; address
;    retn
;@@: far_jump_size = @b - far_jump

far_jump:
    sub esp,4
    db $C7,$04,$24 ; mov [esp],xxxxxxxx
far_jump_address:
    dd ?   ; address
    retn
@@: far_jump_size = @b - far_jump

far_jump_dll:
    mov eax,[esp+4]
    db $05 ; add eax,xxxxxxxx
far_jump_dll_address:
    dd ?   ; address
    jmp eax
@@: far_jump_dll_size = @b - far_jump_dll


; ############## loader here ##############

loader_proc:
loader_rubbish_0_137:
     db 137 dup($90)
loader_rubbish_1_137:
     db 137 dup($90)
loader_rubbish_2_137:
     db 137 dup($90)
     db $B8 ;mov eax,xxxxxxxx
loader_dllflag_2:
     dd ? ; if zero then .exe
loader_rubbish_3_137:
     db 137 dup($90)
loader_rubbish_4_137:
     db 137 dup($90)
     and eax,IMAGE_FILE_DLL
     je @f
     cmp dword [esp+$08],DLL_PROCESS_ATTACH
     jne loader_crypt_start
@@:  call @f
@@:  pop eax
     add eax,loader_crypt_start-@b
loader_rubbish_5_67:
     db 67 dup($90)
     call @f
@@:  pop edx
     add edx,loader_decrypt_key_data1-@b
     mov ecx,loader_crypt_end-loader_crypt_start
     push ebx edi esi
loader_rubbish_6_111:
     db 111 dup($90)
     ; crc check - restore key
     push eax edx ecx
     call @f
@@:  pop eax
     sub eax,@b-loader_proc
     add edx,4
     mov dword [edx],1
     mov ecx,loader_crypt_start-loader_proc
     call Adler32_Update_2
     mov eax,[edx+8]
     xor [edx],eax
     pop ecx edx eax
     ; -----------------------
     call TEA_DecryptECB_2
     pop esi edi ebx
;-----------------------------------------
loader_crypt_start:
loader_rubbish_7_507:
     db 507 dup($90)
     db $B8 ;mov eax,xxxxxxxx
loader_dllflag:
     dd ? ; if zero then exe
     and eax,IMAGE_FILE_DLL
     jne loader_dll
     call loader_exe
;******************************************
loader_dll: ; dll loader
;******************************************
loader_rubbish_8_501:
     db 501 dup($90)
     push dword [esp+4]
loader_rubbish_9_69:
     db 69 dup($90)
     db $81,$04,$24 ; add [esp],xxxxxxxx
loader_oep_dll_part1:
     dd ?   ; dll oep address part 1
loader_rubbish_10_121:
     db 121 dup($90)
     db $81,$04,$24 ; add [esp],xxxxxxxx
loader_oep_dll_part2:
     dd ?   ; dll oep address part 2
loader_rubbish_11_119:
     db 119 dup($90)
     cmp dword [esp+$0C],DLL_PROCESS_ATTACH
     jne loader_dll_ret
     push ebx edi esi
     mov eax,[esp+$0C]
     call @f
@@:  pop edx
     add edx,loader_code_key_data1-@b
     db $B9 ; mov ecx,xxxxxxxx
loader_ecx_dll_oep:
     dd ?
loader_rubbish_12_37:
     db 37 dup($90)
     ; crc check - restore key
     push eax edx ecx
     call @f
@@:  pop eax
     sub eax,@b-loader_crypt_start
     mov dword [edx],1
     mov ecx,loader_crypt_end_adler-loader_crypt_start
     call Adler32_Update
     mov eax,[edx+8]
     xor [edx],eax
     pop ecx edx eax
     ; -----------------------
     call TEA_DecryptECB
;<><><><><><><><><><><><><><><><><><>;
     db $BF ; mov edi,xxxxxxxx
loader_reloc_base:
     dd ?
     db $BE ; mov esi,xxxxxxxx
loader_reloc_rva:
     dd ?
     db $B9 ; mov ecx,xxxxxxxx
loader_reloc_size:
     dd ?
     or esi,esi
     je @_ldr_reloc_skip
     jecxz @_ldr_reloc_skip
     mov ebx,[esp+$14] ; image base
     add esi,ebx ; reloc va
     sub edi,ebx ; delta
@_ldr_reloc_next_page:
     mov eax,[esi+IMAGE_FIXUPS_DIRECTORY.PageRVA]
     or eax,eax
     je @_ldr_reloc_skip
     add eax,ebx
     push esi ecx
     mov ecx,[esi+IMAGE_FIXUPS_DIRECTORY.BlockSize]
     sub ecx,8
     add esi,8
     xor edx,edx
@@:  mov dx,[esi]
     or dx,dx
     je @f
     and dx,$0FFF
     sub [eax+edx],edi
     add esi,2
     sub ecx,2
     jne @b
@@:  pop ecx esi
     sub ecx,[esi+IMAGE_FIXUPS_DIRECTORY.BlockSize]
     add esi,[esi+IMAGE_FIXUPS_DIRECTORY.BlockSize]
     or ecx,ecx
     jne @_ldr_reloc_next_page
@_ldr_reloc_skip:
;<><><><><><><><><><><><><><><><><><>;
     pop esi edi ebx
loader_dll_ret:
     retn
loader_rubbish_13_91:
     db 91 dup($90)
loader_lol:
     xor eax,eax
     xor esi,esi
     xor edi,edi
     mov ecx,$1000
@@:  popad

⌨️ 快捷键说明

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