GithubHelp home page GithubHelp logo

Comments (7)

duduWang20 avatar duduWang20 commented on April 25, 2024 1

See codes in dyld:
const ImageLoader::Symbol* ImageLoaderMachOClassic::findShallowExportedSymbol(const char* name, const ImageLoader** foundIn) const
{
const struct macho_nlist* sym = NULL;
if ( fDynamicInfo->tocoff == 0 )
sym = binarySearch(name, fStrings, &fSymbolTable[fDynamicInfo->iextdefsym], fDynamicInfo->nextdefsym);
else
sym = binarySearchWithToc(name, fStrings, fSymbolTable, (dylib_table_of_contents*)&fLinkEditBase[fDynamicInfo->tocoff],
fDynamicInfo->ntoc, fDynamicInfo->nextdefsym);
if ( sym != NULL ) {
if ( foundIn != NULL )
foundIn = (ImageLoader)this;
return (const Symbol*)sym;
}
return NULL;
}

Look at this --->
binarySearch(name, fStrings, &fSymbolTable[fDynamicInfo->iextdefsym], fDynamicInfo->nextdefsym);
That's the point , the symbol to be replaced is dynamic !

So the address read directly from the symbol is a indirect address , a address value in the stub .
This happens every time you replacing a third party libs symbol .

from fishhook.

grp avatar grp commented on April 25, 2024

Interesting. I wonder if you could find out what the original symbol is β€” is it the binding stub for that symbol? You might be able to disassemble at the address in the debugger and see if it's clear. If nothing else, you should be able to tell there what library the symbol fishhook is returning comes from.

For now, you can probably work around this by just still using dlsym(), but good to track this.

from fishhook.

grp avatar grp commented on April 25, 2024

I'll also cc in @uroboro in case they have any ideas :)

from fishhook.

tirodkar avatar tirodkar commented on April 25, 2024

We initially thought it was the binding stub as well. Can you see any particular reason why other symbols are not affected by this?

from fishhook.

uroboro avatar uroboro commented on April 25, 2024

Inserting printf("fishhook;%s: %p\n", &symbol_name[1], indirect_symbol_bindings[i]); in fishhook.c at line 100 (that's just after the name check), I see only two symbols that correspond to GSEventPopRunLoopMode (open and close have a couple more). Both addresses are the same as opposed to open and close which in my tests have the first address different from the others.

Testing for this symbol rebinding, I've written the following code (that is compiled into two dylibs to test if multiple hooks are possible):

#import <dlfcn.h>
#import <stdio.h>

#import "fishhook.h"

#include <CoreFoundation/CFString.h>
void GSEventPopRunLoopMode(CFStringRef mode);
static void (*orig_GSEventPopRunLoopMode)(CFStringRef mode);
static void my_GSEventPopRunLoopMode(CFStringRef mode) {
        orig_GSEventPopRunLoopMode(mode);
}

__attribute__((constructor)) static void ctor(int argc, char **argv, char **envp) {
        printf("dlsym(\"GSEventPopRunLoopMode\"):%p\n", dlsym(RTLD_DEFAULT, "GSEventPopRunLoopMode"));
        printf("GSEventPopRunLoopMode:%p | my_GSEventPopRunLoopMode:%p\n", GSEventPopRunLoopMode, my_GSEventPopRunLoopMode);

        struct rebinding rebinds[1] = (struct rebinding[1]){{"GSEventPopRunLoopMode", my_GSEventPopRunLoopMode, (void **)&orig_GSEventPopRunLoopMode}};
        rebind_symbols(rebinds, sizeof(rebinds)/sizeof(struct rebinding));

        printf("GSEventPopRunLoopMode:%p | orig_GSEventPopRunLoopMode:%p\n", GSEventPopRunLoopMode, orig_GSEventPopRunLoopMode);
        printf("dlsym(\"GSEventPopRunLoopMode\"):%p\n", dlsym(RTLD_DEFAULT, "GSEventPopRunLoopMode"));
}

I get the following output

dlsym("GSEventPopRunLoopMode"):0x353f2425
GSEventPopRunLoopMode:0x353f2425 | my_GSEventPopRunLoopMode:0xae701
fishhook;GSEventPopRunLoopMode: 0x353f2425
GSEventPopRunLoopMode:0xae701 | orig_GSEventPopRunLoopMode:0x353f2425
dlsym("GSEventPopRunLoopMode"):0x353f2425
fishhook;GSEventPopRunLoopMode: 0x353f2425
dlsym("GSEventPopRunLoopMode"):0x353f2425
GSEventPopRunLoopMode:0xae701 | my_GSEventPopRunLoopMode:0xb1701
fishhook;GSEventPopRunLoopMode: 0xae701
fishhook;GSEventPopRunLoopMode: 0xae701
GSEventPopRunLoopMode:0xb1701 | orig_GSEventPopRunLoopMode:0xae701
dlsym("GSEventPopRunLoopMode"):0x353f2425

While dlsym finds the original symbol address, both orig_GSEventPopRunLoopMode contain the previous address so I'm unable to reproduce.

from fishhook.

tirodkar avatar tirodkar commented on April 25, 2024

I tried the code above, without the constructor, however we still seem to get the issue.
The way I tried was by using rebind_symbols directly in a viewDidLoad or in the +load :

#import "ViewController.h"
#import <dlfcn.h>
#import "fishhook.h"

void GSEventPopRunLoopMode(CFStringRef mode);
static void (*orig_GSEventPopRunLoopMode)(CFStringRef mode);
static void (*orig_dlsym_GSEventPopRunLoopMode)(CFStringRef mode);
static void rebound_GSEventPopRunLoopMode(CFStringRef mode) {
  orig_GSEventPopRunLoopMode(mode);
}

@implementation ViewController
- (void)viewDidLoad {
  [super viewDidLoad];

  orig_dlsym_GSEventPopRunLoopMode = dlsym(RTLD_DEFAULT, "GSEventPopRunLoopMode");
  struct rebinding rebinds[1] = (struct rebinding[1]){{"GSEventPopRunLoopMode",
    rebound_GSEventPopRunLoopMode,
    (void **)&orig_GSEventPopRunLoopMode}};
  rebind_symbols(rebinds, sizeof(rebinds)/sizeof(struct rebinding));

  printf("dlsym %p orig %p rebound %p\n", orig_dlsym_GSEventPopRunLoopMode, orig_GSEventPopRunLoopMode, rebound_GSEventPopRunLoopMode);
}
@end

and got :

dlsym 0x112ea2b88 orig 0x11003f748 rebound 0x10ec42010

Is there something that I'm doing wrong in the way I'm using fishhook here?

from fishhook.

tirodkar avatar tirodkar commented on April 25, 2024

Also, we are using the latest Xcode with a freshly created app with no changes whatsoever except the above ones.

from fishhook.

Related Issues (20)

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.