Skip to content

Commit 8092250

Browse files
authored
fix communication with debuggserver on ios-14 (#471)
* fix communication with debuggserver on ios-14 * decrease read buffer size, create socket with correct flags * fix regression on older iOS devices
1 parent 5276058 commit 8092250

File tree

2 files changed

+71
-12
lines changed

2 files changed

+71
-12
lines changed

src/ios-deploy/MobileDevice.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,14 @@ typedef unsigned int mach_error_t;
6565

6666
typedef unsigned int afc_error_t;
6767
typedef unsigned int usbmux_error_t;
68-
typedef unsigned int service_conn_t;
68+
69+
typedef struct {
70+
char unknown[0x10];
71+
int sockfd;
72+
void * sslContext;
73+
// ??
74+
} service_conn_t;
75+
6976
typedef service_conn_t * ServiceConnRef;
7077

7178
struct am_recovery_device;

src/ios-deploy/ios-deploy.m

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <signal.h>
1313
#include <getopt.h>
1414
#include <pwd.h>
15+
#include <dlfcn.h>
16+
1517
#include <netinet/in.h>
1618
#include <netinet/tcp.h>
1719

@@ -75,13 +77,19 @@
7577
mach_error_t AMDeviceSecureStartService(AMDeviceRef device, CFStringRef service_name, unsigned int *unknown, ServiceConnRef * handle);
7678
mach_error_t AMDeviceCreateHouseArrestService(AMDeviceRef device, CFStringRef identifier, CFDictionaryRef options, AFCConnectionRef * handle);
7779
CFSocketNativeHandle AMDServiceConnectionGetSocket(ServiceConnRef con);
80+
void AMDServiceConnectionInvalidate(ServiceConnRef con);
81+
82+
bool AMDeviceIsAtLeastVersionOnPlatform(AMDeviceRef device, CFDictionaryRef vers);
7883
int AMDeviceSecureTransferPath(int zero, AMDeviceRef device, CFURLRef url, CFDictionaryRef options, void *callback, int cbarg);
7984
int AMDeviceSecureInstallApplication(int zero, AMDeviceRef device, CFURLRef url, CFDictionaryRef options, void *callback, int cbarg);
8085
int AMDeviceSecureInstallApplicationBundle(AMDeviceRef device, CFURLRef url, CFDictionaryRef options, void *callback, int cbarg);
8186
int AMDeviceMountImage(AMDeviceRef device, CFStringRef image, CFDictionaryRef options, void *callback, int cbarg);
8287
mach_error_t AMDeviceLookupApplications(AMDeviceRef device, CFDictionaryRef options, CFDictionaryRef *result);
8388
int AMDeviceGetInterfaceType(AMDeviceRef device);
8489

90+
int AMDServiceConnectionSend(ServiceConnRef con, const void * data, size_t size);
91+
int AMDServiceConnectionReceive(ServiceConnRef con, void * data, size_t size);
92+
8593
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;
8694
bool command_only = false;
8795
char *command = NULL;
@@ -104,7 +112,7 @@
104112
NSMutableArray *_file_meta_info = nil;
105113
int port = 0; // 0 means "dynamically assigned"
106114
CFStringRef last_path = NULL;
107-
service_conn_t gdbfd;
115+
ServiceConnRef dbgServiceConnection = NULL;
108116
pid_t parent = 0;
109117
// PID of child process running lldb
110118
pid_t child = 0;
@@ -135,6 +143,22 @@
135143
} \
136144
} while (false);
137145

