DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
What's in store for DevOps in 2023? Hear from the experts in our "DZone 2023 Preview: DevOps Edition" on Fri, Jan 27!
Save your seat

LLDB: Examining a Program: Part III

By the end of Part III, you'll have an application running on iOS and we're debugging it from our local mac!

Christopher Lamb user avatar by
Christopher Lamb
CORE ·
Oct. 15, 16 · Opinion
Like (2)
Save
Tweet
Share
2.88K Views

Join the DZone community and get the full member experience.

Join For Free

We have everything set at this point to start remote debugging. We have our remote debugger configured and signed, we've moved over and signed our executable as well, and it runs. Let's spin it up and take a look.

Starting a Program with Debugserver

So, we need to do a couple of things here. First, you need to configure gandalf to multiplex the debug port on your phone to a port on your localsystem. To do this, your gandalf mapping file should contain something like this:

{"udid":"53b02cd8f5e3826f76dc0c70467fbf0b8b9684ae",
  "name":"i11", "forwarding": [{"local_port":2002, "device_port":22},
                               {"local_port":3000, "device_port":1122},
                               {"local_port":23946,"device_port":23946}]
                               }

Note the last line, where we map the port 23946 on the phone to 23946 on your local system. This is vital - this is the port debugserver will use to share debugging information with your local installation of lldb.

If this isn't in your mapping file, include it (the last line specifically, remember, the udid of your device will differ, and you need to make sure that these ports aren't being used for anything else or by another multiplexed phone on your computer).

Restart gandalf, you should be able to log back into your phone via SSH.

Now, on your phone, execute this command:

$ debugserver *:23946 ./function
debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-340.3.124 for arm64.
Listening to port 23946 for a connection from *...

Good! It's hanging out, waiting for a remote debugger to attach. The *:23946 clause tells debugserver to accept connections from anywhere over port 23946. You can make this more restrictive, but as I use usbmux on a phone with no internet connection, this is fine. If you're attaching over TCP/IP (which you can do), I'd include the address of the host system, so this clause would look something like <my mac workstation address>:23946.

Now, let's attach.

Attaching with LLDB

Attaching is pretty straightforward:

$ lldb
(lldb) platform select remote-ios 
  Platform: remote-ios
 Connected: no
  SDK Path: "/Users/cclamb/Library/Developer/Xcode/iOS DeviceSupport/9.3.3 (13G34)"
  SDK Roots: [ 0] "/Users/cclamb/Library/Developer/Xcode/iOS DeviceSupport/9.3.3 (13G34)"
(lldb) process connect connect://localhost:23946
Process 1543 stopped
* thread #1: tid = 0xae1f0, 0x1fe29000 dyld`_dyld_start, stop reason = signal SIGSTOP
    frame #0: 0x1fe29000 dyld`_dyld_start
dyld`_dyld_start:
->  0x1fe29000 <+0>:  mov    r8, sp
    0x1fe29004 <+4>:  sub    sp, sp, #16
    0x1fe29008 <+8>:  bic    sp, sp, #15
    0x1fe2900c <+12>: ldr    r3, [pc, #0x70]           ; <+132>
(lldb)

Sweet!

Your data after selecting the remote-ios platform may very well differ; this is just fine. This is configured when you attach a device with a particular iOS revision level to your mac, and I haven't attached any devices at iOS 10 yet.

So, you can see some disassembly here. But wait, why not C code? you compiled with -g right?

Well, that's because you're not actually in your program yet! Let's see where we are:

(lldb) thread backtrace 
* thread #1: tid = 0xae1f0, 0x1fe29000 dyld`_dyld_start, stop reason = signal SIGSTOP
  * frame #0: 0x1fe29000 dyld`_dyld_start

So, we're in dyld:_dyld_start (you can actually see this in the previous output too). Wait, what?

Well, in iOS, every executable needs to be dynamically linked; as a result, every executable is started from _dyld_start(.) in the dynamic linker (dyld). You can see details on this linker by looking at the currently loaded libraries:

(lldb) image list
[  0] 02354203-2680-372F-8D38-3C4C2B42A8A3 0x1fe28000 /Users/cclamb/Library/Developer/Xcode/iOS DeviceSupport/9.3.3 (13G34)/Symbols/usr/lib/dyld 

We only have one library loaded right now - dynamic linker. This will change.

Now, let's set a breakpoint in main and run:

(lldb) breakpoint set --name main
Breakpoint 1: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.
(lldb) continue
Process 1543 resuming
1 location added to breakpoint 1
Process 1543 stopped
* thread #1: tid = 0xae1f0, 0x0000bff4 function`main(argc=1, argv=0x0010ff44) + 22 at function.c:7, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000bff4 function`main(argc=1, argv=0x0010ff44) + 22 at function.c:7
   4   }
   5   
   6   int main(int argc, char* argv[]) {
-> 7     int i = 0xdeadc0de;
   8     call();
   9     return 0;
   10  }

Ah, here's some C source. Excellent - we have an application running on iOS and we're debugging it from our local mac!

Feel free to experiment with some additional lldb commands at this point to learn your way around a bit. In the next installment we'll look over the registers and stack, and then we'll start building a stack buffer overflow exploit example.

LLDB (debugger)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Explainer: Building High Performing Data Product Platform
  • Simulating and Troubleshooting StackOverflowError in Kotlin
  • How to Perform Accessibility Testing of Websites and Web Apps
  • Build CRUD RESTful API Using Spring Boot 3, Spring Data JPA, Hibernate, and MySQL Database

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: