LDE на исключениях |
Oct. 20th, 2011|12:46 pm |
Indy предложил интересную идею для LDE - вместо того, чтобы парсить инструкции, пытаться исполнять их на границе двух страниц (RWX и NOACCESS), и по генерируемым исключениям определять длину. Скачать Индин код можно здесь Написал приблизительную реализацию для Linux:uint32_t esp, feip, fcr2;
extern void restore(void);
int lde_handler(int n, volatile struct sigcontext ctx)
{
feip = ctx.eip;
fcr2 = ctx.cr2;
ctx.eip = (uint32_t)restore;
}
int lde(uint8_t *op)
{
int i, l = 0, r = -1;
uint8_t *m = NULL;
m = mmap(NULL, 8192, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
mprotect(m, 4096, PROT_READ|PROT_WRITE|PROT_EXEC);
signal(SIGSEGV, lde_handler);
for (i = 1; i < 15 - len; i++) {
uint32_t a = (uint32_t)m + 4096 - i;
memcpy(a, op, i);
asm ("pushf; pusha; mov %%esp, esp; jmp *%%eax"::"a"(a));
asm ("restore: mov esp, %esp; popa; popf");
uint32_t t = m + 4096;
if (feip == a && fcr2 == t)
continue;
r = i + l;
break;
}
_error: munmap(m, 8192);
return r;
}
Попытка определить длину int3 закончится плавчевно конечно же, но не суть.
|
|