ARM disassembler/cross-compiler for examining iOS compilation - iphone

Can anyone recommend either:
an ARM disassembler that runs in either Windows or MacOS and which can ideally understand the executable format used by iOS
within MacOS, a way to call the cross-compiling GCC installed by XCode directly from the command line (so that I can run it on a small test file and ask for assembly output).
Basically, I'm interested in seeing how certain things get compiled for ARM/iOS by XCode/gcc to help me with optimisation. As you can see, although I have both a Windows and Linux background, I'm not fundamentally a Mac specialist so I'm not too familiar with e.g. where XCode intsalls all its gubbinry or the ins and outs of whatever binary format iOS uses.
I don't particularly care whether I have to do the "disassembly" under Mac OS or Windows, but what I was trying to avoid is installing a brand new copy of GCC configured to cross-compile to ARM, as XCode presumably has a perfectly good installation already sitting there somewhere... Any help appreciated.

You can always use otool disassembler. It's rather basic but does the job.
IDA Pro can disassemble ARM Mach-O files used in iOS. Using it is (in my biased opinion) much better experience that looking at the dead listing. You can check how it works with the demo version.
Disclaimer: I work for Hex-Rays.

an ARM disassembler that runs in either Windows or MacOS and which can ideally understand the executable format used by iOS
I can suggest you a LLVM. If it is built with default options, llvm-objdump will disassemble ARM.
Also, looks like http://developer.apple.com/technologies/tools/whats-new.html Apple is using LLVM toolchain in iOS SDK.

There is already an ARM cross compile toolchain built into Xcode. You can debug your iOS applications at the source and ASM level with the gdb debugger support already built into Xcode. For example, open your iOS app and select Device and Debug. Then set a breakpoint at a source line and run your program until the breakpoint is hit. Now select "Run -> Debugger" from the menu. When the debugger is showing, select "Run -> Debugger Display -> Source and Disassembly" and you will see a window on the right side that shows the ARM asm code that was generated from your source code. You can step through the code a source line at a time using the buttons. If you want to step one ARM asm instruction at a time, open up the gdb console and use the "stepi" instruction (type it once, then just hit enter to repeat).

Take a look at Hopper. It's darn cheap compared to IDA (though not as powerful) and the recent versions can handle ARM.

Within MacOS, a way to call the cross-compiling GCC installed by XCode directly from the command line (so that I can run it on a small test file and ask for assembly output).
Use this script for a gcc that compiles for iphone:
#!/bin/bash
# Note: The "/Applications/Xcode.app/Contents" prefix is only required on 10.7.2 and
# later (where Xcode is installed through app store rather than as a package).
# If running 10.6 or earlier, cut out that prefix.
PLATFORM=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
# Change this to the iOS version you want to compile for (you must have the platform
# SDK installed in Xcode)
VER=6.1
$PLATFORM/Developer/usr/bin/gcc -arch armv7 -framework IOKit -framework CoreFoundation -F $PLATFORM/Developer/SDKs/ iPhoneOS$VER.sdk/System/Library/Frameworks -I $PLATFORM/DeviceSupport/Latest/Symbols/usr/include -L $PLATFORM/Developer/SDKs/iPhoneOS$VER.sdk/usr/lib -L $PLATFORM/Developer/SDKs/iPhoneOS$VER.sdk/usr/lib/system $*
Source: newosxbook.com

Take a look at Radare2 it is an open Source tool that is rising it's Feature-Set constantly and already supports ARM disassembling.

Related

how write iphone apps using objective-c from terminal

i would like to know how to develop iphone apps for terminal just like we do for android
by using the
android --target 1 --name someApp --package --com.someApp --activity main
command
how to do this for iphone apps
it should be like
iphone // then some options
or what is xcode or someother ide doing behind the scene ..??
If your question is "How do I develop from the terminal?", then, please, don't go there, but if you do:
The xcode project files are xml, they contain all information about your project, compile instructions, source files, resources, etc. You could create and manipulate these and use xcodebuild to compile your project.
If your question is 'How do I compile apps from the terminal?', then there are some valid reasons for doing so, automations, testing, etc. When you have installed Xcode, there are also some command line tools available, like xcodebuild. You can use these tools to build from the command line:
xcodebuild command line
Take a look at the xcoder ruby gem:
https://github.com/rayh/xcoder

