Rewriting symbols in static iOS libraries

2019-02-19 19:10发布

I am working on an iOS app which links several static libraries. The challenge is, those linked libraries define same method names with different implementations. Oddly, I don't get any duplicate symbol definition errors; but, to no surprise, I end up with access to only one implementation of the method.

To be more clear, say I have libA and libB and they both define a global C method called func1()

When I link both libA and libB, and make a call to func1(), it resolves to either libA's or libB's implementation without any compilation warning. I, however, need to be able to access both libA's func1() and libB's func1() separately.

There's a similar SO post that explains how it can be done in C (via symbol renaming) but unfortunately, as I found out, objcopy tool doesn't work for ARM architecture (hence iPhone).

(I will submit it to the App Store, hence, dynamic linking is not an option)

1条回答
欢心
2楼-- · 2019-02-19 19:48

It appears that you are in luck - you can still rename symbols with the ARM binary format, it's just a bit more hacky than the objcopy method...

NOTE: This has only been tested minimally, and I would strongly advise you to make a backup of all libraries in question before trying this!

Also note that this only works for files not compiled with the C++ compiler! This will fail if the C++ compiler was used on these files.

  1. First, you will need a decent hex editor, for this example, I will be using Hex Fiend.
  2. Next, you will open up a copy of your of of your libraries, let's call it lib1-renamed.a, and do the following with it:

    • Find the name of the symbol you wish to re-name. It can be found using the nm tool, or, if you know the header name, you should be set.

    • Next, you will use hex fiend, and to a textual replace of the old name (in this case foo), and give it a new name (in this case, bar). These names must have the same length, or it will corrupt the binary's offsets!

      Note: if there is more than one function that contain's foo's name in it, you may have problems.

  3. Now, you must edit the headers of the library you changed, to use the new function name (bar) instead of the old one.

If you have done the three simple steps above properly, you should now be able to compile & link the two files successfully, and call both implementations.

If you are trying to do this with a universal binary (e.g. one the works on the simulator as well), you'd be best off using lipo to separate the two binaries, using objcopy on the i386/x64 binary, and then using my method on the ARM binary, and lipo it back together.

†: Simplicity is not guaranteed, nor is it covered by the Richard J. Ross III super warranty. For more information about the super warranty, call 1-800-FREE-WARRANTY now. That's 1-800-FREE-WARRANTY now!

查看更多
登录 后发表回答