4 Replies
      Latest reply on Nov 3, 2019 7:57 PM by Vannes
      Vannes Level 1 Level 1 (0 points)

        Hi there,

        I am trying to notarize my macOS app. My app is embedded with some licensed libraries.

        I studied document about how to notarize an app and followed steps, my app can be uploaded to Apple notarize services and exported to use, but when I run my app it crashed. Under Xcode it shows

         

        dyld: Library not loaded: libMotionEngine-bundle.3.dylib
        Referenced from: /Users/kensington/Library/Developer/Xcode/DerivedData/KensingtonWorks-dekfhdrucwmhfogmapgkwzsawyfm/Build/Products/Debug/KensingtonWorks for Ultimate Presenter.app/Contents/MacOS/KensingtonWorks for Ultimate Presenter
         Reason: image not found
        
        

        I've tried several way to run my app successfully including make libraries Required/Optional under Linked Frameworks and Libraries and add my libraries to Embedded Binaries, unfortunately all failed. List conditions and environments below:

         

        Xcode version: 10.3 / 11

        macOS: 10.14.5/10.14.6

        Libraries signed: No

        Runtime Hardened chosen: Allow DYLD Environment Variables & Disable Library Validation

        Below is piece of my library information:

         

        Load command 8
          cmd LC_VERSION_MIN_MACOSX
          cmdsize 16
          version 10.11
          sdk 10.11
        Load command 9
          cmd LC_SOURCE_VERSION
          cmdsize 16
          version 0.0
        Load command 10
          cmd LC_LOAD_DYLIB
          cmdsize 56
          name libMotionEngine-core.3.dylib (offset 24)
          time stamp 2 Thu Jan 1 08:00:02 1970
          current version 3.1.4
        compatibility version 3.0.0
        Load command 11
          cmd LC_LOAD_DYLIB
          cmdsize 48
          name /usr/lib/libc++.1.dylib (offset 24)
          time stamp 2 Thu Jan 1 08:00:02 1970
          current version 120.1.0
        compatibility version 1.0.0
        Load command 12
          cmd LC_LOAD_DYLIB
          cmdsize 56
          name /usr/lib/libSystem.B.dylib (offset 24)
          time stamp 2 Thu Jan 1 08:00:02 1970
          current version 1226.10.1
        compatibility version 1.0.0
        Load command 13
          cmd LC_FUNCTION_STARTS
          cmdsize 16
          dataoff 54872
         datasize 320
        Load command 14
          cmd LC_DATA_IN_CODE
          cmdsize 16
          dataoff 55192
         datasize 0
        Load command 15
          cmd LC_CODE_SIGNATURE
          cmdsize 16
          dataoff 84352
         datasize 19696
        
        

        Appreciate any suggestion/opinions!

        • Re: Library not loaded after Runtime Hardened enabled
          eskimo Apple Staff Apple Staff (12,975 points)

          My app is embedded with some licensed libraries.

          So, just to be clear, you got this library from a vendor and you’re shipping it to users within your app, right?  If so:

          • Where have you placed the library?  The usual location for such things is Contents/Frameworks/.

          • Did you re-sign it using your Developer ID?  That’s pretty much required, and it makes sense when you step back and think about it.  You’re shipping this code to customers, so you take on the responsibility for how it behaves, so you sign it as your code.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: Library not loaded after Runtime Hardened enabled
              Vannes Level 1 Level 1 (0 points)
              • Where have you placed the library?  The usual location for such things is Contents/Frameworks/.

              -->I'm afraid of this, the libraries are dependencies with each other, they are located in /usr/local/bin, I don't have source code and I find they should be inside here because I got these information by otool -L:

              libhidapi.0.dylib:
                /usr/local/lib/libhidapi.0.dylib (compatibility version 1.0.0, current version 1.0.0)
                /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
                /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1349.8.0)
                /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)

              I tried change the path by using install_name_tool but I failed. My install package project installs these libraries in /usr/local/lib originally.

               

              • Did you re-sign it using your Developer ID?  That’s pretty much required, and it makes sense when you step back and think about it.  You’re shipping this code to customers, so you take on the responsibility for how it behaves, so you sign it as your code.

              -->Yes I re-signed the library using my company's Developer ID application.

               

              And there's update here...

              I manually signed these libraries by codesign with developer ID, then I replace the original with these new signed files, there's no more "library not loaded" message shows, it seems running( but crashes on IOHIDManager api that's never happens on 10.14), but somehow when I move all files(application+libraries) to 10.14.6, the message "library not loaded" still appears...

               

              So I got 2 difficult questions:

              1. The "Library not loaded" seems resolved on 10.15 but still appears on 10.14.6

              2. The IOHIDManager api will run fail on 10.15.

               

              Thanks Quinn's time and helpful anwsers!

               

              --Another discovery--

              I found the built binary behavior are not the same between debug and deploy version. Here's a crash report comparison:

              https://imgur.com/dF1qU5Z

              I am wondering why? How do I make the environment the same? Thanks a lot!

                • Re: Library not loaded after Runtime Hardened enabled
                  eskimo Apple Staff Apple Staff (12,975 points)

                  On the library front, you wrote:

                  they are located in /usr/local/bin, I don't have source code

                  I recommend that you raise this issue with the library’s vendor.  Installing libraries globally like this is problematic on a modern Mac because of library validation.  The library has to be signed by someone, either you or the vendor:

                  • If you sign it, only your apps will be able to load it, in which case you don’t want it installed in /usr/local/bin.  Ideally you’d move it to Contents/Frameworks/ within your app but, even if you don’t do that, you need to put it in /usr/local/MyProductName/bin so that you don’t conflict with other folks using the same library.

                  • If the vendor signs it, apps with library validation enabled won’t be able to load it.

                  Unless the library is doing something particularly wacky, it should be feasible to move it to Contents/Frameworks/.  You may be able to do that yourself using install_name_tool but I think you’d be better off working with the vendor to come up with an authorised solution.


                  With regards your HID problem, it’s likely you’re hitting one of the new restrictions around input monitoring.  WWDC 2019 Session 701 Advances in macOS Security has the details.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"

                    • Re: Library not loaded after Runtime Hardened enabled
                      Vannes Level 1 Level 1 (0 points)

                      Thanks Quinn, finally I did it. Yes the key point is on how we handle these libraries...

                      Sort all my working out below:
                      1. The libraries all must be only embedded in Frameworks. So we should make  LC_ID_DYLIB and LC_ID_DYLIB correct. A success Mach-O path content should be like this:

                      @executable_path/../Frameworks/<Library name itself>
                        @loader_path/<Refer Library name> (compatibility version 3.0.0, current version 3.1.4)
                      
                      
                      
                      

                      The first line is the library itself execute path, and the second line is the path of other library referred by this library.

                      2. In the project setting, all library should choose “Embed and sign”. The library itself doesn’t need to be signed manually first. All of them will be auto signed when exporting to notarize service.

                       

                      That’s it, due to some reason we have limited resource to be authorized from 3rd party again, but thanks Apple we still can use these libraries

                      Thank’s Quinn’s strong support!!