0-0
0-0

Reputation: 482

GDB script to trace Objective-C calls on iOS device - issue

I have a gdb script I am working on to trace all objective-C method calls that pass through objc_msgSend but Ive encountered a problem I cant seem to deal with. After review of the Objective-C runtime source code I have developed the following script to print [ ] at each break on objc_msgSend. The issue is that there are situations in which data_NEVER_USE is not a valid pointer but is also not null. The only indicator that I can find of whether a class is initialized is in id->data_NEVER_USE->flags & RW_REALIZED. What aspect of class initialization am I missing here that would allow me to skip this case?

b objc_msgSend
c
commands
silent

if (*$r0 == 0)
    continue
end

set $id = (class_t *)$r0
set $sel = $r1      
print *$id  
if($id->data_NEVER_USE != 0)
    set $data = (class_ro_t *) ($id->data_NEVER_USE)
    if (($data->flags & 0x80000000) && ($data->name))
        set $classname = $data->name
        printf "[%s ", $classname
    else
        continue
    end
end

if ($sel != 0)
    printf "%s", $sel
else
    printf "null"
end

printf "]\n"
continue
end

I appreciate any help on this. Thanks.

Upvotes: 4

Views: 2331

Answers (1)

Mick
Mick

Reputation: 13495

These 2 methods have worked reasonably well for me. Note that in my example I am manually starting "SomeApp" in order to monitor it as soon as it starts up.

gdb
(gdb) attach --waitfor 'SomeApp'

**this is where you manually start SomeApp on your device**

call (void)instrumentObjcMessageSends(YES)

The "instrumentObjcMessageSends" enables/disables message logging from within the runtime. Here's some more information on this method.

Another option, again still using GDB on your iDevice, is to write a small command like this:

FooPad:~ root# gdb
(gdb) attach SBSettings
Attaching to process 440.
Reading symbols for shared libraries . done
Reading symbols for shared libraries ............................. done
0x35686004 in mach_msg_trap ()

(gdb) break objc_msgSend
Breakpoint 1 at 0x3323ef72

(gdb) commands
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".

>printf "-[%s %s]\n", (char *)class_getName(*(long *)$r0,$r1),$r1
>c
>end

(gdb) c
Continuing.
// a ton of information will follow

As soon as you press "c" (right above line that reads "Continuing.", your screen will fill with function names and arguments.

And finally follow these instructions to get a working GDB on your iDevice. For posterity I'll post the short instructions here:

GNU Debugger (gdb) is used to analyze the run time behavior of an iOS application. In recent iOS versions, GNU Debugger directly downloaded from the Cydia is broken and not functioning properly. Following the Pod 2g blog post also did not help me.

To get rid of this problem, add http://cydia.radare.org to cydia source and download the latest GNU Debugger (build 1708). GDB build 1708 is working for iOS 5.x.

Upvotes: 6

Related Questions