]> git.saurik.com Git - ldid.git/blobdiff - ldid.cpp
Fix range check error re-hashing degenerate files.
[ldid.git] / ldid.cpp
index 6ee77c21851c4949b4d9ded5969abacb637f7256..0769e7e32e327a9d9f3aedc5b713d7f2b5d85a93 100644 (file)
--- a/ldid.cpp
+++ b/ldid.cpp
@@ -1933,7 +1933,7 @@ class Signature {
             _assert(cdattr != NULL);
             _scope({ APPLE_CDATTR_free(cdattr); });
 
-            static auto nid(OBJ_create("1.2.840.113635.100.9.2", "", ""));
+            static auto nid(OBJ_create("1.2.840.113635.100.9.2", "apple-2", "Apple 2"));
             cdattr->object = OBJ_nid2obj(nid);
 
             for (Algorithm *pointer : GetAlgorithms()) {
@@ -1968,7 +1968,7 @@ class Signature {
             // XXX: move the "cdhashes" plist code to here and remove xml argument
 
             Octet string(xml);
-            static auto nid(OBJ_create("1.2.840.113635.100.9.1", "", ""));
+            static auto nid(OBJ_create("1.2.840.113635.100.9.1", "apple-1", "Apple 1"));
             auto attribute(X509_ATTRIBUTE_create(nid, V_ASN1_OCTET_STRING, string));
             _assert(attribute != NULL);
             string.release();
@@ -3230,6 +3230,7 @@ int main(int argc, char *argv[]) {
     bool flag_r(false);
     bool flag_e(false);
     bool flag_q(false);
+    bool flag_k(false);
 
     bool flag_H(false);
     bool flag_h(false);
@@ -3399,6 +3400,10 @@ int main(int argc, char *argv[]) {
                 flag_M = true;
             break;
 
+            case 'k':
+                flag_k = true;
+            break;
+
             case 'K':
                 if (argv[argi][2] != '\0')
                     key.open(argv[argi] + 2, O_RDONLY, PROT_READ, MAP_PRIVATE);
@@ -3578,11 +3583,13 @@ int main(int argc, char *argv[]) {
                     if (Swap(super->index[index].type) == CSSLOT_REQUIREMENTS) {
                         uint32_t begin = Swap(super->index[index].offset);
                         struct Blob *requirement = reinterpret_cast<struct Blob *>(blob + begin);
+                        // XXX: this is obviously wrong. but like, -Q is also wrong?!
+                        // maybe I can fix all of this just by fixing both -q and -Q?
                         fwrite(requirement, 1, Swap(requirement->length), stdout);
                     }
             }
 
-            if (flag_s) {
+            if (flag_k) {
                 _assert(signature != NULL);
 
                 uint32_t data = mach_header.Swap(signature->dataoff);
@@ -3592,19 +3599,44 @@ int main(int argc, char *argv[]) {
                 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) {
+                    if (Swap(super->index[index].type) == CSSLOT_SIGNATURESLOT) {
                         uint32_t begin = Swap(super->index[index].offset);
+                        struct Blob *signature = reinterpret_cast<struct Blob *>(blob + begin);
+                        fwrite(signature + 1, 1, Swap(signature->length) - sizeof(*signature), stdout);
+                    }
+            }
+
+            if (flag_s) {
+                _assert(signature != NULL);
+
+                auto algorithms(GetAlgorithms());
+
+                uint32_t data = mach_header.Swap(signature->dataoff);
+
+                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) {
+                    auto type(Swap(super->index[index].type));
+                    if ((type == CSSLOT_CODEDIRECTORY || type >= CSSLOT_ALTERNATE) && type != CSSLOT_SIGNATURESLOT) {
+                        uint32_t begin = Swap(super->index[index].offset);
+                        uint32_t end = index + 1 == Swap(super->count) ? Swap(super->blob.length) : Swap(super->index[index + 1].offset);
                         struct CodeDirectory *directory = reinterpret_cast<struct CodeDirectory *>(blob + begin + sizeof(Blob));
+                        auto type(directory->hashType);
+                        _assert(type > 0 && type <= algorithms.size());
+                        auto &algorithm(*algorithms[type - 1]);
 
-                        uint8_t (*hashes)[LDID_SHA1_DIGEST_LENGTH] = reinterpret_cast<uint8_t (*)[LDID_SHA1_DIGEST_LENGTH]>(blob + begin + Swap(directory->hashOffset));
+                        uint8_t *hashes = reinterpret_cast<uint8_t *>(blob + begin + Swap(directory->hashOffset));
                         uint32_t pages = Swap(directory->nCodeSlots);
 
-                        if (pages != 1)
+                        if (pages != 0) {
                             for (size_t i = 0; i != pages - 1; ++i)
-                                LDID_SHA1(top + PageSize_ * i, PageSize_, hashes[i]);
-                        if (pages != 0)
-                            LDID_SHA1(top + PageSize_ * (pages - 1), ((data - 1) % PageSize_) + 1, hashes[pages - 1]);
+                                algorithm(hashes + i * algorithm.size_, top + PageSize_ * i, PageSize_);
+                            algorithm(hashes + (pages - 1) * algorithm.size_, top + PageSize_ * (pages - 1), ((data - 1) % PageSize_) + 1);
+                        }
                     }
+                }
             }
 
             if (flag_h) {