美文网首页
iOS 15闪退问题-fishhook问题

iOS 15闪退问题-fishhook问题

作者: 码农冰冰 | 来源:发表于2022-06-22 11:17 被阅读0次

    转: https://blog.51cto.com/u_15318120/4309633
    记录下:didFinishLaunchingWithOptions没有进去直接闪退,崩溃日志如下

    Incident Identifier: 2722EB09-28C2-485E-8F
    CrashReporter Key:   2b0889363d8e8ab6d0da6c2cf2d1e334cd4dab4b
    Hardware Model:      iPhone10,2
    Process:            ********** [359]
    Path:                /private/var/containers/Bundle/Application/39DDF82D-54D8-4827-867F-9BC016F7D3DA/**********.app/**********
    Identifier:          com.aliyun.rtc.demo
    Version:             1.0 (1)
    Code Type:           ARM-64 (Native)
    Role:                Foreground
    Parent Process:      launchd [1]
    Coalition:           com.aliyun.rtc.demo [468]
    
    Date/Time:           2022-06-22 09:42:29.4855 +0800
    Launch Time:         2022-06-22 09:42:28.7947 +0800
    OS Version:          iPhone OS 15.2.1 (19C63)
    Release Type:        User
    Baseband Version:    7.02.00
    Report Version:      104
    
    Exception Type:  EXC_BAD_ACCESS (SIGBUS)
    Exception Subtype: KERN_PROTECTION_FAILURE at 0x00000001ec92e0c8
    Exception Codes: 0x0000000000000002, 0x00000001ec92e0c8
    VM Region Info: 0x1ec92e0c8 is in 0x1ec92d968-0x1ec92fb40;  bytes after start: 1888  bytes before end: 6775
          REGION TYPE                 START - END      [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
          __DATA_CONST             1ec92c550-1ec92d968 [    5K] r--/rw- SM=COW  ...em_info.dylib
    --->  __DATA_CONST             1ec92d968-1ec92fb40 [    8K] r--/rw- SM=COW  ...ystem_c.dylib
          __DATA_CONST             1ec92fb40-1ec947a28 [   96K] r--/rw- SM=COW  ...BoardServices
    Exception Note:  EXC_CORPSE_NOTIFY
    Termination Reason: SIGNAL; [10]
    Terminating Process: exc handler [359]
    
    Terminating Process: exc handler [359]
    Triggered by Thread:  0
    
    Thread 0 name:   Dispatch queue: com.apple.main-thread
    Thread 0 Crashed:
    0   **********                     0x10506c198 perform_rebinding_with_section + 600
    1   **********                     0x10506c0f0 perform_rebinding_with_section + 432
    2   **********                     0x10506be00 rebind_symbols_for_image + 636
    3   **********                     0x10506bf34 _rebind_symbols_for_image + 40
    4   dyld                                   0x10750ee88 invocation function for block in dyld4::APIs::_dyld_register_func_for_add_image(void (*)(mach_header const*, long)) + 164
    5   dyld                                   0x1075082a4 dyld4::RuntimeState::withLoadersReadLock(void () block_pointer) + 60
    6   dyld                                   0x10752e790 dyld4::APIs::_dyld_register_func_for_add_image(void (*)(mach_header const*, long)) + 124
    7   **********                     0x10506bea4 rebind_symbols + 96
    8   **********                     0x105077f1c HookAPIEngineInitialize + 100
    9   **********                     0x105040bc8 main + 172
    10  dyld                                   0x10751c250 start + 444
    
    Thread 1:
    0   libsystem_pthread.dylib                0x1dd6f29e8 start_wqthread + 0
    
    Thread 2:
    0   libsystem_pthread.dylib                0x1dd6f29e8 start_wqthread + 0
    
    Thread 3:
    0   libsystem_pthread.dylib                0x1dd6f29e8 start_wqthread + 0
    
    Thread 4:
    0   libsystem_pthread.dylib                0x1dd6f29e8 start_wqthread + 0
    
    Thread 5:
    0   libsystem_pthread.dylib                0x1dd6f29e8 start_wqthread + 0
    
    Thread 6:
    0   libsystem_kernel.dylib                 0x1bd246088 __semwait_signal + 8
    1   libsystem_c.dylib                      0x18d62b8e0 nanosleep + 212
    2   libsystem_c.dylib                      0x18d62c5a8 usleep + 64
    3   **********                     0x1050052b4 CAsyncLog::DoLog() + 260
    4   **********                     0x1050051a0 CAsyncLog::LogProc(void*) + 32
    5   libsystem_pthread.dylib                0x1dd6f43a4 _pthread_start + 116
    6   libsystem_pthread.dylib                0x1dd6f29fc thread_start + 8
    
    Thread 7:
    0   libsystem_kernel.dylib                 0x1bd246088 __semwait_signal + 8
    1   libsystem_c.dylib                      0x18d62b8e0 nanosleep + 212
    2   libsystem_c.dylib                      0x18d62c5a8 usleep + 64
    3   **********                     0x10503c3d8 NetModuleHook::Process() + 84
    4   **********                     0x10503c274 NetModuleHook::NetModuleFunc(void*) + 32
    5   libsystem_pthread.dylib                0x1dd6f43a4 _pthread_start + 116
    6   libsystem_pthread.dylib                0x1dd6f29fc thread_start + 8
    
    
    Thread 0 crashed with ARM Thread State (64-bit):
        x0: 0x0000000000000000   x1: 0x0000000105fcda3c   x2: 0x0000000000000003   x3: 0xfffffffffffffff0
        x4: 0x0000000000000000   x5: 0x0000000000000000   x6: 0x0000000000000000   x7: 0x00000000000005d0
        x8: 0x0000000105078838   x9: 0x00000001ec92e0c8  x10: 0x00000000000000ec  x11: 0x0000000000000018
       x12: 0x000000010a198000  x13: 0x0000000105fcda47  x14: 0x0000000105078b3c  x15: 0x000000010650bac0
       x16: 0x00000001dd6e2f90  x17: 0x0000000000000000  x18: 0x0000000000000000  x19: 0x000000016ae1b530
       x20: 0x00000001075a8060  x21: 0x00000001075519b9  x22: 0x000000018d627000  x23: 0x00000001075ae5f0
       x24: 0x0000000000001308  x25: 0x000000010506bf0c  x26: 0x0000000000000000  x27: 0x0000000000000000
       x28: 0x0000000000000000   fp: 0x000000016ae1b390   lr: 0x000000010506c0f0
        sp: 0x000000016ae1b310   pc: 0x000000010506c198 cpsr: 0x20000000
       far: 0x00000001ec92e0c8  esr: 0x9200004f (Data Abort) byte write Permission fault
    
    Binary Images:
           0x104fe4000 -        0x1063b3fff ********** arm64  <c18d2724d0bc3b4dab5ea2bef95a2c21> /private/var/containers/Bundle/Application/39DDF82D-54D8-4827-867F-9BC016F7D3DA/**********.app/**********
           0x107504000 -        0x107557fff dyld arm64  <0b12aec1caef38ad8fb73cab3da30489> /usr/lib/dyld
           0x1dd6ee000 -        0x1dd701fff libsystem_pthread.dylib arm64  <263a2eadc4f33ef5bc4b7a61e6698c8b> /usr/lib/system/libsystem_pthread.dylib
           0x1bd245000 -        0x1bd276fff libsystem_kernel.dylib arm64  <8f5f208de1bd3eb2994023b6d21843c5> /usr/lib/system/libsystem_kernel.dylib
           0x18d627000 -        0x18d6a1fff libsystem_c.dylib arm64  <abebc366a9d73042907c2cc20aa2b047> /usr/lib/system/libsystem_c.dylib
                   0x0 - 0xffffffffffffffff ??? unknown-arch  <00000000000000000000000000000000> ???
    
    EOF
    

    解决方法:fishhook.c代码替换

    // 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.
    
    #include "fishhook.h"
    
    #include <dlfcn.h>
    #include <stdbool.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/mman.h>
    #include <sys/types.h>
    #include <mach/mach.h>
    #include <mach/vm_map.h>
    #include <mach/vm_region.h>
    #include <mach-o/dyld.h>
    #include <mach-o/loader.h>
    #include <mach-o/nlist.h>
    
    #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 = (struct rebindings_entry *) malloc(sizeof(struct rebindings_entry));
        if (!new_entry) {
            return -1;
        }
        new_entry->rebindings = (struct rebinding *) 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;
    }
    
    #if 0
    static int get_protection(void *addr, vm_prot_t *prot, vm_prot_t *max_prot) {
        mach_port_t task = mach_task_self();
        vm_size_t size = 0;
        vm_address_t address = (vm_address_t)addr;
        memory_object_name_t object;
    #ifdef __LP64__
        mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
        vm_region_basic_info_data_64_t info;
        kern_return_t info_ret = vm_region_64(
                                              task, &address, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_64_t)&info, &count, &object);
    #else
        mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT;
        vm_region_basic_info_data_t info;
        kern_return_t info_ret = vm_region(task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object);
    #endif
        if (info_ret == KERN_SUCCESS) {
            if (prot != NULL)
                *prot = info.protection;
            
            if (max_prot != NULL)
                *max_prot = info.max_protection;
            
            return 0;
        }
        
        return -1;
    }
    #endif
    
    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;
            bool symbol_name_longer_than_1 = symbol_name[0] && symbol_name[1];
            struct rebindings_entry *cur = rebindings;
            while (cur) {
                for (uint j = 0; j < cur->rebindings_nel; j++) {
                    if (symbol_name_longer_than_1 && strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) {
                        kern_return_t err;
                        
                        if (cur->rebindings[j].replaced != NULL && indirect_symbol_bindings[i] != cur->rebindings[j].replacement)
                            *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i];
                        
                        /**
                         * 1. Moved the vm protection modifying codes to here to reduce the
                         *    changing scope.
                         * 2. Adding VM_PROT_WRITE mode unconditionally because vm_region
                         *    API on some iOS/Mac reports mismatch vm protection attributes.
                         * -- Lianfu Hao Jun 16th, 2021
                         **/
                        err = vm_protect (mach_task_self (), (uintptr_t)indirect_symbol_bindings, section->size, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY);
                        if (err == KERN_SUCCESS) {
                            /**
                             * Once we failed to change the vm protection, we
                             * MUST NOT continue the following write actions!
                             * iOS 15 has corrected the const segments prot.
                             * -- Lionfore Hao Jun 11th, 2021
                             **/
                            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, (const struct mach_header *) header, slide);
        if (rebindings_head) {
            free(rebindings_head->rebindings);
        }
        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;
    }
    
    

    相关文章

      网友评论

          本文标题:iOS 15闪退问题-fishhook问题

          本文链接:https://www.haomeiwen.com/subject/bwayvrtx.html