I'm looking to debug an app on a jailbroken iPod Touch 4, iOS (5.1.1) using. The only problem is GDB doesn't appear to have any knowledge of class/selector names for the app.
Attaching and setting address breakpoints work, but it cannot identify symbols when attempting to use objective-c names. For example, break -[Class Selector:] will fail. (I'm aware that + and - represent different class types.)
Also, I do not have the source for this app and will not be able to acquire it.
I'm looking to purely use GDB on the device without xcode or the source.
Has anyone successfully done this before? Thanks in advance for any answers.
Under the assumption that you're trying to debug an app from the store / a release build then your binary will have had the symbols stripped from it by the compiler. Only debug builds retain the symbols: there's no reason for release builds to keep them.
To find out the names you'll need to disassemble the binary manually and figure out what you need from there. This is a lengthy topic, too long to really type up in great detail here (O'Reilly's Hacking & Securing iOS Applications book has a good step by step tutorial).
Bear in mind that under the hood the Objective-C messaging framework is made up of C: if you're not familiar with things like the objc_msgSend series of functions you might find getting to know them better will help you along. Since every method invocation in Objective-C is sent using objc_msgSend you can effectively figure out class and method names by break-pointing every time it's called (or rather, breakpointing and automatically dumping the contents: it will be called so many times that to do it manually would take far too long).
However, this is only going to help you identify the symbol names: as the symbols are stripped from the binary you're still going to have to breakpoint on the addresses themselves.
Related
This question pops up quite often here, even if just implicitly when users mistag their iOS questions. So, what’s the difference between Xcode, Objective-C and Cocoa?
Objective-C is a programming language. It could be said that it’s just a description of what valid Objective-C programs look like and what they mean. If you have a source code listing written in Objective-C, you need an interpreter or a compiler to put the listing to work. Languages like Objective-C are usually compiled, so most people use a compiler (like LLVM). Objective-C is almost exclusively used to develop for iOS and OS X, but there are other uses, too – as an example, some people write Objective-C for Linux.
You can use a text editor to write the sources and a compiler to turn them into an actual programs, but with modern technologies there’s much more to take care of, so that there is another program to make your job easier. These are called Integrated Development Environments, or IDEs. An IDE offers you a convenient way to edit the sources, compile them, debug the resulting programs, read the documentation, and many other things. Xcode is one such IDE. An important observation here is that Xcode does not compile your sources itself, it just calls the standalone compiler (LLVM). And Xcode is not the only IDE you can use to develop Objective-C apps – there’s AppCode, for example.
Writing iOS or OS X apps from scratch each time would be very time-consuming. That’s why Apple provides the developers with a good set of libraries. The libraries are simply a huge amount of source code written by Apple, and this source code takes care of most things that apps have in common. These libraries are called Cocoa.
Now, if you can’t figure out how to extend a class, you are most probably talking about Objective-C. It doesn’t have anything to do with Xcode or Cocoa, you could be very well writing some GNUstep code for Linux using Vim as an IDE and GCC as a compiler. On the other hand, if your Xcode build process fails because of some mysterious setting, or if you’re trying to build a static library in Xcode, that’s clearly an Xcode issue. And if you can’t figure out how to use some NSObject facility or the NSFileManager class, that’s Cocoa. (But it doesn’t have to be Xcode-related, as you could use AppCode or TextMate as your IDE!)
Originally available on my blog. Feel free to link to the blog post or this question when retagging or explaining the difference.
Xcode is the integrated development environment (IDE)—the application—that developers use to write software for iOS and/or OS X. It includes the editor, the build system (determining what to build to produce the desired target), and quite a few other things.
Objective-C is the main language that developers write such software in. They may write bits of it in pure C, use C++ or combine it with Objective-C (producing Objective-C++), or write some or all of the program in another language entirely, such as MacRuby, Java (with j2objc), or C# (with MonoTouch).
Xcode includes the Clang compiler, which turns code written in Objective-C, C, and a few other languages into executable code. Most error messages come from Clang, and Xcode relies heavily on it for search indexing, syntax highlighting, and name completion of Objective-C code.
Cocoa and Cocoa Touch are application frameworks. Each one is a suite of many individual frameworks (libraries stored in folders named blahblah.framework), such as:
Foundation (both): General object-oriented utilities, including NSString, NSURL, NSFileManager, etc.
Core Foundation (both): Mostly the same thing, but different, mainly in having a C-based API rather than Objective-C
Application Kit (Mac): Application and windowing framework
UIKit (iOS): Application and windowing framework
Core Graphics (both): Drawing
Core Animation (both): Sprite-management and animation framework
(and many, many more where they came from, especially on the Mac)
So:
You can use a framework besides Cocoa or Cocoa Touch, but you'll have to have some Cocoa/Cocoa Touch code, at some level, in order for your application to talk to the system, receive events, draw, etc. Frameworks that specifically target Mac and/or iOS will include the relevant wrappers for you, at varying levels of quality.
You can use a language besides Objective-C, but you'll have lots of syntactic awkwardness, as most of Cocoa and Cocoa Touch are designed for Objective-C's unique syntactic features (particularly selectors).
You can use an editor besides Xcode, and you can even use a build system besides Xcode (such as make), but Apple's App Stores expect apps built a particular way (especially with regard to code signing), so unless you're not targeting the App Stores, any other build system has to replicate what Xcode does or risk its users getting rejections.
A clear mistake is failing to differentiate Xcode from everything else. Xcode is the tool you are using to program in - to edit code, run code, etc. So if you are having trouble with the tool (e.g., the window doesn't show you your code properly, or you're having trouble drawing your interface, etc.), that's an Xcode problem.
If you don't understand why your code doesn't work, you're probably having an Objective-C problem or a Cocoa problem. But you won't necessarily know which.
It's an Objective-C problem if the root of your trouble is that you don't know how the language works (e.g. you don't know what the asterisk is for, or that declaration is not instantiation, or that messages to nil do not error out but don't do anything either).
It's a Cocoa problem if you don't grasp the delegate architecture or how a view controller works.
But my experience of the way people pose questions is that you may be ignorant of which of these you are ignorant of. I don't mean you personally, I mean all of us. This can make it difficult to pose the question properly because you don't know what exactly it is that you don't know — if you did, you'd know it and you probably wouldn't be having a problem (you'd be fixing the problem and on to the next thing).
I have an app that uses the ABAddressBook API and I am trying to convert my app to use ARC.
I know the AddressBook API is written in native C and its giving me a lot of errors when ARC is enabled.
Anybody knows how to do it or is it even worth to do it?
Thanks in Advance.
One possible solution is to set compiler flags for the code that is giving you trouble to convert to. Go to Build Settings for the particular target you are using and add the flag "-fno-objc-arc" to the files that are problematic. Also, any more info on the actual problems arising would be helpful.
bartender,
First, working code is working code. You can easily intermix both kinds of memory management mechanisms in the same app. I only convert classes to ARC as I open the code up for other purposes. This allows me to slowly move my app to ARC. Why do you want to change this code to use ARC?
Second, the interface between core foundation items and ARC can appear to be complex ... but it isn't. Most issues are handled by using the __bridge type qualifier. Typically, the compiler/fix-it tells you exactly what you need to do. (Working, non-leaking CF code doesn't need to change. It just needs to tell ARC to leave it alone.)
Andrew
I have developed a number of frameworks that I want to ship with my application. I don't want others to be able to use the frameworks, but i've seen utilities such as class-dump which can get the headers back easily.
My question is, how can I make my frameworks more secure? I know that they'll never be 100% secure, but are there some good general tips to follow?
Thanks!
In short, don't bother. The very nature of the Objective-C runtime is that there is significant metadata available.
The reality is that it would be exceedingly rare for someone to pick up your framework and try to embed/use it.
Note that code obfuscators don't really work very well; there is still quite a bit of metadata that must be exposed. You can go that route, but -- generally -- it makes debugging/crash analysis significantly more difficult without actually solving a real problem.
I see others have pointed you down the path of obfuscation (though I suspect that the answer of #define someSelector mmmrrrggglll wasn't really tested much).
Some specific points to consider as you go down this path (I'm sure I've missed many):
if you use KVO/KVC, make sure you obfuscate all those calls to addObserver:* and the like
if you are targeting Mac OS X, don't forget about Bindings, too!
Interface Builder's xib files will often contain references to instance variables and/or properties and/or methods. Don't forget about those!
Anything that uses runtime introspection will need obfuscation, too.
make sure you don't obfuscate anything that the system frameworks are dependent; wouldn't want to subclass NSView, say, and then obfuscate drawRect: or initWithFrame:.
In some cases, the Info.plist can refer to class names and entry points. Don't mess with those, either!
Also, make sure every use of #selector() is also properly obfuscated; nothing like setting up an NSTimer firing against a method that no longer exists.
Make sure your obfuscation plans also includes the engineering work necessary to create an un-obfuscator for crash logs.
You'll also want to consider how you are going to debug a production binary; assume your stack traces will be obfuscated. b mmmrrrggglll ftw!
If your framework has symbol exports control, make sure to obfuscate 'em, too! Keep in mind that the way symbols are created differs between architecture and compiler, in some cases.
You can use static libraries to link with your application instead of frameworks. However, if you want to ship frameworks, you can use code obsfucators to make your library more difficult to use.
EDIT:
This SO post has a pretty simple description of a basic obsfucation.
How can objective C classes be encrypted
There are products on the market that do this, but they are expensive.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Objective-C Code Obfuscation
I am trying to put together an iOS package that can be reused in multiple apps. I would like to be able to bundle it up for others to easily plug in and use, and I would like to obfuscate the code so that no one can read it.
What would you recommend between building a framework, a static library, or another solution to accomplish this and why?
If you're distributing for iOS, you have two options:
Distribute a precompiled binary and headers
Distribute the source
Since you're asking about hiding stuff, I don't think #2 is what you're looking for.
As for #1, the best you can do is just not tell 3rd party users about more stuff. They'll still be able to use the runtime to find methods and properties and instance variables, etc. If you're doing everything in C-land (ie, no Objective-C classes), then they can still use things like otool to dump symbols.
In short:
It's probably not worth trying to "obfuscate" your code. Just tell them about the stuff they need to know about, then give them a .a file and the headers they need.
A framework is the standard Cocoa approach to shared code. You can distribute a framework as a compiled code library and a collection of public headers without making any of the underlying Objective-C soure code visible. Of course, a dedicated hacker could still read the machine code, but this would be a big undertaking, and probably not worth the time they would have to spend on it.
If you are really concerned about sensitive code, you could consider an internet-based service, in which your library calls out to a remote server under your control to perform some business logic. This approach is quite a bit more involved, and does not offer as much flexibility for your customers.
For the application I am writing, I need to access some other applications' items, for which Applescript seems the best way to go. I have been using the Appscript framework, which worked well, because it allowed me to thread it and not make my app lock up when an Applescript was taking a while. However, now I am attempting to make my application 64 bit compatible, and it seems like the Appscript framework does not support 64 bit. Is there a "good" way to use Applescript in Cocoa that will not lock up my application, but still give me the full control I need?
--firen
It seems like SBApplication should work, but I haven't used it before.
According to #cocoadevcentral:
SBApplication: use to make cross-application scripting calls with Objective-C instead of AppleScript. Ex: get current iTunes track.
Here is is the excerpt from the documentation:
The SBApplication class provides a mechanism enabling an Objective-C program to send Apple events to a scriptable application and receive Apple events in response. It thereby makes it possible for that program to control the application and exchange data with it. Scripting Bridge works by bridging data types between Apple event descriptors and Cocoa objects.
Although SBApplication includes methods that manually send and process Apple events, you should never have to call these methods directly. Instead, subclasses of SBApplication implement application-specific methods that handle the sending of Apple events automatically.
For example, if you wanted to get the current iTunes track, you can simply use the currentTrack method of the dynamically defined subclass for the iTunes application—which handles the details of sending the Apple event for you—rather than figuring out the more complicated, low-level alternative:
[iTunes propertyWithCode:'pTrk'];
If you do need to send Apple events manually, consider using the NSAppleEventDescriptor class.
Hope that helps!
As Blaenk mentioned Scripting Bridge may well be the way to go, although it can prove somewhat inefficient if you have to iterating through large arrays etc.
The simplest way to run an Applescript in Cocoa is using NSAppleScript.
Apple has some pretty good examples, which I found useful when I needed to do something similar. There are three articles you might want to take a look at. They all contain some sample code, which I always find very useful.
A Few Examples of using Scripting Bridge
Performance & Optimisation with Scripting Bridge
NSAppleScript Technote/Example
I created a gist with the full URLs as I can't post more than one link, what with being a newbie and all.
http://gist.github.com/130146
it seems like the Appscript framework does not support 64 bit.
Should work. Make sure you set the correct architectures and SDK (64-bit requires 10.5) in the Xcode project. File a bug report if you have a specific problem.