Changeset 302

Show
Ignore:
Timestamp:
06/13/08 23:27:12 (5 months ago)
Author:
saurik
Message:

Replaced codesign with ldid -S.

Location:
trunk/util
Files:
2 added
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/util/ldid.cpp

    r199 r302  
    3939#include "minimal/mapping.h" 
    4040 
     41#include "sha1.h" 
     42 
    4143#include <cstring> 
    4244#include <string> 
    4345#include <vector> 
     46 
     47#include <sys/wait.h> 
    4448 
    4549struct fat_header { 
     
    6973}; 
    7074 
    71 #define MH_MAGIC 0xfeedface 
     75#define MH_MAGIC 0xfeedface 
    7276#define MH_CIGAM 0xcefaedfe 
    7377 
    74 #define MH_EXECUTE 0x2 
    75 #define MH_DYLIB   0x6 
    76 #define MH_BUNDLE  0x8 
     78#define MH_EXECUTE 0x2 
     79#define MH_DYLIB   0x6 
     80#define MH_BUNDLE  0x8 
    7781 
    7882struct load_command { 
     
    8387#define LC_REQ_DYLD  0x80000000 
    8488 
    85 #define LC_LOAD_DYLIB      0x0c 
    86 #define LC_ID_DYLIB        0x0d 
    87 #define LC_UUID            0x1b 
     89#define LC_LOAD_DYLIB      0x0c 
     90#define LC_ID_DYLIB        0x0d 
     91#define LC_UUID            0x1b 
     92#define LC_CODE_SIGNATURE  0x1d 
    8893#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) 
    8994 
     
    106111    uint8_t uuid[16]; 
    107112}; 
     113 
     114struct linkedit_data_command { 
     115    uint32_t cmd; 
     116    uint32_t cmdsize; 
     117    uint32_t dataoff; 
     118    uint32_t datasize; 
     119}; 
     120 
     121uint16_t Swap_(uint16_t value) { 
     122    return 
     123        ((value >>  8) & 0x00ff) | 
     124        ((value <<  8) & 0xff00); 
     125} 
     126 
     127uint32_t Swap_(uint32_t value) { 
     128    value = ((value >>  8) & 0x00ff00ff) | 
     129            ((value <<  8) & 0xff00ff00); 
     130    value = ((value >> 16) & 0x0000ffff) | 
     131            ((value << 16) & 0xffff0000); 
     132    return value; 
     133} 
     134 
     135int16_t Swap_(int16_t value) { 
     136    return Swap_(static_cast<uint16_t>(value)); 
     137} 
     138 
     139int32_t Swap_(int32_t value) { 
     140    return Swap_(static_cast<uint32_t>(value)); 
     141} 
     142 
     143uint16_t Swap(uint16_t value) { 
     144    return true ? Swap_(value) : value; 
     145} 
     146 
     147uint32_t Swap(uint32_t value) { 
     148    return true ? Swap_(value) : value; 
     149} 
     150 
     151int16_t Swap(int16_t value) { 
     152    return Swap(static_cast<uint16_t>(value)); 
     153} 
     154 
     155int32_t Swap(int32_t value) { 
     156    return Swap(static_cast<uint32_t>(value)); 
     157} 
    108158 
    109159class Framework { 
     
    115165 
    116166  public: 
     167    uint16_t Swap(uint16_t value) const { 
     168        return swapped_ ? Swap_(value) : value; 
     169    } 
     170 
     171    uint32_t Swap(uint32_t value) const { 
     172        return swapped_ ? Swap_(value) : value; 
     173    } 
     174 
    117175    int16_t Swap(int16_t value) const { 
    118176        return Swap(static_cast<uint16_t>(value)); 
     
    121179    int32_t Swap(int32_t value) const { 
    122180        return Swap(static_cast<uint32_t>(value)); 
    123     } 
    124  
    125     uint16_t Swap(uint16_t value) const { 
    126         return !swapped_ ? value : 
    127             ((value >>  8) & 0x00ff) | 
    128             ((value <<  8) & 0xff00); 
    129     } 
    130  
    131     uint32_t Swap(uint32_t value) const { 
    132         if (!swapped_) 
    133             return value; 
    134         else { 
    135             value = ((value >>  8) & 0x00ff00ff) | 
    136                     ((value <<  8) & 0xff00ff00); 
    137             value = ((value >> 16) & 0x0000ffff) | 
    138                     ((value << 16) & 0xffff0000); 
    139             return value; 
    140         } 
    141181    } 
    142182 
     
    199239}; 
    200240 
     241#define CSMAGIC_CODEDIRECTORY 0xfade0c02 
     242#define CSMAGIC_EMBEDDED_SIGNATURE 0xfade0cc0 
     243#define CSSLOT_CODEDIRECTORY 0 
     244 
     245struct BlobIndex { 
     246    uint32_t type; 
     247    uint32_t offset; 
     248}; 
     249 
     250struct SuperBlob { 
     251    uint32_t magic; 
     252    uint32_t length; 
     253    uint32_t count; 
     254    struct BlobIndex index[]; 
     255}; 
     256 
     257struct CodeDirectory { 
     258    uint32_t magic; 
     259    uint32_t length; 
     260    uint32_t version; 
     261    uint32_t flags; 
     262    uint32_t hashOffset; 
     263    uint32_t identOffset; 
     264    uint32_t nSpecialSlots; 
     265    uint32_t nCodeSlots; 
     266    uint32_t codeLimit; 
     267    uint8_t hashSize; 
     268    uint8_t hashType; 
     269    uint8_t spare1; 
     270    uint8_t pageSize; 
     271    uint32_t spare2; 
     272}; 
     273 
    201274extern "C" uint32_t hash(uint8_t *k, uint32_t length, uint32_t initval); 
     275 
     276#define CODESIGN_ALLOCATE "arm-apple-darwin9-codesign_allocate" 
     277 
     278void sha1(uint8_t *hash, uint8_t *data, size_t size) { 
     279    SHA1Context context; 
     280    SHA1Reset(&context); 
     281    SHA1Input(&context, data, size); 
     282    SHA1Result(&context, hash); 
     283} 
    202284 
    203285int main(int argc, const char *argv[]) { 
     
    208290 
    209291    bool flag_T(false); 
     292    bool flag_S(false); 
    210293 
    211294    bool timeh(false); 
     
    223306            case 'u': flag_u = true; break; 
    224307            case 'p': flag_p = true; break; 
     308            case 'S': flag_S = true; break; 
    225309 
    226310            case 'T': { 
     
    246330    size_t filei(0), filee(0); 
    247331    _foreach (file, files) try { 
    248         Framework framework(file->c_str()); 
     332        const char *path(file->c_str()); 
     333        const char *base = strrchr(path, '/'); 
     334        char *temp(NULL), *dir; 
     335 
     336        if (base != NULL) 
     337            dir = strndup(path, base++ - path + 1); 
     338        else { 
     339            dir = strdup(""); 
     340            base = path; 
     341        } 
     342 
     343        if (flag_S) { 
     344            asprintf(&temp, "%s.%s.cs", dir, base); 
     345            const char *allocate = getenv("CODESIGN_ALLOCATE"); 
     346            if (allocate == NULL) 
     347                allocate = "codesign_allocate"; 
     348 
     349            size_t size; { 
     350                Framework framework(path); 
     351                size = framework.GetSize(); 
     352            } 
     353 
     354            pid_t pid = fork(); 
     355            _syscall(pid); 
     356            if (pid == 0) { 
     357                char *ssize; 
     358                asprintf(&ssize, "%u", (sizeof(struct SuperBlob) + sizeof(struct BlobIndex) + sizeof(struct CodeDirectory) + strlen(base) + 1 + (size + 0x1000 - 1) / 0x1000 * 0x14 + 15) / 16 * 16); 
     359                printf("%s\n", ssize); 
     360                execlp(allocate, allocate, "-i", path, "-a", "arm", ssize, "-o", temp, NULL); 
     361                _assert(false); 
     362            } 
     363 
     364            int status; 
     365            _syscall(waitpid(pid, &status, 0)); 
     366            _assert(WIFEXITED(status)); 
     367            _assert(WEXITSTATUS(status) == 0); 
     368        } 
     369 
     370        Framework framework(temp == NULL ? path : temp); 
     371        struct linkedit_data_command *signature(NULL); 
    249372 
    250373        if (flag_p) 
     
    256379            if (flag_R && cmd == LC_REEXPORT_DYLIB) 
    257380                (*load_command)->cmd = framework.Swap(LC_LOAD_DYLIB); 
     381            else if (cmd == LC_CODE_SIGNATURE) 
     382                signature = reinterpret_cast<struct linkedit_data_command *>(*load_command); 
    258383            else if (cmd == LC_UUID) { 
    259384                volatile struct uuid_command *uuid_command(reinterpret_cast<struct uuid_command *>(*load_command)); 
     
    288413        } 
    289414 
     415        if (flag_S) { 
     416            _assert(signature != NULL); 
     417 
     418            uint32_t data = framework.Swap(signature->dataoff); 
     419            uint32_t size = framework.Swap(signature->datasize); 
     420 
     421            uint8_t *top = reinterpret_cast<uint8_t *>(framework.GetBase()); 
     422            uint8_t *blob = top + data; 
     423            struct SuperBlob *super = reinterpret_cast<struct SuperBlob *>(blob); 
     424            super->magic = Swap(CSMAGIC_EMBEDDED_SIGNATURE); 
     425 
     426            uint32_t count = 1; 
     427            uint32_t offset = sizeof(struct SuperBlob) + count * sizeof(struct BlobIndex); 
     428 
     429            super->index[0].type = Swap(CSSLOT_CODEDIRECTORY); 
     430            super->index[0].offset = Swap(offset); 
     431 
     432            uint32_t begin = offset; 
     433            struct CodeDirectory *directory = reinterpret_cast<struct CodeDirectory *>(blob + begin); 
     434            offset += sizeof(struct CodeDirectory); 
     435 
     436            directory->magic = Swap(CSMAGIC_CODEDIRECTORY); 
     437            directory->version = Swap(0x00020001); 
     438            directory->flags = Swap(0); 
     439            directory->codeLimit = Swap(data); 
     440            directory->hashSize = 0x14; 
     441            directory->hashType = 0x01; 
     442            directory->spare1 = 0x00; 
     443            directory->pageSize = 0x0c; 
     444            directory->spare2 = Swap(0); 
     445 
     446            directory->identOffset = Swap(offset - begin); 
     447            strcpy(reinterpret_cast<char *>(blob + offset), base); 
     448            offset += strlen(base) + 1; 
     449 
     450            uint8_t (*hashes)[20] = reinterpret_cast<uint8_t (*)[20]>(blob + offset); 
     451            uint32_t special = 0; 
     452 
     453            uint32_t pages = (data + 0x1000 - 1) / 0x1000; 
     454            directory->nSpecialSlots = Swap(special); 
     455            directory->nCodeSlots = Swap(pages); 
     456 
     457            if (pages != 1) 
     458                for (size_t i = 0; i != pages - 1; ++i) 
     459                    sha1(hashes[special + i], top + 0x1000 * i, 0x1000); 
     460            if (pages != 0) 
     461                sha1(hashes[special + pages - 1], top + 0x1000 * (pages - 1), data % 0x1000); 
     462 
     463            directory->hashOffset = Swap(offset - begin); 
     464            offset += sizeof(*hashes) * (special + pages); 
     465            directory->length = Swap(offset - begin); 
     466 
     467            super->count = Swap(count); 
     468            super->length = Swap(offset); 
     469 
     470            _assert(offset < size); 
     471            memset(blob + offset, 0, size - offset); 
     472        } 
     473 
     474        if (temp) { 
     475            _syscall(unlink(path)); 
     476            _syscall(rename(temp, path)); 
     477            free(temp); 
     478        } 
     479 
     480        free(dir); 
    290481        ++filei; 
    291482    } catch (const char *) {