Page 1 of 1

System reboot when trying to dump kernel cache on iOS

PostPosted: Wed Aug 03, 2016 7:57 am
by chengyang
Hello everyone, I'm just trying to dump the iOS kernel cache on my jailbroken iPad Mini, iOS 8.1
Code: Select all
   kret = task_for_pid(mach_task_self(), 0, &kernel_task);
   if (kret == KERN_SUCCESS) {
      printf("[x]tfp0 attach success!\n");
   } else {
      printf("[!]tfp0 failed with message %s!\n", mach_error_string(kret));

   for (addr = 0x80000000; addr < 0x81F02000; addr += bufsiz) {
      printf("reading aaaat : %x\n", addr);
      kret = vm_read(kernel_task, addr, bufsiz, &buf, &sz);
      if (kret != KERN_SUCCESS) {
         printf("vm_read failed : %x\n", kret);
         return -1;
      if (!buf || sz == 0) {
         printf("continue at %x\n", addr);
      printf("finish reading it \n");

I've already applied an entitlement on my binary to make it executable on my iPad, but the system will reboot during the vm_read loop. So the output will be:
Code: Select all
reading aaaat : 80018000
finish reading it
reading aaaat : 80018c00
finish reading it
reading aaaat : 80019800
finish reading it
reading aaaat : 8001a400
finish reading it
reading aaaat : 8001b000
finish reading it
reading aaaat : 8001bc00
Connection to closed by remote host.
Connection to closed.

Something was wrong but I can't figure it out, Can anyone give me some help plz?

Re: System reboot when trying to dump kernel cache on iOS

PostPosted: Wed Aug 03, 2016 1:16 pm
by Siguza
You're reading from 0x80000000 through 0x81F02000 like it was a block of continuously mapped memory.
But it is not. And as soon as you hit an unmapped portion and the kernel tries to read from there, you get a kernel panic and the device reboots.
Also note that the kernel is in no way guaranteed to reside below 0x81F02000.

The right approach here would be to iterate over all kernel memory regions with vm_region_recurse_64.
You can identify the one containing the kernel by its size being >1GB and its rwx permissions being set to ---. At least up to and including iOS 9.1, only ever one region exists that fulfils both criteria.
Within that region, the kernel lies at offset 0x1000 for 32-bit and 0x2000 for 64-bit, or twice these amounts starting with iOS 9.
At that offset, you should find the magic value 0xFEEDFACE or 0xFEEDFACF, respectively, followed by the rest of a Mach-O header from which you can reconstruct a file with pretty much everything but the symbol table (because that one doesn't get mapped to memory).

You can find an implementation of that vm_region_recurse_64 procedure in the get_kernel_base() function of my kern-utils fork, with additional checks for the magic header, to ensure we're not reading garbage. Tested on 32- and 64-bit on iOS 6 through 9.1.

An implementation of the reconstruction of the kernel from memory can be found in the same repository's kdump.c.

- Siguza

Re: System reboot when trying to dump kernel cache on iOS

PostPosted: Wed Aug 03, 2016 2:01 pm
by chengyang
Thank you very much for pointing out my mistakes! It helps me a lot.
In fact when I search on the forum I've found the code from another answer of you and I'm studying it now :D
The code is well commented. thanks again :D