Page 1 of 1

10.13.2 ASLR slide calculation failed

PostPosted: Tue Nov 14, 2017 10:51 am
by Dipti
In my kernel extension, I calculate the ASLR slide value using below code:

Code: Select all
/* This function tries to find mach-o image header magic bytes in kernel
 * address space. As a starting point address of interrupt descriptor table is
 * used.*/

__asm__ volatile ("sidt %0": "=m" (idtr));

Using tool -l , i checked the KERNEL_MH_START_ADDR == vmaddr == 0xffffff8000200000
but interrupt table address is coming less than base address 0xfffffd0000093580.....

why interrupt descriptor table address is coming less than start address?? Can slide be negative with ASLR? Tried to look for MH_MAGIC_64 around that address but could not find.

Any idea on what is changed with 10.13.2 Beta2???

Re: 10.13.2 ASLR slide calculation failed

PostPosted: Tue Nov 14, 2017 5:45 pm
by Siguza
I'm pretty sure that's a foul value, though I can't tell what's wrong exactly. But examining the kernel_map, I see no mapping whatsoever below 0xffffff7f80000000 (it's possible that there's a page table entry regardless, but that seems unlikely to me).
However, there are by far enough ways to get the kernel slide. I'm using host_priv_self() which returns &realhost, but you could also just instantiate an OSString or so, and read the first qword to get a pointer to its vtable.

Re: 10.13.2 ASLR slide calculation failed

PostPosted: Wed Nov 15, 2017 10:11 am
by Dipti
Thanks for your reply.

I followed steps given here ... roject.txt

i.e. using vm_kernel_unslide_or_perm_external and now I am getting proper slide and everything is working fine.

But I am still wondering why did the slide calculation failed using "side". And this code was working till date, it suddenly started failing from 10.13.2. Below is the code snippet which I was using :

Code: Select all
uint8_t idtr[10];
    __asm__ volatile ("sidt %0": "=m" (idtr));
    struct descriptor_idt * int80_descriptor = *((struct descriptor_idt **) &idtr[2]);
    uint64_t int80_address = ((uint64_t)int80_descriptor->offset_high   << 32) +
                             ((uint64_t)int80_descriptor->offset_middle << 16) +

    uint32_t *temp_address = (uint32_t *)int80_address;
   if ((uintptr_t)temp_address < KERNEL_MH_START_ADDR)
      return NULL;
    while (temp_address && *temp_address != MH_MAGIC_64)
    return temp_address;

Please let me know if you have any clue on why did it fail with above code. Just want to understand if anything is changed w.r.t. to SIDT from 10.13.2. Thanks.