Comments (5)
I ran into the same problem. After some poking around, I think I understand what's causing the infinite recursion:
When building an app with "Thread Sanitizer" or "Address Sanitizer", the compiler generates a special DLL named libclang_rt.tsan_iossim_dynamic.dylib
(tsan
-> Thread Sanitizer) or libclang_rt.asan_iossim_dynamic.dylib
(asan
-> Address Sanitizer). These libraries contain wrapper functions corresponding to system APIs (eg. wrap_getaddrinfo() for getaddrinfo()).
These special DLLs are "interposed" by the linker on top of the system libraries before the app's symbols are resolved. The pseudocode for wrap_getaddrinfo() looks like:
int wrap_getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res)
{
// Some instrumentation
// Forward to original function, the linker is smart enough to bind this symbol to the next DLL
return getaddrinfo(node, service, hints, res);
}
When Fishhook does it's rebinding, it does a massive search & replace of all references of getaddrinfo() to MAM_getaddrinfo(). Including the one in the specially generated DLL. Hence, leading to the infinite recursion.
Whatever the solution, it will involve breaking this cycle.
from fishhook.
A dirty hack that seems to work is:
static void _rebind_symbols_for_image(const struct mach_header *header,
intptr_t slide) {
uint32_t c = _dyld_image_count();
for (uint32_t i = 0; i < c; i++) {
// HACK: Get file name of the mach header
if (_dyld_get_image_header(i) == header) {
const char *path = _dyld_get_image_name(i);
const char *base = basename((char *)path);
// Only rebind libraries that are not the special generated sanitizer ones
if (strcmp(base, "libclang_rt.tsan_iossim_dynamic.dylib") &&
strcmp(base, "libclang_rt.asan_iossim_dynamic.dylib"))
{
_rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i));
}
}
}
}
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++) {
const char *path = _dyld_get_image_name(i);
const char *base = basename((char *)path);
// Only rebind libraries that are not the special generated sanitizer ones
if (strcmp(base, "libclang_rt.tsan_iossim_dynamic.dylib") &&
strcmp(base, "libclang_rt.asan_iossim_dynamic.dylib"))
{
_rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i));
}
}
}
return retval;
}
A better fix would be to better identify these special compiler generated DLLs instead of hardcoding the file names.
from fishhook.
@grp Is there any plan for adding any of the suggested fixes? It would be incredibly advantageous for users trying to debug with sanitizers and fishhook.
from fishhook.
A dirty hack that seems to work is:
static void _rebind_symbols_for_image(const struct mach_header *header, intptr_t slide) { uint32_t c = _dyld_image_count(); for (uint32_t i = 0; i < c; i++) { // HACK: Get file name of the mach header if (_dyld_get_image_header(i) == header) { const char *path = _dyld_get_image_name(i); const char *base = basename((char *)path); // Only rebind libraries that are not the special generated sanitizer ones if (strcmp(base, "libclang_rt.tsan_iossim_dynamic.dylib") && strcmp(base, "libclang_rt.asan_iossim_dynamic.dylib")) { _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); } } } }
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++) { const char *path = _dyld_get_image_name(i); const char *base = basename((char *)path); // Only rebind libraries that are not the special generated sanitizer ones if (strcmp(base, "libclang_rt.tsan_iossim_dynamic.dylib") && strcmp(base, "libclang_rt.asan_iossim_dynamic.dylib")) { _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); } } } return retval; }
A better fix would be to better identify these special compiler generated DLLs instead of hardcoding the file names.
This causes a compilation issue with basename
. Do you have a branch?
from fishhook.
@tirodkar For me, the following change worked:
Add
#include <libgen.h>
at the top section, then the following changes:
static void _rebind_symbols_for_image(const struct mach_header *header, intptr_t slide) {
uint32_t c = _dyld_image_count();
for (uint32_t i = 0; i < c; i++) {
// HACK: Get file name of the mach header
if (_dyld_get_image_header(i) == header) {
const char *path = _dyld_get_image_name(i);
const char *base = basename((char *)path);
// Only rebind libraries that are not the special generated sanitizer ones
if (strcmp(base, "libclang_rt.tsan_iossim_dynamic.dylib") &&
strcmp(base, "libclang_rt.asan_iossim_dynamic.dylib"))
{
rebind_symbols_for_image(_rebindings_head, _dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i));
}
return;
}
}
}
(There was a bug in @dlow-yahoo-inc ‘s code above, but easy to fix.)
from fishhook.
Related Issues (20)
- Hook should call the original method before HOT 1
- fishhook crash on iOS 13.0 beta HOT 1
- hook malloc_zone_malloc EXC_BAD_ACCESS (code=2, address=0x10ecb50cd) HOT 1
- Why is there no integration in my project, but running the program will automatically generate Github/fishhookDemo/...
- iOS13 Thread 1: EXC_BAD_ACCESS (code=2, address=0x1287b4390) HOT 3
- Thread 1: EXC_BAD_ACCESS HOT 5
- Why I don't bind CFReadStreamCreateForHTTPRequest, HOT 1
- build fail when __LP64__ is not defined HOT 2
- iOS 13Crash HOT 7
- Hook called in iOS simulator but not called on-device HOT 2
- How thread-safe is fishhook HOT 3
- Add support for installing via Swift Package Manager
- shimmed method doesn't get called from system libraries for iOS14 with arm64e device HOT 4
- iOS 14.5 crashed HOT 13
- iOS 15 crash HOT 8
- test
- Undefined symbol: _rebind_symbols in new commit 'aadc161ac3b80db07a9908851839a17ba63a9eb1' HOT 1
- Crashes with EXC_BAD_ACCESS on Apple Silicon mac when compiled as arm64e HOT 1
- How about adding a Package.swift? HOT 1
- hook C函数open crash HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fishhook.