1
0
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:
John Reiser 2000-12-17 18:33:42 +00:00
parent 118660205e
commit f275b12837
3 changed files with 29 additions and 18 deletions

View File

@ -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"

View File

@ -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++;

View File

@ -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'