cant's dlopen after protect dylib under macOS 10.13
Posted: Fri Aug 17, 2018 10:19 am
Hi,
dlopen error message: initializer 0x768FAB does not point within __TEXT segment
It works fine under macOS 10.12 and before, How to fix this problem.
Thanks.
Apple's dylib loading process is open source
dyld-519.2.2(macOS 10.13 using this version) download url:
https://opensource.apple.com/tarballs/d ... 2.2.tar.gz
I found the error code from its open source code, at dyld-519.2.2\dyld3\MachOParser.cpp:2485.
diag.error("initializer 0x%0llX does not point within __TEXT segment", anInit);
dlopen error message: initializer 0x768FAB does not point within __TEXT segment
It works fine under macOS 10.12 and before, How to fix this problem.
Thanks.
Apple's dylib loading process is open source
dyld-519.2.2(macOS 10.13 using this version) download url:
https://opensource.apple.com/tarballs/d ... 2.2.tar.gz
I found the error code from its open source code, at dyld-519.2.2\dyld3\MachOParser.cpp:2485.
diag.error("initializer 0x%0llX does not point within __TEXT segment", anInit);
Code: Select all
void MachOParser::forEachInitializer(Diagnostics& diag, void (^callback)(uint32_t offset)) const
{
__block uint64_t textSegAddrStart = 0;
__block uint64_t textSegAddrEnd = 0;
forEachSegment(^(const char* segName, uint32_t fileOffset, uint32_t fileSize, uint64_t vmAddr, uint64_t vmSize, uint8_t protections, bool& stop) {
if ( strcmp(segName, "__TEXT") == 0 ) {
textSegAddrStart = vmAddr;
textSegAddrEnd = vmAddr + vmSize;
stop = true;
}
});
if ( textSegAddrStart == textSegAddrEnd ) {
diag.error("no __TEXT segment");
return;
}
// if dylib linked with -init linker option, that initializer is first
forEachLoadCommand(diag, ^(const load_command* cmd, bool& stop) {
if ( cmd->cmd == LC_ROUTINES ) {
const routines_command* routines = (routines_command*)cmd;
uint64_t dashInit = routines->init_address;
if ( (textSegAddrStart < dashInit) && (dashInit < textSegAddrEnd) )
callback((uint32_t)(dashInit - textSegAddrStart));
else
diag.error("-init does not point within __TEXT segment");
}
else if ( cmd->cmd == LC_ROUTINES_64 ) {
const routines_command_64* routines = (routines_command_64*)cmd;
uint64_t dashInit = routines->init_address;
if ( (textSegAddrStart < dashInit) && (dashInit < textSegAddrEnd) )
callback((uint32_t)(dashInit - textSegAddrStart));
else
diag.error("-init does not point within __TEXT segment");
}
});
// next any function pointers in mod-init section
bool p64 = is64();
unsigned pointerSize = p64 ? 8 : 4;
forEachSection(^(const char* segmentName, const char* sectionName, uint32_t flags, const void* content, size_t size, bool illegalSectionSize, bool& stop) {
if ( (flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS ) {
if ( (size % pointerSize) != 0 ) {
diag.error("initializer section %s/%s has bad size", segmentName, sectionName);
stop = true;
return;
}
if ( illegalSectionSize ) {
diag.error("initializer section %s/%s extends beyond the end of the segment", segmentName, sectionName);
stop = true;
return;
}
if ( ((long)content % pointerSize) != 0 ) {
diag.error("initializer section %s/%s is not pointer aligned", segmentName, sectionName);
stop = true;
return;
}
if ( p64 ) {
const uint64_t* initsStart = (uint64_t*)content;
const uint64_t* initsEnd = (uint64_t*)((uint8_t*)content + size);
for (const uint64_t* p=initsStart; p < initsEnd; ++p) {
uint64_t anInit = *p;
if ( (anInit <= textSegAddrStart) || (anInit > textSegAddrEnd) ) {
diag.error("initializer 0x%0llX does not point within __TEXT segment", anInit);// It's here!
stop = true;
break;
}
callback((uint32_t)(anInit - textSegAddrStart));
}
}
else {
const uint32_t* initsStart = (uint32_t*)content;
const uint32_t* initsEnd = (uint32_t*)((uint8_t*)content + size);
for (const uint32_t* p=initsStart; p < initsEnd; ++p) {
uint32_t anInit = *p;
if ( (anInit <= textSegAddrStart) || (anInit > textSegAddrEnd) ) {
diag.error("initializer 0x%0X does not point within __TEXT segment", anInit);
stop = true;
break;
}
callback(anInit - (uint32_t)textSegAddrStart);
}
}
}
});
}