📄 pcshrink.asm
字号:
; ** BETA VERSION **
;Phrozen Crew PE Shrinker v0.29 by Virogen
;(c)1999 Virogen/PC
;email: vgen@hotmail.com
;www: http://virogen.cjb.net
;----------------------------------------------------------------
;
; PCShrink v0.28 is a competitive PE compressor currently in
; its early to mid stages of development. The biggest difference
; compressed executable size of UPX/Petite and PCShrink is due
; to the compression algorithm (which will be improved upon soon)
; and the current inability of PCShrink to merge more than two
; sections together.
;
; Features:
; +Compresses code, data, imports, and resources.
; +Restructures resource section for better compression.
; +Preserves icons and version information.
; +Removes debug information.
; +Realigns, rebuilds, and trims PE.
; +Very small, fast decompressor (LZRW1).
; +Calculates correct new checksum.
; +Preserves file date/time.
;
; Warning: DO NOT ATTEMPT TO SHRINK DLLs! Support for relocations
; has not been added yet.
;
; v0.30 will introduce:
; +New compression algorithm.
; +Improved section merging.
; +Relocation support.
; +Optimizations.
;
; Usage:
; -PCSHRINK filename
;
; Update: v0.11: Fixed bug like 10 minutes after initial release.
; thanks to nIabI for testing.
; v0.12: Optimized lzrw1 decompression code some
; v0.13: Rewrote lzrw1 decompression procedure, vast improvement.
; Removed NULLing of destination buffer, not necessary
; I don't think.
; v0.14: +Fixed bug in LCC-WIN32 applications, where physical
; size of of sections is, surprisingly enough, not aligned.
; +No longer flagged by AVP as suspicious.
; v0.20: +Removes reloc table because it's not viable anymore
; anyway. This should cause no problems except in DLLs.
; In other words, don't use this utility on DLLs.
; +Compresses all resource data following the last icon,
; group icon, or version information. In other words,
; as much as possible without removing the shell icon and
; version information and not having to restructure
; the entire resource section. v0.30 will restructure the
; import section to improve compression.
; +Added compression of import table.
; +Removes debug information.
; +Moved symbiont up to end of last section raw data.
; +Renamed to PCSHRINK.
; v0.26: +Removes debug directory rva and size.
; +Resource section restructuring added!
; +Bug fix: I imported my resource type equates from
; windows.inc. Turns out the RT_GROUPICON was wrong,
; causing some applications to lose their shell icon
; after compression.
; +Fixed alignfile bug where handle was being closed.
; v0.28: +Added GUI
; +Added option to not restructure resource data
; +Added merging capabilities of first two sections.
; +TiTi/Blizzard suggested and coded an update for
; vgalign. His update to the vgalign routine is
; incorporated.
; v0.29: +Fixed stack bug which caused blue screens in win9x.
; v0.30 ::todo::new compression algorithm
; ::todo::added section merging capabilities of all sect
;
;
;
include mywin.inc
include pcshrink.inc
ID_OFF equ 0ch ; offset of our marker in PE
DECRYPTOR_SIZE equ (offset decryptor_code_end-offset decryptor_code) ;
VIRTUAL_SIZE equ DECRYPTOR_SIZE+5000h
MAX_OBJS equ 10 ; maximum objects we can handle
; by increasing this you are increasing the size
; of the table in decryptor by MAX_OBJS*8.
minimum_object_size equ 50h
.386p
locals
jumps
.model flat,STDCALL
extrn ExitProcess:PROC
extrn CreateFileA:PROC
extrn CloseHandle:PROC
extrn ReadFile:PROC
extrn WriteFile:PROC
extrn SetFilePointer:PROC
extrn MapViewOfFile:PROC
extrn CreateFileMappingA:PROC
extrn UnmapViewOfFile:PROC
extrn SetEndOfFile:PROC
extrn SetFilePointer:PROC
extrn GetFileAttributesA:PROC
extrn SetFileAttributesA:PROC
extrn GetFileSize:PROC
extrn GetFileSize:PROC
extrn GetFileTime:PROC
extrn SetFileTime:PROC
extrn CheckSumMappedFile:PROC
extrn MessageBoxA:PROC
extrn GetCommandLineA:PROC
extrn lstrcat:PROC
extrn IsBadReadPtr:PROC
extrn WriteConsoleA:PROC
extrn GetStdHandle:PROC
extrn ReadConsoleA:PROC
extrn GetProcessHeap:PROC
extrn HeapAlloc:PROC
extrn HeapFree:PROC
extrn PostQuitMessage:PROC
extrn DialogBoxParamA:PROC
extrn GetModuleHandleA:PROC
extrn lstrcpy:PROC
extrn SendMessageA:PROC
extrn LoadIconA:PROC
extrn SetDlgItemTextA:PROC
extrn GetDlgItemTextA:PROC
extrn GetOpenFileNameA:PROC
extrn IsDlgButtonChecked:PROC
extrn CheckDlgButton:PROC
org 0
.data ; data object
cr equ 0dh
lf equ 0ah
tab equ 9
hline equ 196
marker equ 90909090h
cr_lf_tab db cr,lf,tab,tab,0
init_txt db 50 dup(hline),cr,lf
caption db 'Phrozen Crew PE Shrinker v0.29, (c)1999 Virogen/PC',0
success_txt db 'Successfully compressed!'
file_txt db cr,lf,' Installed on file: ',tab,0
db 400 dup (0) ; plenty of space
obj_txt db cr,lf,' Installed in object: ',tab,0
db 9 dup(0)
eobj_txt db cr,lf,' Compressed objects: ',0
db (MAX_OBJS*8)+100 dup(0)
size_txt db cr,lf,'Original size: ',0
db 50 dup(0)
a_org_size db 15 dup(0)
inter db ' New size : ',0
a_new_size db 15 dup(0)
already_txt db 'File appears to already be compressed.',0
error_txt db 'There was an error compressing the file!',cr,lf
fname_txt db 'Specified file: ',0
db 260 dup(0)
obj_size db ' '
dd 0,0
cmdline_file db 256 dup(0)
;size_chg_txt db tab,'Aligned phys. size change : ',0
direction_txt db ' -> ',0
filter db 'PE EXE files',0,'*.exe',0
creation dd 0,0
lastaccess dd 0,0
lastwrite dd 0,0
oldchksum dd 0
new_fsize dd 0
p_lz_mem dd 0
fsize dd 0
orgalign dd 0
map_ptr dd 0
oldattrib dd 0
fnameptr dd 0
ptrpeheader dd 0
objPsize dd 0
maphandle dd 0
org_fsize dd 0
handle dd 0
objtblVA dd 0
objptr dd 0
lastobjimageoff dd 0
originalpsize dd 0
originalvsize dd 0
error db -1 ;
exporttbl dd 0
file_alignment dd 0
byteswrote dd 0
csize dd 0
IsRsrc dd 0
NewRsrcSize dd 0
RsrcStartRva dd 0
TotalSections dd 0
LastSectionUnaligned dd 0
SymbiontOffset dd 0
curUncompressableRsrcTable dd 0
pUncompressableRsrcTable dd 0
pCompressableRsrcTable dd 0
curCompressableRsrcTable dd 0
CompressableRsrc dd 0
HeapHandle dd 0
TreeLevel dd 0
RawLastSection dd 0
hInst dd 0
hMain dd 0
ofn OFN <0>
MergeTable dd MAX_OBJS dup(0)
CompressedSizeTable dd MAX_OBJS dup(0)
curSectionTableDisplacement dd 0
SectionMerging dd 1
RestructureResources dd 1
DoResource dd 1
secpt dd 0
bad_otbl:
dd 'ler.' ; relo
dd 'ade.' ; edata
dd 'ete.' ; etext
dd 'slt.' ; tls
dd 'SSB' ; .bss
db 'ssb.'
dd 0
;---- decompression symbiont code installed into file ----
;
;
unpre_reg equ edx ; the only register not
; preserved
decryptor_code:
pushfd
pushad
db 0bdh ; mov ebp
delta_offset dd 0
add dcomp_buffer_offset[ebp],ebp
lea esi,SymbiontMergeTable[ebp]
lodsd
or eax,eax
jz no_symbiont_merge
push eax
lodsd
xchg eax,ecx
lodsd
xchg eax,edi
pop esi
rep movsd
no_symbiont_merge:
call GlobalAllocVA[ebp],64,largest_needed_buffer[ebp]
push eax eax
sub eax,offset critical_symbiont
mov second_delta[ebp],eax
pop edi
lea esi,critical_symbiont[ebp]
mov ecx,(offset decryptor_code_end-offset critical_symbiont)/4+1
rep movsd
pop edi
jmp edi
critical_symbiont:
db 0bdh
second_delta dd 0
lea esi,otable[ebp]
;pop edi
add edi,(offset decryptor_code_end-offset critical_symbiont)
decomp_loop:
push ebp edi esi
lodsd
or eax,eax
jz decomp_done
xchg eax,edx
; edx->object
lodsd
xchg eax,ecx
; ecx=compressed size
push edi ecx
mov esi,edx
rep movsb
pop ecx edi
cmp edx,RsrcRva[ebp]
jnz not_rsrc_decrypt
mov eax,RsrcDisplacement[ebp]
pushad
mov esi,edi
mov edi,edx
mov ecx,eax
rep movsb
popad
add edi,eax
add edx,eax
sub ecx,eax
not_rsrc_decrypt:
call LZRW1_Decompress,edi,ecx,edx
pop esi edi ebp
add esi,8
jmp decomp_loop
decomp_done:
add esp,12 ; fixup stack from loop exit
goto_entry:
call ProcessImports
popad
popfd
db 0bah ; mov edx,dword
host_eip dd 0
jmp unpre_reg
ProcessImports proc
mov esi,iAddress[ebp]
or esi,esi
jz import_success
mov edx,svd_imgbase[ebp]
add esi,edx
dir_loop:
call ProcessImportDir,esi,edx
jc import_error
add esi,size ImportDir
cmp dword ptr iNameRva[esi],0
jnz dir_loop
import_success:
clc
ret
import_error:
stc
ret
ProcessImports endp
;
; ProcessImportDir(DWORD *IMPORT_DIRECTORY_VA, DWORD *IMAGEBASE)
;
;
ProcessImportDir proc
pop eax
pop esi ;1st import dir
pop edx ;edx->imagebase
push eax
mov ecx,iLookupRva[esi] ;ecx->lookup tbl
mov edi,iAddressRva[esi] ;edi->Address tbl
or ecx,ecx
jnz lr_ok
mov ecx,edi
lr_ok:
add ecx,edx
add edi,edx
mov eax,iNameRva[esi] ;eax->dll name
add eax,edx
push ecx edx
call [LoadLibraryVA+ebp],eax
pop edx ecx
or eax,eax
jz iret_error
mov DllHandle[ebp],eax
lookup_loop:
mov ebx,[ecx]
or ebx,ebx
jz iret_success
test ebx,80000000h ; import by ordinal flag
jnz import_by_ordinal
add ebx,edx
inc ebx
inc ebx
import_by_ordinal:
and ebx,7fffffffh
push ecx edx
call [GetProcAddressVA+ebp],DllHandle[ebp],ebx
pop edx ecx
or eax,eax
jz iret_error
stosd
add ecx,4 ; to next lookup tbl entry
jmp lookup_loop
iret_success:
clc
ret
iret_error:
stc
ret
ProcessImportDir endp
include lzrw1dec.asm ; LZRW1 decompression code
largest_needed_buffer dd 0
SymbiontMergeTable dd 0 ; offset into first section
dd 0 ; size in dwords
dd 0 ; address to move to
DllHandle dd 0
iAddress dd 0
svd_imgbase dd 0
RsrcDisplacement dd 0
RsrcRva dd 0
dcomp_buffer_offset dd offset dcomp_buffer
fake_it:
add1 dd offset lookup_tbl-offset fake_it
dd 0,0
add2 dd offset sz_first_dll-offset fake_it
add3 dd offset lookup_tbl-offset fake_it
dd 0,0,0,0,0
lookup_tbl:
add4:
LoadLibraryVA dd offset sz_api1-offset fake_it
add5:
GetProcAddressVA dd offset sz_api2-offset fake_it
add6:
GlobalAllocVA dd offset sz_api3-offset fake_it
dd 0
sz_first_dll db 'KERNEL32.DLL',0
name_tbl:
sz_api1 dw 0
db 'LoadLibraryA',0
sz_api2 dw 0
db 'GetProcAddress',0
sz_api3 dw 0
db 'GlobalAlloc',0
end_it:
otable dd ((MAX_OBJS+1)*2) dup (0)
otable_end:
;geteip:
; call getme
;getme:
; pop ebp
; sub ebp,offset getme ; fix it up
; ret
dcomp_buffer:
decryptor_code_end:
; --- end of decompressor code ---
; --- start of PCShrink ---
.code ; code object - change flags to rwx
start:
call GetProcessHeap
mov HeapHandle,eax
call GetCommandLineA ; retrieve command line
or eax,eax
jz no_cmd_line ; if none then abort /w msg
xchg esi,eax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -