Over a million developers have joined DZone.

LLDB: Examining a Program: Part I

DZone's Guide to

LLDB: Examining a Program: Part I

Today, we're going to start looking at LLDB, and how you can use it for dynamic program analysis.

· Mobile Zone
Free Resource

Get gorgeous, multi-touch charts for your iOS application with just a few lines of code.

So in my past few pieces, I've reviewed how to examine programs compiled for iOS. I've used common UNIX staples like strings, and file; I've also used MacOS specific tools like oTool and class-dump. I've shown you how you can use tcpdump with Wireshark for communication analysis too. I haven't shown you how to do any binary analysis yet, either static or dynamic.

Static analysis involves using tools like r2, IDA, or Angr. You can use tools like the Retargetable Decompiler as well. Dynamic analysis involves running the program and looking for potential exploits. There's a slew of tools out there for this kind of thing too, including debuggers like GDB or LLDB.

Today, we're going to start looking at LLDB, and how you can use it for dynamic program analysis.

Setting up Remote Debugging

The first thing you'll need to do is get your hands on a jailbroken iPhone. I've written a couple of pieces on how to do this, you can follow those as guides. The difficult thing at this point is that iOS has been updated to 10.0.2, and you'll need a device at 9.2 - 9.3.3 to successfully jailbreak today. There's iOS 10.0.X jailbreaks out there in the wild, but nothing that's been released publicly yet, unfortunately.

You need to connect your jailbroken iDevice to your workstation via gandalf, and you'll need to log in (the configuration you need to do this is covered in past articles too). Next, you need to sign the debugserver executable and move it to your iPhone (or iPad). You can follow the 64-bit section in this guide to configure and move your debugserver executable.

Now, you can debug executables remotely on your iPhone. Now let's configure your build environment.

Building Simple C Programs for iOS

Okay, so you need to find a copy of ldid and install it on your phone. This will allow you to pseudo-sign the executables we'll run. You can install ldid via Cydia, just like you did OpenSSH. There's other ways to sign executables, but this one is the easiest I think.

Anyway, now let's put together a simple program and makefile, and get the executable onto our phone.

Here's your makefile:

IOS_TARGET=-target armv7s-apple-ios -isysroot $(SDK)


%.o: %.c
$(CC) -c -o $@ $< $(ARGS)

main: $(OBJ)
$(CC) -o function function.o $(ARGS) $(NO_ASLR_FLAGS)

rm *.o function
rm -rf *.dSYM

(EDIT: a line in the above makefile isn't displaying correctly - it should be "$(CC) -c -o $@ $< $(ARGS)")

This makefile uses clang as the C compiler on a mac. We have a simple program we'll compile, function.c, but we'll get to that later. We're going to compile the program with full debugging symbols (-g) and no ASLR (-wl,-no_pie). We're also going to compile a 32-bit program, not a 64-bit program, via the armv7s-apple-ios triple. We could compile for 64-bit using arm64-apple-ios, but then we can't turn off ASLR, and with ASLR off, the addresses won't shift around between executions. Also note the SDK we're using - iPhoneOS10.0.sdk. You might want to copy this somewhere for safekeeping - these SDKs are replaced based on your version of XCode, and old ones may not be maintained.

The program we'll use is simple:

void call(void) {
  int j = 0xcafed00d;

int main(int argc, char* argv[]) {
  int i = 0xdeadc0de;
  return 0;

All we're doing is compiling a simple program that calls a function. We're using the values 0xcafed00d and 0xdeadc0de to identify locations in memory.

With this program next to your makefile, you should be able to compile function.c. Next time, we'll copy the program to your phone, sign it, and debug it.

.Net developers: use Highcharts, the industry's leading interactive charting library, without writing a single line of JavaScript.

iphone (ios) ,lldb

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}