How to compile distributable Fortran binaries on Mac OS X Mountain Lion?

Since Apple have stopped distributing gfortran with Xcode, how should I compile architecture independent Fortran code? I have Mac OS X Mountain Lion (10.8), and XCode 4.4 installed, with the Command Line Tools package installed.
Apple's Native Compilers
As far as I can tell, the Xcode C / C++ / ObjC compilers use a fork of the GNU compiler collection, with llvm as a backend; the latter I figure enables compiling and optimising "universal" binaries, for both Intel and PPC architectures.
3rd party binary Fortran compilers
HPC
I've only found a single website that distributes a binary version of gfortran specifically for Mountain Lion: the HPC website. However, I failed to get this to compile SciPy, and later saw in SciPy's README that it is "known to generate buggy scipy binaries".
CRAN/R
SciPy's recommended (free) Fortran compiler is the one on CRAN's R server, but this has not been updated for Mountain Lion yet. They provide instructions and a script for Building a Universal Compiler, but, again, this hasn't been updated for Mountain Lion yet..
G95
The G95 project hasn't had an update since 2010, so I didn't try it.. Anyone tried this on Mountain Lion?
MacPorts
I guess this will be the easiest way to get gfortran installed, but port search gfortran comes up with nothing, and I've not had any joy with MacPorts in the past (no offence to MacPorts; it's looks like a very active project, but I've been spoilt with Linux package managers, my favourite manager being aptitude) so on Mac OS X I've compiled software and libraries from source code in the past. Never been a problem 'til now...
Building a Fortran compiler
Having dug around on the internet a lot in the last couple of days, I've found other Fortran compilers, but I've failed to get any to cross-compile universal binaries, or to compile SciPy.
GCC - The Gnu Compiler Collection
I compiled the entire GCC collection (v4.6.3), including autotools, automake, libtool and m4 - like the GCC wiki and this blog describe - but the resulting compilers didn't compile universal binaries, probably because LLVM wasn't used as a backend.
DragonEgg
DragonEgg is a "gcc plugin that replaces GCC's optimisers and code-generators ... with LLVM". This looks interesting, but I don't know how I could use it to compile 'llvm-gfortran-4.x'. Can this be done?
Compatibility
Libraries
The compiler that comes with Xcode is (a fork of?) GCC v4.2. But GCC's current release and development branches are versions 4.6 and 4.7, respectively. Apparently, a GNU license change, or something, stopped Apple from updating to more modern versions of GCC. So, if I was to build dynamic libraries made with GCC's gfortran v4.6, could they then be linked with C code compiled by Xcode's native compiler? At a minimum, I figure resulting Mach-O binaries need both x86_64 and i386 code paths. Do GCC provide backwards compatibility with Apple's (forks of?) GCC? I know gfortran has the -ff2c flag, but is this stable across versions?
Compile flags
The GCC Fortran compiler I built from source didn't support the use of the -arch compile flag. I had been including the flags -arch x86_64 -arch i386 in both CFLAGS and FFLAGS environment variables on earlier OSX versions (Snow Leopard to Lion). Python's distutils, and probably other OSX compilers, expect these flags to work, when configured to build apps or frameworks, using Xcode's universal SDK.
In case you're wondering what compile flags I use, I've uploaded the script I use to pastebin, which I source before I compile anything, using: source ~/.bash_devenv.
The Ideal OSX Fortran Compiler
Create ppc and intel (32 and 64bit) universal binaries, specified by using the -arch flags.
Makes binaries compatible with XCode's linker.
Compiles SciPy, giving no errors (compatible with numpy's distutils and f2py).
I don't use Xcode so much, but integration with it would surely benefit other users. Even Intel are still having problems integrating ifort into Xcode 4.4, so this is not something I expect to work..
If you read all the above, then thank you! You can probably tell that I'm not averse to building my own Fortran compiler from source, but is it even possible? Have I missed something? A configure flag maybe? And if such a compiler is not available yet, then why not?!
(Update:) Apple's GCC
Apple provide the source code for their patched version of GCC, at opensource.apple.com. This actually includes the source code for gfortran, but what do you know - it doesn't compile (easily). I'm in the process of writing a build script to get this to work. Unfortunately, I've had to apply a couple of patches, and learn about "the Apple way" of building GNU software. This is the way to go I think. Any reasons why it shouldn't be? I'll update with an answer if I get it to work...
I managed to compile after installing gfortran from http://r.research.att.com/tools/gcc-42-5666.3-darwin11.pkg, as explained here. I had to try to open the package a couple of times, though. First time it said that only apps from App Store can be installed. After installing gfortran, python setup.py build and python setup.py install worked fine. The unit tests of scipy though give a fairly high number of fails, not sure it's normal.
Ran 5481 tests in 82.079s
FAILED (KNOWNFAIL=13, SKIP=42, errors=11, failures=72)
<nose.result.TextTestResult run=5481 errors=11 failures=72>
In case you didn't already notice this: In newer versions of Xcode you have to explicitly install command line tools in the following way:
Preferences -> Downloads -> Components
And then click the "install" button for command line tools. This includes gfortran:
> gfortran -v
Using built-in specs.
Target: i686-apple-darwin10
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5664)
Admittedly, this does not solve all of my fortran needs (in some cases "./configure" scripts will complain that they cannot "compile a simple fotran program").
You could use brew (or Homebrew) to install gfortran.
$ brew install gfortran
I know you said you don't like MacPorts, but if you install the gcc48 port, it does in fact include gfortran (although you'll also have to do sudo port select --set gcc mp-gcc48 to get it to set up the symlink named gfortran).
Also, FWIW, the MacPorts option is not necessarily a binary - MacPorts can actually build it from source, which is why it sometimes takes a while. On the other hand, it also sometimes seems to get archived binaries from somewhere, but I think it depends on what the original author of the portfile uploaded.
I ended up compiling gfortran the source code provided at Apple's developer tools source code page. This seems to be working okay now - I've successfully compiled x86-64 and i386/i686 LAPACK, ATLAS and BLAS fortran libraries - but there are some ranlib tests which fail, when running make -k test in the build directories. (I could provide more info on that pastebin or somewhere, if someone wants...)
Build process
After asking the question, I downloaded Apple's llvmgcc42 source code tar archive, which includes the source code for llvm/gcc C, C++, ObjC and fortran compilers, and spent some time trying to compile a universal build of gfortran. The build takes about 30-60 minutes on my quad-core 2.8GHz Mac Pro, and became quite an involved process, so I wrote a set of build scripts for it, which I've shared at github.com.
....
I'll keep a tar archive of my build here for the time being, if anyone would like a copy. (Updated 26-Sep-2012) It'll only work if installed with a prefix of /usr/local/ though, unless you run install_name_tool on the executables and dylibs, to change the prefix from /usr/local to wherever you want to put it. You can test install_name's with otool -L filename (more info on the reasons for this is here).
The final build I'm now using also includes updates to the gcc/fortran and libgfortran directories, which I got from GNU GCC 4.2.4. These sources I got from my local GCC's mirror. There were only minor changes between 4.2.1 and 4.2.4, and the build scripts include the patches needed to upgrade the code.
The build-gfortran.sh script I wrote downloads missing dependencies (mpfr and gmp), compiles and cross-compiles them, patches differing headers with architecture-dependent preprocessor macros, and runs lipo to create universal binaries and libraries, eventually supporting both i386 and x86_64 architectures. The process is similar for llvmCore, and then GCC. I mostly copied code from the build_llvm and build_gcc bash scripts provided with Apple's llvmgcc42, but had some of it had to be modified, including a few lipo and install_name_tool commands.
The official way to compile Apple's gcc, using Xcode's gnumake just didn't work for me. I thought this should work just byadding "fortran" to the LANGUAGES variable in build_gcc.
With regards to compiling Scipy, still can't get that building perfectly. I've had to use clang and clang++ as C/C++ compilers, or else I get EXC_BAD_ACCESS malloc errors. Haven't tried the gcc/g++ compilers I built, just used the system ones. This is as reported for Lion, on the Scipy install page. I'm down to 11 errors and 1 failure, which are all raised from the same 3 function calls (_fitpack._bspleval, numeric.asarray, testing.utils.chk_same_position). Think that's pretty good, but I'd like every test to pass...

