In case anyone needs this.
git diff
+++ b/main.m
@@ -41,6 +41,9 @@
vm_region_info_t info,
mach_msg_type_number_t *count,
mach_port_t *object_name);
+
+extern kern_return_t mach_vm_protect(vm_map_t, mach_vm_address_t, mach_vm_size_t, boolean_t, vm_prot_t);
+
#else
#include <mach/mach_vm.h>
#endif
@@ -147,15 +150,9 @@ int main(int argc, char *argv[])
if ((substring = memmem((const void *)buffer, bufferSize, &oldValue, sizeof(oldValue))) != NULL)
{
occurranceCount++;
-#if CGFLOAT_IS_DOUBLE
long realAddress = (long)substring - (long)buffer + (long)address;
printf("Search result %2d: %d at 0x%0lx (%s)\n", occurranceCount, oldValue, realAddress, (protection & VM_PROT_WRITE) != 0 ? "writable" : "non-writable");
[substringArray addObject:[NSNumber numberWithLong:realAddress]];
-#else
- int realAddress = (int)substring - (int)buffer + (int)address;
- printf("Search result %2d: %d at 0x%0x (%s)\n", occurranceCount, oldValue, realAddress, (protection & VM_PROT_WRITE) != 0 ? "writable" : "non-writable");
- [substringArray addObject:[NSNumber numberWithInt:realAddress]];
-#endif
[protectionArray addObject:[NSString stringWithUTF8String:(protection & VM_PROT_WRITE) != 0 ? "writable" : "non-writable"]];
}
}
@@ -190,8 +187,44 @@ int main(int argc, char *argv[])
printf("Enter the new value: ");
int newValue; // change type: unsigned int, long, unsigned long, etc. Should be customizable!
scanf("%d", &newValue);
+
+
+ //Changes for iOS9 ASLR
+ //get original memory protection
+ mach_vm_size_t size = 0;
+ mach_port_t object_name = 0;
+ vm_region_basic_info_data_64_t info = {0};
+ mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
+ /* mach_vm_region will return the address of the map into the address argument so we need to make a copy */
+ mach_vm_address_t dummyadr = modAddress;
+ if ( (kret = mach_vm_region(task, &dummyadr, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_t)&info, &count, &object_name)) )
+ {
+ printf("mach_vm_region failed with error %d", kret);
+ exit(1);
+ }
+
+ //change protections, write, and restore original protection
+ task_suspend(task);
+ if ( (kret = mach_vm_protect(task, modAddress, sizeof(newValue), FALSE, VM_PROT_WRITE | VM_PROT_READ | VM_PROT_COPY)) )
+ {
+ printf("mach_vm_protect failed with error %d.", kret);
+ exit(1);
+ }
+
+ if ( (kret = mach_vm_write(task, modAddress, (pointer_t)&newValue, sizeof(newValue))) )
+ {
+ printf("mach_vm_write failed at 0x%llx with error %d.", modAddress, kret);
+ exit(1);
+ }
- if ((kret = mach_vm_write(task, modAddress, (pointer_t)&newValue, sizeof(newValue))) != KERN_SUCCESS) printf("mach_vm_write failed, error %d: %s\n", kret, mach_error_string(kret));
+ // restore original protection
+ if ( (kret = mach_vm_protect(task, modAddress, sizeof(newValue), FALSE, info.protection)) )
+ {
+ printf("mach_vm_protect failed with error %d.", kret);
+ exit(1);
+ }
+ task_resume(task);
+
goto NextAction;
}
case 2:
@@ -202,21 +235,12 @@ int main(int argc, char *argv[])
pointer_t buffer;
size = sizeof(int); // because oldValue and newValue are int
mach_msg_type_number_t bufferSize = size;
-#if CGFLOAT_IS_DOUBLE
long substring = [substringNumber longValue];
if ((kret = mach_vm_read(task, (mach_vm_address_t)substring, size, &buffer, &bufferSize)) == KERN_SUCCESS)
{
printf("Search result %2d: %ld at 0x%0llx (%s)\n", i + 1, *(long *)buffer, (mach_vm_address_t)substring, [[protectionArray objectAtIndex:i] UTF8String]);
}
else printf("mach_vm_read failed at 0x%0llx, error %d: %s\n", (mach_vm_address_t)substring, kret, mach_error_string(kret));
-#else
- int substring = [substringNumber intValue];
- if ((kret = mach_vm_read(task, (mach_vm_address_t)substring, size, &buffer, &bufferSize)) == KERN_SUCCESS)
- {
- printf("Search result %2d: %ld at 0x%0llx (%s)\n", i + 1, *(long *)buffer, (mach_vm_address_t)substring, [[protectionArray objectAtIndex:i] UTF8String]);
- }
- else printf("mach_vm_read failed at 0x%0llx, error %d: %s\n", (mach_vm_address_t)substring, kret, mach_error_string(kret));
-#endif
}
goto NextAction;
}