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:
+5
-3
@@ -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 F f_cto32_e8_bswap_le
|
||||||
#define U u_cto32_e8_bswap_le
|
#define U u_cto32_e8_bswap_le
|
||||||
#include "fcto_ml2.ch"
|
#include "fcto_ml2.ch"
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
#undef F
|
#undef F
|
||||||
#undef COND
|
#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 F f_cto32_e9_bswap_le
|
||||||
#define U u_cto32_e9_bswap_le
|
#define U u_cto32_e9_bswap_le
|
||||||
#include "fcto_ml2.ch"
|
#include "fcto_ml2.ch"
|
||||||
@@ -88,7 +88,9 @@
|
|||||||
#undef F
|
#undef F
|
||||||
#undef COND
|
#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 F f_cto32_e8e9_bswap_le
|
||||||
#define U u_cto32_e8e9_bswap_le
|
#define U u_cto32_e8e9_bswap_le
|
||||||
#include "fcto_ml2.ch"
|
#include "fcto_ml2.ch"
|
||||||
|
|||||||
+11
-10
@@ -43,8 +43,7 @@ static int F(Filter *f)
|
|||||||
#endif
|
#endif
|
||||||
const unsigned size = f->buf_len;
|
const unsigned size = f->buf_len;
|
||||||
|
|
||||||
unsigned ic, jc, kc;
|
unsigned ic;
|
||||||
unsigned cto;
|
|
||||||
unsigned char cto8;
|
unsigned char cto8;
|
||||||
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
||||||
unsigned lastnoncall = size, lastcall = 0;
|
unsigned lastnoncall = size, lastcall = 0;
|
||||||
@@ -59,7 +58,7 @@ static int F(Filter *f)
|
|||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
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;
|
buf[b[ic+1]] |= 1;
|
||||||
}
|
}
|
||||||
@@ -67,7 +66,7 @@ static int F(Filter *f)
|
|||||||
{
|
{
|
||||||
int i = size - 6;
|
int i = size - 6;
|
||||||
do {
|
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;
|
buf[b[i+1]] |= 1;
|
||||||
} while (--i >= 0);
|
} while (--i >= 0);
|
||||||
}
|
}
|
||||||
@@ -101,13 +100,13 @@ static int F(Filter *f)
|
|||||||
return -1;
|
return -1;
|
||||||
cto8 = (unsigned char) ic;
|
cto8 = (unsigned char) ic;
|
||||||
}
|
}
|
||||||
cto = (unsigned)cto8 << 24;
|
unsigned const cto = (unsigned)cto8 << 24;
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
for (ic = 0; ic < size - 5; ic++)
|
||||||
{
|
{
|
||||||
if (!COND(b,ic))
|
if (!COND(b,ic,lastcall))
|
||||||
continue;
|
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
|
// try to detect 'real' calls only
|
||||||
if (jc < size)
|
if (jc < size)
|
||||||
{
|
{
|
||||||
@@ -117,8 +116,9 @@ static int F(Filter *f)
|
|||||||
if (ic - lastnoncall < 5)
|
if (ic - lastnoncall < 5)
|
||||||
{
|
{
|
||||||
// check the last 4 bytes before this call
|
// check the last 4 bytes before this call
|
||||||
|
unsigned kc;
|
||||||
for (kc = 4; kc; 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;
|
break;
|
||||||
if (kc)
|
if (kc)
|
||||||
{
|
{
|
||||||
@@ -164,11 +164,12 @@ static int U(Filter *f)
|
|||||||
const unsigned size5 = f->buf_len - 5;
|
const unsigned size5 = f->buf_len - 5;
|
||||||
const unsigned addvalue = f->addvalue;
|
const unsigned addvalue = f->addvalue;
|
||||||
const unsigned cto = f->cto << 24;
|
const unsigned cto = f->cto << 24;
|
||||||
|
unsigned lastcall = 0;
|
||||||
|
|
||||||
unsigned ic, jc;
|
unsigned ic, jc;
|
||||||
|
|
||||||
for (ic = 0; ic < size5; ic++)
|
for (ic = 0; ic < size5; ic++)
|
||||||
if (COND(b,ic))
|
if (COND(b,ic,lastcall))
|
||||||
{
|
{
|
||||||
jc = get_be32(b+ic+1);
|
jc = get_be32(b+ic+1);
|
||||||
if (b[ic+1] == f->cto)
|
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);
|
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
|
||||||
f->calls++;
|
f->calls++;
|
||||||
ic += 4;
|
ic += 4;
|
||||||
f->lastcall = ic+1;
|
f->lastcall = lastcall = ic+1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
f->noncalls++;
|
f->noncalls++;
|
||||||
|
|||||||
+13
-5
@@ -95,17 +95,25 @@ cjt16_L2:
|
|||||||
;; ============= 32-BIT CALLTRICK & JUMPTRICK
|
;; ============= 32-BIT CALLTRICK & JUMPTRICK
|
||||||
;; =============
|
;; =============
|
||||||
|
|
||||||
;; call & jump trick : 2 in 1
|
;; call & jump & Jxx trick : 3 in 1
|
||||||
%macro cjt32 1
|
%macro cjt32 1
|
||||||
%ifdef __CALLTR00__
|
%ifdef __CALLTR00__
|
||||||
|
mov bh, 0x0f ; avoid displ and literal in same instr
|
||||||
mov ecx, 'TEXL'
|
mov ecx, 'TEXL'
|
||||||
calltrickloop:
|
calltrickloop:
|
||||||
mov al, [edi]
|
mov al, [edi]
|
||||||
inc 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:
|
ct1:
|
||||||
cmp al, 1
|
cmp al, 0xE9 - 0xE8 ; span of JMP/CALL <d32>
|
||||||
ja calltrickloop
|
ja calltrickloop
|
||||||
|
ct3:
|
||||||
%ifdef __CTCLEVE1__
|
%ifdef __CTCLEVE1__
|
||||||
cmp byte [edi], '?'
|
cmp byte [edi], '?'
|
||||||
jnz calltrickloop
|
jnz calltrickloop
|
||||||
@@ -122,14 +130,14 @@ ct1:
|
|||||||
xchg al, ah
|
xchg al, ah
|
||||||
%endif; __CALLTR02__
|
%endif; __CALLTR02__
|
||||||
sub eax, edi
|
sub eax, edi
|
||||||
sub bl, 0xE8
|
sub bl, 0xE8 ; base of JMP/CALL <d32>
|
||||||
%ifnidn %1,0
|
%ifnidn %1,0
|
||||||
add eax, %1
|
add eax, %1
|
||||||
%endif
|
%endif
|
||||||
mov [edi], eax
|
mov [edi], eax
|
||||||
add edi, byte 5
|
add edi, byte 5
|
||||||
mov al, bl
|
mov al, bl
|
||||||
loop ct1
|
loop ct1 ; no Jxx <d32> next: needs 0x0f prefix first
|
||||||
%else; __CALLTR10__
|
%else; __CALLTR10__
|
||||||
;; 32-bit call XOR jump trick
|
;; 32-bit call XOR jump trick
|
||||||
mov ecx, 'TEXL'
|
mov ecx, 'TEXL'
|
||||||
|
|||||||
Reference in New Issue
Block a user