本工具第五版本第三个功能就是,逆向输出代码。
结合第三版和第四版的逆向输出策略,折中出一种方便人工判断可内联选择的输出策略,输出分支结构。
另外就是将函数调用输出插入到分支代码中。
我选了一个函数做示范,分别贴上反汇编代码和逆向输出的代码:
相信没什么人会去看反汇编代码的了,就先贴逆向输出的代码:(!不是表示ne,nz,ns等否定跳转条件,而是指跳转条件不成功的情况分支)
void CA::Layer::commit_animations(CA::Transaction*, double(*)(CA::Layer*, double, void*), void(*)(CA::Layer*, CA::Render::Animation*, void*), void(*)(CA::Layer*, __CFString const*, void*), void*) { // 51 if (!) { _b127: // from 774 // 134 if () { // gen jmp 470 goto _f470; } else { // 134 next // 142 if (!) { // 159 call CAAnimationGetFlags;; // 170 if (!) { // 190 call // %rsi = "beginTimeMode" objc_msgSend;; // 203 if () { // gen jmp 235 goto _f235; // 215 call // %rsi = "beginTime" objc_msgSend;; } // 233 else if () { // gen jmp 351 goto _f351; } else { // 233 next _f235: // from 203 } // 235 // 242 if () { // gen jmp 335 goto _f335; } else { // 242 next // 248 if () // gen jmp 446 goto _f446; // 268 call // %rsi = "isEqualToString:" objc_msgSend;; // 276 if () { // gen jmp 308 goto _f308; // 288 call // %rsi = "beginTime" objc_msgSend;; } // 306 else if () { // gen jmp 351 goto _f351; } else { // 306 next _f308: // from 276 } // 308 // 325 call // %rsi = "isEqualToString:" objc_msgSend;; // 333 if () // gen jmp 446 goto _f446; } // 335 _f335: // from 242 // 345 call // %rsi = "beginTime" objc_msgSend;; _f351: // from 306 _f351: // from 233 } // 351 // 358 call *-0x68(%rbp);; // 377 call CAAnimationSetFlags;; // 408 call // %rsi = "setBeginTime:" *%rbx;; // 425 call // %rsi = "setBeginTimeMode:" *%rbx;; // 441 call CAAnimationSetFlags;; _f446: // from 333 _f446: // from 248 // 459 goto _f546; } // 461 // 468 if () // gen jmp 512 goto _f512; } // 470 _f470: // from 134 // 479 if (!) { // 493 if (!) { // 507 goto _f768; _f512: // from 468 // 526 if (!) { // 528 call CA::Render::Object::unref() const;; } // 538 _f546: // from 459 // 548 if (!) { // 570 call // %rsi = "_copyRenderAnimationForLayer:" objc_msgSend;; // 582 if (!) { // 595 call CA::Render::Animation::set_identifier(__CFString const*);; // 633 call // %rsi = "class" // %rdi = (void *)0x000000010421c658: CAPropertyAnimation *%r12;; // 649 call // %rsi = "isKindOfClass:" *%r12;; // 654 if (!) { // 663 call CA::Render::key_path_count(void* const*);; // 671 if (!) { // 684 call CA::Render::key_path_copy(void**, void* const*);; // 695 call CA::Render::PropertyAnimation::set_property(void* const*);; } // 700 } // 700 // 714 call *-0x78(%rbp);; // 729 if (!) { // 731 call CA::Render::Object::ref() const;; } // 736 // 743 call CA::Render::Object::unref() const;; } // 748 } // 748 // 753 if (!) { // 759 call CAMediaTimingCopyRenderTiming;; _f768: // from 507 } // 768 } // 768 } // 768 // 774 if () goto _b127; _b791: // from 890 _b794: // from 864 // 800 if (!) { // 818 if (!) { // 830 call *-0x48(%rbp);; } // 833 // 836 call schedule_stop_callback(CA::Layer::Animation*);; // 864 if () goto _b794; // 866 goto _f892; } // 868 // 870 if (!) { } // 881 // 890 if () goto _b791; _f892: // from 866 // 899 call CA::Layer::set_animations(CA::Layer::Animation*);; } // 904 }
然后就是反汇编代码:
QuartzCore`CA::Layer::commit_animations: <+0>: pushq %rbp <+1>: movq %rsp, %rbp <+4>: pushq %r15 <+6>: pushq %r14 <+8>: pushq %r13 <+10>: pushq %r12 <+12>: pushq %rbx <+13>: subq $0x78, %rsp <+17>: movq %r8, -0x48(%rbp) <+21>: movq %rcx, -0x78(%rbp) <+25>: movq %rdx, -0x68(%rbp) <+29>: movq %rdi, %r12 <+32>: movq %r12, -0x80(%rbp) <+36>: movq 0x98(%r12), %r15 <+44>: movq %r15, -0x30(%rbp) <+48>: testq %r15, %r15 <+51>: je 0x1041b1e4e ; <+904> <+57>: movq %r9, -0x58(%rbp) <+61>: movq %r15, -0x90(%rbp) <+68>: movq 0x50(%rsi), %rax <+72>: movl 0x5c(%rax), %eax <+75>: movl %eax, -0x3c(%rbp) <+78>: leaq 0x746f5(%rip), %rax ; kCAAnimationNonZero <+85>: movq (%rax), %rax <+88>: movq %rax, -0x70(%rbp) <+92>: leaq 0x746f7(%rip), %rax ; kCAAnimationRelative <+99>: movq (%rax), %rax <+102>: movq %rax, -0x88(%rbp) <+109>: leaq 0x746de(%rip), %rax ; kCAAnimationAbsolute <+116>: movq (%rax), %rax <+119>: movq %rax, -0x60(%rbp) <+123>: leaq -0x30(%rbp), %r14 <+127>: movzwl 0x38(%r15), %eax <+132>: testb $0x8, %al <+134>: jne 0x1041b1c9c ; <+470> <+140>: testb $0x2, %al <+142>: jne 0x1041b1c93 ; <+461> <+148>: movl -0x3c(%rbp), %eax <+151>: movl %eax, 0x2c(%r15) <+155>: movq 0x8(%r15), %rdi <+159>: callq 0x1041914d3 ; CAAnimationGetFlags <+164>: xorpd %xmm0, %xmm0 <+168>: testb $0x4, %al <+170>: jne 0x1041b1c25 ; <+351> <+176>: movq 0x8(%r15), %r13 <+180>: movq %r13, %rdi <+183>: movq 0x691c4(%rip), %rsi ; "beginTimeMode" <+190>: callq *0x6e6ae(%rip) ; (void *)0x000000010357d800: objc_msgSend <+196>: movq %rax, %rbx <+199>: cmpq -0x70(%rbp), %rbx <+203>: jne 0x1041b1bb1 ; <+235> <+205>: movq %r13, %rdi <+208>: movq 0x688cb(%rip), %rsi ; "beginTime" <+215>: callq *0x6e695(%rip) ; (void *)0x000000010357d800: objc_msgSend <+221>: movapd %xmm0, %xmm1 <+225>: xorpd %xmm0, %xmm0 <+229>: ucomisd %xmm0, %xmm1 <+233>: je 0x1041b1c25 ; <+351> <+235>: cmpq -0x88(%rbp), %rbx <+242>: je 0x1041b1c15 ; <+335> <+244>: cmpq -0x60(%rbp), %rbx <+248>: je 0x1041b1c84 ; <+446> <+254>: movq %rbx, %rdi <+257>: movq 0x68532(%rip), %rsi ; "isEqualToString:" <+264>: movq -0x70(%rbp), %rdx <+268>: callq *0x6e660(%rip) ; (void *)0x000000010357d800: objc_msgSend <+274>: testb %al, %al <+276>: je 0x1041b1bfa ; <+308> <+278>: movq %r13, %rdi <+281>: movq 0x68882(%rip), %rsi ; "beginTime" <+288>: callq *0x6e64c(%rip) ; (void *)0x000000010357d800: objc_msgSend <+294>: movapd %xmm0, %xmm1 <+298>: xorpd %xmm0, %xmm0 <+302>: ucomisd %xmm0, %xmm1 <+306>: je 0x1041b1c25 ; <+351> <+308>: movq %rbx, %rdi <+311>: movq 0x684fc(%rip), %rsi ; "isEqualToString:" <+318>: movq -0x88(%rbp), %rdx <+325>: callq *0x6e627(%rip) ; (void *)0x000000010357d800: objc_msgSend <+331>: testb %al, %al <+333>: je 0x1041b1c84 ; <+446> <+335>: movq %r13, %rdi <+338>: movq 0x68849(%rip), %rsi ; "beginTime" <+345>: callq *0x6e613(%rip) ; (void *)0x000000010357d800: objc_msgSend <+351>: movq %r12, %rdi <+354>: movq -0x58(%rbp), %rsi <+358>: callq *-0x68(%rbp) <+361>: movsd %xmm0, -0x50(%rbp) <+366>: movq 0x8(%r15), %rdi <+370>: movl $0x5, %esi <+375>: xorl %edx, %edx <+377>: callq 0x1041914ba ; CAAnimationSetFlags <+382>: movq 0x8(%r15), %rdi <+386>: movq 0x687e1(%rip), %rsi ; "setBeginTime:" <+393>: movsd -0x50(%rbp), %xmm0 <+398>: movq 0x6e5dd(%rip), %rax ; (void *)0x000000010357d800: objc_msgSend <+405>: movq %rax, %rbx <+408>: callq *%rbx <+410>: movq 0x8(%r15), %rdi <+414>: movq 0x690bd(%rip), %rsi ; "setBeginTimeMode:" <+421>: movq -0x60(%rbp), %rdx <+425>: callq *%rbx <+427>: movq 0x8(%r15), %rdi <+431>: movl $0x1, %esi <+436>: movl $0xffffffff, %edx <+441>: callq 0x1041914ba ; CAAnimationSetFlags <+446>: movzwl 0x38(%r15), %eax <+451>: orl $0x2, %eax <+454>: movw %ax, 0x38(%r15) <+459>: jmp 0x1041b1ce8 ; <+546> <+461>: movl -0x3c(%rbp), %ecx <+464>: cmpl %ecx, 0x2c(%r15) <+468>: jne 0x1041b1cc6 ; <+512> <+470>: testb $0x8, 0x85(%r12) <+479>: jne 0x1041b1dc6 ; <+768> <+485>: movl %eax, %ecx <+487>: andl $0x1, %ecx <+490>: testw %cx, %cx <+493>: je 0x1041b1dc6 ; <+768> <+499>: orl $0x4, %eax <+502>: movw %ax, 0x38(%r15) <+507>: jmp 0x1041b1dc6 ; <+768> <+512>: movl -0x3c(%rbp), %ecx <+515>: movl %ecx, 0x2c(%r15) <+519>: movq 0x20(%r15), %rdi <+523>: testq %rdi, %rdi <+526>: je 0x1041b1ce0 ; <+538> <+528>: callq 0x1040f45ac ; CA::Render::Object::unref() const <+533>: movzwl 0x38(%r15), %eax <+538>: movq $0x0, 0x20(%r15) <+546>: testb $0x40, %al <+548>: je 0x1041b1db2 ; <+748> <+554>: movq 0x8(%r15), %rdi <+558>: movq 0x10(%r12), %rdx <+563>: movq 0x688e8(%rip), %rsi ; "_copyRenderAnimationForLayer:" <+570>: callq *0x6e532(%rip) ; (void *)0x000000010357d800: objc_msgSend <+576>: movq %rax, %r13 <+579>: testq %r13, %r13 <+582>: je 0x1041b1db2 ; <+748> <+588>: movq 0x18(%r15), %rsi <+592>: movq %r13, %rdi <+595>: callq 0x1040c40c8 ; CA::Render::Animation::set_identifier(__CFString const*) <+600>: movl 0x28(%r15), %eax <+604>: movl %eax, 0x30(%r13) <+608>: movq 0x8(%r15), %rbx <+612>: movq 0x69b6f(%rip), %rdi ; (void *)0x000000010421c658: CAPropertyAnimation <+619>: movq 0x68448(%rip), %rsi ; "class" <+626>: movq 0x6e4f9(%rip), %r12 ; (void *)0x000000010357d800: objc_msgSend <+633>: callq *%r12 <+636>: movq %rbx, %rdi <+639>: movq 0x6850c(%rip), %rsi ; "isKindOfClass:" <+646>: movq %rax, %rdx <+649>: callq *%r12 <+652>: testb %al, %al <+654>: je 0x1041b1d82 ; <+700> <+656>: movq %r13, %rdi <+659>: addq $0x40, %rdi <+663>: callq 0x1040e057c ; CA::Render::key_path_count(void* const*) <+668>: testq %rax, %rax <+671>: jne 0x1041b1d82 ; <+700> <+673>: leaq 0x10(%r15), %rsi <+677>: leaq -0x38(%rbp), %rbx <+681>: movq %rbx, %rdi <+684>: callq 0x1040e07c2 ; CA::Render::key_path_copy(void**, void* const*) <+689>: movq %r13, %rdi <+692>: movq %rbx, %rsi <+695>: callq 0x1040c410c ; CA::Render::PropertyAnimation::set_property(void* const*) <+700>: movq -0x80(%rbp), %r12 <+704>: movq %r12, %rdi <+707>: movq %r13, %rsi <+710>: movq -0x58(%rbp), %rdx <+714>: callq *-0x78(%rbp) <+717>: movq 0x10(%r13), %rdi <+721>: testq %rdi, %rdi <+724>: movl $0x0, %eax <+729>: je 0x1041b1da6 ; <+736> <+731>: callq 0x1040f44d2 ; CA::Render::Object::ref() const <+736>: movq %rax, 0x20(%r15) <+740>: movq %r13, %rdi <+743>: callq 0x1040f45ac ; CA::Render::Object::unref() const <+748>: cmpq $0x0, 0x20(%r15) <+753>: jne 0x1041b1dc6 ; <+768> <+755>: movq 0x8(%r15), %rdi <+759>: callq 0x1041be3d5 ; CAMediaTimingCopyRenderTiming <+764>: movq %rax, 0x20(%r15) <+768>: movq (%r15), %r15 <+771>: testq %r15, %r15 <+774>: jne 0x1041b1b45 ; <+127> <+780>: movq -0x58(%rbp), %r15 <+784>: movq -0x90(%rbp), %rax <+791>: movq %rax, %rbx <+794>: movzwl 0x38(%rbx), %eax <+798>: testb $0xc, %al <+800>: je 0x1041b1e2a ; <+868> <+802>: movq (%rbx), %rax <+805>: movq %rax, (%r14) <+808>: movzwl 0x38(%rbx), %eax <+812>: andl $0x4c, %eax <+815>: cmpl $0x44, %eax <+818>: jne 0x1041b1e07 ; <+833> <+820>: movq 0x18(%rbx), %rsi <+824>: movq %r12, %rdi <+827>: movq %r15, %rdx <+830>: callq *-0x48(%rbp) <+833>: movq %rbx, %rdi <+836>: callq 0x1041b159c ; schedule_stop_callback(CA::Layer::Animation*) <+841>: movq 0x6d932(%rip), %rax ; animation_state (.2) <+848>: movq %rax, (%rbx) <+851>: movq %rbx, 0x6d928(%rip) ; animation_state (.2) <+858>: movq (%r14), %rbx <+861>: testq %rbx, %rbx <+864>: jne 0x1041b1de0 ; <+794> <+866>: jmp 0x1041b1e42 ; <+892> <+868>: testb $0x10, %al <+870>: je 0x1041b1e37 ; <+881> <+872>: andl $0xffef, %eax <+877>: movw %ax, 0x38(%rbx) <+881>: movq (%rbx), %rax <+884>: testq %rax, %rax <+887>: movq %rbx, %r14 <+890>: jne 0x1041b1ddd ; <+791> <+892>: movq -0x30(%rbp), %rsi <+896>: movq %r12, %rdi <+899>: callq 0x1041b0e50 ; CA::Layer::set_animations(CA::Layer::Animation*) <+904>: addq $0x78, %rsp <+908>: popq %rbx <+909>: popq %r12 <+911>: popq %r13 <+913>: popq %r14 <+915>: popq %r15 <+917>: popq %rbp <+918>: retq
分析大厂的源代码,没源代码就自已逆向出来。