承接上一篇,上一篇讲到可以在lldb调试中调用QuartzCore.framework里的CA::Render::Object::show方法来是观察CA::Render模块内的类的信息,但是在lldb控制台上却并没有任何输出信息,到底信息输出到哪里了呢,不知道最终目的去向,就等同功亏一篑。不着急(,话虽这样说),我们还是去看里面的反汇编代码,通过反汇编代码我们可以看到信息都是通过x_log函数输出的,里面又调用了x_logv函数。我要的答案就在这个x_logv函数里面,让我们来看看它的反汇编代码:
QuartzCore`x_logv: 0x107d10e54 <+0>: pushq %rbp 0x107d10e55 <+1>: movq %rsp, %rbp 0x107d10e58 <+4>: pushq %r15 0x107d10e5a <+6>: pushq %r14 0x107d10e5c <+8>: pushq %r13 0x107d10e5e <+10>: pushq %r12 0x107d10e60 <+12>: pushq %rbx 0x107d10e61 <+13>: subq $0x1018, %rsp 0x107d10e68 <+20>: movq %rdx, %r14 0x107d10e6b <+23>: movq %rsi, %rbx 0x107d10e6e <+26>: movl %edi, %r15d 0x107d10e71 <+29>: movq 0x36268(%rip), %r13 ; (void *)0x000000010bede070: __stack_chk_guard 0x107d10e78 <+36>: movq (%r13), %r13 0x107d10e7c <+40>: movq %r13, -0x30(%rbp) 0x107d10e80 <+44>: movq $0x0, -0x1038(%rbp) 0x107d10e8b <+55>: cmpq $-0x1, 0x35c4d(%rip) ; x_log_stream_slot + 7 0x107d10e93 <+63>: jne 0x107d10ff1 ; <+413> 0x107d10e99 <+69>: leal -0x1(%r15), %eax 0x107d10e9d <+73>: cmpl $0x1, %eax 0x107d10ea0 <+76>: ja 0x107d10ee4 ; <+144> 0x107d10ea2 <+78>: movb 0x35c18(%rip), %al ; x_log_html 0x107d10ea8 <+84>: testb %al, %al 0x107d10eaa <+86>: je 0x107d10ee4 ; <+144> 0x107d10eac <+88>: cmpl $0x2, %r15d 0x107d10eb0 <+92>: leaq 0x20cd8(%rip), %rax ; "err" 0x107d10eb7 <+99>: leaq 0x20cd5(%rip), %rdx ; "warn" 0x107d10ebe <+106>: cmoveq %rax, %rdx 0x107d10ec2 <+110>: leaq 0x20ccf(%rip), %rsi ; "<span class="%s">%s</span>" 0x107d10ec9 <+117>: leaq -0x1038(%rbp), %rdi 0x107d10ed0 <+124>: xorl %eax, %eax 0x107d10ed2 <+126>: movq %rbx, %rcx 0x107d10ed5 <+129>: callq 0x107d13bd8 ; symbol stub for: asprintf 0x107d10eda <+134>: testl %eax, %eax 0x107d10edc <+136>: cmovnsq -0x1038(%rbp), %rbx 0x107d10ee4 <+144>: movq 0x35bed(%rip), %rdi ; x_log_stream_slot 0x107d10eeb <+151>: testq %rdi, %rdi 0x107d10eee <+154>: je 0x107d10f2e ; <+218> 0x107d10ef0 <+156>: callq 0x107d13e96 ; symbol stub for: pthread_getspecific 0x107d10ef5 <+161>: movq %rax, %r12 0x107d10ef8 <+164>: testq %r12, %r12 0x107d10efb <+167>: je 0x107d10f2e ; <+218> 0x107d10efd <+169>: leaq -0x1030(%rbp), %r15 0x107d10f04 <+176>: movl $0x1000, %esi 0x107d10f09 <+181>: xorl %edx, %edx 0x107d10f0b <+183>: movl $0x1000, %ecx 0x107d10f10 <+188>: movq %r15, %rdi 0x107d10f13 <+191>: movq %rbx, %r8 0x107d10f16 <+194>: movq %r14, %r9 0x107d10f19 <+197>: callq 0x107d13bae ; symbol stub for: __vsnprintf_chk 0x107d10f1e <+202>: cmpl $0xfff, %eax 0x107d10f23 <+207>: jg 0x107d10f64 ; <+272> 0x107d10f25 <+209>: movq %r15, -0x1040(%rbp) 0x107d10f2c <+216>: jmp 0x107d10f76 ; <+290> 0x107d10f2e <+218>: movq 0x35b83(%rip), %rax ; x_log_function 0x107d10f35 <+225>: testq %rax, %rax 0x107d10f38 <+228>: je 0x107d10f4b ; <+247> 0x107d10f3a <+230>: movq 0x35b87(%rip), %rdx ; x_log_function_info 0x107d10f41 <+237>: movq %rbx, %rdi 0x107d10f44 <+240>: movq %r14, %rsi 0x107d10f47 <+243>: callq *%rax 0x107d10f49 <+245>: jmp 0x107d10fc8 ; <+372> 0x107d10f4b <+247>: movq 0x35b5e(%rip), %rdi ; x_log_file_handle 0x107d10f52 <+254>: testq %rdi, %rdi 0x107d10f55 <+257>: je 0x107d10fa0 ; <+332> 0x107d10f57 <+259>: movq %rbx, %rsi 0x107d10f5a <+262>: movq %r14, %rdx 0x107d10f5d <+265>: callq 0x107d13f98 ; symbol stub for: vfprintf 0x107d10f62 <+270>: jmp 0x107d10fc8 ; <+372> 0x107d10f64 <+272>: leaq -0x1040(%rbp), %rdi 0x107d10f6b <+279>: movq %rbx, %rsi 0x107d10f6e <+282>: movq %r14, %rdx 0x107d10f71 <+285>: callq 0x107d13f92 ; symbol stub for: vasprintf 0x107d10f76 <+290>: testl %eax, %eax 0x107d10f78 <+292>: jle 0x107d10f8d ; <+313> 0x107d10f7a <+294>: movq (%r12), %rdi 0x107d10f7e <+298>: movslq %eax, %rdx 0x107d10f81 <+301>: leaq -0x1030(%rbp), %rsi 0x107d10f88 <+308>: callq 0x107d12f64 ; x_stream_write 0x107d10f8d <+313>: movq -0x1040(%rbp), %rdi 0x107d10f94 <+320>: cmpq %r15, %rdi 0x107d10f97 <+323>: je 0x107d10fc8 ; <+372> 0x107d10f99 <+325>: callq 0x107d13d10 ; symbol stub for: free 0x107d10f9e <+330>: jmp 0x107d10fc8 ; <+372> 0x107d10fa0 <+332>: cmpl $0x1, %r15d 0x107d10fa4 <+336>: setne %al 0x107d10fa7 <+339>: movzbl %al, %eax 0x107d10faa <+342>: orl $0x4, %eax 0x107d10fad <+345>: cmpl $0x2, %r15d 0x107d10fb1 <+349>: movl $0x3, %edx 0x107d10fb6 <+354>: cmovnel %eax, %edx 0x107d10fb9 <+357>: xorl %edi, %edi 0x107d10fbb <+359>: xorl %esi, %esi 0x107d10fbd <+361>: movq %rbx, %rcx 0x107d10fc0 <+364>: movq %r14, %r8 0x107d10fc3 <+367>: callq 0x107d13bd2 ; symbol stub for: asl_vlog 0x107d10fc8 <+372>: movq -0x1038(%rbp), %rdi 0x107d10fcf <+379>: testq %rdi, %rdi 0x107d10fd2 <+382>: je 0x107d10fd9 ; <+389> 0x107d10fd4 <+384>: callq 0x107d13d10 ; symbol stub for: free 0x107d10fd9 <+389>: cmpq -0x30(%rbp), %r13 0x107d10fdd <+393>: jne 0x107d1100b ; <+439> 0x107d10fdf <+395>: addq $0x1018, %rsp 0x107d10fe6 <+402>: popq %rbx 0x107d10fe7 <+403>: popq %r12 0x107d10fe9 <+405>: popq %r13 0x107d10feb <+407>: popq %r14 0x107d10fed <+409>: popq %r15 0x107d10fef <+411>: popq %rbp 0x107d10ff0 <+412>: retq 0x107d10ff1 <+413>: leaq 0x35ae8(%rip), %rdi ; x_log_once 0x107d10ff8 <+420>: leaq 0x11(%rip), %rdx ; x_log_init 0x107d10fff <+427>: xorl %esi, %esi 0x107d11001 <+429>: callq 0x107d13c62 ; symbol stub for: dispatch_once_f 0x107d11006 <+434>: jmp 0x107d10e99 ; <+69> 0x107d1100b <+439>: callq 0x107d13b9c ; symbol stub for: __stack_chk_fail
相信也不会有人看的了,我下面贴上逆向出来的主要代码:
// 257 if (0 == x_log_file_handle) { // 254 (0 == rdi) // inline jmp 332 // 367 call asl_vlog(0, 0, (handle != 0x2) ? ((handle != 0x1) | 0x4) : 0x3, fmt, va_list); // natural flow goto _f372; } else { // 257 next // 265 call vfprintf(x_log_file_handle, fmt, va_list); // 270 goto _f372; } // 270 unreachable _f372: // from 330
可以看到这里有一个分支,分别用asl_vlog或vfprintf来输出信息。首先asl_vlog就是bsd系统的syslog系统日志函数,接着是vfprintf是我们熟悉的crt函数。当没有指定目标输出文件时,信息将输出到系统日志。好这就可以去系统日志控制台查找,但是系统日志var/logs里面的虽然有不少asl节点, 却权限问题访问不了的有很多,而且在可访问的节点里找不到我想要的信息。这也好办,可以使用vfprintf函数的输出,我们只要在lldb调试当中将打开的文件写入到全局变量x_log_file_handle,然后再使用上一篇介绍过的方法调用CA::Render::Layer::show方法。日志文件被写入了信息,这样我们就可以使用其自身的日志功能,查找收集一些内部的信息了。