X-Git-Url: https://git.saurik.com/ldid.git/blobdiff_plain/5567b35f03e6186922e6c6a75987ac1044853b76..ab113d2205a8e142ffccfe3b385877a7330009b9:/ldid.cpp diff --git a/ldid.cpp b/ldid.cpp index d5b739c..ff9358d 100644 --- a/ldid.cpp +++ b/ldid.cpp @@ -1,5 +1,5 @@ -/* JocStrap - Java/Objective-C Bootstrap - * Copyright (C) 2007 Jay Freeman (saurik) +/* ldid - (Mach-O) Link-Loader Identity Editor + * Copyright (C) 2007-2010 Jay Freeman (saurik) */ /* @@ -78,6 +78,9 @@ struct mach_header { #define MH_MAGIC 0xfeedface #define MH_CIGAM 0xcefaedfe +#define MH_MAGIC_64 0xfeedfacf +#define MH_CIGAM_64 0xcffaedfe + #define MH_DYLDLINK 0x4 #define MH_EXECUTE 0x2 @@ -175,12 +178,14 @@ int32_t Swap_(int32_t value) { return Swap_(static_cast(value)); } +bool little_(true); + uint16_t Swap(uint16_t value) { - return true ? Swap_(value) : value; + return little_ ? Swap_(value) : value; } uint32_t Swap(uint32_t value) { - return true ? Swap_(value) : value; + return little_ ? Swap_(value) : value; } int16_t Swap(int16_t value) { @@ -198,8 +203,12 @@ class Framework { private: void *base_; size_t size_; - mach_header *mach_header_; + + struct mach_header *mach_header_; + struct load_command *load_command_; + bool swapped_; + bool bits64_; public: uint16_t Swap(uint16_t value) const { @@ -244,9 +253,27 @@ class Framework { } found: - if (Swap(mach_header_->magic) == MH_CIGAM) - swapped_ = !swapped_; - else _assert(Swap(mach_header_->magic) == MH_MAGIC); + switch (Swap(mach_header_->magic)) { + case MH_CIGAM: + swapped_ = !swapped_; + case MH_MAGIC: + bits64_ = false; + break; + + case MH_CIGAM_64: + swapped_ = !swapped_; + case MH_MAGIC_64: + bits64_ = true; + break; + + default: + _assert(false); + } + + void *post = mach_header_ + 1; + if (bits64_) + post = (uint32_t *) post + 1; + load_command_ = (struct load_command *) post; _assert( Swap(mach_header_->filetype) == MH_EXECUTE || @@ -263,14 +290,22 @@ class Framework { return base_; } - size_t GetSize() { + size_t GetSize() const { return size_; } + uint32_t GetCPUType() const { + return Swap(mach_header_->cputype); + } + + uint16_t GetCPUSubtype() const { + return Swap(mach_header_->cpusubtype) & 0xff; + } + std::vector GetLoadCommands() { std::vector load_commands; - struct load_command *load_command = reinterpret_cast(mach_header_ + 1); + struct load_command *load_command = load_command_; for (uint32_t cmd = 0; cmd != Swap(mach_header_->ncmds); ++cmd) { load_commands.push_back(load_command); load_command = (struct load_command *) ((uint8_t *) load_command + Swap(load_command->cmdsize)); @@ -430,6 +465,13 @@ void sha1(uint8_t *hash, uint8_t *data, size_t size) { } int main(int argc, const char *argv[]) { + union { + uint16_t word; + uint8_t byte[2]; + } endian = {1}; + + little_ = endian.byte[0]; + bool flag_R(false); bool flag_t(false); bool flag_p(false); @@ -538,7 +580,7 @@ int main(int argc, const char *argv[]) { size_t size = _not(size_t); const char *arch; { Framework framework(path); - framework->flags |= MH_DYLDLINK; + framework->flags = framework.Swap(framework.Swap(framework->flags) | MH_DYLDLINK); _foreach (load_command, framework.GetLoadCommands()) { uint32_t cmd(framework.Swap((*load_command)->cmd)); @@ -553,10 +595,31 @@ int main(int argc, const char *argv[]) { if (size == _not(size_t)) size = framework.GetSize(); - switch (framework->cputype) { - case 12: switch (framework->cpusubtype) { + switch (framework.GetCPUType()) { + case 7: switch (framework.GetCPUSubtype()) { + case 3: arch = "i386"; break; + default: arch = NULL; break; + } break; + + case 12: switch (framework.GetCPUSubtype()) { case 0: arch = "arm"; break; case 6: arch = "armv6"; break; + case 9: arch = "armv7"; break; + default: arch = NULL; break; + } break; + + case 18: switch (framework.GetCPUSubtype()) { + case 10: arch = "ppc7400"; break; + default: arch = NULL; break; + } break; + + case 16777223: switch (framework.GetCPUSubtype()) { + case 3: arch = "x86_64"; break; + default: arch = NULL; break; + } break; + + case 16777234: switch (framework.GetCPUSubtype()) { + case 0: arch = "ppc64"; break; default: arch = NULL; break; } break;