There is metadata in a fat binary (or in bitcode) that makes reversing more convenient, but there is none that makes reversing possible; reversing raw ARM assembly spat out by a normal compiler backend is always possible.
It's 2015. Lack of source code is no longer a meaningful obstacle for attackers.
I agree, reverse engineering is always possible :) However, reverse engineering with the LLVM bitcode present is much much easier, which is a problem.
Also, if Apple requires apps to be submitted as LLVM bitcode, then certain things like integrity checks and certain useful types of obfuscation will become impossible, making apps much easier to reverse engineer, or to pirate and repackage on another app store.
I disagree that LLVM bitcode makes reverse-engineering any easier on iOS. You can do everything in bitcode that you can do in native ARM code. The limitations are already there in terms of code signing, sandboxing, and page protection and bitcode distribution doesn't change any of these OS attributes.
Are you concerned about Apple reversing your code? You can still use arbitrary types (e.g. int64 instead of a pointer) and give them no additional data about the structure of your code. As you pointed out elsewhere, tools like OLLVM perform obfuscation at the bitcode level already.
I'm guessing Apple made this change to make it easier to do program analysis of iOS apps being published. You can certainly find bugs easier in bitcode that has proper type information and clear differentiation between safe and unsafe branches. One of the first steps in program analysis tools is to lift native code to an IR in order to determine its correctness.
With bitcode distribution, Apple has potentially made it easier on themselves to skip the lifting and type recovery steps for conforming apps in order to look for bugs. But unless they start requiring bitcode conform to certain additional standards, you can always transform bitcode to obfuscated bitcode, destroy type information via aliasing, etc.
I concede that LLVM bitcode can be obfuscated just like machine code ( with enough effort, and LLVM bugs aside ) . However, you're still losing the ability to self-checksum your code, which in turn means you can't protect against things like piracy or unwanted modification of your binary.
I agree also that Apple probably made this change to better analyze programs being submitted to the app store. That and to recompile programs to use intrinsics more efficiently, as new intrinsics become available.
And finally, while I would not be concerned about Apple reversing my code, certain companies are and have to undertake steps to make that as difficult as possible.
If you are concerned about anyone reversing your code (Apple or otherwise), you must obfuscate it. Either you work at the ARM level or the bitcode level (watchOS for now), but the basic techniques are the same. Or, you can avoid changing tools by doing source-level transformation.
One of the companies probably impacted by this change is Arxan or other obfuscators. They have to change both front and backend to be LLVM -> LLVM.
[1] Except for the case I mentioned before, where you predict the generated code for known architectures and use that to generate your constants. This still breaks if Apple generates code for a new architecture without your help.
I dispute the claim that bitcode makes this task so much easier that it presents a real threat. Everyone with a financial or policy interest in backdooring Signal can do so on stripped ARM binaries without any trouble.
Iirc Signal is open source, so anyone can simply insert a backdoor into the source code and compile it, and then distribute the modified binary.
However, I'm talking about applications for who the source code is not available. If you properly use integrity checks, signature verification, and obfuscation, you can make repackaging and piracy of applications significantly more difficult. With LLVM bitcode this is no longer the case.
It's 2015. Lack of source code is no longer a meaningful obstacle for attackers.