Update C examples for new FFI

This commit is contained in:
Jackson Coxson
2025-05-26 16:33:58 -06:00
parent f6cc68cb98
commit bc6a1c0503
13 changed files with 302 additions and 659 deletions

View File

@@ -7,187 +7,189 @@
#include <unistd.h>
void print_usage() {
printf("Usage: ipa_installer [options] <ipa_path>\n");
printf("Options:\n");
printf(" --ip IP_ADDRESS Device IP address (default: 10.7.0.2)\n");
printf(" --pairing FILE Pairing file path (default: pairing_file.plist)\n");
printf(" --udid UDID Device UDID (optional)\n");
printf("Usage: ipa_installer [options] <ipa_path>\n");
printf("Options:\n");
printf(" --ip IP_ADDRESS Device IP address (default: 10.7.0.2)\n");
printf(" --pairing FILE Pairing file path (default: "
"pairing_file.plist)\n");
printf(" --udid UDID Device UDID (optional)\n");
}
int read_file(const char *filename, uint8_t **data, size_t *length) {
FILE *file = fopen(filename, "rb");
if (!file) {
perror("Failed to open file");
return 0;
}
FILE *file = fopen(filename, "rb");
if (!file) {
perror("Failed to open file");
return 0;
}
fseek(file, 0, SEEK_END);
*length = ftell(file);
fseek(file, 0, SEEK_SET);
*data = malloc(*length);
if (!*data) {
perror("Failed to allocate memory");
fclose(file);
return 0;
}
if (fread(*data, 1, *length, file) != *length) {
perror("Failed to read file");
free(*data);
fclose(file);
return 0;
}
fseek(file, 0, SEEK_END);
*length = ftell(file);
fseek(file, 0, SEEK_SET);
*data = malloc(*length);
if (!*data) {
perror("Failed to allocate memory");
fclose(file);
return 1;
return 0;
}
if (fread(*data, 1, *length, file) != *length) {
perror("Failed to read file");
free(*data);
fclose(file);
return 0;
}
fclose(file);
return 1;
}
int main(int argc, char **argv) {
// Initialize logger
idevice_init_logger(Debug, Disabled, NULL);
// Initialize logger
idevice_init_logger(Debug, Disabled, NULL);
// Default values
char *ip = "10.7.0.2";
char *pairing_file_path = "pairing_file.plist";
char *udid = NULL;
char *ipa_path = NULL;
// Default values
char *ip = "10.7.0.2";
char *pairing_file_path = "pairing_file.plist";
char *udid = NULL;
char *ipa_path = NULL;
// Parse arguments
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--ip") == 0) {
if (i + 1 >= argc) {
printf("Error: Missing IP address argument\n");
return 1;
}
ip = argv[++i];
} else if (strcmp(argv[i], "--pairing") == 0) {
if (i + 1 >= argc) {
printf("Error: Missing pairing file argument\n");
return 1;
}
pairing_file_path = argv[++i];
} else if (strcmp(argv[i], "--udid") == 0) {
if (i + 1 >= argc) {
printf("Error: Missing UDID argument\n");
return 1;
}
udid = argv[++i];
} else if (strcmp(argv[i], "help") == 0) {
print_usage();
return 0;
} else {
ipa_path = argv[i];
break;
}
}
if (!ipa_path) {
print_usage();
// Parse arguments
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--ip") == 0) {
if (i + 1 >= argc) {
printf("Error: Missing IP address argument\n");
return 1;
}
// Create the socket address
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCKDOWN_PORT);
if (inet_pton(AF_INET, ip, &addr.sin_addr) != 1) {
fprintf(stderr, "Invalid IP address\n");
}
ip = argv[++i];
} else if (strcmp(argv[i], "--pairing") == 0) {
if (i + 1 >= argc) {
printf("Error: Missing pairing file argument\n");
return 1;
}
// Read pairing file
IdevicePairingFile *pairing_file = NULL;
IdeviceErrorCode err = idevice_pairing_file_read(pairing_file_path, &pairing_file);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to read pairing file: %d\n", err);
}
pairing_file_path = argv[++i];
} else if (strcmp(argv[i], "--udid") == 0) {
if (i + 1 >= argc) {
printf("Error: Missing UDID argument\n");
return 1;
}
// Create TCP provider
TcpProviderHandle *provider = NULL;
err = idevice_tcp_provider_new((struct sockaddr *)&addr, pairing_file,
"IPAInstaller", &provider);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to create TCP provider: %d\n", err);
idevice_pairing_file_free(pairing_file);
return 1;
}
// Connect to AFC service
AfcClientHandle *afc_client = NULL;
err = afc_client_connect_tcp(provider, &afc_client);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to connect to AFC service: %d\n", err);
tcp_provider_free(provider);
return 1;
}
// Extract filename from path
char *filename = strrchr(ipa_path, '/');
if (filename == NULL) {
filename = ipa_path;
}
udid = argv[++i];
} else if (strcmp(argv[i], "help") == 0) {
print_usage();
return 0;
} else {
filename++; // Skip the '/'
ipa_path = argv[i];
break;
}
}
// Create destination path
char dest_path[256];
snprintf(dest_path, sizeof(dest_path), "/PublicStaging/%s", filename);
if (!ipa_path) {
print_usage();
return 1;
}
// Upload IPA file
printf("Uploading %s to %s...\n", ipa_path, dest_path);
uint8_t *data = NULL;
size_t length = 0;
if (!read_file(ipa_path, &data, &length)) {
fprintf(stderr, "Failed to read IPA file\n");
afc_client_free(afc_client);
return 1;
}
// Create the socket address
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCKDOWN_PORT);
if (inet_pton(AF_INET, ip, &addr.sin_addr) != 1) {
fprintf(stderr, "Invalid IP address\n");
return 1;
}
AfcFileHandle *file = NULL;
err = afc_file_open(afc_client, dest_path, AfcWrOnly | AfcCreat, &file);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to open destination file: %d\n", err);
free(data);
afc_client_free(afc_client);
return 1;
}
// Read pairing file
IdevicePairingFile *pairing_file = NULL;
IdeviceErrorCode err =
idevice_pairing_file_read(pairing_file_path, &pairing_file);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to read pairing file: %d\n", err);
return 1;
}
err = afc_file_write(file, data, length);
free(data);
afc_file_close(file);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to write file: %d\n", err);
afc_client_free(afc_client);
return 1;
}
printf("Upload completed successfully\n");
// Create TCP provider
IdeviceProviderHandle *provider = NULL;
err = idevice_tcp_provider_new((struct sockaddr *)&addr, pairing_file,
"IPAInstaller", &provider);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to create TCP provider: %d\n", err);
idevice_pairing_file_free(pairing_file);
return 1;
}
// Connect to installation proxy
InstallationProxyClientHandle *instproxy_client = NULL;
err = installation_proxy_connect_tcp(provider, &instproxy_client);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to connect to installation proxy: %d\n", err);
afc_client_free(afc_client);
return 1;
}
// Connect to AFC service
AfcClientHandle *afc_client = NULL;
err = afc_client_connect(provider, &afc_client);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to connect to AFC service: %d\n", err);
idevice_provider_free(provider);
return 1;
}
// Install the uploaded IPA
printf("Installing %s...\n", dest_path);
err = installation_proxy_install(instproxy_client, dest_path, NULL);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to install IPA: %d\n", err);
} else {
printf("Installation completed successfully\n");
}
// Extract filename from path
char *filename = strrchr(ipa_path, '/');
if (filename == NULL) {
filename = ipa_path;
} else {
filename++; // Skip the '/'
}
// Cleanup
installation_proxy_client_free(instproxy_client);
// Create destination path
char dest_path[256];
snprintf(dest_path, sizeof(dest_path), "/PublicStaging/%s", filename);
// Upload IPA file
printf("Uploading %s to %s...\n", ipa_path, dest_path);
uint8_t *data = NULL;
size_t length = 0;
if (!read_file(ipa_path, &data, &length)) {
fprintf(stderr, "Failed to read IPA file\n");
afc_client_free(afc_client);
tcp_provider_free(provider);
return 1;
}
return err == IdeviceSuccess ? 0 : 1;
AfcFileHandle *file = NULL;
err = afc_file_open(afc_client, dest_path, AfcWrOnly, &file);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to open destination file: %d\n", err);
free(data);
afc_client_free(afc_client);
return 1;
}
err = afc_file_write(file, data, length);
free(data);
afc_file_close(file);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to write file: %d\n", err);
afc_client_free(afc_client);
return 1;
}
printf("Upload completed successfully\n");
// Connect to installation proxy
InstallationProxyClientHandle *instproxy_client = NULL;
err = installation_proxy_connect_tcp(provider, &instproxy_client);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to connect to installation proxy: %d\n", err);
afc_client_free(afc_client);
return 1;
}
// Install the uploaded IPA
printf("Installing %s...\n", dest_path);
err = installation_proxy_install(instproxy_client, dest_path, NULL);
if (err != IdeviceSuccess) {
fprintf(stderr, "Failed to install IPA: %d\n", err);
} else {
printf("Installation completed successfully\n");
}
// Cleanup
installation_proxy_client_free(instproxy_client);
afc_client_free(afc_client);
idevice_provider_free(provider);
return err == IdeviceSuccess ? 0 : 1;
}