146+
147+
void disable_ssl(ServiceConnRef con)
148+
{
149+
// MobileDevice links with SSL, so function will be available;
150+
typedef void (*SSL_free_t)(void*);
151+
static SSL_free_t SSL_free = NULL;
152+
if (SSL_free == NULL)
153+
{
154+
SSL_free = (SSL_free_t)dlsym(RTLD_DEFAULT, "SSL_free");
155+
}
156+
157+
SSL_free(con->sslContext);
158+
con->sslContext = NULL;
159+
}
160+
161+
138162
void on_error(NSString* format, ...)
139163
{
140164
va_list valist;
@@ -959,13 +983,24 @@ void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) {
959983
void
960984
server_callback (CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
961985
{
962-
if (CFDataGetLength (data) == 0) {
986+
char buffer[0x1000];
987+
int bytesRead = AMDServiceConnectionReceive(dbgServiceConnection, buffer, sizeof(buffer));
988+
if (bytesRead == 0)
989+
{
963990
// close the socket on which we've got end-of-file, the server_socket.
964991
CFSocketInvalidate(s);
965992
CFRelease(s);
966993
return;
967994
}
968-
write(CFSocketGetNative(lldb_socket), CFDataGetBytePtr(data), CFDataGetLength(data));
995+
write(CFSocketGetNative (lldb_socket), buffer, bytesRead);
996+
while (bytesRead == sizeof(buffer))
997+
{
998+
bytesRead = AMDServiceConnectionReceive(dbgServiceConnection, buffer, sizeof(buffer));
999+
if (bytesRead > 0)
1000+
{
1001+
write(CFSocketGetNative (lldb_socket), buffer, bytesRead);
1002+
}
1003+
}
9691004
}
9701005

9711006
void lldb_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
@@ -978,7 +1013,8 @@ void lldb_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef a
9781013
CFRelease(s);
9791014
return;
9801015
}
981-
write (gdbfd, CFDataGetBytePtr (data), CFDataGetLength (data));
1016+
int sent = AMDServiceConnectionSend(dbgServiceConnection, CFDataGetBytePtr(data), CFDataGetLength (data));
1017+
assert (CFDataGetLength (data) == sent);
9821018
}
9831019

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

10131049
void start_remote_debug_server(AMDeviceRef device) {
10141050

1015-
ServiceConnRef con = NULL;
1016-
int start_err = AMDeviceSecureStartService(device, CFSTR("com.apple.debugserver"), NULL, &con);
1051+
dbgServiceConnection = NULL;
1052+
CFStringRef serviceName = CFSTR("com.apple.debugserver");
1053+
CFStringRef keys[] = { CFSTR("MinIPhoneVersion"), CFSTR("MinAppleTVVersion") };
1054+
CFStringRef values[] = { CFSTR("14.0"), CFSTR("14.0")};
1055+
CFDictionaryRef version = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1056+
1057+
bool useSecureProxy = AMDeviceIsAtLeastVersionOnPlatform(device, version);
1058+
if (useSecureProxy)
1059+
{
1060+
serviceName = CFSTR("com.apple.debugserver.DVTSecureSocketProxy");
1061+
}
1062+
1063+
int start_err = AMDeviceSecureStartService(device, serviceName, NULL, &dbgServiceConnection);
10171064
if (start_err != 0)
10181065
{
10191066
// After we mount the image, iOS needs to scan the image to register new services.
@@ -1037,15 +1084,20 @@ void start_remote_debug_server(AMDeviceRef device) {
10371084
default:
10381085
check_error(start_err);
10391086
}
1040-
check_error(AMDeviceSecureStartService(device, CFSTR("com.apple.debugserver"), NULL, &con));
1087+
check_error(AMDeviceSecureStartService(device, serviceName, NULL, &dbgServiceConnection));
1088+
}
1089+
assert(dbgServiceConnection != NULL);
1090+
1091+
if (!useSecureProxy)
1092+
{
1093+
disable_ssl(dbgServiceConnection);
10411094
}
1042-
assert(con != NULL);
1043-
gdbfd = AMDServiceConnectionGetSocket(con);
1095+
10441096
/*
10451097
* The debugserver connection is through a fd handle, while lldb requires a host/port to connect, so create an intermediate
10461098
* socket to transfer data.
10471099
*/
1048-
server_socket = CFSocketCreateWithNative (NULL, gdbfd, kCFSocketDataCallBack, &server_callback, NULL);
1100+
server_socket = CFSocketCreateWithNative (NULL, AMDServiceConnectionGetSocket(dbgServiceConnection), kCFSocketReadCallBack, &server_callback, NULL);
10491101
if (server_socket_runloop) {
10501102
CFRelease(server_socket_runloop);
10511103
}
@@ -2007,7 +2059,7 @@ void handle_device(AMDeviceRef device) {
20072059
CFStringRef values[] = { CFSTR("Developer") };
20082060
options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
20092061
check_error(AMDeviceSecureTransferPath(0, device, url, options, transfer_callback, 0));
2010-
close(*afcFd);
2062+
AMDServiceConnectionInvalidate(afcFd);
20112063

20122064
connect_and_start_session(device);
20132065
check_error(AMDeviceSecureInstallApplication(0, device, url, options, install_callback, 0));

0 commit comments

Comments
 (0)