filters for unix(linux)
Modified Files: filteri.cpp filter/ctojr.h linker.cpp linker.h mem.cpp mem.h p_lx_elf.cpp p_lx_elf.h p_lx_exc.cpp p_lx_exc.h p_lx_sh.cpp p_lx_sh.h p_unix.cpp packer.cpp packer.h packhead.cpp stub/Makefile stub/macros.ash stub/l_lx_elf.c stub/l_lx_elf86.asm stub/l_lx_elf86.lds stub/l_lx_exec.c stub/l_lx_exec86.asm stub/l_lx_exec86.lds stub/l_lx_sh86.asm stub/l_lx_sh86.lds Added Files: filter/ctok.h stub/fold_elf86.asm stub/fold_exec86.asm stub/fold_sh86.asm committer: jreiser <jreiser> 979796725 +0000
This commit is contained in:
@@ -168,6 +168,53 @@ ctend:
|
||||
%endmacro
|
||||
|
||||
|
||||
;; call/jump/jcc trick; also used more than once (and/or optionally), so
|
||||
;; ecx has byte count (not count of applied instances), and
|
||||
;; edi points to buffer.
|
||||
%macro ckt32 1 ; param: where is cto8 (dl, bl, or literal)
|
||||
;__CKLLTR00__
|
||||
mov esi, edi ; base of block
|
||||
jmps ckstart
|
||||
ckloop3:
|
||||
mov al, [edi]
|
||||
inc edi
|
||||
;__CKLLTR10__ Jcc only
|
||||
cmp al, 0x80 ; lo of 6-byte Jcc
|
||||
jb ckloop2
|
||||
cmp al, 0x8f ; hi of 6-byte Jcc
|
||||
ja ckloop2
|
||||
cmp byte [edi -2], 0x0F ; prefix of 6-byte Jcc
|
||||
je ckmark
|
||||
ckloop2:
|
||||
;__CKLLTR20__
|
||||
sub al, 0xE8
|
||||
cmp al, 0xE9 - 0xE8
|
||||
ja ckcount
|
||||
ckmark:
|
||||
cmp byte [edi], %1 ; cto8
|
||||
jnz ckcount
|
||||
mov eax, [edi]
|
||||
|
||||
shr ax, 8
|
||||
rol eax, 16
|
||||
xchg al, ah
|
||||
|
||||
sub eax, edi
|
||||
add eax, esi
|
||||
mov [edi], eax
|
||||
add edi, byte 4
|
||||
ckstart:
|
||||
sub ecx, byte 4
|
||||
;__CKLLTR30__ Jcc only
|
||||
mov al, [edi]
|
||||
inc edi
|
||||
loop ckloop2 ; prefix cannot overlap previous displacement
|
||||
;__CKLLTR40__
|
||||
ckcount:
|
||||
dec ecx
|
||||
jg ckloop3
|
||||
ckend:
|
||||
%endmacro
|
||||
|
||||
;; =============
|
||||
;; ============= 32-BIT RELOCATIONS
|
||||
@@ -213,4 +260,312 @@ reloc_endx:
|
||||
%endmacro
|
||||
|
||||
|
||||
;; =============
|
||||
;; ============= 32-BIT CALL TRICK UNFILTER WITH MostRecentlyUsed BUFFER
|
||||
;; =============
|
||||
|
||||
;;;; names of pseudo-sections for addLoader:
|
||||
;; LXUNFnnn Linux unfilter
|
||||
;; LXMRUnnn MostRecentlyUsed recoding of destinations
|
||||
;; MRUARBnn arbitrary number of entries in wheel
|
||||
;; MRUBITSn power of 2 entries in wheel (smaller code)
|
||||
;; MRUBYTEn 256 entries in wheel (smallest code)
|
||||
|
||||
%macro ctojr32 0
|
||||
;; I got confused by the syntactic sugar of the fake %ifdefs.
|
||||
;; I can read the section name more easily when it is at the left margin.
|
||||
;; Also, some of the logic to select the sections is not that simple,
|
||||
;; and any mismatch between the logic and the %ifdefs is very confusing.
|
||||
;; Instead, I use comments after the section name, and blank lines for grouping.
|
||||
|
||||
;__LXUNF000__ enter at +0 for decompression; +2 for unfiltering
|
||||
jmps decompr0
|
||||
;__LXUNF002__
|
||||
;; 2+ address of decompress subroutine
|
||||
;; unfilter(upx_byte *, length, cto8)
|
||||
lxunfilter:
|
||||
pop edx ; return address
|
||||
pop eax ; upx_byte *, same as addvalue
|
||||
pop ecx ; length
|
||||
xchg eax, edi ; edi= pointer; eax= saved_edi
|
||||
pusha ; save C-convention ebx, ebp, esi, edi; also eax, edx
|
||||
|
||||
; at most one of the next 2
|
||||
;__MRUBYTE0__ 256==n_mru
|
||||
xor ebx, ebx ; zero
|
||||
;__LXMRU005__ 0!=n_mru
|
||||
mov ebx, 'NMRU' ; modified N_MRU or N_MRU -1
|
||||
|
||||
;__LXMRU006__ 0!=n_mru
|
||||
push byte 0x0f ; prefix of 6-byte Jcc <d32>
|
||||
pop eax
|
||||
mov ah, [esp + 8*4] ; cto8
|
||||
;__LXMRU007__ 0==n_mru
|
||||
push byte 0x0f ; prefix of 6-byte Jcc <d32>
|
||||
pop ebx
|
||||
mov bh, [esp + 8*4] ; cto8
|
||||
|
||||
;__LXUNF008__
|
||||
mov dl, [esp + 8*4] ; cto8
|
||||
|
||||
;__LXUNF010__
|
||||
jmpn lxunf0
|
||||
decompr0:
|
||||
|
||||
;; These %define are only if 0!=n_mru;
|
||||
;; else 0x0F==bl && cto8==bh==dh && 0xE8==dl && addvalue==esi .
|
||||
%define n_mru [esi]
|
||||
%define n_mru1 [esi]
|
||||
%define tail [esi + 4*1]
|
||||
%define cto8_e8e9 [esi + 4*2]
|
||||
%define cto8_0f [esi + 4*3]
|
||||
%define addvalue [esi + 4*4]
|
||||
%define tmp ebp
|
||||
%define hand ebx
|
||||
%define hand_l bl
|
||||
%define kh edx
|
||||
%define kh_l dl
|
||||
|
||||
;__LXJCC010__
|
||||
lxunf2: ; have seen 0x80..0x8f of possible recoded 6-byte Jcc <d32>
|
||||
movzx ebp, word [edi] ; 2 bytes, zero-extended
|
||||
|
||||
;__LXMRU045__ 0!=n_mru
|
||||
sub ebp, cto8_0f
|
||||
;__LXMRU046__ 0==n_mru
|
||||
sub ebp, ebx
|
||||
|
||||
;__LXJCC020__ 0==n_mru, or Jcc excluded ('sub' of equals clears Carry)
|
||||
jne unfcount
|
||||
;__LXJCC021__ 0!=n_mru and Jcc participates; must set Carry
|
||||
sub ebp, byte 1 ; set Carry iff in range
|
||||
jnb unfcount
|
||||
|
||||
;__LXJCC023__ found Jcc; re-swap 0x8Y opcode and 0x0f prefix
|
||||
mov byte [edi -1], bl ; 0x0f prefix
|
||||
dec ecx ; preserve Carry
|
||||
mov byte [edi], al ; Jcc opcode
|
||||
inc edi ; preserve Carry
|
||||
|
||||
;__LXUNF037__
|
||||
%define jc eax
|
||||
|
||||
lxunf: ; in: Carry set iff we should apply mru and 0!=n_mru
|
||||
mov eax, [edi] ; BE32 displacement with cto8 in low 8 bits
|
||||
|
||||
;__LXUNF386__ 0!=n_mru && 386
|
||||
pushf
|
||||
;__LXUNF387__ ==386
|
||||
shr ax, 8
|
||||
rol eax, 16
|
||||
xchg al, ah
|
||||
;__LXUNF388__ 0!=n_mru && 386
|
||||
popf
|
||||
jnc unf_store ; do not apply mru
|
||||
|
||||
;__LXUNF486__ >=486
|
||||
mov al, byte 0
|
||||
bswap eax ; preserve Carry (2-byte instruction)
|
||||
;__LXUNF487__ 0!=n_mru && >=486
|
||||
jnc unf_store ; do not apply mru
|
||||
|
||||
;__LXMRU065__ 0!=n_mru
|
||||
shr jc, 1 ; eax= jc, or mru index
|
||||
jnc mru4 ; not 1st time for this jc
|
||||
;__MRUBYTE3__
|
||||
dec hand_l
|
||||
;__MRUARB30__
|
||||
dec hand
|
||||
;__MRUBITS3__
|
||||
and hand, n_mru1
|
||||
;__MRUARB40__
|
||||
jge mru3
|
||||
add hand, n_mru
|
||||
mru3:
|
||||
;__LXMRU070__
|
||||
|
||||
mov [esp + 4*hand], jc ; 1st time: mru[hand] = jc
|
||||
jmps unf_store
|
||||
|
||||
mru4: ; not 1st time for this jc
|
||||
lea kh, [jc + hand] ; kh = jc + hand
|
||||
;__MRUBYTE4__
|
||||
movzx kh, kh_l
|
||||
;__MRUBITS4__
|
||||
and kh, n_mru1
|
||||
;__MRUARB50__
|
||||
cmp kh, n_mru
|
||||
jb mru5
|
||||
sub kh, n_mru
|
||||
mru5:
|
||||
;__LXMRU080__
|
||||
mov jc, [esp + 4*kh] ; jc = mru[kh]
|
||||
;__MRUBYTE5__
|
||||
dec hand_l
|
||||
;__MRUARB60__
|
||||
dec hand
|
||||
;__MRUBITS5__
|
||||
and hand, n_mru1
|
||||
;__MRUARB70__
|
||||
jge mru6
|
||||
add hand, n_mru
|
||||
mru6:
|
||||
;__LXMRU090__
|
||||
|
||||
mov tmp, [esp + 4*hand] ; tmp = mru[hand]
|
||||
test tmp,tmp
|
||||
jnz mru8
|
||||
|
||||
push jc ; ran out of registers
|
||||
mov eax, tail
|
||||
|
||||
;__MRUBYTE6__
|
||||
dec al
|
||||
;__MRUARB80__
|
||||
dec eax
|
||||
;__MRUBITS6__
|
||||
and eax, n_mru1
|
||||
;__MRUARB90__
|
||||
jge mru7
|
||||
add eax, n_mru
|
||||
mru7:
|
||||
;__LXMRU100__
|
||||
|
||||
xor tmp,tmp
|
||||
mov tail, eax
|
||||
xchg [4+ esp + 4*eax], tmp ; tmp = mru[tail]; mru[tail] = 0
|
||||
pop jc
|
||||
mru8:
|
||||
mov [esp + 4*kh ], tmp ; mru[kh] = tmp
|
||||
mov [esp + 4*hand], jc ; mru[hand] = jc
|
||||
;__LXUNF040__
|
||||
unf_store:
|
||||
sub eax, edi
|
||||
sub ecx, byte 4
|
||||
|
||||
; one of the next2
|
||||
;__LXMRU110__ 0!=n_mru
|
||||
add eax, addvalue
|
||||
;__LXMRU111__ 0==n_mru
|
||||
add eax, esi ; addvalue (same as initial pointer)
|
||||
|
||||
;__LXUNF041__
|
||||
mov [edi], eax
|
||||
add edi, byte 4
|
||||
jmps unfcount
|
||||
;__LXUNF042__
|
||||
lxunf0: ;; continuation of entry prolog for unfilter
|
||||
;__LEXEC016__ bug in APP: jmp and label must be in same .asx/.asy
|
||||
jmp lxunf0 ; this instr does not really go here!
|
||||
|
||||
;__LXMRU010__ 0!=n_mru
|
||||
push eax ; cto8_0f
|
||||
;__LXJMPA00__ only JMP, and not CALL, is filtered
|
||||
mov al, 0xE9
|
||||
;__LXCALLB0__ only CALL, or both CALL and JMP are filtered
|
||||
mov al, 0xE8
|
||||
;__LXUNF021__ common tail
|
||||
push eax ; cto8_e8e9
|
||||
push byte 0 ; tail
|
||||
push ebx ; n_mru or n_mru1
|
||||
mov esi, esp ; flat model "[esi]" saves a byte over "[ebp]"
|
||||
|
||||
;__LXMRU022__ 0==n_mru
|
||||
pop esi ; addvalue
|
||||
mov edx, ebx ; dh= cto8
|
||||
;__LXJMPA01__ only JMP, and not CALL, is filtered
|
||||
mov dl, 0xE9
|
||||
;__LXCALLB1__ only CALL, or both CALL and JMP are filtered
|
||||
mov dl, 0xE8
|
||||
|
||||
|
||||
;__MRUBITS1__
|
||||
inc hand ; n_mru1 ==> n_mru
|
||||
;__LXMRU030__
|
||||
lxunf1: ; allocate and clear mru[]
|
||||
push byte 0
|
||||
|
||||
; one of the next 2, if n_mru
|
||||
;__MRUBYTE1__
|
||||
dec hand_l
|
||||
;__MRUARB10__
|
||||
dec hand
|
||||
|
||||
;__LXMRU040__ 0!=n_mru
|
||||
jnz lxunf1 ; leaves 0=='hand'
|
||||
|
||||
;__LXUNF030__
|
||||
lxctloop:
|
||||
movzx eax, word [edi] ; 2 bytes, zero extended
|
||||
inc edi
|
||||
;__LXJCC000__
|
||||
cmp al, 0x80 ; lo of Jcc <d32>
|
||||
jb lxct1
|
||||
cmp al, 0x8f ; hi of Jcc <d32>
|
||||
jbe lxunf2
|
||||
lxct1:
|
||||
|
||||
;__LXCJ0MRU__ 0==n_mru
|
||||
sub eax, edx
|
||||
;__LXCJ1MRU__ 0!=n_mru
|
||||
sub eax, cto8_e8e9
|
||||
|
||||
; both CALL and JMP are filtered
|
||||
;__LXCALJMP__
|
||||
sub eax, byte 1+ (0xE9 - 0xE8) ; set Carry iff in range (result: -2, -1)
|
||||
|
||||
; only CALL, or only JMP, is filtered
|
||||
;__LXCALL00__ 0==n_mru
|
||||
je lxunf
|
||||
;__LXCALL01__ 0!=n_rmu
|
||||
sub eax, byte 1 ; set Carry iff in range
|
||||
|
||||
;__LXCJ2MRU__ 0==n_mru, or apply mru to all that are filtered here
|
||||
jb lxunf ; only Carry (Borrow) matters
|
||||
;__LXCJ4MRU__ 0!=n_mru, but apply mru only to subset of filtered here
|
||||
jnb unfcount ; was not filtered anyway: do not unfilter
|
||||
|
||||
;we will unfilter, and 0!=n_mru, but should we apply mru?
|
||||
;__LXCJ6MRU__ apply mru to JMP only (0xFF==al)
|
||||
jpe lxct3 ; jump if even number of 1 bits in al
|
||||
;__LXCJ7MRU__ apply mru to CALL only (0xFE==al)
|
||||
jpo lxct3 ; jump if odd number of 1 bits in al
|
||||
;__LXCJ8MRU__ do not apply mru to one or both
|
||||
clc
|
||||
lxct3:
|
||||
jmps lxunf
|
||||
|
||||
;__LXUNF034__
|
||||
unfcount:
|
||||
dec ecx
|
||||
jg lxctloop
|
||||
|
||||
;__LXMRU055__
|
||||
mov edi, esp ; clear mru[] portion of stack
|
||||
;__MRUBYTE2__
|
||||
mov ecx, 4+ 256 ; unused, tail, cto8_e8e9, cto8_0f
|
||||
;__MRUBITS2__
|
||||
mov ecx, n_mru1
|
||||
add ecx, byte 1+ 4 ; n_mru1, tail, cto8_e8e9, cto8_0f
|
||||
;__MRUARB20__
|
||||
mov ecx, n_mru
|
||||
add ecx, byte 4 ; n_mru, tail, cto8_e8e9, cto8_0f
|
||||
;__LXMRU057__
|
||||
xor eax, eax
|
||||
rep
|
||||
stosd
|
||||
mov esp, edi
|
||||
|
||||
;__LXMRU058__ 0==n_mru
|
||||
push esi
|
||||
;__LXUNF035__
|
||||
popa
|
||||
xchg eax, edi
|
||||
push ecx
|
||||
push eax
|
||||
push edx
|
||||
ret
|
||||
|
||||
%endmacro
|
||||
|
||||
; vi:ts=8:et:nowrap
|
||||
|
||||
Reference in New Issue
Block a user