diff --git a/src/lindbergh/graphics.c b/src/lindbergh/graphics.c index 73e1b2b..6e9817f 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -77,12 +77,40 @@ Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int // Ensure that the windows will respond with keyboard and mouse events attributes->event_mask = attributes->event_mask | KeyPressMask | KeyReleaseMask | PointerMotionMask; + attributes->override_redirect = 0; Window window = _XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valueMask, attributes); - + printf("%d %d %d %d\n", x, y, width, height); return window; } +int XGrabPointer(Display *display, Window grab_window, Bool owner_events, unsigned int event_mask, int pointer_mode, int keyboard_mode, Window confine_to, Cursor cursor, Time time) +{ + int (*_XGrabPointer)(Display * display, Window grab_window, Bool owner_events, unsigned int event_mask, int pointer_mode, int keyboard_mode, Window confine_to, Cursor cursor, Time time) = dlsym(RTLD_NEXT, "XGrabPointer"); + int returnValue = _XGrabPointer(display, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, time); + XUngrabPointer(display, time); + return returnValue; +} + +int XGrabKeyboard(Display *display, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode, Time time) +{ + int (*_XGrabKeyboard)(Display * display, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode, Time time) = dlsym(RTLD_NEXT, "XGrabKeyboard"); + int returnValue = _XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, time); + XUngrabKeyboard(display, time); + return returnValue; +} + +int XDefineCursor(Display *display, Window w, Cursor cursor) +{ + return 0; +} + +int XStoreName(Display *display, Window w, const char *window_name) +{ + int (*_XStoreName)(Display * display, Window w, const char *window_name) = dlsym(RTLD_NEXT, "XStoreName"); + return _XStoreName(display, w, getGameName()); +} + int XNextEvent(Display *display, XEvent *event_return) { @@ -96,6 +124,7 @@ int XNextEvent(Display *display, XEvent *event_return) { case 28: securityBoardSetSwitch(BUTTON_TEST, 1); + abort(); break; case 39: securityBoardSetSwitch(BUTTON_SERVICE, 1); diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index dd693ee..ab5bb7e 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -31,10 +31,83 @@ int hooks[4] = {-1, -1, -1, -1}; uint16_t basePortAddress = 0xFFFF; +static void handleSegfault(int signal, siginfo_t *info, void *ptr) +{ + ucontext_t *ctx = ptr; + + uint8_t *code = (uint8_t *)ctx->uc_mcontext.gregs[REG_EIP]; + + switch (*code) + { + case 0xED: + { + uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; + + // The first port called is usually random, but everything after that + // is a constant offset, so this is a hack to fix that. + // When run as sudo it works fine!? + + if (basePortAddress == 0xFFFF) + basePortAddress = port; + + if (port > 0x38) + port = port - basePortAddress; + + securityBoardIn(port, (uint32_t *)&(ctx->uc_mcontext.gregs[REG_EAX])); + + ctx->uc_mcontext.gregs[REG_EIP]++; + return; + } + break; + + case 0xE7: // OUT IMMIDIATE + { + ctx->uc_mcontext.gregs[REG_EIP] += 2; + return; + } + break; + + case 0xE6: // OUT IMMIDIATE + { + ctx->uc_mcontext.gregs[REG_EIP] += 2; + return; + } + break; + + case 0xEE: // OUT + { + uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; + uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF; + ctx->uc_mcontext.gregs[REG_EIP]++; + return; + } + break; + + case 0xEF: // OUT + { + uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; + ctx->uc_mcontext.gregs[REG_EIP]++; + return; + } + break; + + default: + printf("Warning: Skipping SEGFAULT %X\n", *code); + ctx->uc_mcontext.gregs[REG_EIP]++; + // abort(); + } +} + void __attribute__((constructor)) hook_init() { printf("SEGA Lindbergh Loader\nRobert Dilley 2022\nNot for public consumption\n\n"); + // Implement SIGSEGV handler + struct sigaction act; + act.sa_sigaction = handleSegfault; + act.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &act, NULL); + initConfig(); if (initEeprom() != 0) @@ -64,6 +137,8 @@ int open(const char *pathname, int flags) { int (*_open)(const char *pathname, int flags) = dlsym(RTLD_NEXT, "open"); + printf("Open %s\n", pathname); + if (strcmp(pathname, "/dev/lbb") == 0) { hooks[BASEBOARD] = open(HOOK_FILE_NAME, flags); @@ -100,6 +175,7 @@ int open(const char *pathname, int flags) FILE *fopen(const char *restrict pathname, const char *restrict mode) { FILE *(*_fopen)(const char *restrict pathname, const char *restrict mode) = dlsym(RTLD_NEXT, "fopen"); + printf("FOpen %s\n", pathname); if (strcmp(pathname, "/root/lindbergrc") == 0) { @@ -254,81 +330,8 @@ int system(const char *command) return _system(command); } -static void handleSegfault(int signal, siginfo_t *info, void *ptr) -{ - ucontext_t *ctx = ptr; - - uint8_t *code = (uint8_t *)ctx->uc_mcontext.gregs[REG_EIP]; - - switch (*code) - { - case 0xED: - { - uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; - - // The first port called is usually random, but everything after that - // is a constant offset, so this is a hack to fix that. - // When run as sudo it works fine!? - - if (basePortAddress == 0xFFFF) - basePortAddress = port; - - if (port > 0x38) - port = port - basePortAddress; - - securityBoardIn(port, (uint32_t *)&(ctx->uc_mcontext.gregs[REG_EAX])); - - ctx->uc_mcontext.gregs[REG_EIP]++; - return; - } - break; - - case 0xE7: // OUT IMMIDIATE - { - ctx->uc_mcontext.gregs[REG_EIP] += 2; - return; - } - break; - - case 0xE6: // OUT IMMIDIATE - { - ctx->uc_mcontext.gregs[REG_EIP] += 2; - return; - } - break; - - case 0xEE: // OUT - { - uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; - uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF; - ctx->uc_mcontext.gregs[REG_EIP]++; - return; - } - break; - - case 0xEF: // OUT - { - uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; - ctx->uc_mcontext.gregs[REG_EIP]++; - return; - } - break; - - default: - printf("Error: Unknown segfault %X\n", *code); - abort(); - } -} - int iopl(int level) { - struct sigaction act; - - act.sa_sigaction = handleSegfault; - act.sa_flags = SA_SIGINFO; - - sigaction(SIGSEGV, &act, NULL); - return 0; } @@ -351,3 +354,10 @@ float powf(float base, float exponent) { return (float)pow((double)base, (double)exponent); } + +/* +int futex(int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3) +{ + return 0; +} +*/