Tag Archive: osx


In last week’s episode we single stepped through the assembly code generated by the compiler, to see what happens when a function is called.  We learned that selectors are just C strings, how they are stored and how to find them in the code.

Now we will use otool to explore the program as it’s saved on disk, so we can find the selector strings themselves.  Compile the helloworld example from the previous episode.  Click the disclosure arrow by Product.  Open a terminal window, then type “cd ” (note the space following, it’s important) in the terminal and drag helloworld.app to the terminal to paste in the path.

Enter “otool -o helloworld | less” on the terminal.  What you see is a list of all the objective-c classes defined in the executable, along with the protocols they adopt, and the ivars and methods they define.  What you’re looking at here is the __OBJC segment of the executable.

Have a look at the MACH-O specification.  Programs on disk are divided into segments.  For simple C programs, there’s just __TEXT and __DATA.  The __TEXT segment contains the assembly language from the compiled code and immutable constants.  You can look at the generated code with otool -tV executable_file | less.  If it’s a C++ program, also pipe it through c++filt to demangle the names.  By using less’s search feature or the -p flag to otool you can find the compiled code corresponding to any function in your program.

The __DATA segment contains all the mutable constants declared in your program.  Integer and shorter constants are just immediates in the code, e.g. MOV r0,7, but strings, arrays, and structs are put in the data segment.

Which leads us to sections.  A segment is broken up into one or more sections.  For example, the constant C strings are stored in the __cstring section of the __TEXT segment.  Note that segment names are all caps, and section names are all lower case.

Enter otool -s __TEXT __cstring helloworld.  If you compiled for both armv6 and armv7 you’ll notice that each architecture has its own cstring section.  You’ll also notice that the output is in hex, with the load address as determined by the linker on the left, then the string data as 4-byte words.  Add the -v flag and you’ll see the output as strings.

The segment and section for the selectors is __TEXT __objc_methname, so if you enter otool -arch armv7 -v -s __TEXT __objc_methname helloworld you’ll see all the selectors that your program calls as strings.

otool -arch armv7 -v -s __TEXT __objc_methname helloworld
helloworld:
Contents of (__TEXT,__objc_methname) section
000036ec  release
000036f4  init
000036f9  alloc
000036ff  window
00003706  viewController
00003715  setWindow:
00003720  setViewController:
00003733  dealloc
…

Now that we know what selectors our program calls, the next step is to determine which ones correspond to illegal calls.

Tune in next week for the exciting conclusion!  In the mean time, read up on the mach-o specification and otool, there is a lot of interesting information you can query out of a program.

Forbidden APIs, part 1

Anyone who’s submitted an application to Apple’s app store knows that your app will be rejected if it uses any undocumented APIs.  Which is a shame, since there is lots of useful stuff in there.

I recently had to resubmit an app because of a forbidden API, and started wondering if there were a way to detect these things automatically, and save a bunch of heartache.

Continue reading

Welcome and Introduction

Welcome to Rob’s Adam’s Apple, where I will blog about my trials and travails as a programmer and occasional hardware hacker.

I am currently an iThing developer at Barnes and Noble, working on the Nook Reader application. I am also developing an Arduino clone called the Carduino, and am building a Nixie Tube Calculator.

Having over a quarter century of programming experience, there are a few things that I have found to be very important to be a successful programmer.  The first is communication.  This one still trips me up.  When not talking to computers in their respective native tongues, you are talking to:

  1. Other Programmers
  2. People who do not necessarily understand what you are doing, but want to control how you do it.  Also known as Managers.
  3. People who likely don’t understand what you are doing, but want to change how you do it.  Also known as Customers, Clients, and/or Stakeholders.
  4. Other people.  These may include friends, significant others, potential managers, or potential significant others.

I will concern myself with the first 3, the last is up to you.

When communicating with other programmers, be respectful.  You may not understand why they didn’t initialize a variable, which caused it to have a random value and crash the system during a customer demo.  Which may make you think they are stupid or incompetent.  Even if they are, it won’t help to accuse them of it.  When talking to anyone, always consider how you would feel if they said what you’re about to say to you, in the tone of voice you’re about to use.  Now think of how you’d rather hear it and say it that way.  These people may have your back some day – do you want them to tell you about your uninitialized variable first, or the CEO?

When talking to managers, honesty is the key.  These people need to represent you up the food chain.  To do this, they need to know what’s going on.  Resist the temptation to say that the project that you feel will take four weeks can be done in 1.  It can’t, and you may be fired after week two when it’s still only half done.  Better to find out what they need implemented next week, then plan out the following three.  They’ll be less upset, and in the long run you’ll get the reputation of dependability, which leads to promotions.

Stakeholders don’t care how you’re implementing your web fetches.  If you tell them you’re performing asynchronous background fetches, they won’t understand and will feel frustrated.  You always want stakeholders to associate you with warm fuzzies.  Delegate the bad news and compromise to the manager, and come through for the clients.

I definitely speak autobiographically here – hopefully some of you reading this can get the benefit of my mistakes 🙂