Crashes with EXC_BAD_ACCESS on Apple Silicon mac when compiled as arm64e
Compiling an arm64e macOS app on an M1 Mac Mini in macOS 11.6. When a hooked function gets called, the app crashes with EXC_BAD_ACCESS. The following code when compiled as arm64e will crash on the second (hooked) call to malloc:
#include <stdio.h>
#include <stdlib.h>
#include "fishhook.h"
void * (*originalMalloc)(size_t);
static void * overrideMalloc(size_t size) {
void * result = originalMalloc(size);
printf("calling overrideMalloc!\n");
return result;
}
int main(int argc, const char * argv[]) {
void *data;
printf("Calling malloc before\n");
data = malloc(10);
free(data);
int result = rebind_symbols((struct rebinding[2]){{"malloc", overrideMalloc, (void *)&originalMalloc}}, 1);
if (result != 0) {
printf("rebind_symbols failed with result: %d ... cannot proceed", result);
return 0;
}
printf("Calling malloc after\n");
data = malloc(10);
free(data);
return 0;
}
Note that in order to run arm64e code on macOS, you must disable system integrity protection and set the following boot parameter:
sudo nvram boot-args=-arm64e_preview_abi
You will need to resign the function pointer that fishhook is writing using the asia key discriminated with the address that fishhook is writing to. An incomplete example:
void *__memcpy_chk_fptr_resigned = ptrauth_sign_unauthenticated(
ptrauth_strip((void *)__memcpy_chk, ptrauth_key_asia), ptrauth_key_asia,
(void *)0x0000000100004020 + _dyld_get_image_slide(&__dso_handle));
struct rebinding rebindings[] = {
{"__memcpy_chk", __memcpy_chk_fptr_resigned, NULL},
};
In the above example, 0x0000000100004020 is the address of the binding that fishhook is writing to.
See this page for more info: https://github.com/apple/llvm-project/blob/next/clang/docs/PointerAuthentication.rst