Page 1 of 1

cant's dlopen after protect dylib under macOS 10.13

Posted: Fri Aug 17, 2018 10:19 am
by flowercodec
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);

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);
                }
            }
        }
    });
}

Re: cant's dlopen after protect dylib under macOS 10.13

Posted: Mon Aug 20, 2018 4:05 am
by Admin
It seems Apple added new crap in the latest dyld :))

Re: cant's dlopen after protect dylib under macOS 10.13

Posted: Tue Aug 21, 2018 3:29 am
by flowercodec
Hi Admin,
after protect dylib, I find sectname __mod_init_func, segname __TEXT1.(not found before protect)
I think this should be the reason why dlopen gave an error.
Is it possible to manually call some initialization through the VMP SDK (a new feature).
Then we can bypass "the new crap".
Or is there any other way to solve this problem?

Thanks.

Code: Select all

otool -l my.dylib
Section
  sectname __mod_init_func
   segname __TEXT1
      addr 0x000000000078a850
      size 0x00000000000002f0
    offset 7895120
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000009
 reserved1 0
 reserved2 0

Re: cant's dlopen after protect dylib under macOS 10.13

Posted: Tue Sep 04, 2018 8:03 am
by Admin
Please try the 1013 build.

Re: cant's dlopen after protect dylib under macOS 10.13

Posted: Wed Sep 05, 2018 1:21 am
by flowercodec
Admin wrote:Please try the 1013 build.
Hi Admin,

I instal 1013 build version. it seem to be another problem.
dlopen error message: REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB pointer rebase is in executable segment

I search dylib source code again, found the error code. at dyld-519.2.2\dyld3\MachOParser.cpp:2612, funcation name is "invalidRebaseState"
diag.error("%s pointer rebase is in executable segment", opcodeName);
opcodeName is "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB"

Thanks.

Re: cant's dlopen after protect dylib under macOS 10.13

Posted: Thu Sep 06, 2018 3:47 am
by flowercodec
Admin wrote:Please try the 1013 build.
I want to send the binary to you, is it sent to info@vmpsoft.com ?

Re: cant's dlopen after protect dylib under macOS 10.13

Posted: Thu Nov 08, 2018 5:29 pm
by Admin
Please try the 1028 build.

Re: cant's dlopen after protect dylib under macOS 10.13

Posted: Sat Nov 10, 2018 7:42 am
by flowercodec
Admin wrote:Please try the 1028 build.
1028 build works fine.
I also test it under macOS 10.14.1, works fine too!
Thanks.

Is 1028 build is a stable version? So I can use it for my release application.

Re: cant's dlopen after protect dylib under macOS 10.13

Posted: Sun Nov 25, 2018 3:09 pm
by Admin
Yes, it's stable.