-
Notifications
You must be signed in to change notification settings - Fork 57
/
amfid_tools.m
80 lines (64 loc) · 2.4 KB
/
amfid_tools.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#import "amfid_tools.h"
#import "amfi_utils.h"
#import "amfid.h"
static unsigned int hash_rank(const CodeDirectory *cd)
{
uint32_t type = cd->hashType;
unsigned int n;
for (n = 0; n < sizeof(hashPriorities) / sizeof(hashPriorities[0]); ++n)
if (hashPriorities[n] == type)
return n + 1;
return 0; /* not supported */
}
int get_hash(const CodeDirectory* directory, uint8_t dst[CS_CDHASH_LEN]) {
uint32_t realsize = ntohl(directory->length);
if (ntohl(directory->magic) != CSMAGIC_CODEDIRECTORY) {
NSLog(@"[get_hash] wtf, not CSMAGIC_CODEDIRECTORY?!");
return 1;
}
uint8_t out[CS_HASH_MAX_SIZE];
uint8_t hash_type = directory->hashType;
switch (hash_type) {
case CS_HASHTYPE_SHA1:
CC_SHA1(directory, realsize, out);
break;
case CS_HASHTYPE_SHA256:
case CS_HASHTYPE_SHA256_TRUNCATED:
CC_SHA256(directory, realsize, out);
break;
case CS_HASHTYPE_SHA384:
CC_SHA384(directory, realsize, out);
break;
default:
NSLog(@"[get_hash] Unknown hash type: 0x%x", hash_type);
return 2;
}
memcpy(dst, out, CS_CDHASH_LEN);
return 0;
}
// see cs_validate_csblob in xnu bsd/kern/ubc_subr.c
// 0 on success
int parse_superblob(uint8_t *code_dir, uint8_t dst[CS_CDHASH_LEN]) {
int ret = 1;
const CS_SuperBlob *sb = (const CS_SuperBlob *)code_dir;
uint8_t highest_cd_hash_rank = 0;
for (int n = 0; n < ntohl(sb->count); n++){
const CS_BlobIndex *blobIndex = &sb->index[n];
uint32_t type = ntohl(blobIndex->type);
uint32_t offset = ntohl(blobIndex->offset);
if (ntohl(sb->length) < offset) {
NSLog(@"offset of blob #%d overflows superblob length", n);
return 1;
}
const CodeDirectory *subBlob = (const CodeDirectory *)(code_dir + offset);
// size_t subLength = ntohl(subBlob->length);
if (type == CSSLOT_CODEDIRECTORY || (type >= CSSLOT_ALTERNATE_CODEDIRECTORIES && type < CSSLOT_ALTERNATE_CODEDIRECTORY_LIMIT)) {
uint8_t rank = hash_rank(subBlob);
if (rank > highest_cd_hash_rank) {
ret = get_hash(subBlob, dst);
highest_cd_hash_rank = rank;
}
}
}
return ret;
}