I would like to encrypt a few of my obj c classes in my iphone game which handle openfeint data and classes which handle scores.
I have heard there is a way to encrypt this data to act as another level of security, at least enough to discourage some from cracking it and forging scores on a jailbroken iphone and then spam the leaderboards.
How is this done, what are good techniques to secure this data and discourage some from attempting to spoof data?
Thanks
To truly encrypt compiled code is probably more trouble than it is worth. You have to isolate the code that will be decrypted into a dynamic library and load the library manually after decrypting it in memory. Dynamic libraries, and the other methods you might use to modify code at runtime, are frowned on by Apple when used with iOS.
With Objective-C you essentially ship with the headers build into your code. That makes it much easier to dig around in your application. Anything you can do in C, where symbols may be stripped, will be slightly harder to read. You can also use #define to obfuscate your class and method names a little. This is nowhere near encryption, but is much easier to implement and less likely to introduce wacky bugs.
#define MyNicelyNamedClass somegarblegarble
#define myNicelyNamedMethod othergarblegarble
#interface MyNicelyNamedClass
-(id) myNicelyNamedMethod;
#end
This is a relatively painless way for a developer to make their Objective-C code less obvious to others. It is about as effective as javascript obfuscation, which is to say it is one more little hurdle that will dissuade many casual attackers.
If you choose meaningful but misleading names instead of straight garbage you may even trick someone into spending hours digging through the wrong code. Not that you would ever know, but it is a satisfying thought.
Encrypting classes suffers the "shipping the lock with the key" problem that any DRM or similar security system has.
What you are looking for is self modifying code, where the code is either loaded and decrypted later by the application, or is present as machine code in the binary and modified at runtime by a key the application has.
Note that you'll likely create some very subtle and interesting bugs, and your method will be bypassed (it will take someone maybe an extra day).
Related
I work on a large, old program owned by a large corporation. Soon, we hope to start moving from Objective-C to Swift. One of the reasons we want to move is because Swift is more secure than Objective-C. However, we'd love to avoid any security holes if possible. Aside from business logic, are there any examples of safe code I might write in Obj-C that are inherently unsafe in Swift, or vice-versa?
I'm mostly worried about user-provided data, and man-in-the-middle attacks spoofing as legitimate communications with our servers.
While I think the move to Swift is prudent, but I think it overstates the case to argue that Swift is significantly more secure that Objective-C. Even, in Objective-C, if you avoid C-like manipulation of buffers and stick with Cocoa classes, you're generally safe from buffer overruns and the like.
But if this is your concern, my main Swift caveats would be to carefully review any use of the appropriately named "unsafe buffer pointers" (e.g. unsafeAddressOf, unsafeBufferPointer, UnsafeMutablePointer, etc.). Also, review any C API that you have to call that still takes buffer pointers.
My earlier point was merely that this is such a small portion of the overall security risks, that I'm not sure this would be very high in my list of Swift transition rationale. Swift, itself, does little to address more egregious concerns such as failure to sandbox and use keychain, sloppy network and/or cache management, etc., as discussed in WWDC 2015 Security and Your Apps and WWDC security presentations from prior years. These sorts of security concerns are addressed through a rigorous development process including judicious design, coding, testing, and reviews, but can be tackled equally effectively in both Objective-C and Swift.
I've been introduced to an Objective-C codebase which has ~50,000 LoC and I'd estimate that 25% or so is duplicate code. Unfortunately, OO principles have been mostly ignored up to this point in the codebase in favor of copy and pasting logic. Yay!
I'm coming from a Java background and a lot of this duplication is fixable with good old-fashioned objective oriented programming. Extracting shared logic into a base class feels like the correct solution in a lot of cases.
However, before I embark on creating a bunch of base classes and sharing common logic between derived classes, I thought I should stop and see if there are any other options available to me. After watching Ken Kocienda's 'Writing Easy-To-Change Code' WWDC session from 2011, he's advising me to keep object hierarchies as shallow as possible. He doesn't offer up any hard statistics as to why he has this opinion, so I'm wondering whether I'm missing out on something.
I'm not an Objective-C expert by any stretch of the imagination, so I'm wondering if there's any best practices when deciding on an object hierarchy. Basically, I'd like to get opinions on when you decide to stop creating base classes and start using composition instead of inheritance as a way of sharing code between classes.
Also, from a runtime performance standpoint, is there anything to sway me away from creating object hierarchies?
I wrote up some thoughts awhile back on coming to iOS from other backgrounds, including Java. Some things have changed due to ARC. In particular, memory management is no longer so front-and-center. That said, all the things you used to do to make memory management easy (use accessors, use accessors, use accessors) is still equally valid in ARC.
#Radu is completely correct that you should often keep your class hierarchies fairly simple and shallow (as you read). Composition is often a much better approach in Cocoa than extensive subclassing (this is likely true in Java, too, but it's common practice in ObjC). ObjC also has no concept of an abstract method or class, which makes certain kinds of subclassing a little awkward. Rather than extracting shared logic into base classes (particularly abstract base classes), it is often better to extract them into a separate strategy object.
Look at UITableView and its use of delegates and datasources. Look at things like NSAttributedString which HAS-A NSString rather than IS-A. That's common and often keeps things cleaner. As with all large object hierarchies, keep LSP in mind at all times. I see a lot of ObjC design go sideways when someone forgets that a square is not a rectangle. Again, this is true of all languages, but it's worth remembering as you design.
Immutable (value) objects are a real win whenever you can use them.
The other piece you will quickly discover is that there are very few "safety decorations" like "final" or "protected" (there is a #protected, but it isn't actually that useful in practice and is seldom used). People from a Java and C++ background tend to fret about compiler enforcement of various access rules. ObjC doesn't have compiler enforcement of most protections (you can always send any message you want to any object at runtime). You just use consistent naming conventions and don't go poking around at private methods. Programmer discipline takes the place of compiler enforcement. In practice, it works just fine that way in the vast majority of cases.
That said, ObjC has a lot of warnings, and you absolutely must eliminate all warnings. Most ObjC warnings are actually errors.
I've strayed a little from the specific question of object hierarchies, but hopefully it's useful.
One major problem with deep hierarchies in Objective-C is that Xcode doesn't help you at all understanding/managing them. Another is simply that just about anything in Objective-C gets about twice as complex than the equivalent in Java, so you need to work harder to keep stuff simple.
But I find composition in Objective-C to be awkward (though I can't say exactly why), so there is no "perfect" answer.
I have observed that small subroutines are much rarer in Objective-C vs Java, and one is much more likely to see code duplicated between mostly-identical view controllers and the like. I think a big part of this is simply the development tools and the relative awkwardness with creating new classes.
PS: I had to rework an app that contained roughly 55K lines, close as we could count. As you found, there was likely about 25% duplication, but there was also another 25% or so of totally dead code. (Thankfully, that app has been pretty much abandoned since.)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I've researched quite a bit, both on SO, as well google-ing all over the place, but I can't seem to find a straight-forward answer in regards to code obfuscation for iPhone/iPad apps written in Objective-C.
My questions are these:
Is there a way to do it? If so, how?
Is it worth it?
Does Apple allow it, or have a problem with it, when the app is submitted to them?
There doesn't seem to a code obfuscator for Objective-C. But let's assume for a moment that one does exist.
Apple will probably not reject an obfuscated app as long as it doesn't crash. The main question is: what is the point of obfuscation ? Normally, you want to obfuscate code to protect your knowledge, for example if your program uses a copy protection you want to make it harder for a potential cracker or if you're using some advanced algorithm you don't want the business competitors to be able to decompile it.
The copy protection is already been taken care of on iOS. Although through jailbreaking a normal app can be copied and run, I'd say the actual number of users who do this is fairly low (at least a lot lower than on "regular" computers like PC and Mac). Do you expect piracy such a big problem that you need to obfuscate ?
If you do have important knowledge to protect then obfuscation might be worthwhile. Obfuscation has its downsides: you can't debug your obfuscated app any more. Crash reports will be useless.
You might also want to read the article Obfuscating Cocoa.
Back to the fact there doesn't seem to be an obfuscator: What you can do is this trick: say you have a header like this:
#interface MyClass : NSObject {
}
- (void)myMethod;
You could do a cheap obfuscation like this:
#ifndef DEBUG
#define MyClass aqwe
#define myMethod oikl
#endif
#interface MyClass : NSObject {
}
- (void)myMethod;
This way you can still use meaningful symbols in your source, but the compiler would turn it into "garbage" when not compiling for debugging.
Yes, you can take a look at EnsureIT for Apple iOS or Contaxiom Code Protection
It depends. Security normally introduce complexity, you have to balance it between usability.
Apple should not have any problem with it (correct me if I'm wrong), and I personally have few apps that uses code obfuscator.
Further to the earlier answers there are now several 3rd party tools that offer some degree of obfuscation and integrity protection including :-
Arxan,
Metaforic,
Cryptanium
They vary in capabilities and include :-
Control flow obfuscation e.g. ARM instruction flows are mangled with redundant instructions to try to hide the original purpose of the code,
Class and Method renaming - renames your methods and classes to meaningless names although you have to be careful where this is used as you can easily break your app because the Objective-C runtime is expecting to find certain names,
String encryption - all static strings in the app are encrypted and code is inserted to decrypt the strings just before use in order to make static analysis harder
Anti-debug - code is inserted to break the usual debuggers (not always successfully),
Anti-tamper - usually builds a network of checksums that protect the binary code from modification,
Objective-C runtime protection - usually checks obj-c registered method implementations to make sure that they are in the app and haven't been 'swizzled'.
All of these tools are very expensive and not without their problems so you really need an application that requires a high degree of integrity in order to consider them e.g. banking or where DRM is very important.
For these types of app you will also need skilled penetration testers to ensure that your app is not exposed in other ways as these tools are often only as good as the people using them and there are still other OS vulnerabilities that will need mitigating that the tools don't address.
The executable of an app is already encrypted by Apple, and the executable code segment of the app sandbox isn't writeable, so you can't do additional encryption that requires runtime arm code modification. And the optimizer pass of the Objective C/C compiler already creates something very different from the original source code. Using more C and less Objective C will reveal less of your function names, as method names are embedded in visible plain text, but C function names are not. So any trade secret type code should probably be coded in plain C, and compiled with the optimizer turned all the way up. You could obfuscate any webKit Javascript embedded within the app bundle, or any other embedded VM code (as long as interpreted code isn't downloaded).
Probably not because Objective-C compiles out to processor instructions rather than being interpreted or compiling to byte code, so decompiling the code will already produce pretty obscure results. Obfuscation is something you usually only needed when you have to distribute the source of your code, like in interpreted languages like JavaScript, in order for it to run even when you want the code to remain secret.
Are there any other database engines that could be used on the iPhone, besides sqlite3? Something like textDb is for PHP, single-file and no server.
There are a slew of alternatives to SQLite, but there is little point to using them as others have pointed out.
Before pointing out some alternatives, some points:
First, SQLite is an excellent single-file, non-client-server, small-footprint SQL database. The performance is excellent, it is a relatively tiny runtime, and it is thoroughly fast. There isn't an embeddable SQL-interpreting alternative that is either all around technically superior or anywhere near as popular.
Secondly, if you are doing persistency in an iPhone application, you should very likely be using CoreData. There are certainly reasons not to, but they are pretty uncommon. Beyond being a higher level mapping to a relational store that is quite adeptly integrated with Cocoa Touch, Core Data solves a number of very difficult problems above and beyond persistency; object graph management, efficient memory use (i.e. push stuff out of memory when no longer needed), and undo support, to name a few.
Finally, if you do decide to use some other database persistency layer, keep in mind that the iPhone 3G and prior is an extremely memory constrained runtime environment. The very presence of any kind of additional library can significantly reduce the working memory available to your app. Whatever solution you choose, make sure it is optimized to use as little memory as possible.
So, seriously, if you are looking to not use SQLite or CoreData it is either because you have a very rare case where they aren't appropriate or because you are being curious. If curious, well... good for you!
If you are looking for alternatives, the SQLite documentation includes a set of links to similar products.
Pretty sparse list and it isn't because the author is hiding anything. There simply isn't a lot of motivation in the industry to try and re-invent this particular wheel because SQLite does a really good job. There is a reason why Google, Adobe, GE, FireFox, Microsoft, Sun, REALBasic, Skype, Symbian, Apple, and others have pretty much standardized on SQLite to solve their non-client/server relational persistency needs; it just works.
If you're looking for an alternative, I would say Core Data.
I had the same question for a long time and even used SQLite in some projects. After speaking with an Apple Engineer though, he pointed out that Core Data could do everything that I was using SQLite for (mainly just storing information and accessing it in a few different ways).
I would start with the with Core Data Programming Guide and see how it works for what you're looking to do.
I think your problem is that you are thinking of a software library more like a software product. People want choice between Internet browsers for all sorts of reasons. But when you have a software library, it's pretty much set up for one purpose. If it doesn't fulfill that purpose well enough, it shouldn't be a library.
Do you not like NSObject? Do you not like the Core Foundation library? Then write your own. However, to drag up an unfortunately overused analogy, don't reinvent the wheel, unless your job is making new and innovative wheels.
SQLite does perform acceptably, and so it is supplied as a library on the iPhone platform. SQLite works for what I need it to do. If it doesn't work for you, then maybe you have some reason you'd like to share?
Freedom of choice is fine if you want to choose between Internet browsers, but I would think that as a programmer, one should have a very specific reason for going out of their way, spending valuable time to fix something that already works. Even with my choice of Internet browser, I have specific reasons I choose one over another.
No. Everyone seems to be happy with SQLite.
I've heard a ton of complaining over the years about inherited projects that us developers have to work with. The WTF site has tons of examples of code that make me actually mutter under my breath "WTF?"
But have any of you actually been presented with code that made you go, "Holy crap this was well thought out!" or "Wow, I never thought of that!"
What inherited code have you had to work with that made you smile and why?
Long ago, I was responsible for the Turbo C/C++ run-time library. Tanj Bennett wrote the original 80x87 floating point emulator in 16-bit assembler. I hadn't looked closely at Tanj's code since it worked well and didn't require attention. But we were making the move to 32-bits and the task fell to me to stretch the emulator.
If programming could ever be said to have something in common with art this was it.
Tanj's core math functions managed to keep an 80-bit floating point temporary result in five 16-bit registers without having to save and restore them from memory. X86 assembly programmers will understand just what an accomplishment this was. Register space was scarce and keeping five registers as your temp while simultaneously doing complex math was a beautiful site to behold.
If it was only a matter of clever coding that would have been enough to qualify it as art but it was more than that. Tanj had carefully picked the underlying math algorithms that would be most suitable for keeping the temp in registers. The result was a blazing-fast floating point emulator which was an important selling point for many of our customers.
By the time the 386 came along most people who cared about floating-point performance weren't using an emulator but we had to support Intel's 386SX so the emulator needed an overhaul. I rewrote the instruction-decode logic and exception handling but left the core math functions completely untouched.
In my first job, I was amazed to discover a "safe ID" class in the codebase (c++), which was wrapping numerical IDs in a class templated with an empty tag class, that ensured that the compiler would complain if you tried for example to compare or assign a UserId into an OrderId.
Not only did I made sure that I had an equivalent Id class in all subsequent codebases I would be using, but it actually opened my eyes on what the compiler could do to guarantee correctness and help writing stronger code.
The code that impresses me the most, and which I try to emulate - is code that seems too simple and easy to understand.
It is damn difficult to write that kind of code. :-)
I have a funny story to tell here.
I was working on this Javaish application, filled with getters & setters that did nothing but get or set and interfaces and everything ever invented to make code unreadable. One day I stumbled upon some code which seemed very well crafted -- it was basically an algorithm implementation that looked very elegant = few lines of readable code, even though it respected every possible rule the project had to adhere to (it was checkstyled automatically).
I couldn't figure out who on the team could have written such code. I was dying to discuss with him and share thoughts. Thankfully, we had switched to subversion (from cvs) a few months earlier and I quickly ran am 'svn blame'. I loled all over the place, seeing my name next to the implementation.
I had heard stories about people not remembering code they wrote 6 months back, code that is a nightmare to maintain. I could not believe such a thing could happen: how can you forget code you wrote? Well, now I'm convinced it can happen. Thankfully the code was alright and easy to extend, so I've only experienced half of the story.
Some VB6 code by another programmer at my company I came across that handled the error conditions very well (whether it be deal with them directly or log them).
Along with some rather complex code that was well commented.
I know this will bring a lot of answers like,
"I've never find good code before I step in" and variations.
I think the real problem there is not that there isn't good coders or excellent projects out there, is that there's an excess of NIH syndrome and the fact that no body likes code from others. The latter is just because you have to make an intellectual effort to understand it, a much bigger effort than you need to understand you own code so that you dislike it (it's making you think and work after all).
Personally I can remember (as everyone I guess) some cases of really bad code but also I remember some pretty well documented, elegant code.
Currently, the project that most impressed me was a very potent, Dynamic Workflow Engine, not only by the simplicity but also for the way it is coded. I can remember some very clever snippets here and there, as well as a beautiful metaprogramming library based on a full IDL developed by some friends of mine (Aspl.es)
I inherited a large bunch of code that was SO well written I actually spent the $40 online to find the guy, I went to his house and thanked him.
I think Rocky Lhotka should get the credit, but I had to touch a CSLA.NET application recently {in my private practice on the side} and I was very impressed with the orderliness of the code. The app worked extremely well, but the client needed a few extensions. The original author had died tragically, and the new guy was unsophisticated. He didn't understand CSLA.NET's business object based approach, and he wanted to do it all over again in cut-and-dried VB.NET, without any fancy framework.
So I got the call. Looking at a working example of WinForm binding and CSLA.NET was pretty instructive about a lot of things.
Symbian OS - the old core bit of it anyway, the bit that dated back to the Psion days or those who even today keep that spirit alive.
And sitting right along side it and all over it is all the new crap created by the lowest bidders hired by the big phone corporations. It was startling, you could actually feel in your bones whether a bit of the code-base was old or new somehow.
I remember when I wrote my bachelor thesis on type inference, my Pascal-to-Pascal 'compiler' was an extension of a Parser my supervisor programmed (in Java). It had a pretty good structure as far as I can remember, and for me who had never done any serious Object-oriented programming, it was quite a revelation.
I've been doing a lot of Eclipse plug-in development and often had to debug into the actual Eclipse source code. While I haven't "inherited" it in the sense that I'm not continuing work on it, I've always been impressed with the design and quality of the early core.