mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
call+jmp trick filter: add Jxx with 32-bit displacement
src/fcto_ml.ch src/fcto_ml2.ch src/stub/macros.ash committer: jreiser <jreiser> 977078022 +0000
This commit is contained in:
parent
118660205e
commit
f275b12837
|
@ -66,7 +66,7 @@
|
|||
//
|
||||
**************************************************************************/
|
||||
|
||||
#define COND(b,x) (b[x] == 0xe8)
|
||||
#define COND(b,x,lastcall) (b[x] == 0xe8)
|
||||
#define F f_cto32_e8_bswap_le
|
||||
#define U u_cto32_e8_bswap_le
|
||||
#include "fcto_ml2.ch"
|
||||
|
@ -77,7 +77,7 @@
|
|||
#undef F
|
||||
#undef COND
|
||||
|
||||
#define COND(b,x) (b[x] == 0xe9)
|
||||
#define COND(b,x,lastcall) (b[x] == 0xe9)
|
||||
#define F f_cto32_e9_bswap_le
|
||||
#define U u_cto32_e9_bswap_le
|
||||
#include "fcto_ml2.ch"
|
||||
|
@ -88,7 +88,9 @@
|
|||
#undef F
|
||||
#undef COND
|
||||
|
||||
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||
#define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9 \
|
||||
|| (lastcall!=(x) && 0xf==b[(x)-1] \
|
||||
&& 0x80<=b[x] && b[x]<=0x8f) )
|
||||
#define F f_cto32_e8e9_bswap_le
|
||||
#define U u_cto32_e8e9_bswap_le
|
||||
#include "fcto_ml2.ch"
|
||||
|
|
|
@ -43,8 +43,7 @@ static int F(Filter *f)
|
|||
#endif
|
||||
const unsigned size = f->buf_len;
|
||||
|
||||
unsigned ic, jc, kc;
|
||||
unsigned cto;
|
||||
unsigned ic;
|
||||
unsigned char cto8;
|
||||
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
||||
unsigned lastnoncall = size, lastcall = 0;
|
||||
|
@ -59,7 +58,7 @@ static int F(Filter *f)
|
|||
|
||||
#if 1
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
if (COND(b,ic) && get_le32(b+ic+1)+ic+1 >= size)
|
||||
if (COND(b,ic,lastcall) && get_le32(b+ic+1)+ic+1 >= size)
|
||||
{
|
||||
buf[b[ic+1]] |= 1;
|
||||
}
|
||||
|
@ -67,7 +66,7 @@ static int F(Filter *f)
|
|||
{
|
||||
int i = size - 6;
|
||||
do {
|
||||
if (COND(b,i) && get_le32(b+i+1)+i+1 >= size)
|
||||
if (COND(b,i,lastcall) && get_le32(b+i+1)+i+1 >= size)
|
||||
buf[b[i+1]] |= 1;
|
||||
} while (--i >= 0);
|
||||
}
|
||||
|
@ -101,13 +100,13 @@ static int F(Filter *f)
|
|||
return -1;
|
||||
cto8 = (unsigned char) ic;
|
||||
}
|
||||
cto = (unsigned)cto8 << 24;
|
||||
unsigned const cto = (unsigned)cto8 << 24;
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
{
|
||||
if (!COND(b,ic))
|
||||
if (!COND(b,ic,lastcall))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
unsigned const jc = get_le32(b+ic+1)+ic+1;
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
|
@ -117,8 +116,9 @@ static int F(Filter *f)
|
|||
if (ic - lastnoncall < 5)
|
||||
{
|
||||
// check the last 4 bytes before this call
|
||||
unsigned kc;
|
||||
for (kc = 4; kc; kc--)
|
||||
if (COND(b,ic-kc) && b[ic-kc+1] == cto8)
|
||||
if (COND(b,ic-kc,lastcall) && b[ic-kc+1] == cto8)
|
||||
break;
|
||||
if (kc)
|
||||
{
|
||||
|
@ -164,11 +164,12 @@ static int U(Filter *f)
|
|||
const unsigned size5 = f->buf_len - 5;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
const unsigned cto = f->cto << 24;
|
||||
unsigned lastcall = 0;
|
||||
|
||||
unsigned ic, jc;
|
||||
|
||||
for (ic = 0; ic < size5; ic++)
|
||||
if (COND(b,ic))
|
||||
if (COND(b,ic,lastcall))
|
||||
{
|
||||
jc = get_be32(b+ic+1);
|
||||
if (b[ic+1] == f->cto)
|
||||
|
@ -176,7 +177,7 @@ static int U(Filter *f)
|
|||
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
|
||||
f->calls++;
|
||||
ic += 4;
|
||||
f->lastcall = ic+1;
|
||||
f->lastcall = lastcall = ic+1;
|
||||
}
|
||||
else
|
||||
f->noncalls++;
|
||||
|
|
|
@ -95,17 +95,25 @@ cjt16_L2:
|
|||
;; ============= 32-BIT CALLTRICK & JUMPTRICK
|
||||
;; =============
|
||||
|
||||
;; call & jump trick : 2 in 1
|
||||
;; call & jump & Jxx trick : 3 in 1
|
||||
%macro cjt32 1
|
||||
%ifdef __CALLTR00__
|
||||
mov bh, 0x0f ; avoid displ and literal in same instr
|
||||
mov ecx, 'TEXL'
|
||||
calltrickloop:
|
||||
mov al, [edi]
|
||||
inc edi
|
||||
sub al, 0xE8
|
||||
sub al, 0x80 ; base of Jxx <d32>
|
||||
cmp al, 0x8f - 0x80 ; span of Jxx <d32>
|
||||
ja ct2 ; not Jxx <d32>
|
||||
cmp byte [edi -2], bh ; prefix opcode of Jxx <d32>
|
||||
je ct3
|
||||
ct2:
|
||||
sub al, 0xE8 - 0x80 ; base of JMP/CALL <d32>
|
||||
ct1:
|
||||
cmp al, 1
|
||||
cmp al, 0xE9 - 0xE8 ; span of JMP/CALL <d32>
|
||||
ja calltrickloop
|
||||
ct3:
|
||||
%ifdef __CTCLEVE1__
|
||||
cmp byte [edi], '?'
|
||||
jnz calltrickloop
|
||||
|
@ -122,14 +130,14 @@ ct1:
|
|||
xchg al, ah
|
||||
%endif; __CALLTR02__
|
||||
sub eax, edi
|
||||
sub bl, 0xE8
|
||||
sub bl, 0xE8 ; base of JMP/CALL <d32>
|
||||
%ifnidn %1,0
|
||||
add eax, %1
|
||||
%endif
|
||||
mov [edi], eax
|
||||
add edi, byte 5
|
||||
mov al, bl
|
||||
loop ct1
|
||||
loop ct1 ; no Jxx <d32> next: needs 0x0f prefix first
|
||||
%else; __CALLTR10__
|
||||
;; 32-bit call XOR jump trick
|
||||
mov ecx, 'TEXL'
|
||||
|
|
Loading…
Reference in New Issue
Block a user