自制反汇编逆向分析工具 迭代第四版本

上一个版本,本工具支持的第一个逆向策略,(对反汇编的函数体内的分支控制结构逆向生成cpp代码,)一直都可以正常工作,直到遇上了一个函数。这个使我的逆向策略算法失效的函数,主要的特点是它含有众多无条件跳转指令(,都是在函数体内的跳转)。

为什么无条件跳转指令会使得我的第一个逆向算法失效,因为这些无条件跳转指令让函数的执行流变得不易于线性理解。

在一个没有反汇编出来的函数汇编代码中,如果无条件跳转指令很少,特殊地连一条无条件跳转指令也没有时,将汇编代码的执行流当作行文阅读,总可以找到一个特例让所有条件跳转满足一种情况,使得行文可以从头到尾。中间的条件跳转就像,你愿意不愿意对跳转的区域行文阅读,但总的来说,情节还是单线顺序发展的。

但是反汇编出来的函数汇编代码中,包含了很多无条件跳转指令,代码的行文就会变得支离破碎。或者说有很多插叙或倒叙,你的行文阅读(某条主线或支线,执行流)并不要知道某些插叙或倒叙,这时就会有无条件跳转。你不得不去不停地翻书的页(,在函数汇编代码中跳来跳去)。插叙和倒叙,叙述了并行发展的情节(,不是并行执行的那个并行),而且不同的情节之间还会有关联(相交点),每个情节抽离出来都是一个故事支线。要完整呈现这个支线故事就不得不从其他支线故事中引用相关(双线交叉)的情节,就像内联一样。所有的顺叙,插叙或倒叙中的某段情节都将可能会内联到某一个支线故事当中去。

所以对于这种包含了很多无条件跳转指令的函数,我想到的是函数体使用了内联,还可能是宏的方式。比如定义了三个代码片段的宏ABCBC都使用了A。一个函数内多次是使用了这三个宏的话,编译器可能会将A抽出来,将A内联到的地方都无条件跳转到A的代码片段,A代码片段结束处又无条件跳转到另一处。因此我也使用同样的策略来处理这种逆向情况,将汇编代码进行内联。

 

下面这个包含多个jmp指令的函数CA::Layer::collect_animations__的反汇编代码:

 

