Skip to content

Instantly share code, notes, and snippets.

Created May 18, 2015 17:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/759f6d02301b25e18db5 to your computer and use it in GitHub Desktop.
Save anonymous/759f6d02301b25e18db5 to your computer and use it in GitHub Desktop.
com.apple.dt.fetchsymbols example usage for iOS 7
#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