Ejemplo n.º 1
0
int copyAcrossVolumes(Volume* volume1, Volume* volume2, char* path1, char* path2) {
	void* buffer;
	size_t bufferSize;
	AbstractFile* tmpFile;
	int ret;
	
	buffer = malloc(1);
	bufferSize = 0;
	tmpFile = createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize);
	
	if(!silence)
	{
		printf("retrieving... "); fflush(stdout);
	}

	get_hfs(volume1, path1, tmpFile);
	tmpFile->seek(tmpFile, 0);

	if(!silence)
	{
		printf("writing (%ld)... ", (long) tmpFile->getLength(tmpFile)); fflush(stdout);
	}

	ret = add_hfs(volume2, tmpFile, path2);

	if(!silence)
	{
		printf("done\n");
	}
	
	free(buffer);
	
	return ret;
}
Ejemplo n.º 2
0
void fs_cmd_add(int argc, char** argv)
{
	if(argc < 6)
	{
		bufferPrintf("usage: %s <device> <partition> <file> <location> <size>\r\n", argv[0]);
		return;
	}

	bdevfs_device_t *dev = bdevfs_open(parseNumber(argv[1]), parseNumber(argv[2]));
	uint32_t address = parseNumber(argv[4]);
	uint32_t size = parseNumber(argv[5]);

	if(add_hfs(dev->volume, (uint8_t*) address, size, argv[3]))
	{
		bufferPrintf("%d bytes of 0x%x stored in %s\r\n", size, address, argv[3]);
	}
	else
	{
		bufferPrintf("add_hfs failed for %s!\r\n", argv[3]);
	}

	if(block_device_sync(dev->handle) < 0)
		bufferPrintf("FS sync error!\n");

	bdevfs_close(dev);
}
Ejemplo n.º 3
0
void fixupBootNeuterArgs(Volume* volume, char unlockBaseband, char selfDestruct, char use39, char use46) {
	const char bootNeuterPlist[] = "/System/Library/LaunchDaemons/com.devteam.bootneuter.auto.plist";
	AbstractFile* plistFile;
	char* plist;
	Dictionary* info;
	size_t bufferSize;
	ArrayValue* arguments;
	
	XLOG(0, "fixing up BootNeuter arguments...\n");
	
	plist = malloc(1);
	bufferSize = 0;
	plistFile = createAbstractFileFromMemoryFile((void**)&plist, &bufferSize);
	get_hfs(volume, bootNeuterPlist, plistFile);	
	plistFile->close(plistFile);
	info = createRoot(plist);
	free(plist);

	arguments = (ArrayValue*) getValueByKey(info, "ProgramArguments");
	addStringToArray(arguments, "-autoMode");
	addStringToArray(arguments, "YES");
	addStringToArray(arguments, "-RegisterForSystemEvents");
	addStringToArray(arguments, "YES");
	
	if(unlockBaseband) {
		addStringToArray(arguments, "-unlockBaseband");
		addStringToArray(arguments, "YES");
	}
	
	if(selfDestruct) {
		addStringToArray(arguments, "-selfDestruct");
		addStringToArray(arguments, "YES");
	}
	
	if(use39) {
		addStringToArray(arguments, "-bootLoader");
		addStringToArray(arguments, "3.9");
	} else if(use46) {
		addStringToArray(arguments, "-bootLoader");
		addStringToArray(arguments, "4.6");
	}
	
	plist = getXmlFromRoot(info);
	releaseDictionary(info);
	
	plistFile = createAbstractFileFromMemory((void**)&plist, sizeof(char) * strlen(plist));
	add_hfs(volume, plistFile, bootNeuterPlist);
	free(plist);
}
Ejemplo n.º 4
0
Archivo: hfs.c Proyecto: arkanoid1/xpwn
void cmd_add(Volume* volume, int argc, const char *argv[]) {
	AbstractFile *inFile;
	
	if(argc < 3) {
		printf("Not enough arguments");
		return;
	}
	
	inFile = createAbstractFileFromFile(fopen(argv[1], "rb"));
	
	if(inFile == NULL) {
		printf("file to add not found");
	}

	add_hfs(volume, inFile, argv[2]);
}
Ejemplo n.º 5
0
void createRestoreOptions(Volume* volume, const char *optionsPlist, int SystemPartitionSize, int UpdateBaseband) {
	AbstractFile* plistFile;
	Dictionary* info;
	char* plist;

	HFSPlusCatalogRecord* record;
	info = NULL;
	record = getRecordFromPath(optionsPlist, volume, NULL, NULL);
	if(record != NULL && record->recordType == kHFSPlusFileRecord) {
		HFSPlusCatalogFile* file = (HFSPlusCatalogFile*)record;
		size_t bufferSize = 512;
		plist = malloc(bufferSize);
		plistFile = createAbstractFileFromMemory((void**)&plist, bufferSize);
		if (plistFile) {
			char zero = 0;
			writeToFile(file, plistFile, volume);
			plistFile->write(plistFile, &zero, sizeof(zero));
			plistFile->close(plistFile);
			info = createRoot(plist);
			removeKey(info, "CreateFilesystemPartitions");
			removeKey(info, "SystemPartitionSize");
			removeKey(info, "UpdateBaseband");
			removeKey(info, "MinimumSystemPartition");
			addIntegerToDictionary(info, "MinimumSystemPartition", SystemPartitionSize);
			XLOG(0, "got %s from ramdisk\n", optionsPlist);
		}
		free(plist);
	}

	XLOG(0, "start create restore options\n");

	if (!info) info = createRoot("<dict></dict>");
	addBoolToDictionary(info, "CreateFilesystemPartitions", TRUE);
	addIntegerToDictionary(info, "SystemPartitionSize", SystemPartitionSize);
	addBoolToDictionary(info, "UpdateBaseband", UpdateBaseband);

	plist = getXmlFromRoot(info);
	releaseDictionary(info);
	
	XLOG(0, "%s", plist);

	plistFile = createAbstractFileFromMemory((void**)&plist, sizeof(char) * strlen(plist));

	add_hfs(volume, plistFile, optionsPlist);
	free(plist);
}
Ejemplo n.º 6
0
void doPatchInPlace(Volume* volume, const char* filePath, const char* patchPath) {
	void* buffer;
	void* buffer2;
	size_t bufferSize;
	size_t bufferSize2;
	AbstractFile* bufferFile;
	AbstractFile* patchFile;
	AbstractFile* out;

	
	buffer = malloc(1);
	bufferSize = 0;
	bufferFile = createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize);

	XLOG(0, "retrieving..."); fflush(stdout);
	get_hfs(volume, filePath, bufferFile);
	bufferFile->close(bufferFile);
	
	XLOG(0, "patching..."); fflush(stdout);
				
	patchFile = createAbstractFileFromFile(fopen(patchPath, "rb"));

	buffer2 = malloc(1);
	bufferSize2 = 0;
	out = duplicateAbstractFile(createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize), createAbstractFileFromMemoryFile((void**)&buffer2, &bufferSize2));

	// reopen the inner package
	bufferFile = openAbstractFile(createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize));
	
	if(!patchFile || !bufferFile || !out) {
		XLOG(0, "file error\n");
		exit(0);
	}

	if(patch(bufferFile, out, patchFile) != 0) {
		XLOG(0, "patch failed\n");
		exit(0);
	}
	
	XLOG(0, "writing... "); fflush(stdout);
	add_hfs(volume, createAbstractFileFromMemoryFile((void**)&buffer2, &bufferSize2), filePath);
	free(buffer2);
	free(buffer);

	XLOG(0, "success\n"); fflush(stdout);
}
Ejemplo n.º 7
0
int copyAcrossVolumes(Volume* volume1, Volume* volume2, char* path1, char* path2) {
	void* buffer;
	size_t bufferSize;
	AbstractFile* tmpFile;
	int ret;
	
	buffer = malloc(1);
	bufferSize = 0;
	tmpFile = createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize);
	
	get_hfs(volume1, path1, tmpFile);
	tmpFile->seek(tmpFile, 0);
	ret = add_hfs(volume2, tmpFile, path2);
	
	free(buffer);
	
	return ret;
}
Ejemplo n.º 8
0
void hfs_untar(Volume* volume, AbstractFile* tarFile) {
	size_t tarSize = tarFile->getLength(tarFile);
	size_t curRecord = 0;
	char block[512];

	while(curRecord < tarSize) {
		tarFile->seek(tarFile, curRecord);
		tarFile->read(tarFile, block, 512);

		uint32_t mode = 0;
		char* fileName = NULL;
		const char* target = NULL;
		uint32_t type = 0;
		uint32_t size;
		uint32_t uid;
		uint32_t gid;

		sscanf(&block[100], "%o", &mode);
		fileName = &block[0];
		sscanf(&block[156], "%o", &type);
		target = &block[157];
		sscanf(&block[124], "%o", &size);
		sscanf(&block[108], "%o", &uid);
		sscanf(&block[116], "%o", &gid);

		if(fileName[0] == '\0')
			break;

		if(fileName[0] == '.' && fileName[1] == '/') {
			fileName += 2;
		}

		if(fileName[0] == '\0')
			goto loop;

		if(fileName[strlen(fileName) - 1] == '/')
			fileName[strlen(fileName) - 1] = '\0';

		HFSPlusCatalogRecord* record = getRecordFromPath3(fileName, volume, NULL, NULL, TRUE, FALSE, kHFSRootFolderID);
		if(record) {
			if(record->recordType == kHFSPlusFolderRecord || type == 5) {
				if(!silence)
					printf("ignoring %s, type = %d\n", fileName, type);
				free(record);
				goto loop;
			} else {
				printf("replacing %s\n", fileName);
				free(record);
				removeFile(fileName, volume);
			}
		}

		if(type == 0) {
			if(!silence)
				printf("file: %s (%04o), size = %d\n", fileName, mode, size);
			void* buffer = malloc(size);
			tarFile->seek(tarFile, curRecord + 512);
			tarFile->read(tarFile, buffer, size);
			AbstractFile* inFile = createAbstractFileFromMemory(&buffer, size);
			add_hfs(volume, inFile, fileName);
			free(buffer);
		} else if(type == 5) {
			if(!silence)
				printf("directory: %s (%04o)\n", fileName, mode);
			newFolder(fileName, volume);
		} else if(type == 2) {
			if(!silence)
				printf("symlink: %s (%04o) -> %s\n", fileName, mode, target);
			makeSymlink(fileName, target, volume);
		}

		chmodFile(fileName, mode, volume);
		chownFile(fileName, uid, gid, volume);

loop:

		curRecord = (curRecord + 512) + ((size + 511) / 512 * 512);
	}

}
Ejemplo n.º 9
0
Archivo: main.c Proyecto: OPK/xpwn
int main(int argc, char* argv[]) {
    init_libxpwn();

    Dictionary* info;
    Dictionary* firmwarePatches;
    Dictionary* patchDict;
    ArrayValue* patchArray;

    void* buffer;

    StringValue* actionValue;
    StringValue* pathValue;

    StringValue* fileValue;

    StringValue* patchValue;
    char* patchPath;

    char* rootFSPathInIPSW;
    io_func* rootFS;
    Volume* rootVolume;
    size_t rootSize;
    size_t preferredRootSize = 0;
    size_t minimumRootSize = 0;

    char* ramdiskFSPathInIPSW;
    unsigned int ramdiskKey[16];
    unsigned int ramdiskIV[16];
    unsigned int* pRamdiskKey = NULL;
    unsigned int* pRamdiskIV = NULL;
    io_func* ramdiskFS;
    Volume* ramdiskVolume;

    char* updateRamdiskFSPathInIPSW = NULL;

    int i;

    OutputState* outputState;

    char* bundlePath;
    char* bundleRoot = "FirmwareBundles/";

    int mergePaths;
    char* outputIPSW;

    void* imageBuffer;
    size_t imageSize;

    AbstractFile* bootloader39 = NULL;
    AbstractFile* bootloader46 = NULL;
    AbstractFile* applelogo = NULL;
    AbstractFile* recoverymode = NULL;

    char noWipe = FALSE;

    char unlockBaseband = FALSE;
    char selfDestruct = FALSE;
    char use39 = FALSE;
    char use46 = FALSE;
    char doBootNeuter = FALSE;
    char updateBB = FALSE;
    char useMemory = FALSE;

    unsigned int key[16];
    unsigned int iv[16];

    unsigned int* pKey = NULL;
    unsigned int* pIV = NULL;

    if(argc < 3) {
        XLOG(0, "usage %s <input.ipsw> <target.ipsw> [-b <bootimage.png>] [-r <recoveryimage.png>] [-s <system partition size>] [-memory] [-bbupdate] [-nowipe] [-e \"<action to exclude>\"] [[-unlock] [-use39] [-use46] [-cleanup] -3 <bootloader 3.9 file> -4 <bootloader 4.6 file>] <package1.tar> <package2.tar>...\n", argv[0]);
        return 0;
    }

    outputIPSW = argv[2];

    int* toRemove = NULL;
    int numToRemove = 0;

    for(i = 3; i < argc; i++) {
        if(argv[i][0] != '-') {
            break;
        }

        if(strcmp(argv[i], "-memory") == 0) {
            useMemory = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-s") == 0) {
            int size;
            sscanf(argv[i + 1], "%d", &size);
            preferredRootSize = size;
            i++;
            continue;
        }

        if(strcmp(argv[i], "-nowipe") == 0) {
            noWipe = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-bbupdate") == 0) {
            updateBB = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-e") == 0) {
            numToRemove++;
            toRemove = realloc(toRemove, numToRemove * sizeof(int));
            toRemove[numToRemove - 1] = i + 1;
            i++;
            continue;
        }

        if(strcmp(argv[i], "-unlock") == 0) {
            unlockBaseband = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-cleanup") == 0) {
            selfDestruct = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-use39") == 0) {
            if(use46) {
                XLOG(0, "error: select only one of -use39 and -use46\n");
                exit(1);
            }
            use39 = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-use46") == 0) {
            if(use39) {
                XLOG(0, "error: select only one of -use39 and -use46\n");
                exit(1);
            }
            use46 = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-b") == 0) {
            applelogo = createAbstractFileFromFile(fopen(argv[i + 1], "rb"));
            if(!applelogo) {
                XLOG(0, "cannot open %s\n", argv[i + 1]);
                exit(1);
            }
            i++;
            continue;
        }

        if(strcmp(argv[i], "-r") == 0) {
            recoverymode = createAbstractFileFromFile(fopen(argv[i + 1], "rb"));
            if(!recoverymode) {
                XLOG(0, "cannot open %s\n", argv[i + 1]);
                exit(1);
            }
            i++;
            continue;
        }

        if(strcmp(argv[i], "-3") == 0) {
            bootloader39 = createAbstractFileFromFile(fopen(argv[i + 1], "rb"));
            if(!bootloader39) {
                XLOG(0, "cannot open %s\n", argv[i + 1]);
                exit(1);
            }
            i++;
            continue;
        }

        if(strcmp(argv[i], "-4") == 0) {
            bootloader46 = createAbstractFileFromFile(fopen(argv[i + 1], "rb"));
            if(!bootloader46) {
                XLOG(0, "cannot open %s\n", argv[i + 1]);
                exit(1);
            }
            i++;
            continue;
        }
    }

    mergePaths = i;

    if(use39 || use46 || unlockBaseband || selfDestruct || bootloader39 || bootloader46) {
        if(!(bootloader39) || !(bootloader46)) {
            XLOG(0, "error: you must specify both bootloader files.\n");
            exit(1);
        } else {
            doBootNeuter = TRUE;
        }
    }

    info = parseIPSW2(argv[1], bundleRoot, &bundlePath, &outputState, useMemory);
    if(info == NULL) {
        XLOG(0, "error: Could not load IPSW\n");
        exit(1);
    }

    firmwarePatches = (Dictionary*)getValueByKey(info, "FilesystemPatches");

    int j;
    for(j = 0; j < numToRemove; j++) {
        removeKey(firmwarePatches, argv[toRemove[j]]);
    }
    free(toRemove);

    firmwarePatches = (Dictionary*)getValueByKey(info, "FirmwarePatches");
    patchDict = (Dictionary*) firmwarePatches->values;
    while(patchDict != NULL) {
        fileValue = (StringValue*) getValueByKey(patchDict, "File");

        StringValue* keyValue = (StringValue*) getValueByKey(patchDict, "Key");
        StringValue* ivValue = (StringValue*) getValueByKey(patchDict, "IV");
        pKey = NULL;
        pIV = NULL;

        if(keyValue) {
            sscanf(keyValue->value, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
                   &key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8],
                   &key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15]);

            pKey = key;
        }

        if(ivValue) {
            sscanf(ivValue->value, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
                   &iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8],
                   &iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]);
            pIV = iv;
        }

        if(strcmp(patchDict->dValue.key, "Restore Ramdisk") == 0) {
            ramdiskFSPathInIPSW = fileValue->value;
            if(pKey) {
                memcpy(ramdiskKey, key, sizeof(key));
                memcpy(ramdiskIV, iv, sizeof(iv));
                pRamdiskKey = ramdiskKey;
                pRamdiskIV = ramdiskIV;
            } else {
                pRamdiskKey = NULL;
                pRamdiskIV = NULL;
            }
        }

        if(strcmp(patchDict->dValue.key, "Update Ramdisk") == 0) {
            updateRamdiskFSPathInIPSW = fileValue->value;
        }

        patchValue = (StringValue*) getValueByKey(patchDict, "Patch2");
        if(patchValue) {
            if(noWipe) {
                XLOG(0, "%s: ", patchDict->dValue.key);
                fflush(stdout);
                doPatch(patchValue, fileValue, bundlePath, &outputState, pKey, pIV, useMemory);
                patchDict = (Dictionary*) patchDict->dValue.next;
                continue; /* skip over the normal Patch */
            }
        }

        patchValue = (StringValue*) getValueByKey(patchDict, "Patch");
        if(patchValue) {
            XLOG(0, "%s: ", patchDict->dValue.key);
            fflush(stdout);
            doPatch(patchValue, fileValue, bundlePath, &outputState, pKey, pIV, useMemory);
        }

        if(strcmp(patchDict->dValue.key, "AppleLogo") == 0 && applelogo) {
            XLOG(0, "replacing %s\n", fileValue->value);
            fflush(stdout);
            ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&outputState, fileValue->value), pKey, pIV, applelogo, &imageSize)) != NULL, "failed to use new image");
            addToOutput(&outputState, fileValue->value, imageBuffer, imageSize);
        }

        if(strcmp(patchDict->dValue.key, "RecoveryMode") == 0 && recoverymode) {
            XLOG(0, "replacing %s\n", fileValue->value);
            fflush(stdout);
            ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&outputState, fileValue->value), pKey, pIV, recoverymode, &imageSize)) != NULL, "failed to use new image");
            addToOutput(&outputState, fileValue->value, imageBuffer, imageSize);
        }

        patchDict = (Dictionary*) patchDict->dValue.next;
    }

    fileValue = (StringValue*) getValueByKey(info, "RootFilesystem");
    rootFSPathInIPSW = fileValue->value;

    size_t defaultRootSize = ((IntegerValue*) getValueByKey(info, "RootFilesystemSize"))->value;
    minimumRootSize = defaultRootSize * 1000 * 1000;
    minimumRootSize -= minimumRootSize % 512;

    if(preferredRootSize == 0) {
        preferredRootSize = defaultRootSize;
    }

    rootSize =  preferredRootSize * 1000 * 1000;
    rootSize -= rootSize % 512;

    if(useMemory) {
        buffer = malloc(rootSize);
    } else {
        buffer = NULL;
    }

    if(buffer == NULL) {
        XLOG(2, "using filesystem backed temporary storage\n");
    }

    extractDmg(
        createAbstractFileFromFileVault(getFileFromOutputState(&outputState, rootFSPathInIPSW), ((StringValue*)getValueByKey(info, "RootFilesystemKey"))->value),
        openRoot((void**)&buffer, &rootSize), -1);


    rootFS = IOFuncFromAbstractFile(openRoot((void**)&buffer, &rootSize));
    rootVolume = openVolume(rootFS);
    XLOG(0, "Growing root to minimum: %ld\n", (long) defaultRootSize);
    fflush(stdout);
    grow_hfs(rootVolume, minimumRootSize);
    if(rootSize > minimumRootSize) {
        XLOG(0, "Growing root: %ld\n", (long) preferredRootSize);
        fflush(stdout);
        grow_hfs(rootVolume, rootSize);
    }

    firmwarePatches = (Dictionary*)getValueByKey(info, "FilesystemPatches");
    patchArray = (ArrayValue*) firmwarePatches->values;
    while(patchArray != NULL) {
        for(i = 0; i < patchArray->size; i++) {
            patchDict = (Dictionary*) patchArray->values[i];
            fileValue = (StringValue*) getValueByKey(patchDict, "File");

            actionValue = (StringValue*) getValueByKey(patchDict, "Action");
            if(strcmp(actionValue->value, "ReplaceKernel") == 0) {
                pathValue = (StringValue*) getValueByKey(patchDict, "Path");
                XLOG(0, "replacing kernel... %s -> %s\n", fileValue->value, pathValue->value);
                fflush(stdout);
                add_hfs(rootVolume, getFileFromOutputState(&outputState, fileValue->value), pathValue->value);
            }
            if(strcmp(actionValue->value, "Patch") == 0) {
                patchValue = (StringValue*) getValueByKey(patchDict, "Patch");
                patchPath = (char*) malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue->value) + 2));
                strcpy(patchPath, bundlePath);
                strcat(patchPath, "/");
                strcat(patchPath, patchValue->value);

                XLOG(0, "patching %s (%s)... ", fileValue->value, patchPath);
                doPatchInPlace(rootVolume, fileValue->value, patchPath);
                free(patchPath);
            }
        }

        patchArray = (ArrayValue*) patchArray->dValue.next;
    }

    for(; mergePaths < argc; mergePaths++) {
        XLOG(0, "merging %s\n", argv[mergePaths]);
        AbstractFile* tarFile = createAbstractFileFromFile(fopen(argv[mergePaths], "rb"));
        if(tarFile == NULL) {
            XLOG(1, "cannot find %s, make sure your slashes are in the right direction\n", argv[mergePaths]);
            releaseOutput(&outputState);
            closeRoot(buffer);
            exit(0);
        }
        hfs_untar(rootVolume, tarFile);
        tarFile->close(tarFile);
    }

    if(pRamdiskKey) {
        ramdiskFS = IOFuncFromAbstractFile(openAbstractFile2(getFileFromOutputStateForOverwrite(&outputState, ramdiskFSPathInIPSW), pRamdiskKey, pRamdiskIV));
    } else {
        XLOG(0, "unencrypted ramdisk\n");
        ramdiskFS = IOFuncFromAbstractFile(openAbstractFile(getFileFromOutputStateForOverwrite(&outputState, ramdiskFSPathInIPSW)));
    }
    ramdiskVolume = openVolume(ramdiskFS);
    XLOG(0, "growing ramdisk: %d -> %d\n", ramdiskVolume->volumeHeader->totalBlocks * ramdiskVolume->volumeHeader->blockSize, (ramdiskVolume->volumeHeader->totalBlocks + 4) * ramdiskVolume->volumeHeader->blockSize);
    grow_hfs(ramdiskVolume, (ramdiskVolume->volumeHeader->totalBlocks + 4) * ramdiskVolume->volumeHeader->blockSize);

    if(doBootNeuter) {
        firmwarePatches = (Dictionary*)getValueByKey(info, "BasebandPatches");
        if(firmwarePatches != NULL) {
            patchDict = (Dictionary*) firmwarePatches->values;
            while(patchDict != NULL) {
                pathValue = (StringValue*) getValueByKey(patchDict, "Path");

                fileValue = (StringValue*) getValueByKey(patchDict, "File");
                if(fileValue) {
                    XLOG(0, "copying %s -> %s... ", fileValue->value, pathValue->value);
                    fflush(stdout);
                    if(copyAcrossVolumes(ramdiskVolume, rootVolume, fileValue->value, pathValue->value)) {
                        patchValue = (StringValue*) getValueByKey(patchDict, "Patch");
                        if(patchValue) {
                            patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue->value) + 2));
                            strcpy(patchPath, bundlePath);
                            strcat(patchPath, "/");
                            strcat(patchPath, patchValue->value);
                            XLOG(0, "patching %s (%s)... ", pathValue->value, patchPath);
                            fflush(stdout);
                            doPatchInPlace(rootVolume, pathValue->value, patchPath);
                            free(patchPath);
                        }
                    }
                }

                if(strcmp(patchDict->dValue.key, "Bootloader 3.9") == 0 && bootloader39 != NULL) {
                    add_hfs(rootVolume, bootloader39, pathValue->value);
                }

                if(strcmp(patchDict->dValue.key, "Bootloader 4.6") == 0 && bootloader46 != NULL) {
                    add_hfs(rootVolume, bootloader46, pathValue->value);
                }

                patchDict = (Dictionary*) patchDict->dValue.next;
            }
        }

        fixupBootNeuterArgs(rootVolume, unlockBaseband, selfDestruct, use39, use46);
    }

    createRestoreOptions(ramdiskVolume, preferredRootSize, updateBB);
    closeVolume(ramdiskVolume);
    CLOSE(ramdiskFS);

    if(updateRamdiskFSPathInIPSW)
        removeFileFromOutputState(&outputState, updateRamdiskFSPathInIPSW);

    closeVolume(rootVolume);
    CLOSE(rootFS);

    buildDmg(openRoot((void**)&buffer, &rootSize), getFileFromOutputStateForReplace(&outputState, rootFSPathInIPSW));

    closeRoot(buffer);

    writeOutput(&outputState, outputIPSW);

    releaseDictionary(info);

    free(bundlePath);

    return 0;
}
Ejemplo n.º 10
0
void images_install(void* newData, size_t newDataLen, uint32_t newFourcc, uint32_t replaceFourcc) {
	ImageDataList* list = NULL;
	ImageDataList* cur = NULL;
	ImageDataList* toReplace = NULL;
    ImageDataList* verify = NULL;
    
	int isReplace = (replaceFourcc != newFourcc) ? TRUE : FALSE;
	int isUpgrade = FALSE;

	Image* curImage = imageList;
    
	while(curImage != NULL) {
		if(cur == NULL) {
			list = cur = verify = malloc(sizeof(ImageDataList));
		} else {
			cur->next = malloc(sizeof(ImageDataList));
			cur = cur->next;
		}

		bufferPrintf("Reading: ");
		print_fourcc(curImage->type);
		bufferPrintf(" (%d bytes)\r\n", curImage->padded);

		cur->type = curImage->type;
		cur->next = NULL;
		cur->data = malloc(curImage->padded);
		nor_read(cur->data, curImage->offset, curImage->padded);

		if(isReplace && cur->type == replaceFourcc) {
			isUpgrade = TRUE;
		} else if(cur->type == newFourcc) {
			toReplace = cur;
		}

		curImage = curImage->next;
	}

	if(!isUpgrade) {
		bufferPrintf("Performing installation... (%d bytes)\r\n", newDataLen);

		ImageDataList* ibox = malloc(sizeof(ImageDataList));
		ibox->type = replaceFourcc;
		ibox->data = toReplace->data;
		ibox->next = toReplace->next;

		toReplace->next = ibox;
		toReplace->data = images_inject_img3(toReplace->data, newData, newDataLen);
		images_change_type(ibox->data, ibox->type);
	} else {
		bufferPrintf("Performing upgrade... (%d bytes)\r\n", newDataLen);
		void* newIBoot = images_inject_img3(toReplace->data, newData, newDataLen);
		free(toReplace->data);
		toReplace->data = newIBoot;
	}

    //check for size and availability
    size_t newPaddedDataLen=0;
    size_t totalBytes=0;
    //if somebody can find how to get padded length for new ibot maybe this loop not needed
    while(verify != NULL) {
        cur = verify;
        verify = verify->next;
        AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data;
        totalBytes += header->base.size;
        
        if(cur->type == newFourcc) {
            newPaddedDataLen = header->base.size;
        }
    }
    
    bufferPrintf("Total size to be written %d\r\n",totalBytes);
    if((ImagesStart + totalBytes) >= 0xfc000) {
        bufferPrintf("**ABORTED** Writing total image size: 0x%x, new ibot size: 0x%x at 0x%x would overflow NOR!\r\n", totalBytes, newPaddedDataLen,ImagesStart);
        images_rewind();
        images_release();
        images_setup();
        return;
    }
    
	bufferPrintf("Flashing...\r\n");

	images_rewind();
	while(list != NULL) {
		cur = list;
		list = list->next;
		AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data;

		bufferPrintf("Flashing: ");
		print_fourcc(cur->type);
		bufferPrintf(" (%x, %d bytes)\r\n", cur->data, header->base.size);

		images_append(cur->data, header->base.size);

		free(cur->data);
		free(cur);
	}
	bufferPrintf("Flashing Complete, Free space after flashing %d\r\n",0xfc000-MaxOffset);

	images_release();
	images_setup();

    bufferPrintf("Configuring openiBoot settings...\r\n");
    
    Volume* volume;
    io_func* io;

    io = bdev_open(0);
    volume = openVolume(io);

    char buffer [sizeof(XSTRINGIFY(OPENIBOOT_VERSION))];
    strcpy(buffer, XSTRINGIFY(OPENIBOOT_VERSION));
    add_hfs(volume, (uint8_t*)buffer, sizeof(buffer), "/openiboot");

    closeVolume(volume);
    CLOSE(io);

    ftl_sync();
    
    if(!nvram_getvar("opib-temp-os")) {
    	nvram_setvar("opib-temp-os", "0");
    }
    
    if(!nvram_getvar("opib-default-os")) {
		nvram_setvar("opib-default-os", "1");
    }

    if(!nvram_getvar("opib-menu-timeout")) {
		nvram_setvar("opib-menu-timeout", "10000");
    }

    nvram_save();
    bufferPrintf("openiBoot installation complete.\r\n");
}