QuartzCore`CA::Layer::collect_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   $0x48, %rsp
     <+17>:   movq   %rsi, %rbx
     <+20>:   movapd %xmm0, %xmm1
     <+24>:   movss  0x8(%rdx), %xmm0
     <+29>:   andps  0x3d8de(%rip), %xmm0      ; .memset_pattern + 560
     <+36>:   orps   0x3d8e7(%rip), %xmm0      ; .memset_pattern + 576
     <+43>:   cvtss2sd %xmm0, %xmm0
     <+47>:   movsd  %xmm0, -0x48(%rbp)
     <+52>:   movq   0x98(%rdi), %rax
     <+59>:   movq   %rax, -0x30(%rbp)
     <+63>:   testq  %rax, %rax
     <+66>:   je     0x1041b20bf               ; <+145>
     <+68>:   leaq   0x4(%rdi), %rsi
     <+72>:   leaq   -0x30(%rbp), %rcx
     <+76>:   movq   %rcx, -0x40(%rbp)
     <+80>:   xorl   %r12d, %r12d
     <+83>:   testl  $0x1800000, 0x4(%rdi)
     <+90>:   je     0x1041b20c6               ; <+152>
     <+92>:   movq   %rbx, -0x60(%rbp)
     <+96>:   lock   
     <+97>:   andl   $0xfe7fffff, (%rsi)
     <+103>:  movq   -0x30(%rbp), %rax
     <+107>:  xorl   %ecx, %ecx
     <+109>:  testq  %rax, %rax
     <+112>:  je     0x1041b235a               ; <+812>
     <+118>:  movq   %rsi, -0x68(%rbp)
     <+122>:  movq   %rdx, %r14
     <+125>:  xorl   %ecx, %ecx
     <+127>:  movq   %rcx, -0x50(%rbp)
     <+131>:  movsd  %xmm1, -0x38(%rbp)
     <+136>:  movq   %rdi, -0x70(%rbp)
     <+140>:  xorl   %r12d, %r12d
     <+143>:  jmp    0x1041b20e0               ; <+178>
     <+145>:  xorl   %eax, %eax
     <+147>:  jmp    0x1041b24b8               ; <+1162>
     <+152>:  movq   %rsi, -0x68(%rbp)
     <+156>:  movq   %rdx, %r14
     <+159>:  xorl   %ecx, %ecx
     <+161>:  movq   %rcx, -0x50(%rbp)
     <+165>:  movsd  %xmm1, -0x38(%rbp)
     <+170>:  movq   %rdi, -0x70(%rbp)
     <+174>:  movq   %rbx, -0x60(%rbp)
     <+178>:  xorl   %ecx, %ecx
     <+180>:  movq   %rcx, -0x58(%rbp)
     <+184>:  movq   %rax, %rbx
     <+187>:  testb  $0x2, 0x38(%rbx)
     <+191>:  je     0x1041b22ee               ; <+704>
     <+197>:  movq   0x20(%rbx), %rdi
     <+201>:  testq  %rdi, %rdi
     <+204>:  je     0x1041b22ee               ; <+704>
     <+210>:  movq   0x20(%rdi), %r15
     <+214>:  callq  0x104101b12               ; CA::Render::Timing::end_time() const
     <+219>:  movq   0x20(%rbx), %rax
     <+223>:  movl   0x8(%rax), %r13d
     <+227>:  shrl   $0x12, %r13d
     <+231>:  andb   $0x1, %r13b
     <+235>:  movl   0x8(%rax), %ecx
     <+238>:  shrl   $0x11, %ecx
     <+241>:  andb   $0x1, %cl
     <+244>:  movss  0x8(%r14), %xmm1
     <+250>:  xorpd  %xmm2, %xmm2
     <+254>:  ucomiss %xmm1, %xmm2
     <+257>:  je     0x1041b21ef               ; <+449>
     <+263>:  movd   %xmm0, %rax
     <+268>:  ucomiss %xmm2, %xmm1
     <+271>:  jae    0x1041b2146               ; <+280>
     <+273>:  movq   %rax, %rdx
     <+276>:  movb   %cl, %al
     <+278>:  jmp    0x1041b2152               ; <+292>
     <+280>:  movq   %r15, %rdx
     <+283>:  movq   %rax, %r15
     <+286>:  movb   %r13b, %al
     <+289>:  movb   %cl, %r13b
     <+292>:  movd   %rdx, %xmm0
     <+297>:  ucomiss %xmm2, %xmm1
     <+300>:  jbe    0x1041b217b               ; <+333>
     <+302>:  movsd  -0x38(%rbp), %xmm1
     <+307>:  ucomisd %xmm1, %xmm0
     <+311>:  ja     0x1041b220b               ; <+477>
     <+317>:  movd   %r15, %xmm0
     <+322>:  ucomisd %xmm1, %xmm0
     <+326>:  jbe    0x1041b2199               ; <+363>
     <+328>:  jmp    0x1041b221d               ; <+495>
     <+333>:  movsd  -0x38(%rbp), %xmm1
     <+338>:  ucomisd %xmm1, %xmm0
     <+342>:  jb     0x1041b220b               ; <+477>
     <+348>:  movd   %r15, %xmm0
     <+353>:  ucomisd %xmm1, %xmm0
     <+357>:  jb     0x1041b221d               ; <+495>
     <+363>:  movsd  %xmm1, -0x38(%rbp)
     <+368>:  movq   0x8(%rbx), %rdi
     <+372>:  movl   $0x2, %esi
     <+377>:  movl   $0xffffffff, %edx
     <+382>:  callq  0x1041914ba               ; CAAnimationSetFlags
     <+387>:  movq   %rbx, %rdi
     <+390>:  callq  0x1041b159c               ; schedule_stop_callback(CA::Layer::Animation*)
     <+395>:  testb  $0x1, 0x38(%rbx)
     <+399>:  je     0x1041b224c               ; <+542>
     <+405>:  movq   (%rbx), %rax
     <+408>:  movq   -0x40(%rbp), %rcx
     <+412>:  movq   %rax, (%rcx)
     <+415>:  movq   0x6d574(%rip), %rax       ; animation_state (.2)
     <+422>:  movq   %rax, (%rbx)
     <+425>:  movq   %rbx, 0x6d56a(%rip)       ; animation_state (.2)
     <+432>:  movq   (%rcx), %rbx
     <+435>:  testq  %rbx, %rbx
     <+438>:  jne    0x1041b20e9               ; <+187>
     <+444>:  jmp    0x1041b2310               ; <+738>
     <+449>:  movd   %r15, %xmm1
     <+454>:  movsd  -0x38(%rbp), %xmm2
     <+459>:  ucomisd %xmm2, %xmm1
     <+463>:  movapd %xmm2, %xmm1
     <+467>:  jbe    0x1041b2256               ; <+552>
     <+469>:  movb   %r13b, %al
     <+472>:  jmp    0x1041b22b4               ; <+646>
     <+477>:  movzwl 0x38(%rbx), %ecx
     <+481>:  testw  $0x220, %cx
     <+486>:  je     0x1041b2262               ; <+564>
     <+488>:  movsd  %xmm1, -0x38(%rbp)
     <+493>:  jmp    0x1041b2284               ; <+598>
     <+495>:  movsd  %xmm0, -0x40(%rbp)
     <+500>:  movsd  %xmm1, -0x38(%rbp)
     <+505>:  movq   %rbx, %rdi
     <+508>:  callq  0x1041b24d0               ; schedule_start_callback(CA::Layer::Animation*)
     <+513>:  testb  $0x4, 0x39(%rbx)
     <+517>:  jne    0x1041b2243               ; <+533>
     <+519>:  movb   $0x1, %al
     <+521>:  cmpq   $0x0, 0x30(%rbx)
     <+526>:  movsd  -0x48(%rbp), %xmm0
     <+531>:  je     0x1041b2284               ; <+598>
     <+533>:  movb   $0x1, %al
     <+535>:  movsd  -0x40(%rbp), %xmm0
     <+540>:  jmp    0x1041b2284               ; <+598>
     <+542>:  movb   %r13b, %al
     <+545>:  movsd  -0x48(%rbp), %xmm0
     <+550>:  jmp    0x1041b2284               ; <+598>
     <+552>:  movb   $0x1, %al
     <+554>:  ucomisd %xmm1, %xmm0
     <+558>:  ja     0x1041b22b4               ; <+646>
     <+560>:  movb   %cl, %al
     <+562>:  jmp    0x1041b22b4               ; <+646>
     <+564>:  testb  $0x4, %ch
     <+567>:  jne    0x1041b226e               ; <+576>
     <+569>:  cmpq   $0x0, 0x30(%rbx)
     <+574>:  je     0x1041b227a               ; <+588>
     <+576>:  movsd  %xmm1, -0x38(%rbp)
     <+581>:  movd   %r15, %xmm0
     <+586>:  jmp    0x1041b2284               ; <+598>
     <+588>:  movsd  %xmm1, -0x38(%rbp)
     <+593>:  movsd  -0x48(%rbp), %xmm0
     <+598>:  xorpd  %xmm1, %xmm1
     <+602>:  ucomiss 0x8(%r14), %xmm1
     <+607>:  jae    0x1041b2299               ; <+619>
     <+609>:  ucomisd -0x48(%rbp), %xmm0
     <+614>:  setb   %cl
     <+617>:  jmp    0x1041b22a1               ; <+627>
     <+619>:  ucomisd -0x48(%rbp), %xmm0
     <+624>:  seta   %cl
     <+627>:  movsd  -0x38(%rbp), %xmm1
     <+632>:  testb  %cl, %cl
     <+634>:  jne    0x1041b22af               ; <+641>
     <+636>:  movsd  -0x48(%rbp), %xmm0
     <+641>:  movsd  %xmm0, -0x48(%rbp)
     <+646>:  testb  %al, %al
     <+648>:  je     0x1041b22e9               ; <+699>
     <+650>:  movzwl 0x38(%rbx), %eax
     <+654>:  movl   %eax, %ecx
     <+656>:  andl   $0x20, %ecx
     <+659>:  testw  %cx, %cx
     <+662>:  je     0x1041b22e9               ; <+699>
     <+664>:  movl   %eax, %ecx
     <+666>:  andl   $0x80, %ecx
     <+672>:  testw  %cx, %cx
     <+675>:  je     0x1041b22d9               ; <+683>
     <+677>:  movb   $0x1, %cl
     <+679>:  movq   %rcx, -0x50(%rbp)
     <+683>:  andl   $0x100, %eax
     <+688>:  testw  %ax, %ax
     <+691>:  je     0x1041b22e9               ; <+699>
     <+693>:  movb   $0x1, %al
     <+695>:  movq   %rax, -0x58(%rbp)
     <+699>:  movsd  %xmm1, -0x38(%rbp)
     <+704>:  leaq   0x10(%rbx), %rdi
     <+708>:  xorl   %esi, %esi
     <+710>:  callq  0x1040e0598               ; CA::Render::key_path_atom(void* const*, unsigned long)
     <+715>:  cmpl   $0x63, %eax
     <+718>:  cmoveq %rbx, %r12
     <+722>:  movq   (%rbx), %rax
     <+725>:  testq  %rax, %rax
     <+728>:  movq   %rbx, -0x40(%rbp)
     <+732>:  jne    0x1041b20e6               ; <+184>
     <+738>:  movq   -0x68(%rbp), %rsi
     <+742>:  movl   (%rsi), %ebx
     <+744>:  movq   -0x50(%rbp), %rax
     <+748>:  testb  $0x1, %al
     <+750>:  movl   $0x0, %ecx
     <+755>:  je     0x1041b232f               ; <+769>
     <+757>:  lock   
     <+758>:  orl    $0x1000000, (%rsi)
     <+764>:  movl   $0x1000, %ecx
     <+769>:  movl   %ebx, %eax
     <+771>:  andl   $0x3000, %eax
     <+776>:  movq   -0x58(%rbp), %rdx
     <+780>:  testb  $0x1, %dl
     <+783>:  je     0x1041b234c               ; <+798>
     <+785>:  orl    $0x2000, %ecx
     <+791>:  lock   
     <+792>:  orl    $0x800000, (%rsi)
     <+798>:  movq   -0x70(%rbp), %rdi
     <+802>:  movsd  -0x38(%rbp), %xmm1
     <+807>:  movq   %r14, %rdx
     <+810>:  jmp    0x1041b2366               ; <+824>
     <+812>:  movl   (%rsi), %ebx
     <+814>:  movl   %ebx, %eax
     <+816>:  andl   $0x3000, %eax
     <+821>:  xorl   %r12d, %r12d
     <+824>:  cmpl   %eax, %ecx
     <+826>:  jne    0x1041b238f               ; <+865>
     <+828>:  testl  %eax, %eax
     <+830>:  je     0x1041b24a9               ; <+1147>
     <+836>:  xorpd  %xmm0, %xmm0
     <+840>:  ucomiss 0x8(%rdx), %xmm0
     <+844>:  jne    0x1041b2386               ; <+856>
     <+846>:  cmpl   $0x0, 0xc(%rdx)
     <+850>:  je     0x1041b24a9               ; <+1147>
     <+856>:  movq   %r12, %r13
     <+859>:  movq   0x10(%rdi), %r14
     <+863>:  jmp    0x1041b23b2               ; <+900>
     <+865>:  movq   %r12, %r13
     <+868>:  movq   0x10(%rdi), %r14
     <+872>:  movl   %ebx, %eax
     <+874>:  orl    $0xffffcfff, %eax
     <+879>:  xorl   $0x3000, %eax
     <+884>:  movq   %rcx, %rdx
     <+887>:  andl   %eax, %ecx
     <+889>:  lock   
     <+890>:  orl    %ecx, (%rsi)
     <+892>:  movq   %rdx, %rcx
     <+895>:  orl    %ecx, %eax
     <+897>:  lock   
     <+898>:  andl   %eax, (%rsi)
     <+900>:  movq   %rdi, %r15
     <+903>:  testl  %ecx, %ecx
     <+905>:  je     0x1041b245c               ; <+1070>
     <+911>:  movq   %rcx, %r12
     <+914>:  movsd  %xmm1, -0x38(%rbp)
     <+919>:  movq   0x68964(%rip), %rsi       ; "_scheduleAnimationTimer"
     <+926>:  movq   %r14, %rdi
     <+929>:  callq  *0x6de63(%rip)            ; (void *)0x000000010357d800: objc_msgSend
     <+935>:  testb  %al, %al
     <+937>:  movq   -0x60(%rbp), %rbx
     <+941>:  movq   %r15, %rdi
     <+944>:  je     0x1041b24ad               ; <+1151>
     <+950>:  movq   %r12, %rax
     <+953>:  testb  $0x10, %ah
     <+956>:  je     0x1041b2408               ; <+986>
     <+958>:  movq   0x68855(%rip), %rsi       ; "setNeedsLayout"
     <+965>:  movq   %rdi, %r15
     <+968>:  movq   %r14, %rdi
     <+971>:  movq   %rax, %r12
     <+974>:  callq  *0x6de36(%rip)            ; (void *)0x000000010357d800: objc_msgSend
     <+980>:  movq   %r12, %rax
     <+983>:  movq   %r15, %rdi
     <+986>:  testb  $0x20, %ah
     <+989>:  je     0x1041b2450               ; <+1058>
     <+991>:  movq   %rdi, %r15
     <+994>:  testq  %r13, %r13
     <+997>:  je     0x1041b2436               ; <+1032>
     <+999>:  movq   0x6809c(%rip), %rdx       ; "removeAnimationForKey:"
     <+1006>: movq   0x68915(%rip), %rsi       ; "performSelectorOnMainThread:withObject:waitUntilDone:"
     <+1013>: leaq   0x7a106(%rip), %rcx       ; @"contents"
     <+1020>: xorl   %r8d, %r8d
     <+1023>: movq   %r14, %rdi
     <+1026>: callq  *0x6de02(%rip)            ; (void *)0x000000010357d800: objc_msgSend
     <+1032>: movq   0x68823(%rip), %rsi       ; "setNeedsDisplay"
     <+1039>: movq   %r14, %rdi
     <+1042>: callq  *0x6ddf2(%rip)            ; (void *)0x000000010357d800: objc_msgSend
     <+1048>: movq   %r15, %rdi
     <+1051>: orb    $0x20, 0x85(%rdi)
     <+1058>: movsd  -0x38(%rbp), %xmm0
     <+1063>: movsd  %xmm0, -0x48(%rbp)
     <+1068>: jmp    0x1041b24ad               ; <+1151>
     <+1070>: movq   0x688dd(%rip), %rsi       ; "_cancelAnimationTimer"
     <+1077>: movq   %r14, %rdi
     <+1080>: callq  *0x6ddcc(%rip)            ; (void *)0x000000010357d800: objc_msgSend
     <+1086>: testb  $0x10, %bh
     <+1089>: je     0x1041b2481               ; <+1107>
     <+1091>: movq   0x687d0(%rip), %rsi       ; "setNeedsLayout"
     <+1098>: movq   %r14, %rdi
     <+1101>: callq  *0x6ddb7(%rip)            ; (void *)0x000000010357d800: objc_msgSend
     <+1107>: testb  $0x20, %bh
     <+1110>: jne    0x1041b248f               ; <+1121>
     <+1112>: movq   -0x60(%rbp), %rbx
     <+1116>: movq   %r15, %rdi
     <+1119>: jmp    0x1041b24ad               ; <+1151>
     <+1121>: movq   0x687ca(%rip), %rsi       ; "setNeedsDisplay"
     <+1128>: movq   %r14, %rdi
     <+1131>: callq  *0x6dd99(%rip)            ; (void *)0x000000010357d800: objc_msgSend
     <+1137>: movq   %r15, %rdi
     <+1140>: orb    $0x20, 0x85(%rdi)
     <+1147>: movq   -0x60(%rbp), %rbx
     <+1151>: movq   -0x30(%rbp), %rsi
     <+1155>: callq  0x1041b0e50               ; CA::Layer::set_animations(CA::Layer::Animation*)
     <+1160>: movb   $0x1, %al
     <+1162>: movsd  -0x48(%rbp), %xmm0
     <+1167>: movsd  %xmm0, (%rbx)
     <+1171>: addq   $0x48, %rsp
     <+1175>: popq   %rbx
     <+1176>: popq   %r12
     <+1178>: popq   %r13
     <+1180>: popq   %r14
     <+1182>: popq   %r15
     <+1184>: popq   %rbp
     <+1185>: retq   
View Code

下面是跳转的形态图:

这个函数一共有17jmp指令,我将其划分成17jmp block孤岛,分支跳转指令在这17座孤岛中穿插。下面我借用UML对象图的符号来描述,符号的作用被重定义为:

~package),入口地址。

+public),外出跳转。

#protected),往回走(backwards)的外出跳转。

-private),jmp block内跳转,没有离开jmp block的跳转。

=(初始值),表示跳转的目的偏移位置。

->direct-link),有向线表示jmp blocks之间的跳转,蓝色代表跳转到另一个jmp block的入口,黑色代表跳转到另一个jmp block的体内。

对象符号表示一个jmp block孤岛,绿色代表按某种策略选定为主线成员,不宜作为inline候选。

下面是反映这个函数分支连接的图:

 

可以看出(黑色)非主线成员的孤岛可以被内联到(绿色)主线成员孤岛的分支中,然后回到主线上。但是并没有一条线路可以满足将17个孤岛连成线的。

 

下面是对第#4JmpBlock进行内联后逆向分支输出:

  

#6JmpBlock被内联到#4号在offset 342处的分支内,#11内联到了#6号内联块的结尾offset 493,并且#11号内联片段是从体内截取出来,而不是#11号内联从头开始的整个代码块。

477493598617的片段被内联到了offset 342的分支内,分支外继续#4JmpBlock的执行流。这样就减少了,逆向代码中凌乱的跳转,而且将跳转的单位上升到JmpBlock的粒度,并且是non-inlineJmpBlock。虽然没有减少goto的数量,但是大大减少了goto目的选择的可能性,而且内联减少了很多中间的跳转,使跳转更加直接,容易归纳分析。

另外在每个JmpBlock的开头输出的注释,提供了有力的跟踪分析的信息。例如内联块的指令数目,可以看出#6#11都是只有几条指令的小内联块。还有内联块的入边和出边分别关联到哪些其它块的可能,也还是从何处来往何处走,#11内联的注释表示这个块将内联到多处,但结果都将走向#12JmpBlock

 

世上没有通杀的银子弹,和包治百病的药,具体问题还要具体分析,所以针对像这样包含了很无条件跳转指令的函数的逆向分析,我使用了另一个逆向策略-内联。其实,这只策略在本文中分析的目标函数,也并不完全适用,因为在后面4JmpBlock中它们的关联并非内联,而更多是二路分支if-else

 

总算是多了一个帮助分析的选择。

最后贴上部分输出结果:

/***
* Summary:
* total JmpBlock(s): 17
* noninline block(s): #0, #2, #4, #7, #10, #12, #13, #14, #15, #16
* inline block(s): #1, #3, #5, #6, #8, #9, #11
*/


/***
* #0<<JmpBlock>>
* 0 to 143
* instrs: 40
* inners: 0
*
*/
_f0:
// 66
if () {
    /***
    * #1<<Inline JmpBlock>>
    * 145(145) to 147
    * instrs: 2
    * incomings: 1    ; #0
    * outgoings: 1    ; #16
    * depth: 1
    *
    */
    // 145
    // 147
    goto _f1162;    // to #16
                    // end of inline #1
}
// 90
if () {
    goto _f152;    // to #2, BoJ
}
// 112
if () {
    goto _f812;    // to #13, BoJ
}
// 143
goto _f178;    // to #2
            // end of non-inline #0

            /***
            * #2<<JmpBlock>>
            * 152 to 278
            * instrs: 34
            * inners: 0
            *
            */
_f152:
_f152:    // from #0(90)
_f178:    // from #0(143, EoJ)
_b184:    // from #12(732)
_b187:    // from #4(438)
        // 191
if () {
    goto _f704;    // to #12
}
// 204
if () {
    goto _f704;    // to #12
}
// 257
if () {
    /***
    * #5<<Inline JmpBlock>>
    * 449(449) to 472
    * instrs: 7
    * incomings: 1    ; #2
    * outgoings: 2    ; #9, #12
    * depth: 1
    *
    */
    // 449
    // 467
    if () {
        /***
        * #9<<Inline JmpBlock>>
        * 552(552) to 562
        * instrs: 5
        * incomings: 1    ; #5
        * outgoings: 2    ; #12
        * depth: 2
        *
        */
        // 552
        // 558
        if () {
            goto _f646;    // to #12
        }
        // 562
        goto _f646;    // to #12
                    // end of inline #9
    }
    // 472
    goto _f646;    // to #12
                // end of inline #5
}
// 271
if () {
    /***
    * #3<<Inline JmpBlock>>
    * 280(280) to 328
    * instrs: 14
    * incomings: 2    ; #2
    * outgoings: 4    ; #4, #6, #7
    * depth: 1
    *
    */
    // 280
    // 300
    if () {
        goto _f333;    // to #4, BoJ
    }
    // 311
    if () {
        /***
        * #6<<Inline JmpBlock>>
        * 477(477) to 493
        * instrs: 5
        * incomings: 2    ; #3, #4
        * outgoings: 2    ; #10, #11
        * depth: 2
        *
        */
        // 477
        // 486
        if () {
            goto _f564;    // to #10, BoJ
        }
        // 493
        /***
        * #11<<Inline JmpBlock>>
        * 588(598) to 617
        * instrs: 8
        * incomings: 6    ; #6, #7, #8, #10
        * outgoings: 2    ; #12
        * depth: 3
        * concast #6 to #11
        *
        */
        // 598
        // 607
        if () {
            goto _f619;    // to #12, BoJ
        }
        // 617
        goto _f627;    // to #12
                    // end of inline #11
                    // end of inline #6
    }
    // 326
    if () {
        goto _f363;    // to #4
    }
    // 328
    goto _f495;    // to #7, BoJ
                // end of inline #3
}
// 278
/***
* #3<<Inline JmpBlock>>
* 280(292) to 328
* instrs: 14
* incomings: 2    ; #2
* outgoings: 4    ; #4, #6, #7
* depth: 1
* concast #2 to #3
*
*/
// 292
// 300
if () {
    goto _f333;    // to #4, BoJ
}
// 311
if () {
    /***
    * #6<<Inline JmpBlock>>
    * 477(477) to 493
    * instrs: 5
    * incomings: 2    ; #3, #4
    * outgoings: 2    ; #10, #11
    * depth: 2
    *
    */
    // 477
    // 486
    if () {
        goto _f564;    // to #10, BoJ
    }
    // 493
    /***
    * #11<<Inline JmpBlock>>
    * 588(598) to 617
    * instrs: 8
    * incomings: 6    ; #6, #7, #8, #10
    * outgoings: 2    ; #12
    * depth: 3
    * concast #6 to #11
    *
    */
    // 598
    // 607
    if () {
        goto _f619;    // to #12, BoJ
    }
    // 617
    goto _f627;    // to #12
                // end of inline #11
                // end of inline #6
}
// 326
if () {
    goto _f363;    // to #4
}
// 328
goto _f495;    // to #7, BoJ
            // end of inline #3
            // end of non-inline #2

            /***
            * #4<<JmpBlock>>
            * 333 to 444
            * instrs: 25
            * inners: 0
            *
            */
_f333:
_f333:    // from #3(300, inline)
        // 342
if () {
    /***
    * #6<<Inline JmpBlock>>
    * 477(477) to 493
    * instrs: 5
    * incomings: 2    ; #3, #4
    * outgoings: 2    ; #10, #11
    * depth: 1
    *
    */
    // 477
    // 486
    if () {et 
        goto _f564;    // to #10, BoJ
    }
    // 493
    /***
    * #11<<Inline JmpBlock>>
    * 588(598) to 617
    * instrs: 8
    * incomings: 6    ; #6, #7, #8, #10
    * outgoings: 2    ; #12
    * depth: 2
    * concast #6 to #11
    *
    */
    // 598
    // 607
    if () {
        goto _f619;    // to #12, BoJ
    }
    // 617
    goto _f627;    // to #12
                // end of inline #11
                // end of inline #6
}
// 357
if () {
    goto _f495;    // to #7, BoJ
}
_f363:    // from #3(326, inline)
        // 399
if () {
    /***
    * #8<<Inline JmpBlock>>
    * 542(542) to 550
    * instrs: 3
    * incomings: 1    ; #4
    * outgoings: 1    ; #11
    * depth: 1
    *
    */
    // 542
    // 550
    /***
    * #11<<Inline JmpBlock>>
    * 588(598) to 617
    * instrs: 8
    * incomings: 6    ; #6, #7, #8, #10
    * outgoings: 2    ; #12
    * depth: 2
    * concast #8 to #11
    *
    */
    // 598
    // 607
    if () {
        goto _f619;    // to #12, BoJ
    }
    // 617
    goto _f627;    // to #12
                // end of inline #11
                // end of inline #8
}
// 438
if () {
    goto _b187;    // to #2
}
// 444
goto _f738;    // to #12
            // end of non-inline #4

            /***
            * #7<<JmpBlock>>
            * 495 to 540
            * instrs: 13
            * inners: 1
            *
            */
_f495:
_f495:    // from #3(328, inline, EoJ)
_f495:    // from #4(357)
        // 531
if () {
    /***
    * #11<<Inline JmpBlock>>
    * 588(598) to 617
    * instrs: 8
    * incomings: 6    ; #6, #7, #8, #10
    * outgoings: 2    ; #12
    * depth: 1
    *
    */
    // 598
    // 607
    if () {
        goto _f619;    // to #12, BoJ
    }
    // 617
    goto _f627;    // to #12
                // end of inline #11
}
// 540
/***
* #11<<Inline JmpBlock>>
* 588(598) to 617
* instrs: 8
* incomings: 6    ; #6, #7, #8, #10
* outgoings: 2    ; #12
* depth: 1
* concast #7 to #11
*
*/
// 598
// 607
if () {
    goto _f619;    // to #12, BoJ
}
// 617
goto _f627;    // to #12
            // end of inline #11
            // end of non-inline #7

            /***
            * #10<<JmpBlock>>
            * 564 to 586
            * instrs: 7
            * inners: 1
            *
            */
_f564:
_f564:    // from #6(486, inline)
        // 574
if () {
    /***
    * #11<<Inline JmpBlock>>
    * 588(588) to 617
    * instrs: 8
    * incomings: 6    ; #6, #7, #8, #10
    * outgoings: 2    ; #12
    * depth: 1
    *
    */
    // 588
    // 607
    if () {
        goto _f619;    // to #12, BoJ
    }
    // 617
    goto _f627;    // to #12
                // end of inline #11
}
// 586
/***
* #11<<Inline JmpBlock>>
* 588(598) to 617
* instrs: 8
* incomings: 6    ; #6, #7, #8, #10
* outgoings: 2    ; #12
* depth: 1
* concast #10 to #11
*
*/
// 598
// 607
if () {
    goto _f619;    // to #12, BoJ
}
// 617
goto _f627;    // to #12
            // end of inline #11
            // end of non-inline #10

            /***
            * #12<<JmpBlock>>
            * 619 to 810
            * instrs: 56
            * inners: 7
            *
            */
_f619:
_f619:    // from #11(607, inline)
_f627:    // from #11(617, inline, EoJ)
_f646:    // from #5(472, inline, EoJ)
_f646:    // from #9(558, inline)
_f646:    // from #9(562, inline, EoJ)
_f704:    // from #2(191)
_f704:    // from #2(204)
        // 732
if () {
    goto _b184;    // to #2
}
_f738:    // from #4(444, EoJ)
        // 810
goto _f824;    // to #13
            // end of non-inline #12

            /***
            * #13<<JmpBlock>>
            * 812 to 863
            * instrs: 16
            * inners: 1
            *
            */
_f812:
_f812:    // from #0(112)
_f824:    // from #12(810, EoJ)
        // 826
if () {
    goto _f865;    // to #14, BoJ
}
// 830
if () {
    goto _f1147;    // to #16
}
// 850
if () {
    goto _f1147;    // to #16
}
// 863
goto _f900;    // to #14
            // end of non-inline #13

            /***
            * #14<<JmpBlock>>
            * 865 to 1068
            * instrs: 54
            * inners: 3
            *
            */
_f865:
_f865:    // from #13(826)
_f900:    // from #13(863, EoJ)
        // 905
if () {
    goto _f1070;    // to #15, BoJ
}
// 944
if () {
    goto _f1151;    // to #16
}
// 1068
goto _f1151;    // to #16
                // end of non-inline #14

                /***
                * #15<<JmpBlock>>
                * 1070 to 1119
                * instrs: 13
                * inners: 1
                *
                */
_f1070:
_f1070:    // from #14(905)
        // 1110
if () {
    goto _f1121;    // to #16, BoJ
}
// 1119
goto _f1151;    // to #16
                // end of non-inline #15

                /***
                * #16<<JmpBlock>>
                * 1121 to 1185
                * instrs: 19
                * inners: 0
                *
                */
_f1121:
// 1185
return;
// end of non-inline #16
View Code

 

原文地址:https://www.cnblogs.com/bbqzsl/p/5356054.html