Skip to content

Commit

Permalink
Add dsc_extract test
Browse files Browse the repository at this point in the history
  • Loading branch information
alfiecg24 committed Nov 16, 2024
1 parent e4ba2f1 commit bfa5297
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/CodeDirectory.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ void csd_code_directory_update(CS_DecodedBlob *codeDirBlob, MachO *macho)
break;
}
if (!hashLen) {
printf("ERROR: unknown hash type (%d)\n", hashType);
printf("Error: unknown hash type (%d)\n", hashType);
}

// Calculate hash
Expand Down
10 changes: 5 additions & 5 deletions src/DyldSharedCache.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ DyldSharedCache *dsc_init_from_path(const char *path)
// Load main DSC file
DyldSharedCacheFile *mainFile = _dsc_load_file(path, "");
if (!mainFile) {
printf("ERROR: Failed to load main cache file\n");
printf("Error: Failed to load main cache file\n");
dsc_free(sharedCache);
return NULL;
}
Expand Down Expand Up @@ -162,14 +162,14 @@ DyldSharedCache *dsc_init_from_path(const char *path)

sharedCache->files[i+1] = _dsc_load_file(path, subcacheEntry.fileSuffix);
if (!sharedCache->files[i+1]) {
printf("ERROR: Failed to map subcache with suffix %s\n", subcacheEntry.fileSuffix);
printf("Error: Failed to map subcache with suffix %s\n", subcacheEntry.fileSuffix);
dsc_free(sharedCache);
return NULL;
}

struct dyld_cache_header *header = sharedCache->files[i+1]->mapping;
if (memcmp(header->uuid, subcacheEntry.uuid, sizeof(header->uuid)) != 0) {
printf("ERROR: UUID mismatch on subcache with suffix %s\n", subcacheEntry.fileSuffix);
printf("Error: UUID mismatch on subcache with suffix %s\n", subcacheEntry.fileSuffix);
dsc_free(sharedCache);
return NULL;
}
Expand All @@ -182,14 +182,14 @@ DyldSharedCache *dsc_init_from_path(const char *path)

sharedCache->files[sharedCache->symbolFileIndex] = _dsc_load_file(path, ".symbols");
if (!sharedCache->files[sharedCache->symbolFileIndex]) {
printf("ERROR: Failed to map symbols subcache\n");
printf("Error: Failed to map symbols subcache\n");
dsc_free(sharedCache);
return NULL;
}

struct dyld_cache_header *header = sharedCache->files[sharedCache->symbolFileIndex]->mapping;
if (memcmp(header->uuid, mainHeader->symbolFileUUID, sizeof(header->uuid)) != 0) {
printf("ERROR: UUID mismatch on symbols subcache\n");
printf("Error: UUID mismatch on symbols subcache\n");
dsc_free(sharedCache);
return NULL;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Host.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ int host_get_cpu_information(cpu_type_t *cputype, cpu_subtype_t *cpusubtype)

// Query for cputype
len = sizeof(cputype);
if (sysctlbyname("hw.cputype", cputype, &len, NULL, 0) == -1) { printf("ERROR: no cputype.\n"); return -1; }
if (sysctlbyname("hw.cputype", cputype, &len, NULL, 0) == -1) { printf("Error: no cputype.\n"); return -1; }

// Query for cpusubtype
len = sizeof(cpusubtype);
if (sysctlbyname("hw.cpusubtype", cpusubtype, &len, NULL, 0) == -1) { printf("ERROR: no cpusubtype.\n"); return -1; }
if (sysctlbyname("hw.cpusubtype", cpusubtype, &len, NULL, 0) == -1) { printf("Error: no cpusubtype.\n"); return -1; }

return 0;
}
Expand Down
95 changes: 95 additions & 0 deletions tests/dsc_extract/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include <choma/Fat.h>
#include <choma/MemoryStream.h>
#include <choma/DyldSharedCache.h>

char *get_argument_value(int argc, char *argv[], const char *flag)
{
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], flag)) {
if (i+1 < argc) {
return argv[i+1];
}
}
}
return NULL;
}

bool argument_exists(int argc, char *argv[], const char *flag)
{
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], flag)) {
return true;
}
}
return false;
}

void print_usage(char *executablePath) {
printf("Options:\n");
printf("\t-i: Path to input DSC file (e.g. dyld_shared_cache_arm64e)\n");
printf("\t-o: Path output file if required\n");
printf("\t-e: Path of image to extract\n");
printf("\t-l: List images contained in shared cache\n");
printf("\t-h: Print this message\n");
printf("Examples:\n");
printf("\t%s -i <path to DSC file> -l\n", executablePath);
printf("\t%s -i <path to DSC file> -e <path to framework> -o <path to extracted framework>\n", executablePath);
exit(-1);
}

int main(int argc, char *argv[]) {
if (argument_exists(argc, argv, "-h")) {
print_usage(argv[0]);
}

char *inputPath = get_argument_value(argc, argv, "-i");
char *outputPath = get_argument_value(argc, argv, "-o");
char *imageToExtract = get_argument_value(argc, argv, "-e");
bool shouldListImages = argument_exists(argc, argv, "-l");


if (!inputPath) {
printf("Error: input file required\n");
print_usage(argv[0]);
}

if (!shouldListImages && !outputPath) {
printf("Error: output file required\n");
print_usage(argv[0]);
}

DyldSharedCache *dsc = dsc_init_from_path(inputPath);
if (!dsc) {
printf("Error: failed to parse dyld shared cache\n");
return -2;
}

__block Fat *extractedFat = NULL;
dsc_enumerate_images(dsc, ^(const char *path, Fat *imageFAT, bool *stop){
if (shouldListImages) printf("%s\n", path);
if (imageToExtract && !strcmp(path, imageToExtract)) {
extractedFat = imageFAT;
}
});

if (!extractedFat && imageToExtract) {
printf("Error: failed to locate %s in shared cache\n", imageToExtract);
} else if (extractedFat) {
FILE *f = fopen(outputPath, "wb+");
if (f) {
fwrite(memory_stream_get_raw_pointer(extractedFat->stream), memory_stream_get_size(extractedFat->stream), 1, f);
fclose(f);
} else {
printf("Error: failed to open %s for writing\n", outputPath);
}
}

dsc_free(dsc);

return 0;
}

0 comments on commit bfa5297

Please sign in to comment.