Cross compiling FreeTDS to iPhone

Since this question is unanswered and I spent the majority of a semester figuring it I thought I would post how to Cross compiling FreeTDS 0.91 to iPhone ARMv6, ARMv7 architecture. This was done using Xcode 4.2 and iOS 5 SDK.
The reason this question is asked it because you are developing an app for an iOS device that requires connecting to an Mircosoft SQL Sever, which requires using the Tabular Data Stream (TDS) protocol as it is Microsoft proprietary.
I will also mention that you need some level of technical skill to even attempt this. This is a very condensed version of what took me nearly two months to figure out (I left all the things you shouldn't do).
Other documentation relating to this:
Basic How To on using FreeTDS http://www.freetds.org/userguide/samplecode.htm
Microsoft's TDS API documentation
http://msdn.microsoft.com/en-us/library/aa936985(v=sql.80)
See my answer below.
Also see saskathex answer for Xcode 4.5 updated files.
For those like me that will spend hours finding the documentation for these standard configure flags (for running ./configure make make install)
./configure --build is used for specifing the architecture you want to complie for
./configure --host is used to specify the ark of the machine doing the compileing (running xcode)
./configure --target seems to be an alias
Now then to solving the problem.
1) Get the latest version of the FreeTDS http://www.freetds.org/
2) The next step is to make your own bash shell files that correctly run the FreeTDS ./configure. You will need two as the simulator is i386/i686 architecture and an apple device (iPhone, iPod, etc.) is ARM architecture. Also, your compiler files/version within the iPhone development directories may be different, just find what makes logical sense and has similar naming convention. The mac host architecture is supplied with the command uname -p.
Here is my example for building for use on the simulator (i386) build_for_simulator_i386.sh:
#!/bin/sh
#unset some shell variables
unset CC
unset CFLAGS
unset CPP
export buildPath=`pwd`
# make i386 (Simulator) target
export CC=/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/i686-apple-darwin11-llvm-gcc-4.2
export CFLAGS="-isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk"
# if you want Windows Authentication (NTLM) support you must use at least tds version 7
# the default is 5
./configure --build=i386 --host=i386 --target=i386 --with-tdsver=7.1
Example for configuring for ARM compilation (build_for_device_armv7.sh):
#!/bin/sh
# unset some shell variables
unset CC
unset CFLAGS
unset CPP
export buildPath=`pwd`
# make arm target
export CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2
export CFLAGS="-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk"
export CPP=/usr/bin/cpp
./configure --build=arm-apple-darwin10 --host=x86_64-apple-darwin11.3.0 --target=armv7 --with-tdsver=7.1
3) Next cd to the root freetds directory that resulted from unzipping the freetds download, mine was freetds_0.91
4) Run one of your scripts. You can only compile for ONE architecture at a time
sh build_for_(desiered build)
this runs ./configure for you with the correct options
(tds version 7 required for NTLM authentication)
5) Once the configure process completes you have to hack the configuration file. Open freetds_0.91/include/config.h then on line 172 change #define HAVE_ICONV 1 to #define HAVE_ICONV 0
6) If you previously ran ./configure, make, make install then run these commands. Especially if your switching architectures as you will get errors running make without doing this
sudo make clean
sudo make uninstall
7) Perform the compilation using make
make all
sudo make install
The make procedure does through some error on purpose, but if you see errors within six or seven lines of shell prompt, once it returns, you have problems and need to fix them before proceeding. Lets just say lots of things can go wrong at this point.
8) After installing the binary complied file that is the culmination of all the little .o files that freetds makes is /usr/local/lib/libsybdb.a Trust me you don't want to pull a .o file for just the library you want. Copy /usr/local/lib/libsybdb.a to the appropriate folder in your project. What I did was have two separate folders, one per architecture, named "compiled_freetds-0.91_simulator_i386" and "compiled_freetds-0.91_device_armv7."
9) Since you want to make you life easy and have xcode figure out which compiled file to use follow this subset of steps to perform the dynamic linking.
a) Select you project settings on the left had side of xcode
(the blue think with the name of your project on it)
b) Select the Target (usual the same name as your app)
c) Navigate to **build settings**, scroll down to **linking > other linker flags**
d) On the left side of Other Linker Flags a mouse over will reveal an expander,
expanding will reveal Debug and Release rows.
e) Add the appriate architectures by selecting the plus on the right side of
either Debug or Release. When the new row appears select the architecture,
double click the first editable field from the right to open an entry box
that you can then drag the appropriate complied file into it to be dynamically
linked. You must do this for both files and when done correctly the file
under ARMv7 will be used when building for the device and the one for Any iOS
Simulator SDK will be used when running on the simulator.
**Note:** You may also need to add the -all_load flag to resolve linking issues.
10) The final step which seems to avoid problem of dynamic linking error involving libsybdb.5.dylib when running code on device is to make uninstall. Also, when running on the device you will also get lots of warnings, in increments of 36, about CPU_SUBTYPE_ARM_ALL being deprecated, that is normal, but annoying.
sudo make uninstall
I hope this helps.
I used the above bash files but since XCode 4.5 the Developer Tools are inside the app bundle. So I modified the scripts to run with my MacOS Lion and the current XCode Version "4.5.2 (4G2008a)"
build_for_simulator_i386.sh:
#!/bin/sh
# unset some shell variables
unset CC
unset CFLAGS
unset CPP
# make i386 (Simulator) target
export CC=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/i686-apple-darwin11-llvm-gcc-4.2
export CFLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk"
export CPP=/usr/bin/cpp
./configure -build=i686-apple-darwin11 --host=i686-apple-darwin11 --target=i686-apple-darwin11 --with-tdsver=7.1
build_for_device_armv7.sh:
#!/bin/sh
# unset some shell variables
unset CC
unset CFLAGS
unset CPP
# make arm target
export CC=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2
export CFLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk"
export CPP=/usr/bin/cpp
./configure --build=arm-apple-darwin10 --host=x86_64-apple-darwin11 --target=armv7 --with-tdsver=7.1
A nice add-on is to use lipinfo to merge two static libraries into one by
lipo compiled_freetds-0.91_device_armv7/libsybdb.a compiled_freetds-0.91_simulator_i386/libsybdb.a -create -output universal_libsybdb.a
and just adding this to the project's settings.
Wanted to share it, since the above scripts saved me a lot of time.

TiMidity: need help compiling this library for the iPhone

I'm using a powerful library called TiMidity, which I'm sure many iPhone developers have used already used. This is a platform-independent set of programs, but during compile-time in XCode (gcc compiler), there are hundreds of dependency errors that come up.
If anyone here has used TiMidity before for their apps, your advice will be gold.
Thanks everyone,
Phil.
I usually use this script to compile static libraries for the iPhone, but TiMidity++ isn't a library and the API's it uses to output sound on OS X aren't available on the iPhone OS.
Here's what I've gotten so far:
Save build_for_iphoneos somewhere in your path and +x it
cd to the extractd TiMidity++ folder
build_for_iphoneos simulator
This will fail
Copy timidity/newton_tables.c somewhere safe.
make clean
build_for_iphoneos device
Manually edit timidity/makefile and remove all references to DAU_DARWIN and darwin_a
Copy newton_tables.c back into the timidity subfolder and touch it
make
You should now have a timidity binary that can be used from the shell on a jailbroken device (after signed via ldid of course) and object files you can include in your project.
Note: TiMidity++ is GPL, so you will have to release your application under that license if you use any part of it. Also, this is really messy because TiMidity++ wasn't designed to be used this way, all of the darwin integration is broken on iPhone OS, and automake confuses me.
You have to remove AU_DARWIN from ./Makefile as well as timidity/Makefile.

Debugging with Clang

I'd like to use clang on my Xcode iPhone project. However this is the getting started guide:
http://clang.llvm.org/get_started.html
I've been working with Xcode for a year but this is far far far from being understandable to me! Can anyone explain in plain english how to install and use Clang with my existing iPhone project? I am not familiar with loading things from the console.
Thanks!
Dan
Nikita Zhuk has wrapped Clang in a GUI and made it available at http://www.karppinen.fi/analysistool/. Very useful.
Download and extract the clang distribution to some directory. Optionally add this directory to your path, or you can just prepend it's location to the command line later on.
cd to your top level project directory (probably something like cd ~/Documents/yourprojectdirectory)
Tell the clang utility to do a build of your project using your xcode project settings by typing in the following command line: pathtoclangdirectory/scan-build -o ./clang_out xcodebuild
The utilty should give you a message after it has run successfully to run the scan_view utility.
Run the command that was output at the end of the build. This will start a temporary web server on your machine and then open up Safari and show you the code analysis. You may need to prepend the path to your clang directory again, like so: pathtoclangdirectory/scan_view ...
I didn't see this question until after I had done something similar to make Clang more useful inside XCode:
Using Clang Static Analyzer from within XCode