From 20e7eb2982bb3bcb05b1b055faf25e7e70a980e0 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sat, 22 Oct 2011 07:11:53 -0700 Subject: Add ldid -r: reverse ldid. --- ldid.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'ldid.cpp') diff --git a/ldid.cpp b/ldid.cpp index 7e018fe..01f53b4 100644 --- a/ldid.cpp +++ b/ldid.cpp @@ -96,6 +96,7 @@ struct load_command { #define LC_REQ_DYLD uint32_t(0x80000000) #define LC_SEGMENT uint32_t(0x01) +#define LC_SYMTAB uint32_t(0x02) #define LC_LOAD_DYLIB uint32_t(0x0c) #define LC_ID_DYLIB uint32_t(0x0d) #define LC_UUID uint32_t(0x1b) @@ -121,6 +122,15 @@ struct uuid_command { uint8_t uuid[16]; } _packed; +struct symtab_command { + uint32_t cmd; + uint32_t cmdsize; + uint32_t symoff; + uint32_t nsyms; + uint32_t stroff; + uint32_t strsize; +} _packed; + struct segment_command { uint32_t cmd; uint32_t cmdsize; @@ -410,6 +420,10 @@ class FatHeader : std::vector &GetMachHeaders() { return mach_headers_; } + + bool IsFat() const { + return fat_header_ != NULL; + } }; FatHeader Map(const char *path) { @@ -521,6 +535,8 @@ int main(int argc, const char *argv[]) { little_ = endian.byte[0]; bool flag_R(false); + bool flag_r(false); + bool flag_t(false); bool flag_p(false); bool flag_u(false); @@ -555,6 +571,8 @@ int main(int argc, const char *argv[]) { files.push_back(argv[argi]); else switch (argv[argi][1]) { case 'R': flag_R = true; break; + case 'r': flag_r = true; break; + case 't': flag_t = true; break; case 'u': flag_u = true; break; case 'p': flag_p = true; break; @@ -619,6 +637,46 @@ int main(int argc, const char *argv[]) { base = path; } + if (flag_r) { + size_t clip(_not(size_t)); { + FatHeader fat_header(Map(path)); + _foreach (mach_header, fat_header.GetMachHeaders()) { + mach_header->flags = mach_header.Swap(mach_header.Swap(mach_header->flags) | MH_DYLDLINK); + + size_t size(_not(size_t)); { + _foreach (load_command, mach_header.GetLoadCommands()) { + switch (mach_header.Swap(load_command->cmd)) { + case LC_CODE_SIGNATURE: { + struct linkedit_data_command *signature = reinterpret_cast(load_command); + memset(signature, 0, sizeof(struct linkedit_data_command)); + + mach_header->ncmds -= 1; + mach_header->sizeofcmds -= sizeof(struct linkedit_data_command); + } break; + + case LC_SYMTAB: { + struct symtab_command *symtab = reinterpret_cast(load_command); + size = symtab->stroff + symtab->strsize; + } break; + } + } + + _foreach (segment, const_cast(mach_header).GetSegments("__LINKEDIT")) { + segment->filesize -= mach_header.GetSize() - size; + + if (!fat_header.IsFat()) + clip = size; + else + _assert(false); + } + } + } + } + + if (clip != _not(size_t)) + _syscall(truncate(path, clip)); + } + if (flag_S) { asprintf(&temp, "%s.%s.cs", dir, base); const char *allocate = getenv("CODESIGN_ALLOCATE"); -- cgit v1.2.3-56-ge451