Symbol stripping of Swift classes and property names

I have a Swift framework which I'm building via Xcode 13.4.1 for distribution to third parties (BUILD_LIBRARY_FOR_DISTRIBUTION is enabled).

I am trying to protect the intellectual property and security of my framework by ensuring all internal/debug symbols are stripped prior to distribution (i.e. maximum stripping).

Therefore, after I build the framework, I apply the following command:

strip -u -r -no_code_signature_warning MyFramework.framework/MyFramework

I have found that this strips most of the symbols, however I have also noticed that it does not strip the name and properties of any of my Swift classes, they are still visible in the binary if I use a disassembler (e.g. Hopper) then I can see the class name and property names:

For example, if I have the following code:

class MySecretClass {
   private let mySecretVar: String
}

Then I can see in the binary a reference something like:

           objc_ivar_offset__TtC6MyFramework14MySecretClass_mySecretVar:

And Hopper will even partially re-construct the class definition for me:

00000000000de27b     db 0x00 ; '.'
               ; class MyFramework.MySecretClass {
               ;   let mySecretVar: Swift.String
               ; }

Despite the reference to objc_ivar_offset in the binary, these properties are not @objc and it's not clear to me why the compiler is including the names of the class or properties.

Things I have tried:

  • Making the properties private
  • Making the class final
  • Marking the properties @nonobjc

None of these work - the binary still contains the class & property names.

This definitely seems ObjC-related for all the above reasons, plus I have noticed that the binary doesn't contain any names for my structs, but I can't seem to figure out how to either prevent the compiler from emitting the names, or configure the strip command to strip the symbols after release.

I know there are third-party tools which can obfuscate variable names but I was hoping to achieve adequate symbol stripping without resorting to third-party tools.

Is there anyone with a lower-level understanding of all this able to help? Thanks!

Replies

There are limits to how much metadata you can strip from Swift code. There is currently a Swift Evolution proposal in review to give you more options in this space. Right now, however, you only have the heavy hammer of the Reflection Metadata Level (SWIFT_REFLECTION_METADATA_LEVEL) build setting.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • Thanks, applying SWIFT_REFLECTION_METADATA_LEVEL = none helped to some degree, in that I can no longer see the class definition in Hopper (it just shows as empty), however the class name and property names (i.e.  objc_ivar_offset__....) are still visible in the binary. Is there any way to strip these names out entirely?

Add a Comment