4 ms·
I am referring to ObjectiveC metadata, which programs like IDA Pro can use to identify function names/parameters, which give valuable insights to reverse engine
by nekitamo 11y ago
I am referring to ObjectiveC metadata, which programs like IDA Pro can use to identify function names/parameters, which give valuable insights to reverse engineers.
With LLVM bitcode, it doesn't matter if you don't hand over your .dSYM file to Apple, all the symbol information (and more!) is available in the bitcode.
- tptacek 11y agoThere 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.
- nekitamo 11y agoI 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.
- tptacek 11y agoI 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.
- nekitamo 11y agoIirc 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.
- NateLawson 11y agoI 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.
- nekitamo 11y agoI 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.
- NateLawson 11y agoYes, self-checksumming becomes impossible [1]. 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.
- Joky 11y agoYou should really look at the bitcode that is actually submitted. It seems your opinion is based on what clang generates usually.
- nekitamo 11y agoI am actually looking at that bitcode right now :) You can use this program ( https://github.com/AlexDenisov/bitcode_retriever https://github.com/AlexDenisov/bitcode_retriever ) to extract it from the MachO file, then use Xarc to decompress the archive, then use llvm-dis to disassemble the bitcode. You will see it's chalk full of information that is otherwise not available in the machine code.
- Joky 11y agoWhich MachO file are you looking at? Is it the one generated by the compiler or the one after linking in the bundle submitted to the store?
- deleted 11y ago[deleted]
- NateLawson 11y agoThere are already ObjC selector obfuscators that generate a random secret and hash all program values with that on each build. https://github.com/Polidea/ios-class-guard https://github.com/Polidea/ios-class-guard
- nekitamo 11y agoThank you, I had forgotten about class guard. It's a great tool, but I recall having problems getting it to work on larger applications. It's also possible for you to remove the ObjectiveC metadata from a binary entirely, obfuscate/encrypt it, and then add it back to the ObjectiveC runtime as needed. With LLVM bitcode this becomes much more difficult (but maybe not impossible...)