fishhook nwlog_legacy_v to avoid log spam on websocket reconnect
Reviewed By: mmmulani, javache Differential Revision: D5570896 fbshipit-source-id: be98f500434bd2a0113b9abca20c9f21102c09d1
This commit is contained in:
parent
898790d88a
commit
878b7e42fa
|
@ -11,11 +11,27 @@
|
|||
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTDefines.h>
|
||||
#import <fishhook/fishhook.h>
|
||||
|
||||
#import "RCTSRWebSocket.h"
|
||||
|
||||
#if RCT_DEV // Only supported in dev mode
|
||||
|
||||
static void (*orig_nwlog_legacy_v)(int, char*, va_list);
|
||||
|
||||
static void my_nwlog_legacy_v(int level, char *format, va_list args) {
|
||||
static const uint buffer_size = 256;
|
||||
static char buffer[buffer_size];
|
||||
va_list copy;
|
||||
va_copy(copy, args);
|
||||
vsnprintf(buffer, buffer_size, format, copy);
|
||||
va_end(copy);
|
||||
|
||||
if (strstr(buffer, "nw_connection_get_connected_socket_block_invoke") == NULL) {
|
||||
orig_nwlog_legacy_v(level, format, args);
|
||||
}
|
||||
}
|
||||
|
||||
@interface RCTReconnectingWebSocket () <RCTSRWebSocketDelegate>
|
||||
@end
|
||||
|
||||
|
@ -26,6 +42,16 @@
|
|||
|
||||
@synthesize delegate = _delegate;
|
||||
|
||||
+ (void)load
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
rebind_symbols((struct rebinding[1]){
|
||||
{"nwlog_legacy_v", my_nwlog_legacy_v, (void *)&orig_nwlog_legacy_v}
|
||||
}, 1);
|
||||
});
|
||||
}
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
{
|
||||
if (self = [super init]) {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/* Begin PBXBuildFile section */
|
||||
1338BBE01B04ACC80064A9C9 /* RCTSRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 1338BBDD1B04ACC80064A9C9 /* RCTSRWebSocket.m */; };
|
||||
1338BBE11B04ACC80064A9C9 /* RCTWebSocketExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 1338BBDF1B04ACC80064A9C9 /* RCTWebSocketExecutor.m */; };
|
||||
13526A521F362F7F0008EF00 /* libfishhook.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13526A511F362F7F0008EF00 /* libfishhook.a */; };
|
||||
2D3B5F3D1D9B165B00451313 /* RCTSRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 1338BBDD1B04ACC80064A9C9 /* RCTSRWebSocket.m */; };
|
||||
2D3B5F3E1D9B165B00451313 /* RCTWebSocketExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 1338BBDF1B04ACC80064A9C9 /* RCTWebSocketExecutor.m */; };
|
||||
2D3B5F3F1D9B165B00451313 /* RCTWebSocketObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB9106E1C74B1ED00838BBE /* RCTWebSocketObserver.m */; };
|
||||
|
@ -24,6 +25,7 @@
|
|||
1338BBDD1B04ACC80064A9C9 /* RCTSRWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSRWebSocket.m; sourceTree = "<group>"; };
|
||||
1338BBDE1B04ACC80064A9C9 /* RCTWebSocketExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebSocketExecutor.h; sourceTree = "<group>"; };
|
||||
1338BBDF1B04ACC80064A9C9 /* RCTWebSocketExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebSocketExecutor.m; sourceTree = "<group>"; };
|
||||
13526A511F362F7F0008EF00 /* libfishhook.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfishhook.a; path = "libfishhook.a"; sourceTree = "<group>"; };
|
||||
2D2A28881D9B049200D4039D /* libRCTWebSocket-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRCTWebSocket-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3C86DF461ADF2C930047B81A /* libRCTWebSocket.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTWebSocket.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3C86DF7A1ADF695F0047B81A /* RCTWebSocketModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebSocketModule.h; sourceTree = "<group>"; };
|
||||
|
@ -34,7 +36,26 @@
|
|||
A12E9E2D1E5DEC4E0029001B /* RCTReconnectingWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTReconnectingWebSocket.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
13526A4F1F362F770008EF00 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13526A521F362F7F0008EF00 /* libfishhook.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
13526A501F362F7F0008EF00 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13526A511F362F7F0008EF00 /* libfishhook.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3C86DF3D1ADF2C930047B81A = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -49,6 +70,7 @@
|
|||
3C86DF7A1ADF695F0047B81A /* RCTWebSocketModule.h */,
|
||||
3C86DF7B1ADF695F0047B81A /* RCTWebSocketModule.m */,
|
||||
3C86DF471ADF2C930047B81A /* Products */,
|
||||
13526A501F362F7F0008EF00 /* Frameworks */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
|
@ -87,6 +109,7 @@
|
|||
buildConfigurationList = 3C86DF5A1ADF2C930047B81A /* Build configuration list for PBXNativeTarget "RCTWebSocket" */;
|
||||
buildPhases = (
|
||||
3C86DF421ADF2C930047B81A /* Sources */,
|
||||
13526A4F1F362F770008EF00 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
|
@ -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.
|
|
@ -0,0 +1,75 @@
|
|||
# fishhook
|
||||
|
||||
__fishhook__ is a very simple library that enables dynamically rebinding symbols in Mach-O binaries running on iOS in the simulator and on device. This provides functionality that is similar to using [`DYLD_INTERPOSE`][interpose] on OS X. At Facebook, we've found it useful as a way to hook calls in libSystem for debugging/tracing purposes (for example, auditing for double-close issues with file descriptors).
|
||||
|
||||
[interpose]: http://opensource.apple.com/source/dyld/dyld-210.2.3/include/mach-o/dyld-interposing.h "<mach-o/dyld-interposing.h>"
|
||||
|
||||
## Usage
|
||||
|
||||
Once you add `fishhook.h`/`fishhook.c` to your project, you can rebind symbols as follows:
|
||||
```Objective-C
|
||||
#import <dlfcn.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "fishhook.h"
|
||||
|
||||
static int (*orig_close)(int);
|
||||
static int (*orig_open)(const char *, int, ...);
|
||||
|
||||
int my_close(int fd) {
|
||||
printf("Calling real close(%d)\n", fd);
|
||||
return orig_close(fd);
|
||||
}
|
||||
|
||||
int my_open(const char *path, int oflag, ...) {
|
||||
va_list ap = {0};
|
||||
mode_t mode = 0;
|
||||
|
||||
if ((oflag & O_CREAT) != 0) {
|
||||
// mode only applies to O_CREAT
|
||||
va_start(ap, oflag);
|
||||
mode = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
printf("Calling real open('%s', %d, %d)\n", path, oflag, mode);
|
||||
return orig_open(path, oflag, mode);
|
||||
} else {
|
||||
printf("Calling real open('%s', %d)\n", path, oflag);
|
||||
return orig_open(path, oflag, mode);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
rebind_symbols((struct rebinding[2]){{"close", my_close, (void *)&orig_close}, {"open", my_open, (void *)&orig_open}}, 2);
|
||||
|
||||
// Open our own binary and print out first 4 bytes (which is the same
|
||||
// for all Mach-O binaries on a given architecture)
|
||||
int fd = open(argv[0], O_RDONLY);
|
||||
uint32_t magic_number = 0;
|
||||
read(fd, &magic_number, 4);
|
||||
printf("Mach-O Magic Number: %x \n", magic_number);
|
||||
close(fd);
|
||||
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
```
|
||||
### Sample output
|
||||
```
|
||||
Calling real open('/var/mobile/Applications/161DA598-5B83-41F5-8A44-675491AF6A2C/Test.app/Test', 0)
|
||||
Mach-O Magic Number: feedface
|
||||
Calling real close(3)
|
||||
...
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
`dyld` binds lazy and non-lazy symbols by updating pointers in particular sections of the `__DATA` segment of a Mach-O binary. __fishhook__ re-binds these symbols by determining the locations to update for each of the symbol names passed to `rebind_symbols` and then writing out the corresponding replacements.
|
||||
|
||||
For a given image, the `__DATA` segment may contain two sections that are relevant for dynamic symbol bindings: `__nl_symbol_ptr` and `__la_symbol_ptr`. `__nl_symbol_ptr` is an array of pointers to non-lazily bound data (these are bound at the time a library is loaded) and `__la_symbol_ptr` is an array of pointers to imported functions that is generally filled by a routine called `dyld_stub_binder` during the first call to that symbol (it's also possible to tell `dyld` to bind these at launch). In order to find the name of the symbol that corresponds to a particular location in one of these sections, we have to jump through several layers of indirection. For the two relevant sections, the section headers (`struct section`s from `<mach-o/loader.h>`) provide an offset (in the `reserved1` field) into what is known as the indirect symbol table. The indirect symbol table, which is located in the `__LINKEDIT` segment of the binary, is just an array of indexes into the symbol table (also in `__LINKEDIT`) whose order is identical to that of the pointers in the non-lazy and lazy symbol sections. So, given `struct section nl_symbol_ptr`, the corresponding index in the symbol table of the first address in that section is `indirect_symbol_table[nl_symbol_ptr->reserved1]`. The symbol table itself is an array of `struct nlist`s (see `<mach-o/nlist.h>`), and each `nlist` contains an index into the string table in `__LINKEDIT` which where the actual symbol names are stored. So, for each pointer `__nl_symbol_ptr` and `__la_symbol_ptr`, we are able to find the corresponding symbol and then the corresponding string to compare against the requested symbol names, and if there is a match, we replace the pointer in the section with the replacement.
|
||||
|
||||
The process of looking up the name of a given entry in the lazy or non-lazy pointer tables looks like this:
|
||||
![Visual explanation](http://i.imgur.com/HVXqHCz.png)
|
|
@ -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 <dlfcn.h>
|
||||
#import <stdlib.h>
|
||||
#import <string.h>
|
||||
#import <sys/types.h>
|
||||
#import <mach-o/dyld.h>
|
||||
#import <mach-o/loader.h>
|
||||
#import <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;
|
||||
}
|
||||
|
||||
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, (const struct mach_header *) 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;
|
||||
}
|
|
@ -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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
13526A4C1F362F4E0008EF00 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = 13170F8E1F362E530070B900 /* fishhook.h */; };
|
||||
13526A4E1F362F5B0008EF00 /* fishhook.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 13170F8E1F362E530070B900 /* fishhook.h */; };
|
||||
13C5161D1F362E9C00322EB8 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 13170F8D1F362E530070B900 /* fishhook.c */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
13526A4D1F362F520008EF00 /* Copy Headers */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = include/fishhook;
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
13526A4E1F362F5B0008EF00 /* fishhook.h in Copy Headers */,
|
||||
);
|
||||
name = "Copy Headers";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
13170F8D1F362E530070B900 /* fishhook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fishhook.c; sourceTree = "<group>"; };
|
||||
13170F8E1F362E530070B900 /* fishhook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fishhook.h; sourceTree = "<group>"; };
|
||||
134814201AA4EA6300B7C361 /* libfishhook.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libfishhook.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
134814211AA4EA7D00B7C361 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
134814201AA4EA6300B7C361 /* libfishhook.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58B511D21A9E6C8500147676 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13170F8D1F362E530070B900 /* fishhook.c */,
|
||||
13170F8E1F362E530070B900 /* fishhook.h */,
|
||||
134814211AA4EA7D00B7C361 /* Products */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
usesTabs = 0;
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
13526A4B1F362F470008EF00 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13526A4C1F362F4E0008EF00 /* fishhook.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
58B511DA1A9E6C8500147676 /* fishhook */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "fishhook" */;
|
||||
buildPhases = (
|
||||
58B511D71A9E6C8500147676 /* Sources */,
|
||||
13526A4B1F362F470008EF00 /* Headers */,
|
||||
13526A4D1F362F520008EF00 /* Copy Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = fishhook;
|
||||
productName = RCTDataManager;
|
||||
productReference = 134814201AA4EA6300B7C361 /* libfishhook.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
58B511D31A9E6C8500147676 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0610;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
58B511DA1A9E6C8500147676 = {
|
||||
CreatedOnToolsVersion = 6.1.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "fishhook" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 58B511D21A9E6C8500147676;
|
||||
productRefGroup = 58B511D21A9E6C8500147676;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
58B511DA1A9E6C8500147676 /* fishhook */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
58B511D71A9E6C8500147676 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13C5161D1F362E9C00322EB8 /* fishhook.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
58B511ED1A9E6C8500147676 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
WARNING_CFLAGS = (
|
||||
"-Werror",
|
||||
"-Wall",
|
||||
);
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
58B511EE1A9E6C8500147676 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
WARNING_CFLAGS = (
|
||||
"-Werror",
|
||||
"-Wall",
|
||||
);
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
58B511F01A9E6C8500147676 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_STATIC_ANALYZER_MODE = deep;
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
58B511F11A9E6C8500147676 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_STATIC_ANALYZER_MODE = deep;
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "fishhook" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
58B511ED1A9E6C8500147676 /* Debug */,
|
||||
58B511EE1A9E6C8500147676 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "fishhook" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
58B511F01A9E6C8500147676 /* Debug */,
|
||||
58B511F11A9E6C8500147676 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 58B511D31A9E6C8500147676 /* Project object */;
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341802B1AA91779003F314A /* libRCTNetwork.a */; };
|
||||
134A8A2A1AACED7A00945AAE /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 134A8A251AACED6A00945AAE /* libRCTGeolocation.a */; };
|
||||
134CB92A1C85A38800265FA6 /* RCTModuleInitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 134CB9291C85A38800265FA6 /* RCTModuleInitTests.m */; };
|
||||
13526A4A1F362F0E0008EF00 /* libfishhook.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13526A251F362EE70008EF00 /* libfishhook.a */; };
|
||||
138D6A181B53CD440074A87E /* RCTShadowViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 138D6A161B53CD440074A87E /* RCTShadowViewTests.m */; };
|
||||
138DEE241B9EDFB6007F4EA5 /* libRCTCameraRoll.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 138DEE091B9EDDDB007F4EA5 /* libRCTCameraRoll.a */; };
|
||||
1393D0381B68CD1300E1B601 /* RCTModuleMethodTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.mm */; };
|
||||
|
@ -154,6 +155,13 @@
|
|||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTGeolocation;
|
||||
};
|
||||
13526A241F362EE70008EF00 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 13526A1E1F362EE70008EF00 /* fishhook.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = fishhook;
|
||||
};
|
||||
138DEE081B9EDDDB007F4EA5 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 138DEE021B9EDDDB007F4EA5 /* RCTCameraRoll.xcodeproj */;
|
||||
|
@ -432,6 +440,7 @@
|
|||
134180261AA91779003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = "<group>"; };
|
||||
134CB9291C85A38800265FA6 /* RCTModuleInitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuleInitTests.m; sourceTree = "<group>"; };
|
||||
13526A1E1F362EE70008EF00 /* fishhook.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = fishhook.xcodeproj; path = ../Libraries/fishhook/fishhook.xcodeproj; sourceTree = "<group>"; };
|
||||
138D6A161B53CD440074A87E /* RCTShadowViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTShadowViewTests.m; sourceTree = "<group>"; };
|
||||
138DEE021B9EDDDB007F4EA5 /* RCTCameraRoll.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTCameraRoll.xcodeproj; path = ../Libraries/CameraRoll/RCTCameraRoll.xcodeproj; sourceTree = "<group>"; };
|
||||
1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTModuleMethodTests.mm; sourceTree = "<group>"; };
|
||||
|
@ -532,6 +541,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13526A4A1F362F0E0008EF00 /* libfishhook.a in Frameworks */,
|
||||
3D0E379D1F1CC77200DCAC9F /* libReact.a in Frameworks */,
|
||||
52C11BBB1EEACA7100C1A058 /* libRCTBlob.a in Frameworks */,
|
||||
2D66FF8F1ECA406D00F0A767 /* libART.a in Frameworks */,
|
||||
|
@ -605,6 +615,7 @@
|
|||
1316A21D1AA397F400C0188E /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13526A1E1F362EE70008EF00 /* fishhook.xcodeproj */,
|
||||
5281CA4B1EEAC9A700AC40CD /* RCTBlob.xcodeproj */,
|
||||
2D66FF5F1ECA405900F0A767 /* ART.xcodeproj */,
|
||||
14AADEFF1AC3DB95002390C9 /* React.xcodeproj */,
|
||||
|
@ -669,6 +680,14 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13526A1F1F362EE70008EF00 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13526A251F362EE70008EF00 /* libfishhook.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
138DEE031B9EDDDB007F4EA5 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1114,6 +1133,10 @@
|
|||
ProductGroup = 2D66FF601ECA405900F0A767 /* Products */;
|
||||
ProjectRef = 2D66FF5F1ECA405900F0A767 /* ART.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 13526A1F1F362EE70008EF00 /* Products */;
|
||||
ProjectRef = 13526A1E1F362EE70008EF00 /* fishhook.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 147CED471AB34F8C00DA3E4C /* Products */;
|
||||
ProjectRef = 14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */;
|
||||
|
@ -1217,6 +1240,13 @@
|
|||
remoteRef = 134A8A241AACED6A00945AAE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
13526A251F362EE70008EF00 /* libfishhook.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libfishhook.a;
|
||||
remoteRef = 13526A241F362EE70008EF00 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
138DEE091B9EDDDB007F4EA5 /* libRCTCameraRoll.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
13B6C1A31C34225900D3FAF5 /* RCTURLUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */; };
|
||||
13BCE84F1C9C209600DD7AAD /* RCTComponentPropsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BCE84E1C9C209600DD7AAD /* RCTComponentPropsTests.m */; };
|
||||
13BF5DE51F39F33200813C6E /* libfishhook.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13BF5DC61F39F31400813C6E /* libfishhook.a */; };
|
||||
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DB03471B5D2ED500C27245 /* RCTJSONTests.m */; };
|
||||
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */; };
|
||||
13E501F11D07A84A005F35D8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13E501A31D07A502005F35D8 /* libRCTAnimation.a */; };
|
||||
|
@ -230,6 +231,13 @@
|
|||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
13BF5DC51F39F31400813C6E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 13BF5DBF1F39F31300813C6E /* fishhook.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = fishhook;
|
||||
};
|
||||
13E501A21D07A502005F35D8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 13E5019C1D07A502005F35D8 /* RCTAnimation.xcodeproj */;
|
||||
|
@ -411,6 +419,7 @@
|
|||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNTester/main.m; sourceTree = "<group>"; };
|
||||
13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTURLUtilsTests.m; sourceTree = "<group>"; };
|
||||
13BCE84E1C9C209600DD7AAD /* RCTComponentPropsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTComponentPropsTests.m; sourceTree = "<group>"; };
|
||||
13BF5DBF1F39F31300813C6E /* fishhook.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = fishhook.xcodeproj; path = ../Libraries/fishhook/fishhook.xcodeproj; sourceTree = "<group>"; };
|
||||
13CC9D481AEED2B90020D1C2 /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
|
||||
13DB03471B5D2ED500C27245 /* RCTJSONTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJSONTests.m; sourceTree = "<group>"; };
|
||||
13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMethodArgumentTests.m; sourceTree = "<group>"; };
|
||||
|
@ -495,6 +504,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13BF5DE51F39F33200813C6E /* libfishhook.a in Frameworks */,
|
||||
3D4153631F27700D005B8EFE /* libART.a in Frameworks */,
|
||||
1380DCD41E70C44800E7C47D /* libReact.a in Frameworks */,
|
||||
147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */,
|
||||
|
@ -566,6 +576,7 @@
|
|||
1316A21D1AA397F400C0188E /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13BF5DBF1F39F31300813C6E /* fishhook.xcodeproj */,
|
||||
1380DC8B1E70C0DC00E7C47D /* ReactLegacy.xcodeproj */,
|
||||
3D41535A1F276FF9005B8EFE /* ART.xcodeproj */,
|
||||
14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */,
|
||||
|
@ -684,6 +695,14 @@
|
|||
name = RNTester;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13BF5DC01F39F31300813C6E /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13BF5DC61F39F31400813C6E /* libfishhook.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13E5019D1D07A502005F35D8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1069,6 +1088,10 @@
|
|||
ProductGroup = 3D41535B1F276FF9005B8EFE /* Products */;
|
||||
ProjectRef = 3D41535A1F276FF9005B8EFE /* ART.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 13BF5DC01F39F31300813C6E /* Products */;
|
||||
ProjectRef = 13BF5DBF1F39F31300813C6E /* fishhook.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 147CED471AB34F8C00DA3E4C /* Products */;
|
||||
ProjectRef = 14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */;
|
||||
|
@ -1249,6 +1272,13 @@
|
|||
remoteRef = 139FDED81B0651EA00C62182 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
13BF5DC61F39F31400813C6E /* libfishhook.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libfishhook.a;
|
||||
remoteRef = 13BF5DC51F39F31400813C6E /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
13E501A31D07A502005F35D8 /* libRCTAnimation.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
|
|
|
@ -199,9 +199,14 @@ Pod::Spec.new do |s|
|
|||
s.subspec "RCTWebSocket" do |ss|
|
||||
ss.dependency "React/Core"
|
||||
ss.dependency "React/RCTBlob"
|
||||
ss.dependency "React/fishhook"
|
||||
ss.source_files = "Libraries/WebSocket/*.{h,m}"
|
||||
end
|
||||
|
||||
s.subspec "fishhook" do |ss|
|
||||
ss.source_files = "Libraries/fishhook/*.{h,c}"
|
||||
end
|
||||
|
||||
s.subspec "RCTLinkingIOS" do |ss|
|
||||
ss.dependency "React/Core"
|
||||
ss.source_files = "Libraries/LinkingIOS/*.{h,m}"
|
||||
|
|
Loading…
Reference in New Issue