Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/ios-deploy/MobileDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ typedef unsigned int mach_error_t;

typedef unsigned int afc_error_t;
typedef unsigned int usbmux_error_t;
typedef unsigned int service_conn_t;

typedef struct {
char unknown[0x10];
int sockfd;
void * sslContext;
// ??
} service_conn_t;

typedef service_conn_t * ServiceConnRef;

struct am_recovery_device;
Expand Down
74 changes: 63 additions & 11 deletions src/ios-deploy/ios-deploy.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <signal.h>
#include <getopt.h>
#include <pwd.h>
#include <dlfcn.h>

#include <netinet/in.h>
#include <netinet/tcp.h>

Expand Down Expand Up @@ -75,13 +77,19 @@
mach_error_t AMDeviceSecureStartService(AMDeviceRef device, CFStringRef service_name, unsigned int *unknown, ServiceConnRef * handle);
mach_error_t AMDeviceCreateHouseArrestService(AMDeviceRef device, CFStringRef identifier, CFDictionaryRef options, AFCConnectionRef * handle);
CFSocketNativeHandle AMDServiceConnectionGetSocket(ServiceConnRef con);
void AMDServiceConnectionInvalidate(ServiceConnRef con);

bool AMDeviceIsAtLeastVersionOnPlatform(AMDeviceRef device, CFDictionaryRef vers);
int AMDeviceSecureTransferPath(int zero, AMDeviceRef device, CFURLRef url, CFDictionaryRef options, void *callback, int cbarg);
int AMDeviceSecureInstallApplication(int zero, AMDeviceRef device, CFURLRef url, CFDictionaryRef options, void *callback, int cbarg);
int AMDeviceSecureInstallApplicationBundle(AMDeviceRef device, CFURLRef url, CFDictionaryRef options, void *callback, int cbarg);
int AMDeviceMountImage(AMDeviceRef device, CFStringRef image, CFDictionaryRef options, void *callback, int cbarg);
mach_error_t AMDeviceLookupApplications(AMDeviceRef device, CFDictionaryRef options, CFDictionaryRef *result);
int AMDeviceGetInterfaceType(AMDeviceRef device);

int AMDServiceConnectionSend(ServiceConnRef con, const void * data, size_t size);
int AMDServiceConnectionReceive(ServiceConnRef con, void * data, size_t size);

bool found_device = false, debug = false, verbose = false, unbuffered = false, nostart = false, debugserver_only = false, detect_only = false, install = true, uninstall = false, no_wifi = false;
bool command_only = false;
char *command = NULL;
Expand All @@ -104,7 +112,7 @@
NSMutableArray *_file_meta_info = nil;
int port = 0; // 0 means "dynamically assigned"
CFStringRef last_path = NULL;
service_conn_t gdbfd;
ServiceConnRef dbgServiceConnection = NULL;
pid_t parent = 0;
// PID of child process running lldb
pid_t child = 0;
Expand Down Expand Up @@ -135,6 +143,22 @@
} \
} while (false);


void disable_ssl(ServiceConnRef con)
{
// MobileDevice links with SSL, so function will be available;
typedef void (*SSL_free_t)(void*);
static SSL_free_t SSL_free = NULL;
if (SSL_free == NULL)
{
SSL_free = (SSL_free_t)dlsym(RTLD_DEFAULT, "SSL_free");
}

SSL_free(con->sslContext);
con->sslContext = NULL;
}


void on_error(NSString* format, ...)
{
va_list valist;
Expand Down Expand Up @@ -959,13 +983,24 @@ void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) {
void
server_callback (CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
{
if (CFDataGetLength (data) == 0) {
char buffer[0x1000];
int bytesRead = AMDServiceConnectionReceive(dbgServiceConnection, buffer, sizeof(buffer));
if (bytesRead == 0)
{
// close the socket on which we've got end-of-file, the server_socket.
CFSocketInvalidate(s);
CFRelease(s);
return;
}
write(CFSocketGetNative(lldb_socket), CFDataGetBytePtr(data), CFDataGetLength(data));
write(CFSocketGetNative (lldb_socket), buffer, bytesRead);
while (bytesRead == sizeof(buffer))
{
bytesRead = AMDServiceConnectionReceive(dbgServiceConnection, buffer, sizeof(buffer));
if (bytesRead > 0)
{
write(CFSocketGetNative (lldb_socket), buffer, bytesRead);
}
}
}

void lldb_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
Expand All @@ -978,7 +1013,8 @@ void lldb_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef a
CFRelease(s);
return;
}
write (gdbfd, CFDataGetBytePtr (data), CFDataGetLength (data));
int sent = AMDServiceConnectionSend(dbgServiceConnection, CFDataGetBytePtr(data), CFDataGetLength (data));
assert (CFDataGetLength (data) == sent);
}

void fdvendor_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info) {
Expand Down Expand Up @@ -1012,8 +1048,19 @@ void connect_and_start_session(AMDeviceRef device) {

void start_remote_debug_server(AMDeviceRef device) {

ServiceConnRef con = NULL;
int start_err = AMDeviceSecureStartService(device, CFSTR("com.apple.debugserver"), NULL, &con);
dbgServiceConnection = NULL;
CFStringRef serviceName = CFSTR("com.apple.debugserver");
CFStringRef keys[] = { CFSTR("MinIPhoneVersion"), CFSTR("MinAppleTVVersion") };
CFStringRef values[] = { CFSTR("14.0"), CFSTR("14.0")};
CFDictionaryRef version = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

bool useSecureProxy = AMDeviceIsAtLeastVersionOnPlatform(device, version);
if (useSecureProxy)
{
serviceName = CFSTR("com.apple.debugserver.DVTSecureSocketProxy");
}

int start_err = AMDeviceSecureStartService(device, serviceName, NULL, &dbgServiceConnection);
if (start_err != 0)
{
// After we mount the image, iOS needs to scan the image to register new services.
Expand All @@ -1037,15 +1084,20 @@ void start_remote_debug_server(AMDeviceRef device) {
default:
check_error(start_err);
}
check_error(AMDeviceSecureStartService(device, CFSTR("com.apple.debugserver"), NULL, &con));
check_error(AMDeviceSecureStartService(device, serviceName, NULL, &dbgServiceConnection));
}
assert(dbgServiceConnection != NULL);

if (!useSecureProxy)
{
disable_ssl(dbgServiceConnection);
}
assert(con != NULL);
gdbfd = AMDServiceConnectionGetSocket(con);

/*
* The debugserver connection is through a fd handle, while lldb requires a host/port to connect, so create an intermediate
* socket to transfer data.
*/
server_socket = CFSocketCreateWithNative (NULL, gdbfd, kCFSocketDataCallBack, &server_callback, NULL);
server_socket = CFSocketCreateWithNative (NULL, AMDServiceConnectionGetSocket(dbgServiceConnection), kCFSocketReadCallBack, &server_callback, NULL);
if (server_socket_runloop) {
CFRelease(server_socket_runloop);
}
Expand Down Expand Up @@ -2007,7 +2059,7 @@ void handle_device(AMDeviceRef device) {
CFStringRef values[] = { CFSTR("Developer") };
options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
check_error(AMDeviceSecureTransferPath(0, device, url, options, transfer_callback, 0));
close(*afcFd);
AMDServiceConnectionInvalidate(afcFd);

connect_and_start_session(device);
check_error(AMDeviceSecureInstallApplication(0, device, url, options, install_callback, 0));
Expand Down