From 06801c56ca55b6cfa1db49682f6dd11645416846 Mon Sep 17 00:00:00 2001 From: uncor3 Date: Thu, 11 Sep 2025 00:50:18 +0000 Subject: [PATCH] Refactor service includes and remove unused files; add new service for mounted images --- CMakeLists.txt | 2 +- src/appcontext.cpp | 1 - .../detect_has_been_jailbroken_before.cpp | 7 +- src/core/services/detect_jailbroken.cpp | 8 +- src/core/services/get_mounted_image.cpp | 116 +++++++++++++++ src/core/services/init_device.cpp | 10 +- src/core/services/mount_dev_image.cpp | 14 +- src/core/services/restart.cpp | 3 +- src/core/services/set_location.cpp | 2 +- src/core/services/shutdown.cpp | 3 +- src/core/services/take_screenshot copy.cpp | 140 ------------------ src/iDescriptor.h | 65 +++++++- src/realtimescreen.cpp | 1 - src/toolboxwidget.cpp | 2 - src/virtual_location.cpp | 5 +- 15 files changed, 198 insertions(+), 181 deletions(-) create mode 100644 src/core/services/get_mounted_image.cpp delete mode 100644 src/core/services/take_screenshot copy.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 71983cb..e1e256e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,7 @@ find_library(PLIST_LIBRARY file(GLOB PROJECT_SOURCES src/*.cpp src/core/helpers/*.cpp + src/core/services/*.cpp src/*.h src/*.ui resources.qrc @@ -190,7 +191,6 @@ target_link_libraries(iDescriptor PRIVATE airplay ipatool-go ) -target_link_libraries(iDescriptor PRIVATE Qt6::Widgets) # Add compile definition for source directory target_compile_definitions(iDescriptor PRIVATE diff --git a/src/appcontext.cpp b/src/appcontext.cpp index 71d9e6a..26e6a68 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -1,5 +1,4 @@ #include "appcontext.h" -#include "./core/services/init_device.cpp" #include "iDescriptor.h" #include #include diff --git a/src/core/services/detect_has_been_jailbroken_before.cpp b/src/core/services/detect_has_been_jailbroken_before.cpp index b6ae62a..56025b3 100644 --- a/src/core/services/detect_has_been_jailbroken_before.cpp +++ b/src/core/services/detect_has_been_jailbroken_before.cpp @@ -1,3 +1,4 @@ +#include "../../iDescriptor.h" #include #include #include @@ -7,9 +8,6 @@ struct JailbreakDetectionResult { std::vector found_folders; }; -// This is because afc_read_directory accepts "/var/mobile/Media" as "/" -std::string possible_root = "../../../../"; - JailbreakDetectionResult detect_has_jailbroken_before(afc_client_t afc) { std::vector jailbreak_folders = {".installed_palera1n", @@ -18,8 +16,7 @@ JailbreakDetectionResult detect_has_jailbroken_before(afc_client_t afc) JailbreakDetectionResult result = {false, {}}; char **dirs = NULL; - if (afc_read_directory(afc, possible_root.c_str(), &dirs) == - AFC_E_SUCCESS) { + if (afc_read_directory(afc, POSSIBLE_ROOT, &dirs) == AFC_E_SUCCESS) { for (char **dir = dirs; *dir != nullptr; ++dir) { std::string dirname = *dir; for (const auto &jb_folder : jailbreak_folders) { diff --git a/src/core/services/detect_jailbroken.cpp b/src/core/services/detect_jailbroken.cpp index 3a59f6c..1dd1de0 100644 --- a/src/core/services/detect_jailbroken.cpp +++ b/src/core/services/detect_jailbroken.cpp @@ -1,3 +1,4 @@ +#include "../../iDescriptor.h" #include // char *possible_jailbreak_paths[] = { // "/Applications/Cydia.app", @@ -8,13 +9,12 @@ // NULL // }; #include -// This is because afc_read_directory accepts "/var/mobile/Media" as "/" -std::string possible_root = "../../../../"; + bool detect_jailbroken(afc_client_t afc) { char **dirs = NULL; - if (afc_read_directory(afc, (possible_root + "bin").c_str(), &dirs) == - AFC_E_SUCCESS) { + if (afc_read_directory(afc, (std::string(POSSIBLE_ROOT) + "bin").c_str(), + &dirs) == AFC_E_SUCCESS) { // if we can loop through the directory, it means we have access to the // file system for (char **dir = dirs; *dir != nullptr; ++dir) { diff --git a/src/core/services/get_mounted_image.cpp b/src/core/services/get_mounted_image.cpp new file mode 100644 index 0000000..a714861 --- /dev/null +++ b/src/core/services/get_mounted_image.cpp @@ -0,0 +1,116 @@ +#include "../../iDescriptor.h" +#include +#define _GNU_SOURCE 1 +#define __USE_GNU 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef _WIN32 +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QPair _get_mounted_image(const char *udid) +{ + mobile_image_mounter_client_t mim = NULL; + int res = -1; + lockdownd_client_t lckd = NULL; + lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; + afc_client_t afc = NULL; + lockdownd_service_descriptor_t service = NULL; + idevice_t device = NULL; + + mobile_image_mounter_error_t err = MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR; + plist_t result = NULL; + size_t sig_length = 0; + char *imagetype = "Developer"; + + if (IDEVICE_E_SUCCESS != idevice_new_with_options(&device, udid, + + IDEVICE_LOOKUP_USBMUX)) { + qDebug() << "ERROR: Could not create idevice!"; + res = -1; + goto leave; + } + + if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake( + device, &lckd, TOOL_NAME))) { + qDebug() << "ERROR: Could not connect to lockdownd service!"; + res = -1; + goto leave; + } + + lockdownd_start_service(lckd, "com.apple.mobile.mobile_image_mounter", + &service); + + if (!service || service->port == 0) { + printf("ERROR: Could not start mobile_image_mounter service!\n"); + goto leave; + } + + if (mobile_image_mounter_new(device, service, &mim) != + MOBILE_IMAGE_MOUNTER_E_SUCCESS) { + printf("ERROR: Could not connect to mobile_image_mounter!\n"); + goto leave; + } + + if (!service || service->port == 0) { + qDebug() << "ERROR: Could not start mobile_image_mounter service!"; + res = -1; + goto leave; + } + + // if locked + // { + // "Error": "DeviceLocked" + // } + err = mobile_image_mounter_lookup_image(mim, imagetype, &result); + if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) { + res = 0; + } else { + res = -1; + printf("Error: lookup_image returned %d\n", err); + } + +leave: + // if (f) { + // fclose(f); + // } + // TODO:need to free result + // if (result) { + // plist_free(result); + // } + if (mim) { + mobile_image_mounter_free(mim); + } + if (afc) { + afc_client_free(afc); + } + if (lckd) { + lockdownd_client_free(lckd); + } + if (device) { + idevice_free(device); + } + + return {res == 0, result}; +} + +// int main(){return 0;} \ No newline at end of file diff --git a/src/core/services/init_device.cpp b/src/core/services/init_device.cpp index 5aab219..4c98128 100644 --- a/src/core/services/init_device.cpp +++ b/src/core/services/init_device.cpp @@ -1,6 +1,4 @@ #include "../../iDescriptor.h" -#include "./detect_jailbroken.cpp" -#include "./get-device-info.cpp" #include "libirecovery.h" #include #include @@ -77,19 +75,19 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc, PlistNavigator(diagnostics)["IORegistry"]["BatteryData"]["CycleCount"], &cycleCount); - char *batterySerialNumber; + char *batterySerialNumber = nullptr; plist_get_string_val( PlistNavigator( diagnostics)["IORegistry"]["BatteryData"]["BatterySerialNumber"], &batterySerialNumber); - uint64_t designCapacity; + uint64_t designCapacity = 0; plist_get_uint_val( PlistNavigator( diagnostics)["IORegistry"]["BatteryData"]["DesignCapacity"], &designCapacity); - uint64_t absoluteCapacity; + uint64_t absoluteCapacity = 0; plist_get_uint_val( PlistNavigator(diagnostics)["IORegistry"]["AbsoluteCapacity"], &absoluteCapacity); @@ -117,6 +115,8 @@ IDescriptorInitDeviceResult init_idescriptor_device(const char *udid) IDescriptorInitDeviceResult result = {}; lockdownd_client_t client; + // TODO: LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING + // LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING = -19, lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; lockdownd_service_descriptor_t lockdownService = nullptr; diagnostics_relay_client_t diagnostics_client = nullptr; diff --git a/src/core/services/mount_dev_image.cpp b/src/core/services/mount_dev_image.cpp index 207b98a..b3c44fb 100644 --- a/src/core/services/mount_dev_image.cpp +++ b/src/core/services/mount_dev_image.cpp @@ -19,16 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -// TODO: -// we need to dynamically fetch dev imgs because every iOS version has a -// different one - -#ifdef HAVE_CONFIG_H -#include -#endif - -#define TOOL_NAME "ideviceimagemounter" - +#include "../../iDescriptor.h" #include #define _GNU_SOURCE 1 #define __USE_GNU 1 @@ -44,7 +35,6 @@ #ifndef _WIN32 #include #endif - #include #include #include @@ -91,6 +81,8 @@ static ssize_t mim_upload_cb(void *buf, size_t size, void *userdata) // TODO: cleanup // TODO: may not work on a broken ,faulty or fake usb cable // TypeC cables work better +// TODO : sometimes ERROR: Device is locked, can't mount. Unlock device and try +// again. bool mount_dev_image(const char *udid, const char *image_dir_path) { mobile_image_mounter_client_t mim = NULL; diff --git a/src/core/services/restart.cpp b/src/core/services/restart.cpp index 70ba57f..994d670 100644 --- a/src/core/services/restart.cpp +++ b/src/core/services/restart.cpp @@ -19,8 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define TOOL_NAME "idevicediagnostics" - +#include "../../iDescriptor.h" #include #include #include diff --git a/src/core/services/set_location.cpp b/src/core/services/set_location.cpp index dfb505e..3f43368 100644 --- a/src/core/services/set_location.cpp +++ b/src/core/services/set_location.cpp @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "../../iDescriptor.h" #define DT_SIMULATELOCATION_SERVICE "com.apple.dt.simulatelocation" -#define TOOL_NAME "idevicesetlocation" #include #include diff --git a/src/core/services/shutdown.cpp b/src/core/services/shutdown.cpp index d738b9c..dedc45c 100644 --- a/src/core/services/shutdown.cpp +++ b/src/core/services/shutdown.cpp @@ -19,8 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define TOOL_NAME "idevicediagnostics" - +#include "../../iDescriptor.h" #include #include #include diff --git a/src/core/services/take_screenshot copy.cpp b/src/core/services/take_screenshot copy.cpp deleted file mode 100644 index 80222c3..0000000 --- a/src/core/services/take_screenshot copy.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * idevicescreenshot.c - * Gets a screenshot from a device - * - * Copyright (C) 2010 Nikias Bassen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#define TOOL_NAME "idevicescreenshot" - -#include -#include -#include -#include -#include -#include -#include -#ifndef _WIN32 -#include -#endif - -#include -#include - - - -static void get_image_filename(char *imgdata, char **filename) -{ - // If the provided filename already has an extension, use it as is. - if (*filename) { - char *last_dot = strrchr(*filename, '.'); - if (last_dot && !strchr(last_dot, '/')) { - return; - } - } - - // Find the appropriate file extension for the filename. - const char *fileext = NULL; - if (memcmp(imgdata, "\x89PNG", 4) == 0) { - fileext = ".png"; - } else if (memcmp(imgdata, "MM\x00*", 4) == 0) { - fileext = ".tiff"; - } else { - printf("WARNING: screenshot data has unexpected image format.\n"); - fileext = ".dat"; - } - - // If a filename without an extension is provided, append the extension. - // Otherwise, generate a filename based on the current time. - char *basename = NULL; - if (*filename) { - basename = (char*)malloc(strlen(*filename) + 1); - strcpy(basename, *filename); - free(*filename); - *filename = NULL; - } else { - time_t now = time(NULL); - basename = (char*)malloc(32); - strftime(basename, 31, "screenshot-%Y-%m-%d-%H-%M-%S", gmtime(&now)); - } - - // Ensure the filename is unique on disk. - char *unique_filename = (char*)malloc(strlen(basename) + strlen(fileext) + 7); - sprintf(unique_filename, "%s%s", basename, fileext); - int i; - for (i = 2; i < (1 << 16); i++) { - if (access(unique_filename, F_OK) == -1) { - *filename = unique_filename; - break; - } - sprintf(unique_filename, "%s-%d%s", basename, i, fileext); - } - if (!*filename) { - free(unique_filename); - } - free(basename); -} - -int take_screenshot(idevice_t device, lockdownd_service_descriptor_t service) { - screenshotr_client_t *shotr = nullptr; - char *filename = NULL; - int result=1; - try - { - /* code */ - - if (screenshotr_client_new(device, service, &shotr) != SCREENSHOTR_E_SUCCESS) { - printf("Could not connect to screenshotr!\n"); - } else { - char *imgdata = NULL; - uint64_t imgsize = 0; - if (screenshotr_take_screenshot(*shotr, &imgdata, &imgsize) == SCREENSHOTR_E_SUCCESS) { - get_image_filename(imgdata, &filename); - if (!filename) { - printf("FATAL: Could not find a unique filename!\n"); - } else { - FILE *f = fopen(filename, "wb"); - if (f) { - if (fwrite(imgdata, 1, (size_t)imgsize, f) == (size_t)imgsize) { - printf("Screenshot saved to %s\n", filename); - result = 0; - } else { - printf("Could not save screenshot to file %s!\n", filename); - } - fclose(f); - } else { - printf("Could not open %s for writing: %s\n", filename, strerror(errno)); - } - } - } else { - printf("Could not get screenshot!\n"); - } - screenshotr_client_free(shotr); - } - - return result; - } - catch(const std::exception& e) - { - return result; - std::cerr << e.what() << '\n'; - } -} \ No newline at end of file diff --git a/src/iDescriptor.h b/src/iDescriptor.h index cff7afb..2fb0142 100644 --- a/src/iDescriptor.h +++ b/src/iDescriptor.h @@ -4,14 +4,24 @@ #include #include #include +#include #include +#include #include #include #include +#define TOOL_NAME "iDescriptor" +#define APP_LABEL "iDescriptor" +#define APP_VERSION "0.0.1" +#define APP_COPYRIGHT "© 2023 Uncore. All rights reserved." + #define RECOVERY_CLIENT_CONNECTION_TRIES 3 #define APPLE_VENDOR_ID 0x05ac +// This is because afc_read_directory accepts "/var/mobile/Media" as "/" +#define POSSIBLE_ROOT "../../../../" + struct BatteryInfo { QString health; uint64_t cycleCount; @@ -200,10 +210,6 @@ void warn(const QString &message, const QString &title = "Warning", enum class AddType { Regular, Pairing }; -#define APP_LABEL "iDescriptor" -#define APP_VERSION "0.0.1" -#define APP_COPYRIGHT "© 2023 Uncore. All rights reserved." - class PlistNavigator { private: @@ -244,4 +250,53 @@ struct MediaFileTree { }; MediaFileTree get_file_tree(afc_client_t afcClient, idevice_t device, - const std::string &path = "/"); \ No newline at end of file + const std::string &path = "/"); + +bool detect_jailbroken(afc_client_t afc); + +void get_device_info_xml(const char *udid, int use_network, int simple, + pugi::xml_document &infoXml, lockdownd_client_t client, + idevice_t device); + +IDescriptorInitDeviceResult init_idescriptor_device(const char *udid); + +IDescriptorInitDeviceResultRecovery +init_idescriptor_recovery_device(irecv_device_info *info); + +bool set_location(idevice_t device, char *lat, char *lon); + +bool shutdown(idevice_t device); + +TakeScreenshotResult take_screenshot(screenshotr_client_t shotr); + +bool mount_dev_image(const char *udid, const char *image_dir_path); + +struct GetMountedImageResult { + bool success; + std::string output; + std::string message; +}; + +QPair _get_mounted_image(const char *udid); + +bool restart(idevice_t device); + +// TODO:move +struct ImageInfo { + QString version; + QString dmgPath; + QString sigPath; + bool isCompatible = false; + bool isDownloaded = false; + bool isMounted = false; +}; + +struct GetImagesSortedResult { + QStringList compatibleImages; + QStringList otherImages; +}; + +struct GetImagesSortedFinalResult { + QList compatibleImages; + QList otherImages; +}; \ No newline at end of file diff --git a/src/realtimescreen.cpp b/src/realtimescreen.cpp index 56c1127..0758b77 100644 --- a/src/realtimescreen.cpp +++ b/src/realtimescreen.cpp @@ -1,5 +1,4 @@ #include "realtimescreen.h" -#include "./core/services/take_screenshot.cpp" #include "appcontext.h" #include "iDescriptor.h" #include diff --git a/src/toolboxwidget.cpp b/src/toolboxwidget.cpp index d64625a..8109a11 100644 --- a/src/toolboxwidget.cpp +++ b/src/toolboxwidget.cpp @@ -1,6 +1,4 @@ #include "toolboxwidget.h" -#include "./core/services/mount_dev_image.cpp" -#include "./core/services/restart.cpp" #include "airplaywindow.h" #include "appcontext.h" #include "devdiskimageswidget.h" diff --git a/src/virtual_location.cpp b/src/virtual_location.cpp index e5161dc..bd99e92 100644 --- a/src/virtual_location.cpp +++ b/src/virtual_location.cpp @@ -1,5 +1,5 @@ #include "virtual_location.h" -#include "./core/services/set_location.cpp" +#include "devdiskmanager.h" #include "iDescriptor.h" #include #include @@ -24,6 +24,9 @@ VirtualLocation::VirtualLocation(iDescriptorDevice *device, QWidget *parent) : QWidget{parent}, m_device(device) { // Create the main layout + bool res = DevDiskManager::sharedInstance()->mountCompatibleImage( + m_device, QString("/tmp")); + qDebug() << "Mount result:" << res; QHBoxLayout *mainLayout = new QHBoxLayout(this); mainLayout->setContentsMargins(10, 10, 10, 10); mainLayout->setSpacing(10);