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

📄 pcshrink.asm

📁 WIN95/98 PE压缩软件源程序
💻 ASM
📖 第 1 页 / 共 4 页
字号:
        jnz	skip_align2
        mov	eax,handle                
        call	AlignFile 
skip_align2:               

        mov	edx,fsize
        lea	edi,a_new_size
        call	write_decimal
        
        call	lstrcat,offset size_txt,offset a_org_size
        call	lstrcat,offset size_txt,offset inter
        call	lstrcat,offset size_txt,offset a_new_size
                	                
        call    CloseHandle,handle
        
        call    SetFileAttributesA,fnameptr,oldattrib                    ; restore the original attributes                        
        ret                                 
CompressFile endp

; returns eax=new physical size
compress_object proc	                	        
        push	ecx esi ecx                
        call	HeapAlloc,HeapHandle,HEAP_ZERO_MEMORY,ecx
        mov	p_lz_mem,eax
        pop	ecx
        cmp	ecx,50h
        jbe	simple_copy
        call	LZRW1_COMPRESS,offset csize,eax,ecx,esi        
        pop	edi ecx        
    	mov 	esi,p_lz_mem    	
    	rep	movsb    	    	
    	jmp	did_compress_it
simple_copy:		
	pop	edi ecx
	mov	csize,eax
did_compress_it:        			
        call	HeapFree,HeapHandle,0,p_lz_mem
        mov	eax,csize        
	ret        
compress_object endp

test_obj proc    
        cmp     dword ptr [eax+objpoff],0       ; make sure physical offset isn't 0
        jz      ret_stc 
        cmp     dword ptr [eax+objpsize],0      ; make sure physical size isn't 0
        jz      ret_stc
        cmp	dword ptr [eax+objvsize],minimum_object_size
        jbe	ret_stc
	call    test_rvas
	jc      ret_stc	
        lea     esi,bad_otbl                     ; scan thru bad obj    
bobj_loop:                                       ; table       	
        xchg    eax,ebx
        lodsd
        xchg    eax,ebx        
        cmp     ebx,[eax]
        jz      ret_stc                                                         
        or      ebx,ebx
        jnz     bobj_loop
        clc
        ret
ret_stc:
        stc    
        ret
test_obj endp    

test_rvas proc
        pushad                
	mov     edx,exporttbl
	or	edx,edx
	jz	not_bad
        mov     ebx,dword ptr [eax+objrva]        
        cmp     ebx,edx
        jg      not_bad
        jz      ret_stc2
        mov     ebx,dword ptr [eax+40+objrva]
        or      ebx,ebx
        jz	ret_stc
        cmp     ebx,edx
        jg      ret_stc2
not_bad:        
	popad
        clc
        ret
ret_stc2:
	popad
	stc
	ret                
endp


GetPEHeader proc
        mov     esi,[eax+3Ch]                        ; where PE hdr pointer is 
        add     esi,eax                                                        
        mov     ptrpeheader,esi                      ; esi->PE Hdr             
        ret
GetPEHeader endp

; create_mapping - create file mapping of [handle]
; entry: ecx=+adjust mapping size
;
create_mapping proc
        push    ecx                                ; save additional mapping size  
        call    GetFileSize,handle,offset byteswrote        
        call    test_error                                                            
        jnc     no_error_gf
        pop	ecx
        jmp	create_abort
no_error_gf:       
        mov     fsize,eax                                                             
       
        pop     ecx                     ; restore map size
                
        add     eax,ecx
        call    CreateFileMappingA,handle,0,PAGE_READWRITE,0,eax,0
        call    test_error                   
        jc      create_abort
        mov     maphandle,eax
        
        call    MapViewOfFile,eax,FILE_MAP_WRITE,0,0,0
        call    test_error                                        
        jc      create_abort
        mov     map_ptr,eax
create_abort:
        ret
create_mapping endp


; test_error - test API for an error return
;  entry: eax=API return
;  returns: carry if error
;
test_error proc
        cmp     eax,-1 
        jz      api_err
        or      eax,eax
        jz      api_err
        clc
        ret
api_err:
        stc
        ret
test_error endp

; unmap file - Unmap view of file
; 
unmap proc
          
        call    UnmapViewOfFile,map_ptr  
        call    CloseHandle,maphandle
        ret

