4

我有一个 gdb 脚本,我正在处理所有通过 objc_msgSend 的 Objective-C 方法调用,但我遇到了一个我似乎无法处理的问题。在查看了 Objective-C 运行时源代码之后,我开发了以下脚本来在 objc_msgSend 的每个中断处打印 [ ]。问题是在某些情况下 data_NEVER_USE 不是有效指针但也不为空。我能找到的关于一个类是否已初始化的唯一指标是 id->data_NEVER_USE->flags & RW_REALIZED。我在这里遗漏了类初始化的哪些方面可以让我跳过这种情况?

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

我很感激这方面的任何帮助。谢谢。

4

1 回答 1

6

这两种方法对我来说效果很好。请注意,在我的示例中,我手动启动“SomeApp”以便在它启动后立即对其进行监控。

gdb
(gdb) attach --waitfor 'SomeApp'

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

call (void)instrumentObjcMessageSends(YES)

“instrumentObjcMessageSends”在运行时启用/禁用消息记录。这是有关此方法的更多信息。

另一个选项,仍然在你的 iDevice 上使用 GDB,是写一个像这样的小命令:

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

一旦你按下“c”(就在上面写着“Continuing.”的那一行,你的屏幕就会填满函数名和参数。

最后按照这些说明在您的 iDevice 上获得一个正常工作的 GDB。为了后代,我将在此处发布简短说明:

GNU 调试器 (gdb) 用于分析 iOS 应用程序的运行时行为。在最近的 iOS 版本中,直接从 Cydia 下载的 GNU 调试器已损坏且无法正常运行。关注 Pod 2g 博客文章也没有帮助我。

要解决这个问题,请将http://cydia.radare.org添加到 cydia 源并下载最新的 GNU 调试器(build 1708)。GDB build 1708 适用于 iOS 5.x。

于 2012-10-18T22:41:22.513 回答