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

Posted bbqz007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自制反汇编逆向分析工具 迭代第四版本相关的知识,希望对你有一定的参考价值。

上一个版本,本工具支持的第一个逆向策略,(对反汇编的函数体内的分支控制结构逆向生成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内联的注释表示这个块将内联到多处,但结果都将

以上是关于自制反汇编逆向分析工具 迭代第四版本的主要内容,如果未能解决你的问题,请参考以下文章

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

C++反汇编与逆向分析技术揭秘的目录

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段

android逆向必备工具

android逆向必备工具

android逆向必备工具