mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-16 12:30:29 +00:00
145 lines
5.4 KiB
C
145 lines
5.4 KiB
C
//
|
|
// applist.c
|
|
// StikJIT
|
|
//
|
|
// Created by Stephen on 3/27/25.
|
|
//
|
|
|
|
#include "idevice.h"
|
|
#include <arpa/inet.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
#include <limits.h>
|
|
|
|
char *list_installed_apps() {
|
|
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, "10.7.0.1", &addr.sin_addr) <= 0) {
|
|
return strdup("{\"error\": \"Invalid IP address\"}");
|
|
}
|
|
|
|
char pairingFilePath[1024];
|
|
CFURLRef url = CFCopyHomeDirectoryURL();
|
|
if (url) {
|
|
CFStringRef path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
|
|
if (path) {
|
|
CFStringGetCString(path, pairingFilePath, sizeof(pairingFilePath), kCFStringEncodingUTF8);
|
|
strncat(pairingFilePath, "/Documents/pairingFile.plist", sizeof(pairingFilePath) - strlen(pairingFilePath) - 1);
|
|
CFRelease(path);
|
|
}
|
|
CFRelease(url);
|
|
}
|
|
|
|
IdevicePairingFile *pairing_file = NULL;
|
|
IdeviceErrorCode err = idevice_pairing_file_read(pairingFilePath, &pairing_file);
|
|
if (err != IdeviceSuccess) {
|
|
return strdup("{\"error\": \"Failed to read pairing file\"}");
|
|
}
|
|
|
|
TcpProviderHandle *provider = NULL;
|
|
err = idevice_tcp_provider_new((struct sockaddr *)&addr, pairing_file, "ExampleProvider", &provider);
|
|
if (err != IdeviceSuccess) {
|
|
idevice_pairing_file_free(pairing_file);
|
|
return strdup("{\"error\": \"Failed to create TCP provider\"}");
|
|
}
|
|
|
|
InstallationProxyClientHandle *client = NULL;
|
|
err = installation_proxy_connect_tcp(provider, &client);
|
|
if (err != IdeviceSuccess) {
|
|
tcp_provider_free(provider);
|
|
return strdup("{\"error\": \"Failed to connect to installation proxy\"}");
|
|
}
|
|
|
|
void *apps = NULL;
|
|
size_t apps_len = 0;
|
|
err = installation_proxy_get_apps(client, NULL, NULL, 0, &apps, &apps_len);
|
|
if (err != IdeviceSuccess) {
|
|
installation_proxy_client_free(client);
|
|
tcp_provider_free(provider);
|
|
return strdup("{\"error\": \"Failed to get apps\"}");
|
|
}
|
|
|
|
plist_t *app_list = (plist_t *)apps;
|
|
char *result = malloc(8192); // Allocate memory for output
|
|
result[0] = '\0';
|
|
strcat(result, "{\n");
|
|
|
|
int first_entry = 1;
|
|
for (size_t i = 0; i < apps_len; i++) {
|
|
plist_t app = app_list[i];
|
|
// Check if the app has an "Entitlements" dictionary.
|
|
plist_t entitlements = plist_dict_get_item(app, "Entitlements");
|
|
if (entitlements) {
|
|
// Look for the "get-task-allow" key.
|
|
plist_t taskAllowNode = plist_dict_get_item(entitlements, "get-task-allow");
|
|
if (taskAllowNode) {
|
|
int isAllowed = 0;
|
|
plist_get_bool_val(taskAllowNode, &isAllowed);
|
|
if (isAllowed) {
|
|
// Retrieve the bundle identifier if the entitlement is true.
|
|
plist_t bundle_id_node = plist_dict_get_item(app, "CFBundleIdentifier");
|
|
if (bundle_id_node) {
|
|
char *bundle_id = NULL;
|
|
plist_get_string_val(bundle_id_node, &bundle_id);
|
|
|
|
// Skip if bundle ID is empty
|
|
if (bundle_id == NULL || strlen(bundle_id) == 0) {
|
|
free(bundle_id);
|
|
continue;
|
|
}
|
|
|
|
// Retrieve the app name
|
|
plist_t app_name_node = plist_dict_get_item(app, "CFBundleName");
|
|
char *app_name = NULL;
|
|
if (app_name_node) {
|
|
plist_get_string_val(app_name_node, &app_name);
|
|
} else {
|
|
app_name = strdup("Unknown");
|
|
}
|
|
|
|
// Escape special characters in app name and bundle ID
|
|
char escaped_app_name[1024] = {0};
|
|
char escaped_bundle_id[1024] = {0};
|
|
for (int j = 0, k = 0; app_name[j] != '\0'; j++, k++) {
|
|
if (app_name[j] == '"' || app_name[j] == '\\') {
|
|
escaped_app_name[k++] = '\\';
|
|
}
|
|
escaped_app_name[k] = app_name[j];
|
|
}
|
|
for (int j = 0, k = 0; bundle_id[j] != '\0'; j++, k++) {
|
|
if (bundle_id[j] == '"' || bundle_id[j] == '\\') {
|
|
escaped_bundle_id[k++] = '\\';
|
|
}
|
|
escaped_bundle_id[k] = bundle_id[j];
|
|
}
|
|
|
|
// Add the app name and bundle ID to the result in JSON format
|
|
if (!first_entry) {
|
|
strcat(result, ",\n");
|
|
}
|
|
strcat(result, " \"");
|
|
strcat(result, escaped_app_name);
|
|
strcat(result, "\": \"");
|
|
strcat(result, escaped_bundle_id);
|
|
strcat(result, "\"");
|
|
|
|
first_entry = 0;
|
|
free(bundle_id);
|
|
free(app_name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
strcat(result, "\n}\n");
|
|
|
|
installation_proxy_client_free(client);
|
|
tcp_provider_free(provider);
|
|
|
|
return result;
|
|
}
|