Thursday, October 20, 2011

LDE based on exceptions

Recently Indy (from proposed the new design for the length disassembler. Rather than compare the bytes against patterns it's put the instruction on the boundary between RWE and NOACCESS pages. First, one byte is copied, if it's not enough, the CPU would try to fetch the next one and will trigger the exception. Engine will catch the exception and copy the next byte and so on. Here you can download his code. I also write a sketch of this idea for Linux (it needs a lot of improvements, but working in a simple cases):
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)
                r = i + l;
_error: munmap(m, 8192);
        return r;

No comments:

Post a Comment