diff --git a/CMakeLists.txt b/CMakeLists.txt index 19e7c42..6eec21b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,7 @@ target_compile_definitions(palera1n PRIVATE ) # ========================= -# APPLE FRAMEWORKS +# LINKS # ========================= if(APPLE) @@ -177,6 +177,10 @@ if(APPLE) target_link_libraries(palera1n PRIVATE ${IOKIT} ${COREFOUNDATION} ${SECURITY}) endif() +if(WIN32) + target_link_libraries(palera1n PRIVATE setupapi cfgmgr32) +endif() + # ========================= # NON-CMAKE DEPENDENCIES # ========================= diff --git a/src/m8/run.c b/src/m8/run.c index 3c2d577..cd9e8e2 100644 --- a/src/m8/run.c +++ b/src/m8/run.c @@ -13,6 +13,7 @@ #include "../globals.h" #include "../paleinfo.h" #include "../usb/shim.h" +#include "../usb/driver.h" #include "../usb/pongo_helper.h" #include "checkm8.h" @@ -53,6 +54,43 @@ int stage_to_progress(int stage) #endif // WITH_GUI || WITH_TUI +#ifdef _WIN32 + +static void *driver_thread(void *arg) +{ + shared_t *s = (shared_t *)arg; + + LOG_VERBOSE("Starting thread for libusbK driver installing"); + + while (!atomic_load(&s->stop)) { + + if (usb_device_present(VID_APPLE, PID_DFU)) { + driver_result_t ret = + install_libusbk_target(VID_APPLE, PID_DFU); + + if (ret == DRIVER_SUCCESS) + LOG_VERBOSE("DFU libusbK ready"); + } + + if (usb_device_present(VID_APPLE, PID_PONGO)) { + + driver_result_t ret = + install_libusbk_target(VID_APPLE, PID_PONGO); + + if (ret == DRIVER_SUCCESS) { + LOG_SUCCESS("PongoOS libusbK ready"); + break; + } + } + + sleep_ms(500); + } + + return NULL; +} + +#endif + static void *exploit_thread(void *arg) { LOG_VERBOSE("Starting thread for DFU devices"); @@ -175,9 +213,7 @@ static void *pongo_thread(void *arg) atomic_store(&s->stage, STAGE_PONGO); if (palerain_flags & palerain_option_pongo_exit) { - atomic_store(&s->stage, STAGE_DONE); - atomic_store(&s->stop, true); - break; + goto exit; } char paleinfo[64]; @@ -207,6 +243,11 @@ static void *pongo_thread(void *arg) if (strlen(boot_args) > 0) issue_pongo_command(&handle, xargs_cmd); issue_pongo_command(&handle, "bootx"); + exit: + #ifdef _WIN32 + uninstall_libusbk_target(VID_APPLE, PID_DFU); + #endif + atomic_store(&s->stage, STAGE_DONE); atomic_store(&s->stop, true); break; @@ -219,9 +260,15 @@ static void *pongo_thread(void *arg) bool exploit(shared_t *state) { pthread_t t1, t2; + #ifdef _WIN32 + pthread_t td; + #endif pthread_create(&t1, NULL, exploit_thread, state); pthread_create(&t2, NULL, pongo_thread, state); + #ifdef _WIN32 + pthread_create(&td, NULL, driver_thread, state); + #endif while (!atomic_load(&state->stop)) { sleep_ms(10); @@ -229,9 +276,15 @@ bool exploit(shared_t *state) pthread_cancel(t1); pthread_cancel(t2); + #ifdef _WIN32 + pthread_cancel(td); + #endif pthread_join(t1, NULL); pthread_join(t2, NULL); + #ifdef _WIN32 + pthread_join(td, NULL); + #endif return atomic_load(&state->result) == 1; } diff --git a/src/usb/driver.c b/src/usb/driver.c index 4e6cb41..ac84711 100644 --- a/src/usb/driver.c +++ b/src/usb/driver.c @@ -6,6 +6,11 @@ #include #include #include + +#include +#include +#pragma comment(lib, "setupapi.lib") + #include #include "../utils.h" @@ -25,50 +30,103 @@ static void add_target_driver(char list[MAX_MATCHING_DRIVERS][64], int *count, c (*count)++; } -int install_libusbk_target(unsigned short vid, unsigned short pid) +driver_result_t install_libusbk_target(unsigned short vid, unsigned short pid) { struct wdi_device_info *list = NULL; struct wdi_options_create_list cl = { .list_all = TRUE }; - struct wdi_options_prepare_driver prep = { .driver_type = WDI_LIBUSBK, .vendor_name = "libusbK" }; + struct wdi_options_prepare_driver prep = { + .driver_type = WDI_LIBUSBK, + .vendor_name = "libusbK" + }; struct wdi_options_install_driver inst = {0}; LOG_VERBOSE("Target: VID:%04X PID:%04X", vid, pid); if (wdi_create_list(&list, &cl) != WDI_SUCCESS) { - LOG_ERROR("wdi_create_list failed\n"); - return 1; + LOG_ERROR("wdi_create_list failed"); + return DRIVER_ERROR; } - char temp_path[MAX_PATH], driver_path[MAX_PATH]; + char temp_path[MAX_PATH]; + char driver_path[MAX_PATH]; + if (GetTempPathA(MAX_PATH, temp_path) == 0) { - LOG_ERROR("GetTempPathA failed\n"); + LOG_ERROR("GetTempPathA failed"); wdi_destroy_list(list); - return 1; + return DRIVER_ERROR; } snprintf(driver_path, sizeof(driver_path), "%slibusbk_driver\\", temp_path); + CreateDirectoryA(driver_path, NULL); - int found = 0; + bool found = false; + bool installed = false; + bool failed = false; + for (struct wdi_device_info *d = list; d; d = d->next) { - if (d->vid != vid || d->pid != pid) continue; + if (d->vid != vid || d->pid != pid) + continue; - found = 1; - LOG("Found device %04X:%04X. Preparing & installing driver...", vid, pid); + found = true; - if (wdi_prepare_driver(d, driver_path, "libusbk_driver.inf", &prep) != WDI_SUCCESS || - wdi_install_driver(d, driver_path, "libusbk_driver.inf", &inst) != WDI_SUCCESS) { - LOG_ERROR("Driver management pipeline failed for instance node"); - } else { - LOG_SUCCESS("Driver successfully installed"); + if (d->driver && _stricmp(d->driver, "libusbK") == 0) { + LOG_VERBOSE( + "Device %04X:%04X already using libusbK", + vid, + pid + ); + installed = true; + break; } + + LOG("Installing libusbK for %04X:%04X...", vid, pid); + + if (wdi_prepare_driver( + d, + driver_path, + "libusbk_driver.inf", + &prep + ) != WDI_SUCCESS) + { + LOG_ERROR("wdi_prepare_driver failed"); + failed = true; + continue; + } + + if (wdi_install_driver( + d, + driver_path, + "libusbk_driver.inf", + &inst + ) != WDI_SUCCESS) + { + LOG_ERROR("wdi_install_driver failed"); + failed = true; + continue; + } + + LOG_SUCCESS( + "libusbK driver successfully installed for %04X:%04X", + vid, + pid + ); + + installed = true; } wdi_destroy_list(list); - return found ? 0 : 2; + + if (!found) + return DRIVER_NOT_PRESENT; + + if (installed && !failed) + return DRIVER_SUCCESS; + + return DRIVER_ERROR; } -int uninstall_libusbk_target(unsigned short vid, unsigned short pid) +driver_result_t uninstall_libusbk_target(unsigned short vid, unsigned short pid) { char hwid_u[64], hwid_l[64]; snprintf(hwid_u, sizeof(hwid_u), "USB\\VID_%04X&PID_%04X", vid, pid); @@ -77,7 +135,7 @@ int uninstall_libusbk_target(unsigned short vid, unsigned short pid) LOG_VERBOSE("Target Signature: %s (libusbK)", hwid_u); char temp_path[MAX_PATH], log_path[MAX_PATH], cmd[512]; - if (GetTempPathA(MAX_PATH, temp_path) == 0) return 1; + if (GetTempPathA(MAX_PATH, temp_path) == 0) return DRIVER_ERROR; snprintf(log_path, sizeof(log_path), "%spnputil_drivers.txt", temp_path); // Strip active instances first @@ -125,37 +183,74 @@ int uninstall_libusbk_target(unsigned short vid, unsigned short pid) snprintf(cmd, sizeof(cmd), "pnputil /scan-devices >nul 2>&1"); system(cmd); LOG_SUCCESS("All %d libusbK driver instances fully uninstalled.", target_count); - return 0; + return DRIVER_SUCCESS; } LOG_ERROR("No matching libusbK driver package found in system store"); - return 2; + return DRIVER_NOT_PRESENT; } -bool is_installed_with_libusbk(unsigned short vid, unsigned short pid) +bool usb_device_present(unsigned short vid, unsigned short pid) { - struct wdi_device_info *list = NULL; - struct wdi_options_create_list cl = { .list_all = TRUE }; - bool has_libusbk = false; + HDEVINFO info; + SP_DEVINFO_DATA dev_info; - LOG_VERBOSE("Checking driver allocation for VID:%04X PID:%04X", vid, pid); + char target[64]; - if (wdi_create_list(&list, &cl) != WDI_SUCCESS) { - LOG_ERROR("wdi_create_list failed during driver status check"); + snprintf( + target, + sizeof(target), + "VID_%04X&PID_%04X", + vid, + pid + ); + + info = SetupDiGetClassDevsA( + NULL, + "USB", + NULL, + DIGCF_PRESENT | DIGCF_ALLCLASSES + ); + + if (info == INVALID_HANDLE_VALUE) return false; - } - for (struct wdi_device_info *d = list; d; d = d->next) { - if (d->vid == vid && d->pid == pid) { - if (d->driver && (stricmp(d->driver, "libusbK") == 0)) { - has_libusbk = true; - break; + dev_info.cbSize = sizeof(dev_info); + + for (DWORD i = 0; + SetupDiEnumDeviceInfo(info, i, &dev_info); + i++) + { + char hardware_ids[4096]; + DWORD size = 0; + + if (!SetupDiGetDeviceRegistryPropertyA( + info, + &dev_info, + SPDRP_HARDWAREID, + NULL, + (PBYTE)hardware_ids, + sizeof(hardware_ids), + &size)) + { + continue; + } + + char *id = hardware_ids; + + while (*id) { + if (strstr(id, target)) { + SetupDiDestroyDeviceInfoList(info); + return true; } + + id += strlen(id) + 1; } } - wdi_destroy_list(list); - return has_libusbk; + SetupDiDestroyDeviceInfoList(info); + + return false; } #endif \ No newline at end of file diff --git a/src/usb/driver.h b/src/usb/driver.h index 88937fc..eb2a1a5 100644 --- a/src/usb/driver.h +++ b/src/usb/driver.h @@ -9,9 +9,15 @@ extern "C" { #endif -int install_libusbk_target(unsigned short vid, unsigned short pid); -int uninstall_libusbk_target(unsigned short vid, unsigned short pid); -bool is_installed_with_libusbk(unsigned short vid, unsigned short pid); +typedef enum { + DRIVER_SUCCESS = 0, + DRIVER_NOT_PRESENT, + DRIVER_ERROR, +} driver_result_t; + +driver_result_t install_libusbk_target(unsigned short vid, unsigned short pid); +driver_result_t uninstall_libusbk_target(unsigned short vid, unsigned short pid); +bool usb_device_present(unsigned short vid, unsigned short pid); #ifdef __cplusplus }