unmap endp

; sets eax on alignment of ecx
;
file_align_fix:
	mov	ecx,newalign
align_fix proc  
        xor     edx,edx                                                                    
        div     ecx                               ; /alignment                                  
        or      edx,edx				  ; if no remainder then no next
        jz      no_adjust
        inc     eax                               ; next alignment                                
no_adjust:        
        mul     ecx                               ; *alignment                             
        ret
align_fix endp     

OpenFile proc
        call    CreateFileA,esi,0c0000000h,0,0,3,20h,0                                      
        ret
OpenFile endp

newalign equ 200h
;-----------------------------------------------
; align file 
; call with eax=handle
;
AlignFile proc        
                                                                                                                                                                        	
        xor     ecx,ecx                                ; only map size of file      
        call    create_mapping                        ; create file mapping         
        jc      abort_encrypt                                                       
        mov     ecx,fsize
        or	ecx,ecx					; no file size?
        jz	abort_align
        mov 	org_fsize,ecx
                                               ; eax->mapped file                
                                                                                    
        call    GetPEHeader                           ; load esi->PE Header                 

	mov	eax,[esi+filealign]
	mov	orgalign,eax	
was_same:
        xor     eax,eax                                                                              
        mov     ax, word ptr [esi+NtHeaderSize]        ; get header size                             
        add     eax,18h                                ; object table is here                        
        add     eax,esi                                                                                      
        push	esi eax
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
;TiTi/Blizzard contributed the following addition to vgalign
;###########BEGINING OF APPENDED CODE#########################

	;lea	edi, [esi+headlen]		;beginning of obj table
	;virogen slight mod
	xchg	edi,eax
	mov	secpt, edi
	movzx	ecx, word ptr [esi+numObj]	;number of sections
	xor	ebx, ebx
secloop:
	call	SqueezeSection
	inc	ebx
	cmp	ebx, ecx
	je	secdone
	jmp	secloop
secdone:

;###########END OF APPENDED CODE##############################
	pop	eax esi
        
        pushad
        call	RemoveReloc,esi,eax
        popad
        	
	push    eax				       ; save ptr to obj table
	xor     edx,edx				  
	mov     ecx,40 
	xor     eax,eax
	mov     ax,[esi+numObj]
	inc     eax
	mul     ecx
	xchg    eax,ebx	
	pop 	eax	
	push    eax
	add     eax,ebx
	mov     ecx,[esi+filealign]
	call    align_fix
	xchg    ebx,eax					; ebx->phy. start of first obj
	pop 	eax
        
        mov 	ecx,ebx
        sub	ecx,map_ptr
        mov 	[esi+sizehdr],ecx			; save new total size of hdr        
        
        mov     ecx,newalign
        mov     [esi+filealign],ecx
                        
        movzx   ecx,word ptr [esi+numObj]               ; get number of objects           
	mov     edi,ebx					; edi->phy. start of first obj
; edi contains pointer to current writing address of the executable	
otbl_loop2:		
	push    eax ecx					
	mov     ecx,edi					; ecx->current obj poff
	sub     ecx,map_ptr				; get real obj poff
	mov     esi,[eax+objpoff]			; esi->original obj p. off
	mov     [eax+objpoff],ecx			; save new physical offset at cur
	mov	ebx,[eax+objvsize]			; get virtual size
	cmp     ebx,[eax+objpsize]			; bigger than physical size?
	jg      skip_align				; if so skip re-aligning this one
	mov     ecx,newalign				; ecx=200h
	push    eax 					; save obj rec ptr
	xchg    eax,ebx					; eax=object virtual size
	call    align_fix				; align that baby
	xchg    eax,ebx					; ebx=object virtual size
	pop 	eax					; restore obj ptr
	jmp     did_align				
skip_align:		
	mov     ebx,[eax+objpsize]			; use psize if vsize>psize
did_align:
	mov     [eax+objpsize],ebx			; save new aligned physical size
	add     esi,map_ptr				; set esi into mapping
	mov     ecx,ebx				 	; ecx=physical size
	rep     movsb					; store object at new|old location
