GithubHelp home page GithubHelp logo

facebook / fishhook Goto Github PK

View Code? Open in Web Editor NEW
5.1K 230.0 956.0 40 KB

A library that enables dynamically rebinding symbols in Mach-O binaries running on iOS.

License: BSD 3-Clause "New" or "Revised" License

C 95.34% Ruby 4.66%

fishhook's Introduction

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 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).

Usage

Once you add fishhook.h/fishhook.c to your project, you can rebind symbols as follows:

#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 sections 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 nlists (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

fishhook's People

Contributors

compnerd avatar facebook-github-bot avatar grp avatar haolianfu avatar kastiglione avatar lucasxu0 avatar megcanicalkb avatar mringwal avatar ocrickard avatar rosen0510 avatar shonfrazier avatar swolchok avatar tditchek avatar tirodkar avatar uroboro avatar zrait avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fishhook's Issues

can fishhook hook c function in static framework?

A demo project have import a static framework, and the framework have a function named myF. I want to hook it and replace to hook_myFu, but it not work.
Is fishhook hook dylib function only? or I do something wrong?
Thank you!

code in simple ViewController

static void (*orig_myFunction)(void);
void hook_myFu(){
    NSLog(@" 123");
}
viewDidLoad {
    [super viewDidLoad];
    
    struct rebinding open_rebinding = {"myF", hook_myFu, (void *)&orig_myFunction};
    rebind_symbols((struct rebinding[1]){open_rebinding}, 1);
    myF();
}

About the Symbol table ,string table address

I do not understand why the linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff;

not

linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr;

fishhook crash on iOS 13.0 beta

The crash backtrace of crashed thread is list below.

Thread 2 Crashed:
0   Demo                        perform_rebinding_with_section (fishhook.c:105)
1   Demo                        perform_rebinding_with_section (fishhook.c:99)
2   Demo                        rebind_symbols_for_image (fishhook.c:163)
3   Demo                        rebind_symbols (fishhook.c:203)
...

can fishhook hook c function written by ourself?

myFunction is a c function written by me in my project, I want to hook it, but I tried this code failed.

int myFunction(int a){
    return a+1;
}

static int (*orig_myFunction)(int);

int hook_myFunction(int a){
    return a+2;
}

int main(int argc, char * argv[])
{
    @autoreleasepool {
        rebind_symbols((struct rebinding[1]){{"myFunction", hook_myFunction, (void *)&orig_myFunction}}, 1);
        printf("%d\n" , myFunction(1));
       return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

This means fishhook can only hook system api or how to hook c function written by ourself ?
Thanks.

Hooked function is called only once

First of all I want to say thank you for this library! It's really interesting thing.

Now, about a bug. Sorry in advance, if I use wrong terminology.

Short description

I've seen situation when hook function was called only once. 'Some magic' restores the original address of function.

Explanation is simple: 'fishkook' is patching a lazy binded symbol at the moment when original symbols was not yet resolved.
My hook calls original function and this restores original function. This call looks like this:

void* hook_bindBlobStr(void *StorageMapThis, int index, void* WTFStrText)
{
    printf("-----------------------hook_bindBlobStr\n");
    
    return orig_SQLiteStatement_bindBlobStr(StorageMapThis, index, WTFStrText);
}

Assembler code of original call (from debugger) is here:

0x1000097a6 <+70>:  movq   0xb4eb(%rip), %rdx        ; orig_SQLiteStatement_bindBlobStr
  0x1000097ad <+77>:  movq   -0x8(%rbp), %rdi
  0x1000097b1 <+81>:  movl   -0xc(%rbp), %esi
  0x1000097b4 <+84>:  movq   -0x18(%rbp), %rcx
  0x1000097b8 <+88>:  movq   %rdx, -0x30(%rbp)
  0x1000097bc <+92>:  movq   %rcx, %rdx
  0x1000097bf <+95>:  movq   -0x30(%rbp), %rcx
  0x1000097c3 <+99>:  movl   %eax, -0x34(%rbp)
->  0x1000097c6 <+102>: callq  *%rcx

As you can see, code calls original function from $rcx register. Lets take a look what is this:

(lldb) image lookup -a $rcx
      Address: WebKitLegacy[0x00000000000a00be] (WebKitLegacy.__TEXT.__stub_helper + 5906)
      Summary: 
(lldb)
(lldb) disa -s $rcx
    0x1060f50be: pushq  $0x7424                   ; imm = 0x7424 
    0x1060f50c3: jmp    0x1060f39ac
(lldb) 

This is stub for unresolved symbols. So, we will call stub_helper wich will resovle (actually restore) original address of function.

(lldb) image lookup -a 0x1060f39ac
      Address: WebKitLegacy[0x000000000009e9ac] (WebKitLegacy.__TEXT.__stub_helper + 0)
(lldb) 
(lldb) disa -s 0x1060f39ac
->  0x1060f39ac: leaq   0x4d655(%rip), %r11       ; (void *)0x000000010005b108: initialPoolContent + 49368
    0x1060f39b3: pushq  %r11
    0x1060f39b5: jmpq   *0x4d645(%rip)            ; (void *)0x0000000103da03fc: dyld_stub_binder
(lldb) 

Conclusion

When my hook function calls original function then this leads to restore (unhook) original addrress of symbol, and my hook will be never called again.

Environment

Simulator iPhone 6s Plus 10.0
Platform: x64
Hooked function: WebCore::SQLiteStatement::bindBlob() == _ZN7WebCore15SQLiteStatement8bindBlobEiRKN3WTF6StringE
Project works with UIWebView.

Question

Is this the bug or expected behavior?

iOS 14.5 crashed

0 perform_rebinding_with_section(fishhook.c:137)
1 perform_rebinding_with_section(fishhook.c:131)
2 rebind_symbols_for_image(fishhook.c:208)
3 rebind_symbols(fishhook.c:252)

iOS 14.5 crashed when hook GCD.

iOS 15 crash

There's Crash on iOS 15。iPhone7

Exception Type: EXC_BAD_ACCESS (SIGKILL)
Exception Subtype: KERN_PROTECTION_FAILURE at 0x00000001d4424da8
VM Region Info: 0x1d4424da8 is in 0x1d44249b8-0x1d4450278; bytes after start: 1008 bytes before end: 177359
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
__DATA_CONST 1d43fc5c0-1d44249b8 [ 161K] r--/rw- SM=COW ...k/MediaRemote
---> __DATA_CONST 1d44249b8-1d4450278 [ 174K] r--/rw- SM=COW ...ork/CoreUtils
__DATA_CONST 1d4450278-1d4453430 [ 12K] r--/rw- SM=COW .../FamilyCircle

Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d
Termination Description: SPRINGBOARD, <RBSTerminateContext| domain:10 code:0x8BADF00D explanation:scene-create watchdog transgression: application<ctrip.com>:444 exhausted real (wall clock) time allowance of 19.91 seconds | ProcessVisibility: Foreground | ProcessState: Running | WatchdogEvent: scene-create | WatchdogVisibility: Foreground | WatchdogCPUStatistics: ( | "Elapsed total CPU time (seconds): 19.580 (user 14.590, system 4.990), 16% CPU", | "Elapsed application CPU time (seconds): 0.034, 0% CPU" | ) reportType:CrashLog maxTerminationResistance:Interactive>
Triggered by Thread: 0
perform_rebinding_with_section + 7177404 (fishhook.c:149)
perform_rebinding_with_section + 7177312 (fishhook.c:143)
rebind_symbols_for_image + 7176556 (fishhook.c:222)

hook not successfully when symbols is lazy bindings

I use it in mac os x, as dyld_interposing does not works sometimes.
I used it the hook a system api(LSOpenCFURLRef), but this symbol is lazy binding.
And I cannot hook it successfully.
Any idea?
Thanks!

The returned original pointer does not point to the correct symbol.

Hello,

We are using rebind_symbols with GSEventPopRunLoopMode, for which we require the original symbol pointer. With commit 8dbd09b , we passed in a pointer to the rebinding struct to get the original symbol as suggested. However, the symbol-value returned for GSEventPopRunLoopMode is different from that provided by dlsym using the method suggested in the README before the change - _dlsym(RTLD_DEFAULT, “SYMBOL”)_ and also leads to the original implementation never being called.

As of now, this was the only symbol we saw this issue with. It would be great if we could find out why the original pointer value is different, since this means that we have to revert to using dlsym.

Can't hook specific functions

Attempting to hook AudioServicesPlaySystemSound on iOS 9.3 and don't seem to be able to. Anyone else run into this issue?

Thread 1: EXC_BAD_ACCESS

*(cur->rebindings[j].replaced) = indirect_symbol_bindings[i];
FishHook will crash in this function cwsa_perform_rebinding_with_section.
Do someone know solution of this issue, please tell me , thank you.

why can't hook socket function?

I hook the socket function in libsystem_network.dylib by fishhook, It's ok in simulator but not work in iphone.
I debug the program, found the function address is socket function address, fishhook doesn't work
0x1903d88bc <+64>: bl 0x190364fec ; socket
0x1903d88c0 <+68>: mov x19, x0

How thread-safe is fishhook

I want to hook pthread_create in main, but I'm curious if there can be any tearing or otherwise bugs due to thread safety. I don't mind if it's undefined whether concurrent calls use the old or the new function, I just want to be sure that there won't be any peripheral bugs.

Can't hook objc_exception_throw()

Attempting to hook objc_exception_throw() on my iPhone6S Plus(iOS 9.3.5) and don't seem to be able to. But it worked on the iOS 9.3 simulator.
Anyone else run into this issue?

Crash when hook fonction `object_setClass`

What crash

When I hook fonction object_setClass, then call object_setClass, it works. but when I call [NSString stringWithFormat:@"%@", @""];, It crash.

Demo code

#import <UIKit/UIKit.h>
#import "fishhook.h"
#import <objc/runtime.h>

Class _Nullable
(*orig_object_setClass)(id _Nullable obj, Class _Nonnull cls);

Class _Nullable
my_object_setClass(id _Nullable obj, Class _Nonnull cls)
{
    return orig_object_setClass(obj, cls);
}


int main(int argc, char * argv[]) {
    @autoreleasepool {
        rebind_symbols((struct rebinding[]){
            {"object_setClass", my_object_setClass, (void *)&orig_object_setClass}
        }, 1);
        
        object_setClass(@"", NSObject.class);
        
        [NSString stringWithFormat:@"%@", @""];
        
        return 0;
    }
}

hook stat

I'll use fishhook hook stat to get the call all the time thank you
2018-09-05 2 24 26
2018-09-05 2 25 17

Support two-level namespace

After reviewing #31, it seems a piece of missing functionality in fishhook is support for mach-o two-level namespaces. When rebinding a symbol, the logic should check if a specific library has been recorded for that symbol, and if the symbol is bound to a library, then never rebind symbols that happen to be the same name but from other libraries. See <mach-o/nlist.h>.

iOS 13Crash

0 perform_rebinding_with_section (fishhook.c:105)
1 perform_rebinding_with_section (fishhook.c:99)
2 rebind_symbols_for_image (fishhook.c:172)
3 _rebind_symbols_for_image (fishhook.c:180)

device malloc_zone_malloc hook

I am trying to hook “malloc_zone_malloc”,it works well with iOS Simulator ,but useless on an
iOS device。what else should i do?

void my_malloc_zone_malloc(malloc_zone_t *zone, size_t size){
printf("Calling real malloc( %zu)\n", size);

 return orig_malloc_zone_malloc(zone, size);

}

void my_malloc_zone_free(malloc_zone_t *zone, void *ptr){
printf("Calling real free( %zu)\n",malloc_size(ptr));

return orig_malloc_zone_free(zone, ptr);

}

int main(int argc, char * argv[])
{
@autoreleasepool {
rebind_symbols((struct rebinding[2]){{"malloc_zone_malloc", my_malloc_zone_malloc,(void*)&orig_malloc_zone_malloc}, {"malloc_zone_free", my_malloc_zone_free,(void*)&orig_malloc_zone_free}}, 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]));  
}  

}

hook malloc_zone_malloc EXC_BAD_ACCESS (code=2, address=0x10ecb50cd)

I try to hook malloc_zone_malloc, but I get crash.Why?

void *my_malloc_zone_malloc(malloc_zone_t *zone, size_t size){
printf("Calling real malloc( %zu)\n", size);
return malloc_zone_malloc(zone, size);
}

void my_malloc_zone_free(malloc_zone_t *zone, void *ptr){
printf("Calling real free( %zu)\n",malloc_size(ptr));

return malloc_zone_free(zone, ptr);

}

rebind_symbols((struct rebinding[2]){{"malloc_zone_malloc", my_malloc_zone_malloc,(void*)&malloc_zone_malloc}, {"malloc_zone_free", my_malloc_zone_free,(void*)&malloc_zone_free}}, 2);

Crash on iPhone5/4s simulator caused by recursive function call

Recently, we are using fishhook to change some low-level function in linux/socket, but we met a quite strange bug. Use fishhook to rebind connect symbol to our new one leads to recursive call and ultimately crash on iPhone5/4s simulator specifically.

The code works totally fine on iPhone5s/6/6s and etc simulator and iPhone4s/iPhone5 device.

dae70ac2-6f22-4fd5-8c42-c9d5542d133b

Here is some info about my current MacBook and version of fishhook

  • OS X EI Captain 10.11.6
  • MacBook Pro (Retina 13-inch Early 2015)
  • Processor 2.7 GHz Intel Core i5
  • Memory 8 GB 1867 MHz DDR3
  • fishhook 0.2

You can find the ViewController.m file here which contains all the code in this project.

Plus, I don't know the reason for the problem. And I'm not the code are 100 percent safe on a real iOS device. Here are the thing and some idea I have tried to figure out this problem.

  1. I make a breakpoint to print all the symbols in all image files, and there of several dozens of connect symbol. fishhook changes implementation of each connect method
  2. This kind of crash only happens when hooks symbols which located in different images multiple times. And function like SSLWrite doesn't lead to this problem.

Thanks for your reading.

fishhook with dyld 3.0

https://developer.apple.com/videos/play/wwdc2017/413/

Apple is revamping its dynamic linker. One of the major changes is that they will be doing full symbol resolution at launch time, rather than using the on demand resolution using trampolines. Is this a risk for fishhook’s operation?

Right now, they new dynamic linker is not enabled for user applications. This is expected to happen somewhen soon.

How should I use fishhook in replacement of this MSHook code?

uint64_t getRealOffset(uint64_t offset){
return _dyld_get_image_vmaddr_slide(0)+offset;
}

void (update_begin)(void * this);
void _update_begin(void * this) {
update_begin(this);
}
MSHookFunction(((void
)getRealOffset(0x10026A9AC)),(void ) _update_begin, (void*)&update_begin);

Build Error in Objective-c++

Env: xcode 10.1
c++ setting:
image

I added the test code to main.mm file, and builded failed. Error as follow:
"Cannot initialize a member subobject of type 'void *' with an lvalue of type 'int (int)'"
image

How to hook socket or connect

Use fishhook in the simulator hook to connect and socket, but not in the iphone hook.

`static int (*orig_socket)(int, int, int);
static int (*orig_connect)(int, const struct sockaddr *, socklen_t);
int my_socket(int domain, int type, int protocol)
{
printf("this is my socket!");
return orig_socket(domain,type,protocol);;
}
int my_connect(int socket, const struct sockaddr * addr, socklen_t len)
{
printf("this is my connect");
return orig_connect(socket,addr,len);
}
int main(int argc, char * argv[])
{
@autoreleasepool {
rebind_symbols((struct rebinding[2]){{"connect", my_connect, (void *)&orig_connect},{"socket", my_socket, (void *)&orig_socket}}, 2);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

`

iOS13 Thread 1: EXC_BAD_ACCESS (code=2, address=0x1287b4390)

CIFilter * qrFilter = [CIFilter QRCodeGenerator]; Thread 1: EXC_BAD_ACCESS (code=2, address=0x1287b4390)

rebind_symbols_for_image(_rebindings_head, header, slide); Thread 1: EXC_BAD_ACCESS (code=2, address=0x1287b4390)

rcd_perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); Thread 1: EXC_BAD_ACCESS (code=2, address=0x1287b4390)

I can not hook gcd functions

I try to hook dispatch_async function,but it do not work。
here is the code sample:
int result = rebind_symbols(struct rebinding[1]){{"dispatch_async",xcsandbox_dispatch_async}},1);
//result is 0 (no error)
then i call dispatch_async(dispatch_get_global_queue(0,0),{
//do some thing;
});

it call system default dispatch_async function, not my xcsandbox_dispatch_async.
i do not know why,and how to fix this. if you know,please reply me.

thx

ASAP

fishhook would call the new function once when I just hook the old one?

#import "fishhook.h"

static void (*orig_NSLog)(NSString *format, ...);

void my_NSLog(NSString *format, ...) {
    va_list args;
    va_start(args, format);
    NSLogv(format, args);
    va_end(args);
    orig_NSLog(@"---do record log things---", nil);
}


int main(int argc, char * argv[]) {
    @autoreleasepool {
        
        struct rebinding reb_logs[1] = {
            {
                "NSLog",
                my_NSLog,
                (void *)&orig_NSLog
            }
        };
        rebind_symbols(reb_logs, 1);

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
// console output:
2017-08-09 19:09:33.015 TestA[35807:551088] ---do record log things---

I use fishhook to hook the NSLog function, just use 'rebind_symbols', no any NSLog calling.
but my_NSLog been called once, and console output the log.
I wonder why fishhook do calling things when hook?
or, iOS system called NSLog ?

hook not successful in iOS9

It worked in iOS8.x and all lower versions but not in iOS9, I found the reason is that Apple add a new segname of section called "__DATA_CONST" in iOS9, function "rebind_symbols_for_image" just check if segname is "__DATA" ("(strcmp(cur_seg_cmd->segname, SEG_DATA) != 0)"), so when do enumurate to "__DATA_CONST" section, code doesn't work.

Why I don't bind CFReadStreamCreateForHTTPRequest,

@implementation UIViewController (Hook1)
+(void)load {
    struct rebinding _request_binding = { "CFReadStreamCreateForHTTPRequest", wt_CFReadStreamCreateForHTTPRequest, (void *)&original_CFReadStreamCreateForHTTPRequest};

    struct rebinding rebs[]={_request_binding};
    rebind_symbols(rebs, 1);
}

static CFReadStreamRef
wt_CFReadStreamCreateForHTTPRequest(CFAllocatorRef __nullable alloc, CFHTTPMessageRef request);
CFReadStreamRef wt_CFReadStreamCreateForHTTPRequest(CFAllocatorRef __nullable alloc, CFHTTPMessageRef request) {
    
    NSURL *url = (__bridge NSURL *)CFHTTPMessageCopyRequestURL(request);
    NSString *method = (__bridge NSString *)CFHTTPMessageCopyRequestMethod(request);
    
    CFReadStreamRef readStream = original_CFReadStreamCreateForHTTPRequest(alloc, request);
    
    return readStream;
}

static CFReadStreamRef (*original_CFReadStreamCreateForHTTPRequest)(CFAllocatorRef, CFHTTPMessageRef);
@end

This's my code, bind CFNetwork CFReadStreamCreateForHttpRequest function, I want monitoring network status, but, i don't recive result in wt_CFReadStreamCreateForHTTPRequest function, please help me, thanks

Add support for installing via Swift Package Manager

It would be great to add support for installing fishhook via Swift Package Manager. SPM has support for C language targets, although it recommends a specific file structure. If you'd like to keep the file structure unchanged, I think it should be possible to define things manually. I don't have much experience with SPM, so I'd need to do some more research as to exactly what options are available.

For background, AccessibilitySnapshot uses fishhook as a dependency. In order to add SPM support there, we need support in fishhook first.

Let me know if you're open to this. Thanks!

An error line in example code in readme.md

Hi,
I found there is an error line in the example code, that "void *" should be "void **",
rebind_symbols((struct rebinding[2]){{"close", my_close, (void *)&orig_close}, {"open", my_open, (void *)&orig_open}}, 2);

-->
rebind_symbols((struct rebinding[2]){{"close", my_close, (void **)&orig_close}, {"open", my_open, (void **)&orig_open}}, 2);

hope it would be useful for new comer.

linkedit_base always equal mach_header。

// Find base symbol/string table addresses
uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff;

the value of linkedit_base is always equal mach_header,why not substitute mach_header for linkedit_base?

hook symbol "connect" not successfully

I use it in ipad(iOS 9.2), but I can not hook it successfully.
I've written the following code :

rebind_symbols((struct rebinding[1]){
   { "connect", (void *)my_connect, (void *)&ori_connect},
}, 1);

I try to set breakpoint "connect" after rebinding. I get the stack:

frame #0: 0x21623adc libsystem_kernel.dylib`__connect

frame #1: 0x216747d4 libsystem_network.dylib`netcore_create_control_socket + 228

frame #2: 0x21661b1e libsystem_network.dylib`get_host_counts + 62

frame #3: 0x2168813a libsystem_network.dylib`tcp_connection_destination_create + 186

frame #4: 0x21666000 libsystem_network.dylib`tcp_connection_destination_add + 52

frame #5: 0x21665fc4 libsystem_network.dylib`__tcp_connection_start_host_block_invoke + 96

frame #6: 0x216828ca libsystem_network.dylib`tcp_connection_host_resolve_result + 1450

frame #7: 0x215f1a2e libsystem_dnssd.dylib`handle_addrinfo_response + 322

frame #8: 0x215f04b8 libsystem_dnssd.dylib`DNSServiceProcessResult + 528

frame #9: 0x0049d66e libdispatch.dylib`_dispatch_source_latch_and_call + 2246

frame #10: 0x0048bc24 libdispatch.dylib`_dispatch_source_invoke + 712

frame #11: 0x00494050 libdispatch.dylib`_dispatch_queue_drain + 644

frame #12: 0x0048cef8 libdispatch.dylib`_dispatch_queue_invoke + 284

frame #13: 0x00495a8c libdispatch.dylib`_dispatch_root_queue_drain + 420

frame #14: 0x004958e6 libdispatch.dylib`_dispatch_worker_thread3 + 102

frame #15: 0x216c7b28 libsystem_pthread.dylib`_pthread_wqthread + 1024

frame #16: 0x216c7718 libsystem_pthread.dylib`start_wqthread + 8

netcore_create_control_socket assembly :

0x216747ca <+218>: mov r0, r4

0x216747cc <+220>: str.w r10, [sp, #0x20]

0x216747d0 <+224>: blx 0x21623adc ; __connect

0x216747d4 <+228>: cmp r0, #0x0

0x216747d6 <+230>: beq 0x21674806 ; <+278>

0x216747d8 <+232>: mov r0, r4

0x216747da <+234>: blx 0x2169b1ec ; symbol stub for: __destroy_helper_block_73

Why libsystem_network.dylib call connect use blx + direct address? Thanks

Hook should call the original method before

static int (*orig_strlen)(const char *__s);
int my_strlen(const char *__s) {
    printf("===\n");
    return orig_strlen(__s);
} 

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        strlen("s"); // 1
        struct rebinding strlen_rebinding = { "strlen", my_strlen,
            (void *)&orig_strlen };
        
        rebind_symbols((struct rebinding[1]){ strlen_rebinding }, 1);
        
        char *str = "HelloWorld";
        
        strlen(str);
}

hello :
I think the old method (strlen("s")) should be called before calling the rebind_symbols method to ensure that lazy bind is already the real address, right?

Create a new release for the API change in Commit 8dbd09b and make the Podspec point to it.

The merging of PR #18 led to a break in the API. We have made the required changes, however the podspec still points to version 0.1. We use Fishhook rigorously for testing and this change breaks all our pods dependencies. Could we please create a new release for this change and have it added to the podspec (or just have the podspec pointing to head)?

Also, it would be great if we regularly update the podspec with any new releases.

Hook called in iOS simulator but not called on-device

I'm trying to hook os_log_shim_enabled, a private function in CoreFoundation that changes how NSLog() behaves. Here's my code:

static BOOL FLEXDidHookNSLog = NO;
BOOL (*orig_os_log_shim_enabled)() = nil;
BOOL my_os_log_shim_enabled() {
    return NO;
}

@implementation FLEXSystemLogViewController

+ (void)load {
    FLEXDidHookNSLog = rebind_symbols((struct rebinding[1]) {
        "os_log_shim_enabled",
        (void *)my_os_log_shim_enabled,
        (void **)&orig_os_log_shim_enabled
    }, 1) == 0;
}

...

As the title says, it works in the simulator, but has no effect on-device. I came across this issue, but I don't really understand what might be going wrong. rebind_symbols returns 0 in both cases, and stepping through the code running on-device I can see that fishhook does indeed find the symbol and does replace it here from within __la_symbol_ptr:

static void perform_rebinding_with_section(...) {
    ...
--> indirect_symbol_bindings[i] = cur->rebindings[j].replacement;
    ...
}

When I set a breakpoint for the original function, I can see it's being called instead of my replacement. Here's a screenshot of the debugger:

Screenshot 2020-02-19 at 1 37 20 PM

Is _CFLogvEx3 just not using the lazy binding in this case? Does that mean I'll need to use another hooking library that uses trampolines?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.