is there anywhere where I could start MobileSubstrate tweaks programming? - objective-c

After a search here on the forum I found a question like that, and it redirected me to a tutorial which gave em some basic instructions on manipulating SpringBoard with CapitainHook.
To start I'd like to do it with normal %hooks only. Any hint where I could start?

This little introduction is meant for whoever has a minimal knowledge on Objective-C and knows what he is doing.
NOTE: I will refer to the theos install path as $THEOS. This could be ~/theos, /var/theos, /usr/theos... Yeah.
The most popular way of creating MobileSubstrate extensions, also known as tweaks, is using Dustin Howett's theos build suite. Details follow:
What is theos?
So, we should start with what theos is not:
The Operating System
A Greek God
A compiler
And of course, what theos doesn't do:
Teaches you how to code.
Creates tweaks without having you to think
Sets up a whole building environment and/or installs the iOS SDK.
Theos is a cross-platform suite of development tools for managing, developing, and deploying iOS software without the use of Xcode, featuring:
A robust build system driven by GNU Make, which makes its Makefiles easily deployable through everywhere with theos installed too.
NIC, a project templating system which creates ready-to-build empty projects for varying purposes.
Logos, a built-in preprocessor-based library of directives designed to make MobileSubstrate extension development easy and with optimal code generation.
Automated packaging: Theos is capable of directly creating DEB packages for distribution in Cydia, the most popular mean of package distribution in the jailbreak scene.
How to install theos?
On OSX: Have the iOS SDK installed and follow these instructions.
On iOS: Install the BigBoss Recommended Tools package from Cydia and run installtheos3.
On Linux: Find a mean to have the toolchain installed, and follow these instructions.
On Windows: Nothing is impossible, but if you actually manage to do so, please let me know. :P
How to use theos?
This is a very asked question and too vague. Since theos is a whole suite of development tools, it doesn't make sense to ask How to use it, but more specifically, to ask How to create software using theos.
First of all, always have the Theos Makefile Reference in hand. It covers the basics of creating a theos Makefile, and that includes solving your linking issues adding a framework or private framework to the project.
Now, you can either create your own Makefile from scratch, create your little theos clone/symlink and start coding, but theos makes this step easier. You can just use nic.pl.
A very simple example of running NIC to create something can be found here. It's very straight-forward and sets you up right-away for programming.
Now, here's where we start getting back to topic.
Creating a tweak with theos
First of all, do not run NIC when inside $THEOS/bin. NIC will create the project directory exactly where you're running it from, and it avoids any project being created in $THEOS/bin. Therefore, you'll end up with a simple error which can be avoided by creating the project directory somewhere decent.
Run $THEOS/bin/nic.pl and choose the iphone/tweak template. You will be prompted by simple information which you may well know well how to answer, except for the last field: MobileSubstrate bundle filter.
Since a big part of MobileSubstrate is not just the hooker (the library which switches original methods/functions with yours), but also the loader (the part which gets your hooking to be inserted into certain processes), you have to supply this basic information for the Loader to know where to load your tweak. This field is but the bundle identifier for the application where this project will be inserted.
com.apple.springboard, the default option is the bundle identifier for SpringBoard, the application which is:
The iOS Homescreen
The launcher/displayer of common applications
The iOS Status Bar
Handler of some high-level essential background processes
Therefore, there's where many tweaks take place, altering behavior from something as trivial as app launching to something like how the whole homescreen UI looks like.
Programming a tweak with Logos
Now, the directory generated by NIC will contain:
The Theos Makefile, where you'll change information related to compiling
The control file, where you'll change packaging-related information
A symbolic link (or shortcut) to $THEOS named theos/
The main code file, defaulted as Tweak.xm. It is already added to the Makefile for compiling, so you can start coding right-away with it!
On knowing what to do
Now, you don't have SpringBoard's source code laying around, and you can't guess what methods to hook from nowhere. Therefore, you need a SpringBoard header set. For that, you need to use a tool named class-dump-z and run it into the SpringBoard binary (which is inside the iOS filesystem) to obtain header files including all class declarations and its methods inside the application.
From that (a deal of guessing and logging a method call is involved) you can start messing around with what you want in a tweak.
Of course, if you are not hooking SpringBoard you can use class-dump-z as you would in other binaries, such as UIKit, MobileSafari, etc.
Note that for when reversing App Store apps, they'll be encrypted. You'll need to decrypt those (I am unfortunately not allowed to tell you how-to), and then just run class-dump-z on them.
On obtaining private headers
Stuff like preference bundles require the headers for private frameworks, in that case the Preferences framework's headers. Else you'll get endless missing declaration errors (as I guess you could assume).
Getting them has the same logic applied the previous step. Run class-dump-z on, at this case, the Preferences binary and throw the headers at your INCLUDEPATH. The INCLUDEPATH is where the compiler will go looking for headers you include like #include <stdio.h>. Yes, stdio.h is inside one of the directories which build a compiler's INCLUDEPATH!
When compiling with a theos Makefile, $THEOS/include counts as part of your INCLUDEPATH, which means, you can just throw your dumped headers over there and include them later.
(Note that class-dumped headers aren't always perfect, so you're likely to have a couple of header-related compilation errors which can be easily fixed with something like removing a #import directive or changing it, or adding a couple of declarations.)
Code tips
You can't link against SpringBoard, so whenever you require a class from SpringBoard you have to use either the Logos %c directive or the objc_getClass function, as defined at <objc/runtime.h> to get it. Example: [%c(SBUIController) sharedInstance], [objc_getClass("SBUIController") sharedInstance].
When not knowing what a method does or how something works in SpringBoard, try disassembling it with IDA or others. I use IDA Demo (<- noob!) for my disassembling.
Looking at example code is amazingly helpful for both learning and figuring out how something works inside SpringBoard or others (again..). Great people at GitHub to have a projects looked at are rpetrich, chpwn, DHowett, EvilPenguin, and of course way more.
To also find about how SpringBoard and other works (...), have a look at a class's article at the iPhone Dev Wiki!
Epilogue
Wait, where's the good part? Where do I learn about coding in Tweak.xm?
Well, the original question was actually How to start MobileSubstrate tweaks programming?. You're all setup, hopefully with all headers placed, ready to type in make and see your project magically compiled with theos.
All you need to do is now to actually dig into your headers or your disassembly and go hooking, calling, etc.!
Logos Reference contains exactly how to hook and use other features of Logos, and the MobileSubstrate article on the devwiki is also a great read.
In case there is any doubt, don't hesitate joining the irc.saurik.com #theos IRC channel. It's a great way to discuss theos-related topics and ask questions. I'm mostly there, along with other greatly smart people ;)

You are looking for Theos created by DHowett.. Theos allows you to make tweaks, but it doesn't give you everything you need. You don't get every header for iOS, so you have to class-dump-z the frameworks/private-frameworks from the iOS SDK. Get started here: http://iphonedevwiki.net/index.php/Theos/Getting_Started, or join irc.saurik.net #theos for more help. You can also look at my projects that use theos: https://github.com/evilpenguin

You sound like you're looking for theos. Take a look at this, it should help get you started.

Related

How to create documentation for instance variable and methods in Xcode?

I'd like to be able to Alt-Click an instance variable (or a method) as part of the program i created and read what it's purpose is.
The fact that Xcode is telling me the class variable is declared at - is nice but not enough. In this case i'd like to see custom text i typed to describe what an asset really is. Additionally type of the ivar would also be useful to know.
How can this be done? In this case, i wonder what exactly did i mean by assets
I specifically wonder if this information can be viewed from inside Xcode, similar to how Eclipse shows JavaDoc content.
You would need to create a documentation set for your project and install it in Xcode. appledoc can help you with this. This is a command-line tool that can generate documentation in Apple's style from specially formatted comments in your headers. You can also integrate this into your build process with a run script build phase, so that documentation is always up-to-date.
For small projects, it's usually not worth the effort though and you're probably better off just adding comments to your header files and jumping there with Cmd-click (Ctrl+Cmd+left-arrow to go back to where you came from).
You'll probably want to take a look at Apple's documentation on Documentation Sets as well as their article on generating doc sets using Doxygen. The latter is based on Xcode 3.x, so how relevant it is is somewhat questionable, but it'd be a good idea to take a look nonetheless.
That said, if you decide to use Doxygen (alternatives like HeaderDoc can be used for documentation, but I'm not sure what's available to you as far as creating doc sets goes), it looks like the main point is you'll want to throw GENERATE_DOCSET=YES into your Doxyfile (or whatever you decide to call it). After that, you'd just throw the results into ~/Library/Developer/Shared/Documentation/DocSets (according to Doxygen's documentation). I don't know whether this works in Xcode 4.x - it's worth a shot though, and it'd be nice to hear back on it.
Note: most of this was based on this answer by Barry Wark. Figure credit is due there, since I wouldn't have bothered looking into this were it not for his answer.

Replicate class with main method as in Java IDE within Objective-C and Xcode 4

I have a simple question. Coming from a java background and having worked extensively with eclipse, netbeans or any other java IDE, is quite nice to have the possibility to add a main method to a class and execute it within the IDE, with just a click, and see the output.
I was looking for the same possibility within xcode4/objective-c but I couldn't find a way. From time to time, I like testing small piece of software, without compiling and running the whole project.
As I am still "thinking" in Java, could you suggest the proper way to achieve this with xcode4 from an "objective-c developer point of view" ?
thanks
There's not really a lightweight way to do this, but you have two options that I can think of depending on whether you want to keep the harness code you've written.
If you do, then you'd need to make a new target in your project for each class you drive with a harness, and have that target build just the class you are driving and a simple file with just the main code to drive that class.
If you don't, then you could make a target with a main, and each time you want to drive a different class, change which files are built, change the code in main, and rebuild.
This is assuming that you want to avoid both running and compiling the rest of your code. If you don't mind compiling everything, you could have one test-harness target that builds all of your classes, and either change main on the fly, or use #ifdefs or a runtime argument to decide which helper code to run.

Porting newlib to a custom ARM setup

this is my first post, and it covers something which I've been trying to get working on and off for about a year now.
Essentially it boils down to the following: I have a copy of newlib which I'm trying to get working on an LPC2388 (an ARM7TDMI from NXP). This is on a linux box using arm-elf-gcc
The question I have is that I've been looking at a lot of the tutorials talking about porting newlib, and they all talk about the stubs (like exit, open, read/write, sbrk), and I have a pretty good idea of how to implement all of these functions. But where should I put them?
I have the newlib distribution from sources.redhat.com/pub/newlib/newlib-1.18.0.tar.gz and after poking around I found "syscalls.c" (in newlib-1.18.0/newlib/libc/sys/arm) which contains all of the stubs which I have to update, but they're all filled in with rather finished looking code (which does NOT seem to work without the crt0.S, which itself does not work with my chip).
Should I just be wiping out those functions myself, and re-writing them? Or should I write them somewhere else. Should I make a whole new folder in newlib/libc/sys with the name of my "architecture" and change the target to match?
I'm also curious if there's proper etiquette on distribution of something like this after releasing it as an open source project. I currently have a script which downloads binutils, arm-elf-gcc, newlib, and gdb, and compiles them. If I am modifying files which are in the newlib directory, should I hand a patch which my script auto-applies? Or should I add the modified newlib to the repository?
Thanks for bothering to read! Following this is a more detailed breakdown of what I'm doing.
For those who want/need more info about my setup:
I'm building a ARM videogame console based loosely on the Uzebox project ( http://belogic.com/uzebox/ ).
I've been doing all sorts of things pulling from a lot of different resources as I try and figure it out. You can read about the start of my adventures here (sparkfun forums, no one responds as I figure it out on my own): forum.sparkfun.com/viewtopic.php?f=11&t=22072
I followed all of this by reading through the Stackoverflow questions about porting newlib and saw a few of the different tutorials (like wiki.osdev.org/Porting_Newlib ) but they also suffer from telling me to implements stubs without mentioning where, who, what, when, or how!
But where should I put them?
You can put them where you like, so long as they exist in the final link. You might incorporate them in the libc library itself, or you might keep that generic, and have the syscalls as a separate target specific object file or library.
You may need to create your own target specific crt0.s and assemble and link it for your target.
A good tutorial by Miro Samek of Quantum Leaps on getting GNU/ARM development up and running is available here. The examples are based on an Atmel AT91 part so you will need to know a little about your NXP device to adapt the start-up code.
A ready made Newlib porting layer for LPC2xxx was available here, but the links ot teh files appear to be broken. The same porting layer is used in Martin Thomas' WinARM project. This is a Windows port of GNU ARM GCC, but the examples included in it are target specific not host specific.
You should only need to modify the porting layer on Newlib, and since it is target and application specific, you need not (in fact probably should not) submit your code to the project.
When I was using newlib that is exactly what I did, blew away crt0.s, syscalls.c and libcfunc.c. My personal preference was to link in the replacement for crt0.s and syscalls.c (rolled the few functions in libcfunc into the syscalls.c replacement) based on the embedded application.
I never had an interest in pushing any of that work back into the distro, so cannot help you there.
You are on the right path though, crt0.S and syscalls.c are where you want to work to customize for your target. Personally I was interested in a C library (and printf) and would primarily neuter all of the functions to return 0 or 1 or whatever it took to get the function to just work and not get in the way of linking, periodically making the file I/O functions operate on linked in data in rom/ram. Basically without replacing or modifying any other files in newlib I had a fair amount of success, so you are on the right path.

Is there a way to mix MonoTouch and Objective-C?

I'd like to know if there is a way to mix C# and Obj-C code in one project. Specifically, I'd like to use Cocos2D for my UI in Obj-C and call some MonoTouch C#-Library that does some computations and get some values back. Is there a way to do this? Or maybe the other way around, i. e. building in MonoTouch and calling Cocos2D-functions?
Thanks.
The setup that you describe is possible, but the pipeline is not as smooth as it is when you do your entire project in MonoTouch. This is in fact how we bootstrapped MonoTouch: we took an existing Objective-C sample and we then replaced the bits one by one with managed code.
We dropped those samples as they bitrot.
But you can still get this done, use the mtouch's --xcode command line option to generate a sample program for you, and then copy the bits that you want from the generated template.m into your main.m. Customize the components that you want, and just start the XCode project from there.
During your development cycle, you will continue to use mtouch --xcode
Re: unknown (google):
We actually did this as described.
See this page for a quick start, but the last code segment on that page is wrong, because it's omitting the "--xcode"-parameter.
http://monotouch.net/Documentation/XCode
What you have to do to embed your Mono-EXE/DLL into an Objective-C program is to compile your source with SharpDevelop, then run mtouch with these parameters:
/Developer/MonoTouch/usr/bin/mtouch --linksdkonly --xcode=output_dir MyMonoAssembly.exe
This only works with the full version of MonoTouch. The trial does not allow to use the "--xcode"-argument . The "--linksdkonly"-argument is needed if you want mtouch to keep unreferenced classes in the compiled output, otherwise it strips unused code.
Then mtouch compiles your assembly into native ARM-code (file extension .s) and also generates a XCode template which loads the Mono-Runtime and your code inside the XCode/ObjC-program. You can now use this template right away and include your Obj-C-code or extract the runtime loading code from the "main.m"-file and insert it into your existing XCode-project. If you use an existing project you also have to copy all .exe/.dll/.s files from the xcode-output-dir that mtouch made.
Now you have your Mono-Runtime and assembly loaded in an XCode-project. To communicate with your assembly, you have to use the Mono-Embedding-API (not part of MonoTouch, but Mono). These are C-style API calls. For a good introduction see this page.
Also the Mono-Embedding-API documentation might be helpful.
What you have to do now in your Obj-C-code is to make Embedding-API calls. These steps might involve: Get the application domain, get the assembly, get the image of the assembly, locate the class you want to use, instantiate an object from that class, find methods in class, call methods on object, encapsulate method arguments in C-arrays and pass them to the method-call, get and extract method return values.
There are examples for this on the embedding-api-doc-page above.
You just have to be careful with memory consumption of your library, as the mono runtime takes some memory as well.
So this is the way from Obj-C to C#. If you want to make calls from C#/Mono into your Obj-C-program, you have to use the MonoTouch-bindings, which are described here.
You could also use pure C-method calls from the embedding/P/Invoke-API.
Hope this gets you started.
Over the weekend it emerged that someone has been porting Cocos2D to .NET, so you could also do the whole work on .NET:
http://github.com/city41/CocosNet
Cocos2D started as a Python project, that later got ported to Objective-C, and now there is an active effort to bring it to C#. It is not finished, but the author is accepting patches and might be a better way forward.
Calling Objective-C from MonoTouch definitely looks possible. See the Objective-C selector examples
What library are you calling? Perhaps there's an Objective-C equivalent.

Is there a script that turns a Pharo core image into something more useful, that would include an OmniBrowser?

I cannot use the most recent dev Pharo release because of some strange issues with the compiler built into Pharo. Well. I was wondering if there is a quick way to install all the nifty extras into Pharo that the core image misses, as compared to the dev image.
With all non-core Pharo images come a script which was used to build that image. Just edit that file and drag&drop it on a new core.
You could also tell me what you don't like in the Pharo images so that I can enhance them.
There is also the script I published on the Pharo wiki that I use to build my images:
http://code.google.com/p/pharo/wiki/ImageBuildScripts
Of course it is very specific to my preferences and needs, but you can take it as an example and adapt it to your own needs.
CommandShell works with Pharo 9.10.10. You will hit several errors as you try to load the package due to Pharo lacking MVC, but you can simply proceed past the first bunch and abandon the last one (that tries to actually open a CommandShell in Morphic). At that point, you'll have a class called PipeableOSProcess that can be used very easily to grab output. For example:
(PipeableOSProcess command: 'ls /bin') output
will return the contents of your bin directory as a string.
Ok, OB itself can be easily downloaded using ScriptLoader loadSuperOB.
Damien adds (from comment below):
The problem with that approach is that nobody really maintains it.
Moreover, you miss some configuration steps to enhance the use of OB
(for example, you won't have the OB-based browsers if you ask for the
senders of a message from a workspace)