From b2efc0038cdd62a2e485df050e04d79e03ae1c69 Mon Sep 17 00:00:00 2001 From: wutian Date: Thu, 23 Mar 2017 15:05:14 +0800 Subject: [PATCH] Disable PT_DENY_ATTACH and sysctl debugger checking --- IPAPatch.xcodeproj/project.pbxproj | 34 ++++ IPAPatch/IPAPatchBypassAntiDebugging.h | 13 ++ IPAPatch/IPAPatchBypassAntiDebugging.m | 127 +++++++++++++++ IPAPatch/Vendors/fishhook/LICENSE | 22 +++ IPAPatch/Vendors/fishhook/fishhook.c | 210 +++++++++++++++++++++++++ IPAPatch/Vendors/fishhook/fishhook.h | 76 +++++++++ README.md | 26 +++ 7 files changed, 508 insertions(+) create mode 100644 IPAPatch/IPAPatchBypassAntiDebugging.h create mode 100644 IPAPatch/IPAPatchBypassAntiDebugging.m create mode 100755 IPAPatch/Vendors/fishhook/LICENSE create mode 100755 IPAPatch/Vendors/fishhook/fishhook.c create mode 100755 IPAPatch/Vendors/fishhook/fishhook.h diff --git a/IPAPatch.xcodeproj/project.pbxproj b/IPAPatch.xcodeproj/project.pbxproj index af9d5dd..768981d 100644 --- a/IPAPatch.xcodeproj/project.pbxproj +++ b/IPAPatch.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + C63AC1A51E838BB70094B1C5 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = C63AC1A21E838BB70094B1C5 /* fishhook.c */; }; + C63AC1A61E838BB70094B1C5 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = C63AC1A31E838BB70094B1C5 /* fishhook.h */; }; + C63AC1AA1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h in Headers */ = {isa = PBXBuildFile; fileRef = C63AC1A81E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h */; }; + C63AC1AB1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m in Sources */ = {isa = PBXBuildFile; fileRef = C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */; }; C64288391E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C64288371E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp */; }; C6B263271E7BC9DF009B4DEA /* IPAPatchEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = C6B263251E7BC9DF009B4DEA /* IPAPatchEntry.h */; }; C6B263281E7BC9DF009B4DEA /* IPAPatchEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = C6B263261E7BC9DF009B4DEA /* IPAPatchEntry.m */; }; @@ -25,6 +29,11 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + C63AC1A21E838BB70094B1C5 /* fishhook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fishhook.c; sourceTree = ""; }; + C63AC1A31E838BB70094B1C5 /* fishhook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fishhook.h; sourceTree = ""; }; + C63AC1A41E838BB70094B1C5 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + C63AC1A81E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPAPatchBypassAntiDebugging.h; sourceTree = ""; }; + C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IPAPatchBypassAntiDebugging.m; sourceTree = ""; }; C64288371E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectConfigurationWarning.cpp; sourceTree = ""; }; C64288381E7BF9E900C0BBB0 /* ProjectConfigurationWarning.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ProjectConfigurationWarning.hpp; sourceTree = ""; }; C6B263071E7BC97B009B4DEA /* IPAPatch.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IPAPatch.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -57,6 +66,24 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + C63AC1A01E838B8E0094B1C5 /* Vendors */ = { + isa = PBXGroup; + children = ( + C63AC1A11E838BB70094B1C5 /* fishhook */, + ); + path = Vendors; + sourceTree = ""; + }; + C63AC1A11E838BB70094B1C5 /* fishhook */ = { + isa = PBXGroup; + children = ( + C63AC1A31E838BB70094B1C5 /* fishhook.h */, + C63AC1A21E838BB70094B1C5 /* fishhook.c */, + C63AC1A41E838BB70094B1C5 /* LICENSE */, + ); + path = fishhook; + sourceTree = ""; + }; C6B262FD1E7BC97B009B4DEA = { isa = PBXGroup; children = ( @@ -79,9 +106,12 @@ C6B263091E7BC97B009B4DEA /* IPAPatch */ = { isa = PBXGroup; children = ( + C63AC1A01E838B8E0094B1C5 /* Vendors */, C6B2630B1E7BC97B009B4DEA /* Info.plist */, C6B263251E7BC9DF009B4DEA /* IPAPatchEntry.h */, C6B263261E7BC9DF009B4DEA /* IPAPatchEntry.m */, + C63AC1A81E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h */, + C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */, ); path = IPAPatch; sourceTree = ""; @@ -123,6 +153,8 @@ buildActionMask = 2147483647; files = ( C6B263271E7BC9DF009B4DEA /* IPAPatchEntry.h in Headers */, + C63AC1A61E838BB70094B1C5 /* fishhook.h in Headers */, + C63AC1AA1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -244,7 +276,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C63AC1AB1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m in Sources */, C6B263281E7BC9DF009B4DEA /* IPAPatchEntry.m in Sources */, + C63AC1A51E838BB70094B1C5 /* fishhook.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/IPAPatch/IPAPatchBypassAntiDebugging.h b/IPAPatch/IPAPatchBypassAntiDebugging.h new file mode 100644 index 0000000..f59a321 --- /dev/null +++ b/IPAPatch/IPAPatchBypassAntiDebugging.h @@ -0,0 +1,13 @@ +// +// IPAPatchBypassAntiDebugging.h +// IPAPatch +// +// Created by wutian on 2017/3/23. +// Copyright © 2017年 Weibo. All rights reserved. +// + +#import + +@interface IPAPatchBypassAntiDebugging : NSObject + +@end diff --git a/IPAPatch/IPAPatchBypassAntiDebugging.m b/IPAPatch/IPAPatchBypassAntiDebugging.m new file mode 100644 index 0000000..127cca8 --- /dev/null +++ b/IPAPatch/IPAPatchBypassAntiDebugging.m @@ -0,0 +1,127 @@ +// +// IPAPatchBypassAntiDebugging.m +// IPAPatch +// +// Created by wutian on 2017/3/23. +// Copyright © 2017年 Weibo. All rights reserved. +// + +#import "IPAPatchBypassAntiDebugging.h" +#import "fishhook.h" +#import +#import + +#define TESTS_BYPASS 0 + +// Sources: +// https://www.coredump.gr/articles/ios-anti-debugging-protections-part-1/ +// https://www.coredump.gr/articles/ios-anti-debugging-protections-part-2/ +// https://www.theiphonewiki.com/wiki/Bugging_Debuggers + +// Bypassing PT_DENY_ATTACH technique + +static void * (*original_dlsym)(void *, const char *); + +int fake_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data) +{ + return 0; +} + +void * hooked_dlsym(void * __handle, const char * __symbol) +{ + if (strcmp(__symbol, "ptrace") == 0) { + return &fake_ptrace; + } + + return original_dlsym(__handle, __symbol); +} + +static void disable_pt_deny_attach() +{ + original_dlsym = dlsym(RTLD_DEFAULT, "dlsym"); + rebind_symbols((struct rebinding[1]){{"dlsym", hooked_dlsym}}, 1); +} + +// Bypassing sysctl debugger checking technique + +static int (*original_sysctl)(int *, u_int, void *, size_t *, void *, size_t); + +typedef struct kinfo_proc ipa_kinfo_proc; + +int hooked_sysctl(int * arg0, u_int arg1, void * arg2, size_t * arg3, void * arg4, size_t arg5) +{ + bool modify_needed = arg1 == 4 && arg0[0] == CTL_KERN && arg0[1] == KERN_PROC && arg0[2] == KERN_PROC_PID && arg2 && arg3 && (*arg3 >= sizeof(struct kinfo_proc)); + + int ret = original_sysctl(arg0, arg1, arg2, arg3, arg4, arg5); + + if (modify_needed) { + ipa_kinfo_proc * pointer = arg2; + ipa_kinfo_proc info = *pointer; + info.kp_proc.p_flag = 0; + *pointer = info; + } + + return ret; +} + +static void disable_sysctl_debugger_checking() +{ + original_sysctl = dlsym(RTLD_DEFAULT, "sysctl"); + rebind_symbols((struct rebinding[1]){{"sysctl", hooked_sysctl}}, 1); +} + +#if TESTS_BYPASS +// Tests +static void test_aniti_debugger(); +#endif + +@implementation IPAPatchBypassAntiDebugging + ++ (void)load +{ + disable_pt_deny_attach(); + disable_sysctl_debugger_checking(); + +#if TESTS_BYPASS + test_aniti_debugger(); +#endif +} + +@end + +#if TESTS_BYPASS + +typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data); + +#if !defined(PT_DENY_ATTACH) +#define PT_DENY_ATTACH 31 +#endif + +static void test_aniti_debugger() +{ + void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW); + ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace"); + ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0); + dlclose(handle); + + int name[4]; + struct kinfo_proc info; + size_t info_size = sizeof(info); + + info.kp_proc.p_flag = 0; + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PID; + name[3] = getpid(); + + if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) { + perror("sysctl"); + exit(-1); + } + bool debugging = ((info.kp_proc.p_flag & P_TRACED) != 0); + + NSCAssert(!debugging, @"Debug checking should be disabled"); +} + +#endif // TESTS_BYPASS diff --git a/IPAPatch/Vendors/fishhook/LICENSE b/IPAPatch/Vendors/fishhook/LICENSE new file mode 100755 index 0000000..c45bb7c --- /dev/null +++ b/IPAPatch/Vendors/fishhook/LICENSE @@ -0,0 +1,22 @@ +// Copyright (c) 2013, Facebook, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name Facebook nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific +// prior written permission. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/IPAPatch/Vendors/fishhook/fishhook.c b/IPAPatch/Vendors/fishhook/fishhook.c new file mode 100755 index 0000000..e8bec3a --- /dev/null +++ b/IPAPatch/Vendors/fishhook/fishhook.c @@ -0,0 +1,210 @@ +// Copyright (c) 2013, Facebook, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name Facebook nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific +// prior written permission. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#import "fishhook.h" + +#import +#import +#import +#import +#import +#import +#import + +#ifdef __LP64__ +typedef struct mach_header_64 mach_header_t; +typedef struct segment_command_64 segment_command_t; +typedef struct section_64 section_t; +typedef struct nlist_64 nlist_t; +#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 +#else +typedef struct mach_header mach_header_t; +typedef struct segment_command segment_command_t; +typedef struct section section_t; +typedef struct nlist nlist_t; +#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT +#endif + +#ifndef SEG_DATA_CONST +#define SEG_DATA_CONST "__DATA_CONST" +#endif + +struct rebindings_entry { + struct rebinding *rebindings; + size_t rebindings_nel; + struct rebindings_entry *next; +}; + +static struct rebindings_entry *_rebindings_head; + +static int prepend_rebindings(struct rebindings_entry **rebindings_head, + struct rebinding rebindings[], + size_t nel) { + struct rebindings_entry *new_entry = malloc(sizeof(struct rebindings_entry)); + if (!new_entry) { + return -1; + } + new_entry->rebindings = malloc(sizeof(struct rebinding) * nel); + if (!new_entry->rebindings) { + free(new_entry); + return -1; + } + memcpy(new_entry->rebindings, rebindings, sizeof(struct rebinding) * nel); + new_entry->rebindings_nel = nel; + new_entry->next = *rebindings_head; + *rebindings_head = new_entry; + return 0; +} + +static void perform_rebinding_with_section(struct rebindings_entry *rebindings, + section_t *section, + intptr_t slide, + nlist_t *symtab, + char *strtab, + uint32_t *indirect_symtab) { + uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; + void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); + for (uint i = 0; i < section->size / sizeof(void *); i++) { + uint32_t symtab_index = indirect_symbol_indices[i]; + if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || + symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { + continue; + } + uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; + char *symbol_name = strtab + strtab_offset; + if (strnlen(symbol_name, 2) < 2) { + continue; + } + struct rebindings_entry *cur = rebindings; + while (cur) { + for (uint j = 0; j < cur->rebindings_nel; j++) { + if (strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { + if (cur->rebindings[j].replaced != NULL && + indirect_symbol_bindings[i] != cur->rebindings[j].replacement) { + *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; + } + indirect_symbol_bindings[i] = cur->rebindings[j].replacement; + goto symbol_loop; + } + } + cur = cur->next; + } + symbol_loop:; + } +} + +static void rebind_symbols_for_image(struct rebindings_entry *rebindings, + const struct mach_header *header, + intptr_t slide) { + Dl_info info; + if (dladdr(header, &info) == 0) { + return; + } + + segment_command_t *cur_seg_cmd; + segment_command_t *linkedit_segment = NULL; + struct symtab_command* symtab_cmd = NULL; + struct dysymtab_command* dysymtab_cmd = NULL; + + uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); + for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { + cur_seg_cmd = (segment_command_t *)cur; + if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { + if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) { + linkedit_segment = cur_seg_cmd; + } + } else if (cur_seg_cmd->cmd == LC_SYMTAB) { + symtab_cmd = (struct symtab_command*)cur_seg_cmd; + } else if (cur_seg_cmd->cmd == LC_DYSYMTAB) { + dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd; + } + } + + if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment || + !dysymtab_cmd->nindirectsyms) { + return; + } + + // Find base symbol/string table addresses + uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; + nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); + char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); + + // Get indirect symbol table (array of uint32_t indices into symbol table) + uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); + + cur = (uintptr_t)header + sizeof(mach_header_t); + for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { + cur_seg_cmd = (segment_command_t *)cur; + if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { + if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 && + strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) { + continue; + } + for (uint j = 0; j < cur_seg_cmd->nsects; j++) { + section_t *sect = + (section_t *)(cur + sizeof(segment_command_t)) + j; + if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { + perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); + } + if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { + perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); + } + } + } + } +} + +static void _rebind_symbols_for_image(const struct mach_header *header, + intptr_t slide) { + rebind_symbols_for_image(_rebindings_head, header, slide); +} + +int rebind_symbols_image(void *header, + intptr_t slide, + struct rebinding rebindings[], + size_t rebindings_nel) { + struct rebindings_entry *rebindings_head = NULL; + int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); + rebind_symbols_for_image(rebindings_head, header, slide); + free(rebindings_head); + return retval; +} + +int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) { + int retval = prepend_rebindings(&_rebindings_head, rebindings, rebindings_nel); + if (retval < 0) { + return retval; + } + // If this was the first call, register callback for image additions (which is also invoked for + // existing images, otherwise, just run on existing images + if (!_rebindings_head->next) { + _dyld_register_func_for_add_image(_rebind_symbols_for_image); + } else { + uint32_t c = _dyld_image_count(); + for (uint32_t i = 0; i < c; i++) { + _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); + } + } + return retval; +} diff --git a/IPAPatch/Vendors/fishhook/fishhook.h b/IPAPatch/Vendors/fishhook/fishhook.h new file mode 100755 index 0000000..0d8e36a --- /dev/null +++ b/IPAPatch/Vendors/fishhook/fishhook.h @@ -0,0 +1,76 @@ +// Copyright (c) 2013, Facebook, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name Facebook nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific +// prior written permission. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef fishhook_h +#define fishhook_h + +#include +#include + +#if !defined(FISHHOOK_EXPORT) +#define FISHHOOK_VISIBILITY __attribute__((visibility("hidden"))) +#else +#define FISHHOOK_VISIBILITY __attribute__((visibility("default"))) +#endif + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +/* + * A structure representing a particular intended rebinding from a symbol + * name to its replacement + */ +struct rebinding { + const char *name; + void *replacement; + void **replaced; +}; + +/* + * For each rebinding in rebindings, rebinds references to external, indirect + * symbols with the specified name to instead point at replacement for each + * image in the calling process as well as for all future images that are loaded + * by the process. If rebind_functions is called more than once, the symbols to + * rebind are added to the existing list of rebindings, and if a given symbol + * is rebound more than once, the later rebinding will take precedence. + */ +FISHHOOK_VISIBILITY +int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); + +/* + * Rebinds as above, but only in the specified image. The header should point + * to the mach-o header, the slide should be the slide offset. Others as above. + */ +FISHHOOK_VISIBILITY +int rebind_symbols_image(void *header, + intptr_t slide, + struct rebinding rebindings[], + size_t rebindings_nel); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //fishhook_h + diff --git a/README.md b/README.md index 63629a2..4d0c639 100644 --- a/README.md +++ b/README.md @@ -132,3 +132,29 @@ https://github.com/Naituw/IPAPatch/releases/tag/1.0 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#### fishhook + + Copyright (c) 2013, Facebook, Inc. + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +