mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 12:16:08 +00:00
[lld-macho] add code signature for native arm64 macOS
Differential Revision: https://reviews.llvm.org/D96164
This commit is contained in:
parent
e9445765a5
commit
151990dd94
@ -45,6 +45,7 @@ public:
|
||||
size_t numNonHiddenSections() const;
|
||||
|
||||
uint64_t fileOff = 0;
|
||||
uint64_t fileSize = 0;
|
||||
StringRef name;
|
||||
uint32_t maxProt = 0;
|
||||
uint32_t initProt = 0;
|
||||
|
@ -24,6 +24,11 @@
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/SHA256.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::support;
|
||||
@ -887,3 +892,93 @@ void StringTableSection::writeTo(uint8_t *buf) const {
|
||||
off += str.size() + 1; // account for null terminator
|
||||
}
|
||||
}
|
||||
|
||||
CodeSignatureSection::CodeSignatureSection()
|
||||
: LinkEditSection(segment_names::linkEdit, section_names::codeSignature) {
|
||||
align = 16; // required by libstuff
|
||||
fileName = config->outputFile;
|
||||
size_t slashIndex = fileName.rfind("/");
|
||||
if (slashIndex != std::string::npos)
|
||||
fileName = fileName.drop_front(slashIndex + 1);
|
||||
allHeadersSize = alignTo<16>(fixedHeadersSize + fileName.size() + 1);
|
||||
fileNamePad = allHeadersSize - fixedHeadersSize - fileName.size();
|
||||
}
|
||||
|
||||
uint32_t CodeSignatureSection::getBlockCount() const {
|
||||
return (fileOff + blockSize - 1) / blockSize;
|
||||
}
|
||||
|
||||
uint64_t CodeSignatureSection::getRawSize() const {
|
||||
return allHeadersSize + getBlockCount() * hashSize;
|
||||
}
|
||||
|
||||
void CodeSignatureSection::writeHashes(uint8_t *buf) const {
|
||||
uint8_t *code = buf;
|
||||
uint8_t *codeEnd = buf + fileOff;
|
||||
uint8_t *hashes = codeEnd + allHeadersSize;
|
||||
while (code < codeEnd) {
|
||||
StringRef block(reinterpret_cast<char *>(code),
|
||||
std::min(codeEnd - code, static_cast<ssize_t>(blockSize)));
|
||||
SHA256 hasher;
|
||||
hasher.update(block);
|
||||
StringRef hash = hasher.final();
|
||||
assert(hash.size() == hashSize);
|
||||
memcpy(hashes, hash.data(), hashSize);
|
||||
code += blockSize;
|
||||
hashes += hashSize;
|
||||
}
|
||||
#if defined(__APPLE__)
|
||||
// This is macOS-specific work-around and makes no sense for any
|
||||
// other host OS. See https://openradar.appspot.com/FB8914231
|
||||
//
|
||||
// The macOS kernel maintains a signature-verification cache to
|
||||
// quickly validate applications at time of execve(2). The trouble
|
||||
// is that for the kernel creates the cache entry at the time of the
|
||||
// mmap(2) call, before we have a chance to write either the code to
|
||||
// sign or the signature header+hashes. The fix is to invalidate
|
||||
// all cached data associated with the output file, thus discarding
|
||||
// the bogus prematurely-cached signature.
|
||||
msync(buf, fileOff + getSize(), MS_INVALIDATE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CodeSignatureSection::writeTo(uint8_t *buf) const {
|
||||
using namespace llvm::MachO;
|
||||
uint32_t signatureSize = static_cast<uint32_t>(getSize());
|
||||
auto *superBlob = reinterpret_cast<CS_SuperBlob *>(buf);
|
||||
write32be(&superBlob->magic, CSMAGIC_EMBEDDED_SIGNATURE);
|
||||
write32be(&superBlob->length, signatureSize);
|
||||
write32be(&superBlob->count, 1);
|
||||
auto *blobIndex = reinterpret_cast<CS_BlobIndex *>(&superBlob[1]);
|
||||
write32be(&blobIndex->type, CSSLOT_CODEDIRECTORY);
|
||||
write32be(&blobIndex->offset, blobHeadersSize);
|
||||
auto *codeDirectory =
|
||||
reinterpret_cast<CS_CodeDirectory *>(buf + blobHeadersSize);
|
||||
write32be(&codeDirectory->magic, CSMAGIC_CODEDIRECTORY);
|
||||
write32be(&codeDirectory->length, signatureSize - blobHeadersSize);
|
||||
write32be(&codeDirectory->version, CS_SUPPORTSEXECSEG);
|
||||
write32be(&codeDirectory->flags, CS_ADHOC | CS_LINKER_SIGNED);
|
||||
write32be(&codeDirectory->hashOffset,
|
||||
sizeof(CS_CodeDirectory) + fileName.size() + fileNamePad);
|
||||
write32be(&codeDirectory->identOffset, sizeof(CS_CodeDirectory));
|
||||
codeDirectory->nSpecialSlots = 0;
|
||||
write32be(&codeDirectory->nCodeSlots, getBlockCount());
|
||||
write32be(&codeDirectory->codeLimit, fileOff);
|
||||
codeDirectory->hashSize = static_cast<uint8_t>(hashSize);
|
||||
codeDirectory->hashType = kSecCodeSignatureHashSHA256;
|
||||
codeDirectory->platform = 0;
|
||||
codeDirectory->pageSize = blockSizeShift;
|
||||
codeDirectory->spare2 = 0;
|
||||
codeDirectory->scatterOffset = 0;
|
||||
codeDirectory->teamOffset = 0;
|
||||
codeDirectory->spare3 = 0;
|
||||
codeDirectory->codeLimit64 = 0;
|
||||
OutputSegment *textSeg = getOrCreateOutputSegment(segment_names::text);
|
||||
write64be(&codeDirectory->execSegBase, textSeg->fileOff);
|
||||
write64be(&codeDirectory->execSegLimit, textSeg->fileSize);
|
||||
write64be(&codeDirectory->execSegFlags,
|
||||
config->outputType == MH_EXECUTE ? CS_EXECSEG_MAIN_BINARY : 0);
|
||||
auto *id = reinterpret_cast<char *>(&codeDirectory[1]);
|
||||
memcpy(id, fileName.begin(), fileName.size());
|
||||
memset(id + fileName.size(), 0, fileNamePad);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -40,6 +41,7 @@ constexpr const char export_[] = "__export";
|
||||
constexpr const char symbolTable[] = "__symbol_table";
|
||||
constexpr const char indirectSymbolTable[] = "__ind_sym_tab";
|
||||
constexpr const char stringTable[] = "__string_table";
|
||||
constexpr const char codeSignature[] = "__code_signature";
|
||||
constexpr const char got[] = "__got";
|
||||
constexpr const char threadPtrs[] = "__thread_ptrs";
|
||||
constexpr const char unwindInfo[] = "__unwind_info";
|
||||
@ -94,7 +96,7 @@ public:
|
||||
// NOTE: This assumes that the extra bytes required for alignment can be
|
||||
// zero-valued bytes.
|
||||
uint64_t getSize() const override final {
|
||||
return llvm::alignTo(getRawSize(), WordSize);
|
||||
return llvm::alignTo(getRawSize(), align);
|
||||
}
|
||||
};
|
||||
|
||||
@ -482,6 +484,32 @@ public:
|
||||
void writeTo(uint8_t *buf) const override;
|
||||
};
|
||||
|
||||
// The code signature comes at the very end of the linked output file.
|
||||
class CodeSignatureSection : public LinkEditSection {
|
||||
public:
|
||||
static constexpr uint8_t blockSizeShift = 12;
|
||||
static constexpr size_t blockSize = (1 << blockSizeShift); // 4 KiB
|
||||
static constexpr size_t hashSize = 256 / 8;
|
||||
static constexpr size_t blobHeadersSize = llvm::alignTo<8>(
|
||||
sizeof(llvm::MachO::CS_SuperBlob) + sizeof(llvm::MachO::CS_BlobIndex));
|
||||
static constexpr uint32_t fixedHeadersSize =
|
||||
blobHeadersSize + sizeof(llvm::MachO::CS_CodeDirectory);
|
||||
|
||||
uint32_t fileNamePad = 0;
|
||||
uint32_t allHeadersSize = 0;
|
||||
StringRef fileName;
|
||||
|
||||
CodeSignatureSection();
|
||||
uint64_t getRawSize() const override;
|
||||
bool isNeeded() const override { return true; }
|
||||
void writeTo(uint8_t *buf) const override;
|
||||
uint32_t getBlockCount() const;
|
||||
void writeHashes(uint8_t *buf) const;
|
||||
};
|
||||
|
||||
static_assert((CodeSignatureSection::blobHeadersSize % 8) == 0, "");
|
||||
static_assert((CodeSignatureSection::fixedHeadersSize % 8) == 0, "");
|
||||
|
||||
struct InStruct {
|
||||
MachHeaderSection *header = nullptr;
|
||||
RebaseSection *rebase = nullptr;
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
void openFile();
|
||||
void writeSections();
|
||||
void writeUuid();
|
||||
void writeCodeSignature();
|
||||
|
||||
void run();
|
||||
|
||||
@ -62,6 +63,7 @@ public:
|
||||
StringTableSection *stringTableSection = nullptr;
|
||||
SymtabSection *symtabSection = nullptr;
|
||||
IndirectSymtabSection *indirectSymtabSection = nullptr;
|
||||
CodeSignatureSection *codeSignatureSection = nullptr;
|
||||
UnwindInfoSection *unwindInfoSection = nullptr;
|
||||
LCUuid *uuidCommand = nullptr;
|
||||
};
|
||||
@ -400,6 +402,23 @@ public:
|
||||
mutable uint8_t *uuidBuf;
|
||||
};
|
||||
|
||||
class LCCodeSignature : public LoadCommand {
|
||||
public:
|
||||
LCCodeSignature(CodeSignatureSection *section) : section(section) {}
|
||||
|
||||
uint32_t getSize() const override { return sizeof(linkedit_data_command); }
|
||||
|
||||
void writeTo(uint8_t *buf) const override {
|
||||
auto *c = reinterpret_cast<linkedit_data_command *>(buf);
|
||||
c->cmd = LC_CODE_SIGNATURE;
|
||||
c->cmdsize = getSize();
|
||||
c->dataoff = static_cast<uint32_t>(section->fileOff);
|
||||
c->datasize = section->getSize();
|
||||
}
|
||||
|
||||
CodeSignatureSection *section;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static void prepareSymbolRelocation(lld::macho::Symbol *sym,
|
||||
@ -521,6 +540,9 @@ void Writer::createLoadCommands() {
|
||||
}
|
||||
}
|
||||
|
||||
if (codeSignatureSection)
|
||||
in.header->addLoadCommand(make<LCCodeSignature>(codeSignatureSection));
|
||||
|
||||
const uint32_t MACOS_MAXPATHLEN = 1024;
|
||||
config->headerPad = std::max(
|
||||
config->headerPad, (config->headerPadMaxInstallNames
|
||||
@ -624,6 +646,7 @@ static int sectionOrder(OutputSection *osec) {
|
||||
.Case(section_names::symbolTable, -3)
|
||||
.Case(section_names::indirectSymbolTable, -2)
|
||||
.Case(section_names::stringTable, -1)
|
||||
.Case(section_names::codeSignature, std::numeric_limits<int>::max())
|
||||
.Default(0);
|
||||
}
|
||||
// ZeroFill sections must always be the at the end of their segments,
|
||||
@ -678,6 +701,9 @@ void Writer::createOutputSections() {
|
||||
unwindInfoSection = make<UnwindInfoSection>(); // TODO(gkm): only when no -r
|
||||
symtabSection = make<SymtabSection>(*stringTableSection);
|
||||
indirectSymtabSection = make<IndirectSymtabSection>();
|
||||
if (config->outputType == MH_EXECUTE &&
|
||||
(config->arch == AK_arm64 || config->arch == AK_arm64e))
|
||||
codeSignatureSection = make<CodeSignatureSection>();
|
||||
|
||||
switch (config->outputType) {
|
||||
case MH_EXECUTE:
|
||||
@ -743,6 +769,7 @@ void Writer::assignAddresses(OutputSegment *seg) {
|
||||
addr += osec->getSize();
|
||||
fileOff += osec->getFileSize();
|
||||
}
|
||||
seg->fileSize = fileOff - seg->fileOff;
|
||||
}
|
||||
|
||||
void Writer::openFile() {
|
||||
@ -770,6 +797,11 @@ void Writer::writeUuid() {
|
||||
uuidCommand->writeUuid(digest);
|
||||
}
|
||||
|
||||
void Writer::writeCodeSignature() {
|
||||
if (codeSignatureSection)
|
||||
codeSignatureSection->writeHashes(buffer->getBufferStart());
|
||||
}
|
||||
|
||||
void Writer::run() {
|
||||
// dyld requires __LINKEDIT segment to always exist (even if empty).
|
||||
OutputSegment *linkEditSegment =
|
||||
@ -817,6 +849,7 @@ void Writer::run() {
|
||||
|
||||
writeSections();
|
||||
writeUuid();
|
||||
writeCodeSignature();
|
||||
|
||||
if (auto e = buffer->commit())
|
||||
error("failed to write to the output file: " + toString(std::move(e)));
|
||||
|
@ -2007,6 +2007,203 @@ union alignas(4) macho_load_command {
|
||||
};
|
||||
LLVM_PACKED_END
|
||||
|
||||
/* code signing attributes of a process */
|
||||
|
||||
enum CodeSignAttrs {
|
||||
CS_VALID = 0x00000001, /* dynamically valid */
|
||||
CS_ADHOC = 0x00000002, /* ad hoc signed */
|
||||
CS_GET_TASK_ALLOW = 0x00000004, /* has get-task-allow entitlement */
|
||||
CS_INSTALLER = 0x00000008, /* has installer entitlement */
|
||||
|
||||
CS_FORCED_LV =
|
||||
0x00000010, /* Library Validation required by Hardened System Policy */
|
||||
CS_INVALID_ALLOWED = 0x00000020, /* (macOS Only) Page invalidation allowed by
|
||||
task port policy */
|
||||
|
||||
CS_HARD = 0x00000100, /* don't load invalid pages */
|
||||
CS_KILL = 0x00000200, /* kill process if it becomes invalid */
|
||||
CS_CHECK_EXPIRATION = 0x00000400, /* force expiration checking */
|
||||
CS_RESTRICT = 0x00000800, /* tell dyld to treat restricted */
|
||||
|
||||
CS_ENFORCEMENT = 0x00001000, /* require enforcement */
|
||||
CS_REQUIRE_LV = 0x00002000, /* require library validation */
|
||||
CS_ENTITLEMENTS_VALIDATED =
|
||||
0x00004000, /* code signature permits restricted entitlements */
|
||||
CS_NVRAM_UNRESTRICTED =
|
||||
0x00008000, /* has com.apple.rootless.restricted-nvram-variables.heritable
|
||||
entitlement */
|
||||
|
||||
CS_RUNTIME = 0x00010000, /* Apply hardened runtime policies */
|
||||
CS_LINKER_SIGNED = 0x00020000, /* Automatically signed by the linker */
|
||||
|
||||
CS_ALLOWED_MACHO =
|
||||
(CS_ADHOC | CS_HARD | CS_KILL | CS_CHECK_EXPIRATION | CS_RESTRICT |
|
||||
CS_ENFORCEMENT | CS_REQUIRE_LV | CS_RUNTIME | CS_LINKER_SIGNED),
|
||||
|
||||
CS_EXEC_SET_HARD = 0x00100000, /* set CS_HARD on any exec'ed process */
|
||||
CS_EXEC_SET_KILL = 0x00200000, /* set CS_KILL on any exec'ed process */
|
||||
CS_EXEC_SET_ENFORCEMENT =
|
||||
0x00400000, /* set CS_ENFORCEMENT on any exec'ed process */
|
||||
CS_EXEC_INHERIT_SIP =
|
||||
0x00800000, /* set CS_INSTALLER on any exec'ed process */
|
||||
|
||||
CS_KILLED = 0x01000000, /* was killed by kernel for invalidity */
|
||||
CS_DYLD_PLATFORM =
|
||||
0x02000000, /* dyld used to load this is a platform binary */
|
||||
CS_PLATFORM_BINARY = 0x04000000, /* this is a platform binary */
|
||||
CS_PLATFORM_PATH =
|
||||
0x08000000, /* platform binary by the fact of path (osx only) */
|
||||
|
||||
CS_DEBUGGED = 0x10000000, /* process is currently or has previously been
|
||||
debugged and allowed to run with invalid pages */
|
||||
CS_SIGNED = 0x20000000, /* process has a signature (may have gone invalid) */
|
||||
CS_DEV_CODE =
|
||||
0x40000000, /* code is dev signed, cannot be loaded into prod signed code
|
||||
(will go away with rdar://problem/28322552) */
|
||||
CS_DATAVAULT_CONTROLLER =
|
||||
0x80000000, /* has Data Vault controller entitlement */
|
||||
|
||||
CS_ENTITLEMENT_FLAGS = (CS_GET_TASK_ALLOW | CS_INSTALLER |
|
||||
CS_DATAVAULT_CONTROLLER | CS_NVRAM_UNRESTRICTED),
|
||||
};
|
||||
|
||||
/* executable segment flags */
|
||||
|
||||
enum CodeSignExecSegFlags {
|
||||
|
||||
CS_EXECSEG_MAIN_BINARY = 0x1, /* executable segment denotes main binary */
|
||||
CS_EXECSEG_ALLOW_UNSIGNED = 0x10, /* allow unsigned pages (for debugging) */
|
||||
CS_EXECSEG_DEBUGGER = 0x20, /* main binary is debugger */
|
||||
CS_EXECSEG_JIT = 0x40, /* JIT enabled */
|
||||
CS_EXECSEG_SKIP_LV = 0x80, /* OBSOLETE: skip library validation */
|
||||
CS_EXECSEG_CAN_LOAD_CDHASH = 0x100, /* can bless cdhash for execution */
|
||||
CS_EXECSEG_CAN_EXEC_CDHASH = 0x200, /* can execute blessed cdhash */
|
||||
|
||||
};
|
||||
|
||||
/* Magic numbers used by Code Signing */
|
||||
|
||||
enum CodeSignMagic {
|
||||
CSMAGIC_REQUIREMENT = 0xfade0c00, /* single Requirement blob */
|
||||
CSMAGIC_REQUIREMENTS =
|
||||
0xfade0c01, /* Requirements vector (internal requirements) */
|
||||
CSMAGIC_CODEDIRECTORY = 0xfade0c02, /* CodeDirectory blob */
|
||||
CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0, /* embedded form of signature data */
|
||||
CSMAGIC_EMBEDDED_SIGNATURE_OLD = 0xfade0b02, /* XXX */
|
||||
CSMAGIC_EMBEDDED_ENTITLEMENTS = 0xfade7171, /* embedded entitlements */
|
||||
CSMAGIC_DETACHED_SIGNATURE =
|
||||
0xfade0cc1, /* multi-arch collection of embedded signatures */
|
||||
CSMAGIC_BLOBWRAPPER = 0xfade0b01, /* CMS Signature, among other things */
|
||||
|
||||
CS_SUPPORTSSCATTER = 0x20100,
|
||||
CS_SUPPORTSTEAMID = 0x20200,
|
||||
CS_SUPPORTSCODELIMIT64 = 0x20300,
|
||||
CS_SUPPORTSEXECSEG = 0x20400,
|
||||
CS_SUPPORTSRUNTIME = 0x20500,
|
||||
CS_SUPPORTSLINKAGE = 0x20600,
|
||||
|
||||
CSSLOT_CODEDIRECTORY = 0, /* slot index for CodeDirectory */
|
||||
CSSLOT_INFOSLOT = 1,
|
||||
CSSLOT_REQUIREMENTS = 2,
|
||||
CSSLOT_RESOURCEDIR = 3,
|
||||
CSSLOT_APPLICATION = 4,
|
||||
CSSLOT_ENTITLEMENTS = 5,
|
||||
|
||||
CSSLOT_ALTERNATE_CODEDIRECTORIES =
|
||||
0x1000, /* first alternate CodeDirectory, if any */
|
||||
CSSLOT_ALTERNATE_CODEDIRECTORY_MAX = 5, /* max number of alternate CD slots */
|
||||
CSSLOT_ALTERNATE_CODEDIRECTORY_LIMIT =
|
||||
CSSLOT_ALTERNATE_CODEDIRECTORIES +
|
||||
CSSLOT_ALTERNATE_CODEDIRECTORY_MAX, /* one past the last */
|
||||
|
||||
CSSLOT_SIGNATURESLOT = 0x10000, /* CMS Signature */
|
||||
CSSLOT_IDENTIFICATIONSLOT = 0x10001,
|
||||
CSSLOT_TICKETSLOT = 0x10002,
|
||||
|
||||
CSTYPE_INDEX_REQUIREMENTS = 0x00000002, /* compat with amfi */
|
||||
CSTYPE_INDEX_ENTITLEMENTS = 0x00000005, /* compat with amfi */
|
||||
|
||||
CS_HASHTYPE_SHA1 = 1,
|
||||
CS_HASHTYPE_SHA256 = 2,
|
||||
CS_HASHTYPE_SHA256_TRUNCATED = 3,
|
||||
CS_HASHTYPE_SHA384 = 4,
|
||||
|
||||
CS_SHA1_LEN = 20,
|
||||
CS_SHA256_LEN = 32,
|
||||
CS_SHA256_TRUNCATED_LEN = 20,
|
||||
|
||||
CS_CDHASH_LEN = 20, /* always - larger hashes are truncated */
|
||||
CS_HASH_MAX_SIZE = 48, /* max size of the hash we'll support */
|
||||
|
||||
/*
|
||||
* Currently only to support Legacy VPN plugins, and Mac App Store
|
||||
* but intended to replace all the various platform code, dev code etc. bits.
|
||||
*/
|
||||
CS_SIGNER_TYPE_UNKNOWN = 0,
|
||||
CS_SIGNER_TYPE_LEGACYVPN = 5,
|
||||
CS_SIGNER_TYPE_MAC_APP_STORE = 6,
|
||||
|
||||
CS_SUPPL_SIGNER_TYPE_UNKNOWN = 0,
|
||||
CS_SUPPL_SIGNER_TYPE_TRUSTCACHE = 7,
|
||||
CS_SUPPL_SIGNER_TYPE_LOCAL = 8,
|
||||
};
|
||||
|
||||
struct CS_CodeDirectory {
|
||||
uint32_t magic; /* magic number (CSMAGIC_CODEDIRECTORY) */
|
||||
uint32_t length; /* total length of CodeDirectory blob */
|
||||
uint32_t version; /* compatibility version */
|
||||
uint32_t flags; /* setup and mode flags */
|
||||
uint32_t hashOffset; /* offset of hash slot element at index zero */
|
||||
uint32_t identOffset; /* offset of identifier string */
|
||||
uint32_t nSpecialSlots; /* number of special hash slots */
|
||||
uint32_t nCodeSlots; /* number of ordinary (code) hash slots */
|
||||
uint32_t codeLimit; /* limit to main image signature range */
|
||||
uint8_t hashSize; /* size of each hash in bytes */
|
||||
uint8_t hashType; /* type of hash (cdHashType* constants) */
|
||||
uint8_t platform; /* platform identifier; zero if not platform binary */
|
||||
uint8_t pageSize; /* log2(page size in bytes); 0 => infinite */
|
||||
uint32_t spare2; /* unused (must be zero) */
|
||||
|
||||
/* Version 0x20100 */
|
||||
uint32_t scatterOffset; /* offset of optional scatter vector */
|
||||
|
||||
/* Version 0x20200 */
|
||||
uint32_t teamOffset; /* offset of optional team identifier */
|
||||
|
||||
/* Version 0x20300 */
|
||||
uint32_t spare3; /* unused (must be zero) */
|
||||
uint64_t codeLimit64; /* limit to main image signature range, 64 bits */
|
||||
|
||||
/* Version 0x20400 */
|
||||
uint64_t execSegBase; /* offset of executable segment */
|
||||
uint64_t execSegLimit; /* limit of executable segment */
|
||||
uint64_t execSegFlags; /* executable segment flags */
|
||||
};
|
||||
|
||||
static_assert(sizeof(CS_CodeDirectory) == 88, "");
|
||||
|
||||
struct CS_BlobIndex {
|
||||
uint32_t type; /* type of entry */
|
||||
uint32_t offset; /* offset of entry */
|
||||
};
|
||||
|
||||
struct CS_SuperBlob {
|
||||
uint32_t magic; /* magic number */
|
||||
uint32_t length; /* total length of SuperBlob */
|
||||
uint32_t count; /* number of index entries following */
|
||||
/* followed by Blobs in no particular order as indicated by index offsets */
|
||||
};
|
||||
|
||||
enum SecCSDigestAlgorithm {
|
||||
kSecCodeSignatureNoHash = 0, /* null value */
|
||||
kSecCodeSignatureHashSHA1 = 1, /* SHA-1 */
|
||||
kSecCodeSignatureHashSHA256 = 2, /* SHA-256 */
|
||||
kSecCodeSignatureHashSHA256Truncated =
|
||||
3, /* SHA-256 truncated to first 20 bytes */
|
||||
kSecCodeSignatureHashSHA384 = 4, /* SHA-384 */
|
||||
kSecCodeSignatureHashSHA512 = 5, /* SHA-512 */
|
||||
};
|
||||
|
||||
} // end namespace MachO
|
||||
} // end namespace llvm
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user