+ if (flag_s) {
+ _assert(signature != NULL);
+
+ uint32_t data = mach_header.Swap(signature->dataoff);
+ uint32_t size = mach_header.Swap(signature->datasize);
+
+ uint8_t *top = reinterpret_cast<uint8_t *>(mach_header.GetBase());
+ uint8_t *blob = top + data;
+ struct SuperBlob *super = reinterpret_cast<struct SuperBlob *>(blob);
+
+ for (size_t index(0); index != Swap(super->count); ++index)
+ if (Swap(super->index[index].type) == CSSLOT_CODEDIRECTORY) {
+ uint32_t begin = Swap(super->index[index].offset);
+ struct CodeDirectory *directory = reinterpret_cast<struct CodeDirectory *>(blob + begin);
+
+ uint8_t (*hashes)[20] = reinterpret_cast<uint8_t (*)[20]>(blob + begin + Swap(directory->hashOffset));
+ uint32_t pages = Swap(directory->nCodeSlots);
+
+ if (pages != 1)
+ for (size_t i = 0; i != pages - 1; ++i)
+ sha1(hashes[i], top + 0x1000 * i, 0x1000);
+ if (pages != 0)
+ sha1(hashes[pages - 1], top + 0x1000 * (pages - 1), ((data - 1) % 0x1000) + 1);
+ }
+ }
+
+ if (flag_S) {
+ _assert(signature != NULL);
+
+ uint32_t data = mach_header.Swap(signature->dataoff);
+ uint32_t size = mach_header.Swap(signature->datasize);
+
+ uint8_t *top = reinterpret_cast<uint8_t *>(mach_header.GetBase());
+ uint8_t *blob = top + data;
+ struct SuperBlob *super = reinterpret_cast<struct SuperBlob *>(blob);
+ super->blob.magic = Swap(CSMAGIC_EMBEDDED_SIGNATURE);
+
+ uint32_t count = xmld == NULL ? 2 : 3;
+ uint32_t offset = sizeof(struct SuperBlob) + count * sizeof(struct BlobIndex);
+
+ super->index[0].type = Swap(CSSLOT_CODEDIRECTORY);
+ super->index[0].offset = Swap(offset);
+
+ uint32_t begin = offset;
+ struct CodeDirectory *directory = reinterpret_cast<struct CodeDirectory *>(blob + begin);
+ offset += sizeof(struct CodeDirectory);
+
+ directory->blob.magic = Swap(CSMAGIC_CODEDIRECTORY);
+ directory->version = Swap(uint32_t(0x00020001));
+ directory->flags = Swap(uint32_t(0));
+ directory->codeLimit = Swap(data);
+ directory->hashSize = 0x14;
+ directory->hashType = 0x01;
+ directory->spare1 = 0x00;
+ directory->pageSize = 0x0c;
+ directory->spare2 = Swap(uint32_t(0));
+
+ directory->identOffset = Swap(offset - begin);
+ strcpy(reinterpret_cast<char *>(blob + offset), base);
+ offset += strlen(base) + 1;
+
+ uint32_t special = xmld == NULL ? CSSLOT_REQUIREMENTS : CSSLOT_ENTITLEMENTS;
+ directory->nSpecialSlots = Swap(special);
+
+ uint8_t (*hashes)[20] = reinterpret_cast<uint8_t (*)[20]>(blob + offset);
+ memset(hashes, 0, sizeof(*hashes) * special);
+
+ offset += sizeof(*hashes) * special;
+ hashes += special;
+
+ uint32_t pages = (data + 0x1000 - 1) / 0x1000;
+ directory->nCodeSlots = Swap(pages);
+
+ if (pages != 1)
+ for (size_t i = 0; i != pages - 1; ++i)
+ sha1(hashes[i], top + 0x1000 * i, 0x1000);
+ if (pages != 0)
+ sha1(hashes[pages - 1], top + 0x1000 * (pages - 1), ((data - 1) % 0x1000) + 1);
+
+ directory->hashOffset = Swap(offset - begin);
+ offset += sizeof(*hashes) * pages;
+ directory->blob.length = Swap(offset - begin);
+
+ super->index[1].type = Swap(CSSLOT_REQUIREMENTS);
+ super->index[1].offset = Swap(offset);
+
+ memcpy(blob + offset, "\xfa\xde\x0c\x01\x00\x00\x00\x0c\x00\x00\x00\x00", 0xc);
+ offset += 0xc;
+
+ if (xmld != NULL) {
+ super->index[2].type = Swap(CSSLOT_ENTITLEMENTS);
+ super->index[2].offset = Swap(offset);
+
+ uint32_t begin = offset;
+ struct Blob *entitlements = reinterpret_cast<struct Blob *>(blob + begin);
+ offset += sizeof(struct Blob);
+
+ memcpy(blob + offset, xmld, xmls);
+ offset += xmls;
+
+ entitlements->magic = Swap(CSMAGIC_ENTITLEMENTS);
+ entitlements->length = Swap(offset - begin);
+ }
+
+ for (size_t index(0); index != count; ++index) {
+ uint32_t type = Swap(super->index[index].type);
+ if (type != 0 && type <= special) {
+ uint32_t offset = Swap(super->index[index].offset);
+ struct Blob *local = (struct Blob *) (blob + offset);
+ sha1((uint8_t *) (hashes - type), (uint8_t *) local, Swap(local->length));
+ }