next_obj2:
	pop     ecx eax					
	add     eax,40					; onto next object ..whohoo
	loop    otbl_loop2	
		
	sub     eax,40					; adjust to last object
	mov     ecx,[eax+objpsize]			; ecx=last object physical size
	add     ecx,[eax+objpoff]			; ecx=total physical size of file
	push    ecx					

	call    unmap
		
	mov     error,0
	
        pop     ecx                                                                      
        mov     new_fsize,ecx
        call    SetFilePointer,handle,ecx,0,FILE_BEGIN  ; move file pointer to       
                                                 ;	 real EOF                                   
        call    SetEndOfFile,handle
        xor     ecx,ecx
        call    create_mapping
        jc      unmapped2
        call    GetPEHeader
        lea     eax,[esi+checksum]
        call    CheckSumMappedFile,map_ptr,fsize,offset oldchksum,eax
        call    unmap
        
        mov     error,0                                ; if we made it here then no error
        jmp     unmapped2                                
abort_align:
        call    unmap                                  ;unmap if aborted infection
unmapped2:
                                                                                     
;        call    CloseHandle,handle                                                                          
        ret                                 
AlignFile endp
;TiTi/Blizzard
;###########BEGINING OF APPENDED CODE#########################
SqueezeSection	proc	
	push	ebx
	push	ecx
	mov	eax, 28h
	mul	bl
	add	eax, secpt
	mov	esi, eax	;pointer to (i) section entry in table

	mov	eax, [esi+10h]	;get raw size of (i) section
	mov	ecx, eax
	add	eax, [esi+14h]	;add raw offset to size
	add	eax, map_ptr	;add file mapping offset

	mov	edi, eax
	dec	edi
	xor	eax, eax
	std			;set direction flag
	repe	scasb		;calculate REAL end of section (eliminate 00)
	cld			;restore direction flag
	add	edi, 2		;adjust real end of section
		
	sub	edi, [esi+14h]	;sub raw offset from new size
	sub	edi, map_ptr	;sub mapping offset to obtain real size
	
; ---- mods here by Virogen     
        ;and    edi, 0FFFFFF00h ;only get main part     
        ;add    edi, 100h

        mov     ecx,newalign
        xchg    eax,edi
        call    align_fix 
;ssloop:                                ;find a new section size multiple of 'newalign'
;       mov     eax, edi
;       xor     edx, edx
;       div     ecx
;       test    edx, edx
;       je      ssend
;       add     edi, 100h
        
;       jmp     ssloop
ssend:
	cmp	eax, [esi+10h]
	jge	ssnofix		;test is new size is lower than original
	mov	[esi+10h], eax	;write new section size
; --- mods end	

ssnofix:
	pop	ecx
	pop	ebx
	ret
SqueezeSection	endp
;###########END OF APPENDED CODE##############################


write_decimal proc
	push	edi
	mov	ecx,3
	xor	eax,eax
	rep	stosd
	pop	edi
    	mov 	eax,edx
    	mov 	esi,10
    	xor 	ecx,ecx
nz:
	xor 	edx,edx
    	div 	esi
    	push 	edx
    	inc 	ecx
    	or 	eax,eax
    	jnz 	nz
wdl:
    	pop 	edx
    	add 	dl,'0'
    	mov 	al,dl
    	stosb
    	loop wdl
	ret           
write_decimal endp

CalcPhysicalAddress proc
	push	esi edi edx ecx eax	
        mov     eax,objptr
	mov	ecx,TotalSections
continue_find2: 
        mov     edx,eax[objrva]         
        cmp     edx,ebx
        ja 	got_obj_no_dec2
        add	eax,40
        loop	continue_find2        
got_obj_no_dec2:
        sub     eax,40
        sub     ebx,eax[objrva]
        add     ebx,eax[objpoff]
	pop	eax ecx edx edi esi
	ret
CalcPhysicalAddress endp

CalcVirtualAddress proc
	push	esi edi edx ecx eax	
        mov     eax,objptr
	mov	ecx,TotalSections
continue_find: 
        mov     edx,eax[objpoff]         
        cmp     edx,ebx
        ja 	got_obj_no_dec
        add	eax,40
        loop	continue_find        
got_obj_no_dec:
        sub     eax,40
        sub     ebx,eax[objpoff]
        add     ebx,eax[objrva]
	pop	eax ecx edx edi esi
	ret
CalcVirtualAddress endp

include LZRW1COMP.ASM

end start
ends

⌨️ 快捷键说明

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