Created
January 8, 2025 23:22
-
-
Save EthanArbuckle/463e1f9b03aa6541839a5f45405221f1 to your computer and use it in GitHub Desktop.
set and catch breakpoints
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.m | |
// breakpoints | |
// | |
// Created by @objc on 5/01/23. | |
// | |
#import <Foundation/Foundation.h> | |
#include <mach/mach.h> | |
#include <pthread.h> | |
#include "mach_excServer.h" | |
void my_func1(void) { | |
printf("original func running: %s\n", __func__); | |
} | |
void new_func1(void) { | |
printf("replacement func running: %s\n", __func__); | |
} | |
struct hook { | |
uintptr_t original; | |
uintptr_t replacement; | |
}; | |
static struct hook hooks[16]; | |
static int breakpoints; | |
mach_port_t server; | |
kern_return_t catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt) { | |
return KERN_FAILURE; | |
} | |
kern_return_t catch_mach_exception_raise_state_identity(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { | |
return KERN_FAILURE; | |
} | |
kern_return_t catch_mach_exception_raise_state(mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, const thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { | |
for (int i = 0; i < breakpoints; ++i) { | |
if (hooks[i].original == arm_thread_state64_get_pc(*(arm_thread_state64_t *)old_state)) { | |
*((arm_thread_state64_t *)new_state) = *((arm_thread_state64_t *)old_state); | |
*new_stateCnt = old_stateCnt; | |
arm_thread_state64_set_pc_fptr(*((arm_thread_state64_t *)new_state), hooks[i].replacement); | |
return KERN_SUCCESS; | |
} | |
} | |
return KERN_FAILURE; | |
} | |
void *exception_handler(void *unused) { | |
mach_msg_server(mach_exc_server, sizeof(union __RequestUnion__catch_mach_exc_subsystem), server, MACH_MSG_OPTION_NONE); | |
abort(); | |
} | |
bool hook(void *old, void *new) { | |
arm_debug_state64_t state = {}; | |
state.__bvr[breakpoints] = (uintptr_t)old; | |
state.__bcr[breakpoints] = 0x1e5; | |
task_set_state(mach_task_self(), ARM_DEBUG_STATE64, (thread_state_t)&state, ARM_DEBUG_STATE64_COUNT); | |
bool success = true; | |
thread_act_array_t threads; | |
mach_msg_type_number_t thread_count = ARM_DEBUG_STATE64_COUNT; | |
task_threads(mach_task_self(), &threads, &thread_count); | |
for (int i = 0; i < thread_count; ++i) { | |
success = thread_set_state(threads[i], ARM_DEBUG_STATE64, (thread_state_t)&state, ARM_DEBUG_STATE64_COUNT) == KERN_SUCCESS; | |
if (!success) { | |
NSLog(@"hook failed: could not set thread 0x%x debug state", threads[i]); | |
break; | |
} | |
} | |
hooks[breakpoints++] = (struct hook){(uintptr_t)old, (uintptr_t)new}; | |
for (int i = 0; i < thread_count; ++i) { | |
mach_port_deallocate(mach_task_self(), threads[i]); | |
} | |
vm_deallocate(mach_task_self(), (vm_address_t)threads, thread_count * sizeof(*threads)); | |
return success; | |
} | |
int main(int argc, const char * argv[]) { | |
mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &server); | |
mach_port_insert_right(mach_task_self(), server, server, MACH_MSG_TYPE_MAKE_SEND); | |
task_set_exception_ports(mach_task_self(), EXC_MASK_BREAKPOINT, server, EXCEPTION_STATE | MACH_EXCEPTION_CODES, ARM_THREAD_STATE64); | |
pthread_t thread; | |
pthread_create(&thread, NULL, exception_handler, NULL); | |
hook((void *)my_func1, (void *)new_func1); | |
my_func1(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment