Created
May 18, 2015 17:05
-
-
Save anonymous/759f6d02301b25e18db5 to your computer and use it in GitHub Desktop.
com.apple.dt.fetchsymbols example usage for iOS 7
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
#include "stdafx.h" | |
#include "MobileDevice.h" | |
#pragma unmanaged | |
#include "libimobiledevice/libimobiledevice.h" | |
#include "libimobiledevice/lockdown.h" | |
#include "libimobiledevice/installation_proxy.h" | |
#include "libimobiledevice/afc.h" | |
#include "plist/plist.h" | |
#include <libimobiledevice/notification_proxy.h> | |
#include <libimobiledevice/mobile_image_mounter.h> | |
#include <asprintf.h> | |
#include "socket.h" | |
#include "thread.h" | |
#include <time.h> | |
struct timeval_t { | |
long tv_sec; /* seconds */ | |
long tv_usec; /* and microseconds */ | |
}; | |
/* Error Codes */ | |
#define DEVICE_LINK_SERVICE_E_SUCCESS 0 | |
#define DEVICE_LINK_SERVICE_E_INVALID_ARG -1 | |
#define DEVICE_LINK_SERVICE_E_PLIST_ERROR -2 | |
#define DEVICE_LINK_SERVICE_E_MUX_ERROR -3 | |
#define DEVICE_LINK_SERVICE_E_BAD_VERSION -4 | |
#define DEVICE_LINK_SERVICE_E_UNKNOWN_ERROR -256 | |
/** Represents an error code. */ | |
typedef int16_t device_link_service_error_t; | |
struct device_link_service_client_private { | |
void* parent; | |
}; | |
typedef struct device_link_service_client_private *device_link_service_client_t; | |
device_link_service_error_t device_link_service_client_new(idevice_t device, lockdownd_service_descriptor_t service, device_link_service_client_t *client); | |
device_link_service_error_t device_link_service_client_free(device_link_service_client_t client); | |
device_link_service_error_t device_link_service_version_exchange(device_link_service_client_t client, uint64_t version_major, uint64_t version_minor); | |
device_link_service_error_t device_link_service_send_ping(device_link_service_client_t client, const char *message); | |
device_link_service_error_t device_link_service_receive_message(device_link_service_client_t client, plist_t *msg_plist, char **dlmessage); | |
device_link_service_error_t device_link_service_send_process_message(device_link_service_client_t client, plist_t message); | |
device_link_service_error_t device_link_service_receive_process_message(device_link_service_client_t client, plist_t *message); | |
device_link_service_error_t device_link_service_disconnect(device_link_service_client_t client, const char *message); | |
device_link_service_error_t device_link_service_send(device_link_service_client_t client, plist_t plist); | |
device_link_service_error_t device_link_service_receive(device_link_service_client_t client, plist_t *plist); | |
#pragma managed | |
using namespace System; | |
using namespace System::Runtime::InteropServices; | |
#define STR clix::marshalString<clix::E_UTF8 | |
namespace iToolsVS | |
{ | |
namespace MobileDevice | |
{ | |
bool DumpFile(idevice_connection_t connection, int index, String^ file, System::String^ outPath, iToolsVS::Core::IOperationLogger^ log); | |
bool iDevice::FetchSymbols(System::String^ symbolsPath, iToolsVS::Core::IOperationLogger^ log) | |
{ | |
idevice_set_debug_level(0); | |
if (log == nullptr) | |
log = iToolsVS::Core::OperationLogger::Default; | |
// Phone pointer | |
idevice_t phone = NULL; | |
idevice_new(&phone, clix::marshalString<clix::E_UTF8>(this->uuid).c_str()); | |
// Lockdown client | |
lockdownd_client_t client = NULL; | |
if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "com.itoolsvs.fetchsymbols")) { | |
log->LogError("ERROR: Connecting to device failed!"); | |
return false; | |
} | |
// Start fetchsymbols service | |
lockdownd_service_descriptor_t service = NULL; | |
if (LOCKDOWN_E_SUCCESS != lockdownd_start_service(client, "com.apple.dt.fetchsymbols", &service)) { | |
log->LogError("ERROR: Start FetchSymbols service failed!"); | |
return false; | |
} | |
idevice_connection_t connection; | |
if (IDEVICE_E_SUCCESS != idevice_connect(phone, service->port, &connection)) | |
{ | |
log->LogError("ERROR: Start idevice_connect service failed!"); | |
return false; | |
} | |
System::Collections::Generic::List<String^>^ files = GetSymbolFiles(connection, log); | |
// request data | |
for (int i = 0; i < files->Count; i++) | |
{ | |
if (IDEVICE_E_SUCCESS != idevice_disconnect(connection)) | |
{ | |
log->LogError("ERROR: Start idevice_connect service failed!"); | |
return false; | |
} | |
lockdownd_service_descriptor_free(service); | |
service = NULL; | |
if (LOCKDOWN_E_SUCCESS != lockdownd_start_service(client, "com.apple.dt.fetchsymbols", &service)) { | |
log->LogError("ERROR: Start FetchSymbols service failed!"); | |
return false; | |
} | |
if (IDEVICE_E_SUCCESS != idevice_connect(phone, service->port, &connection)) | |
{ | |
log->LogError("ERROR: Start idevice_connect service failed!"); | |
return false; | |
} | |
DumpFile(connection, i, files[i], System::IO::Path::Combine(symbolsPath, files[i]->Replace("/", "\\")->TrimStart('\\')), log); | |
} | |
return true; | |
} | |
bool DumpFile(idevice_connection_t connection, int index, String^ file, System::String^ outPath, iToolsVS::Core::IOperationLogger^ log) | |
{ | |
int op = 0x1000000; | |
uint32_t sent = 0; | |
if (IDEVICE_E_SUCCESS != idevice_connection_send(connection, (const char*)&op, sizeof(op), &sent) || sent != sizeof(op)) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return false; | |
} | |
int res = 0; | |
if (IDEVICE_E_SUCCESS != idevice_connection_receive(connection, (char*)&res, sizeof(res), &sent) || sent != sizeof(res)) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return false; | |
} | |
int i = _byteswap_ulong(index); | |
int32_t sz = sizeof(i); | |
if (IDEVICE_E_SUCCESS != idevice_connection_send(connection, (const char*)&i, sz, &sent) || sent != sz) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return false; | |
} | |
int64_t totalSize = 0; | |
sz = sizeof(totalSize); | |
if (IDEVICE_E_SUCCESS != idevice_connection_receive(connection, (char*)&totalSize, sz, &sent) || sent != sz) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return false; | |
} | |
totalSize = _byteswap_uint64(totalSize); | |
uint32_t bufferSize = 0xa00000; | |
array<byte>^ buffer = gcnew array<byte>(bufferSize); | |
pin_ptr<byte> pin = &buffer[0]; | |
byte* ptrBuffer = pin; | |
String^ path = System::IO::Path::GetDirectoryName(outPath); | |
if (!System::IO::Directory::Exists(path)) | |
System::IO::Directory::CreateDirectory(path); | |
if (System::IO::File::Exists(outPath)) | |
System::IO::File::Delete(outPath); | |
int received = 0; | |
System::IO::FileStream^ fs; | |
fs = System::IO::File::OpenWrite(outPath); | |
System::IO::BinaryWriter^ br = gcnew System::IO::BinaryWriter(fs); | |
auto progress = log->StartProgress(); | |
while (received < totalSize) | |
{ | |
uint32_t count = 0; | |
if (IDEVICE_E_SUCCESS != idevice_connection_receive(connection, (char*)ptrBuffer, bufferSize, &count)) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return false; | |
} | |
received += count; | |
if (count > 0) | |
br->Write(buffer, 0, count); | |
if(progress) | |
progress->LogProgress(String::Format("Downloading {0}", System::IO::Path::GetFileName(outPath)), (received / (totalSize * 1.0)) * 100); | |
} | |
br->Flush(); | |
fs->Close(); | |
if (progress) | |
progress->LogProgress("", 100); | |
} | |
System::Collections::Generic::List<String^>^ iDevice::GetSymbolFiles(idevice_connection_t connection, iToolsVS::Core::IOperationLogger^ log) | |
{ | |
System::Collections::Generic::List<String^>^ ret = gcnew System::Collections::Generic::List<String^>(); | |
int maxSize = 0; | |
uint32_t sent = 0; | |
if (IDEVICE_E_SUCCESS != idevice_connection_send(connection, (const char*)&maxSize, sizeof(maxSize), &sent) || sent != sizeof(maxSize)) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return nullptr; | |
} | |
long res = 0; | |
if (IDEVICE_E_SUCCESS != idevice_connection_receive(connection, (char*)&res, sizeof(res), &sent) || sent != sizeof(res)) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return nullptr; | |
} | |
int count = 0; | |
if (IDEVICE_E_SUCCESS != idevice_connection_receive(connection, (char*)&count, sizeof(count), &sent) || sent != sizeof(count)) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return nullptr; | |
} | |
count = ntohl(count); | |
for (int i = 0; i < count; i++) | |
{ | |
int size = 0; | |
if (IDEVICE_E_SUCCESS != idevice_connection_receive(connection, (char*)&size, sizeof(size), &sent) || sent != sizeof(size)) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return nullptr; | |
} | |
size = ntohl(size); | |
char* data = (char*)malloc(size + 1); | |
ZeroMemory(data, size + 1); | |
uint32_t recv; | |
if (IDEVICE_E_SUCCESS != idevice_connection_receive(connection, data, size, &recv) || recv != size) | |
{ | |
log->LogError("ERROR: idevice_connection_send 1 !"); | |
return nullptr; | |
} | |
ret->Add(clix::marshalString<clix::E_UTF8>(data)); | |
} | |
return ret; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment