main_hook.m 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #import <Foundation/Foundation.h>
  2. #import "PLLogOutputView.h"
  3. #import "SurfaceViewController.h"
  4. #import "ios_uikit_bridge.h"
  5. #import "utils.h"
  6. #include "external/fishhook/fishhook.h"
  7. void (*orig_abort)();
  8. void (*orig_exit)(int code);
  9. int (*orig_open)(const char *path, int oflag, ...);
  10. void handle_fatal_exit(int code) {
  11. if (NSThread.isMainThread) {
  12. return;
  13. }
  14. [PLLogOutputView handleExitCode:code];
  15. if (fatalExitGroup != nil) {
  16. // Likely other threads are crashing, put them to sleep
  17. sleep(INT_MAX);
  18. }
  19. fatalExitGroup = dispatch_group_create();
  20. dispatch_group_enter(fatalExitGroup);
  21. dispatch_group_wait(fatalExitGroup, DISPATCH_TIME_FOREVER);
  22. }
  23. void hooked_abort() {
  24. NSLog(@"abort() called");
  25. handle_fatal_exit(SIGABRT);
  26. orig_abort();
  27. }
  28. void hooked___assert_rtn(const char* func, const char* file, int line, const char* failedexpr)
  29. {
  30. if (func == NULL) {
  31. fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n", failedexpr, file, line);
  32. } else {
  33. fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr, func, file, line);
  34. }
  35. hooked_abort();
  36. }
  37. void hooked_exit(int code) {
  38. NSLog(@"exit(%d) called", code);
  39. if (code == 0) {
  40. dispatch_async(dispatch_get_main_queue(), ^{
  41. [UIApplication.sharedApplication performSelector:@selector(suspend)];
  42. });
  43. usleep(100*1000);
  44. orig_exit(0);
  45. return;
  46. }
  47. handle_fatal_exit(code);
  48. if (runtimeJavaVMPtr != NULL) {
  49. (*runtimeJavaVMPtr)->DestroyJavaVM(runtimeJavaVMPtr);
  50. }
  51. orig_exit(code);
  52. }
  53. int hooked_open(const char *path, int oflag, ...) {
  54. va_list args;
  55. va_start(args, oflag);
  56. mode_t mode = va_arg(args, int);
  57. va_end(args);
  58. if (path && !strcmp(path, "/etc/resolv.conf")) {
  59. return orig_open([NSString stringWithFormat:@"%s/resolv.conf", getenv("POJAV_HOME")].UTF8String, oflag, mode);
  60. }
  61. return orig_open(path, oflag, mode);
  62. }
  63. void init_hookFunctions() {
  64. struct rebinding rebindings[] = (struct rebinding[]){
  65. {"abort", hooked_abort, (void *)&orig_abort},
  66. {"__assert_rtn", hooked___assert_rtn, NULL},
  67. {"exit", hooked_exit, (void *)&orig_exit},
  68. {"open", hooked_open, (void *)&orig_open}
  69. };
  70. rebind_symbols(rebindings, sizeof(rebindings)/sizeof(struct rebinding));
  71. }