经过一个阶段5次迭代之后,本逆向分析工具功能基本成形。工具的基本功能介绍请参看前面的posts。
现在就和hopper的逆向函数伪代码的功能对比一下效果。在这里并非定胜劣,因为差异可以拿来对比参照,通过比较发现有参考的东西。
下面是hopper的输出的伪代码:
void _CABackingStoreUpdate_(int arg0, int arg1, int arg2, int arg3) { var_148 = r9; r12 = arg3; r13 = arg2; var_D8 = arg1; r14 = arg0; r15 = r14 + 0x10; pthread_mutex_lock(r15); rbx = *(r14 + 0x168); if (rbx == 0x0) goto loc_ca71; loc_ca40: if (rbx == pthread_self()) goto loc_d554; loc_ca4e: if (*(r14 + 0x168) != 0x0) { rbx = r14 + 0x50; do { pthread_cond_wait(rbx, r15); } while (*(r14 + 0x168) != 0x0); } goto loc_ca71; loc_ca71: rcx = *(int16_t *)(r14 + 0x174); if ((*(r14 + 0x80) != var_D8) || (*(r14 + 0x88) != r13)) goto loc_cb16; loc_ca9e: var_F8 = r13; rbx = rcx >> 0xa & 0x1; COND = rbx != 0x0; if (COND) goto loc_cb34; loc_cab3: rax = 0x0; rbx = 0x0; if ((rcx & 0x2) == 0x0) { rdi = *(r14 + 0x150); rax = 0x0; rbx = 0x0; if (rdi != 0x0) { CGSBoundingShapeGetRegion(); if ((r12 & 0x80) == 0x0) { rbx = var_F8; xmm2 = intrinsic_punpckldq(zero_extend_64(rbx), *(int128_t *)0x150860); xmm2 = intrinsic_subpd(xmm2, *(int128_t *)0x150870); xmm2 = intrinsic_haddpd(xmm2, xmm2); } else { var_70 = 0x3ff0000000000000; var_58 = 0xbff0000000000000; rbx = var_F8; xmm0 = intrinsic_punpckldq(zero_extend_64(rbx), *(int128_t *)0x150860); xmm0 = intrinsic_subpd(xmm0, *(int128_t *)0x150870); xmm0 = intrinsic_haddpd(xmm0, xmm0); var_F0 = intrinsic_movapd(var_F0, xmm0); intrinsic_movlpd(var_48, xmm0); intrinsic_movss(xmm0, *(int32_t *)0x1508a0); CGSTransformRegion(); CGSReleaseRegion(var_38); xmm2 = intrinsic_movapd(xmm2, var_F0); var_38 = var_40; } var_F8 = rbx; xmm0 = intrinsic_punpckldq(zero_extend_64(var_D8), *(int128_t *)0x150860); xmm0 = intrinsic_subpd(xmm0, *(int128_t *)0x150870); xmm0 = intrinsic_haddpd(xmm0, xmm0); xmm1 = intrinsic_pxor(xmm1, xmm1); var_90 = intrinsic_movdqa(var_90, xmm1); intrinsic_movlpd(var_80, xmm0); intrinsic_movsd(var_78, xmm2); rbx = CGSRectInRegion(); if (rbx == 0x0) { CGSIntersectRegionWithRect(var_38, var_90, 0x0); if (CGSRegionIsEmpty(0x0) != 0x0) { CGSReleaseRegion(0x0); } } CGSReleaseRegion(var_38); rax = 0x0; } } if ((rbx != 0x0) || (rax != 0x0)) goto loc_cb34; loc_d554: pthread_mutex_unlock(r15); return; loc_cb34: var_110 = rbx; var_138 = r15; var_104 = (r12 & 0x1) + (r12 & 0x1) + 0x1; r15 = r14 + 0x138; rcx = *(r14 + 0x138); var_130 = r14; rax = rcx + 0x10; rdi = *(rcx + 0x10); if (rdi == 0x0) goto loc_ccae; loc_cb78: var_F0 = r12; r14 = r12 & 0x4; r13 = rax; var_118 = rax; rbx = rcx; var_100 = rcx; r12 = r15; goto loc_cb9d; loc_cb9d: if (CA::Render::Shmem::set_volatile(rdi, 0x0) == 0x0) goto loc_ccd8; loc_cbae: rax = *r13; if (rax == 0x0) goto loc_ccf8; loc_cbbb: rax = *(rax + 0x18); if ((((*(int32_t *)(rax + 0x10) != var_104) || (*(int32_t *)(rax + 0x14) != var_D8)) || (*(int32_t *)(rax + 0x18) != var_F8)) || (((r14 != 0x0 ? 0x1 : 0x0) & 0xff) != ((*(int32_t *)(rax + 0x1c) > 0x1 ? 0x1 : 0x0) & 0xff))) goto loc_ccd8; loc_cc09: COND = *(int32_t *)rax == 0x0; rax = COND_BYTE_SET(NE); rdx = rbx; if (!COND) { if (*rdx == 0x0) { rax = rdx; rdx = *(int32_t *)(rax + 0x20); rbx = rax; CABackingStoreSynchronize(var_130, arg_8, rdx + 0x1, 0x1e); rcx = *r13; rax = 0x1; if (rcx != 0x0) { rax = *(int32_t *)*(rcx + 0x18) == 0x0 ? 0x1 : 0x0; } rax = rax ^ 0x1; rdx = rbx; } } else { if ((rdx != var_100) && (*rdx != 0x0)) { rax = CABackingStoreSynchronize(var_130, arg_8, *(int32_t *)(rdx + 0x20), 0x0); rdx = rdx; rax = rax ^ 0x1; } } if (rax == 0x0) goto loc_cccc; loc_cc86: rcx = *rdx; if (rcx == 0x0) goto loc_cd04; loc_cc8e: if (rax == 0x0) goto loc_cccc; loc_cc92: r12 = rdx; r13 = rcx + 0x10; rdi = *(rcx + 0x10); rbx = rcx; if (rdi != 0x0) goto loc_cb9d; loc_cca9: rdx = rcx; goto loc_cccc; loc_cccc: r14 = var_110; goto loc_cd47; loc_cd47: if (rdx == *r15) goto loc_cd6c; loc_cd4c: *r12 = *rdx; *rdx = *r15; *r15 = rdx; r15 = var_138; r12 = var_130; goto loc_cd83; loc_cd83: rax = *r13; if (rax == 0x0) goto loc_cd98; loc_cd8c: var_110 = rax; goto loc_ce38; loc_ce38: r13 = r14; rdi = *(rdx + 0x8); if (rdi != *(r12 + 0x90)) { CGColorSpaceRelease(rdi); rax = CGColorSpaceRetain(*(r12 + 0x90)); rdx = rdx; *(rdx + 0x8) = rax; if ((rax != *(var_100 + 0x8)) && (*(rdx + 0x18) != 0x0)) { CGSReleaseRegion(); rdx = rdx; *(rdx + 0x18) = 0x0; } } var_138 = r15; if (*(r12 + 0x150) != 0x0) { CGSBoundingShapeReset(); rdx = rdx; } *(int16_t *)(r12 + 0x174) = *(int16_t *)(r12 + 0x174) & 0xffff & 0xf8ff | 0x200; var_178 = *(rdx + 0x18); rbx = *(r12 + 0x138); var_120 = r13; r12 = r13 & 0x1; if (rbx == 0x0) goto loc_cf5d; loc_ceef: r15 = var_98; goto loc_cef6; loc_cef6: r13 = rbx + 0x18; if (rbx == rdx) goto loc_cf35; loc_ceff: rax = *r13; if (rax == 0x0) goto loc_cf55; loc_cf08: r14 = rdx; if (r12 == 0x0) { CGSUnionRegion(0x0, rax, r15); CGSReleaseRegion(*r13); *r13 = var_98; } else { CGSReleaseRegion(rax); *r13 = 0x0; } goto loc_cf52; loc_cf52: rdx = r14; goto loc_cf55; loc_cf55: rbx = *rbx; if (rbx != 0x0) goto loc_cef6; loc_cf5d: var_140 = rdx; rax = var_F8; r13 = var_178; if ((rdx != var_100) && (r12 == 0x0)) { if (r13 != 0x0) { CGSDiffRegion(r13, 0x0, 0x0); } else { xmm1 = intrinsic_movdqa(xmm1, *(int128_t *)0x150860); xmm0 = intrinsic_punpckldq(zero_extend_64(var_D8), xmm1); xmm2 = intrinsic_movapd(xmm2, *(int128_t *)0x150870); xmm0 = intrinsic_subpd(xmm0, xmm2); xmm0 = intrinsic_haddpd(xmm0, xmm0); xmm3 = intrinsic_punpckldq(zero_extend_64(rax), xmm1); xmm3 = intrinsic_subpd(xmm3, xmm2); xmm3 = intrinsic_haddpd(xmm3, xmm3); xmm1 = intrinsic_pxor(xmm1, xmm1); var_C0 = intrinsic_movdqa(var_C0, xmm1); intrinsic_movlpd(var_B0, xmm0); intrinsic_movlpd(var_A8, xmm3); CGSNewRegionWithRect(var_C0, var_C8); CGSDiffRegion(var_C8, 0x0, 0x0); CGSReleaseRegion(var_C8); } if (CGSRegionIsEmpty(0x0) != 0x0) { CGSReleaseRegion(0x0); } } rcx = var_110; if (rcx == 0x0) goto loc_d0ae; loc_d06a: r15 = *(rcx + 0x18); if (0x0 != 0x0) { rax = *var_118; r13 = 0x1; r12 = var_130; if (rax != 0x0) { CA::Render::ShmemBitmap::copy_pixels(r15, *(rax + 0x18)); rcx = rcx; r13 = var_120; } } else { r13 = var_120; r12 = var_130; } r13 = r13 & 0x1; rbx = var_F0; if ((rbx & 0x2) != 0x0) { CA::Render::ShmemBitmap::fill_pixels(r15, 0x0); rcx = rcx; rbx = rbx & 0xfffffffd; } r14 = rbx; r15 = 0x0; var_149 = r13; rax = 0x0; if (r13 != 0x0) { r15 = 0x0; rax = r15; } *(r12 + 0x158) = rax; rax = *(rcx + 0x18); var_100 = rax; rax = *(int32_t *)(rax + 0x1c); var_110 = rax; if (rax == 0x0) goto loc_d4af; loc_d14e: xmm0 = intrinsic_movdqa(xmm0, *(int128_t *)0x150860); xmm2 = intrinsic_punpckldq(zero_extend_64(var_D8), xmm0); xmm1 = intrinsic_movapd(xmm1, *(int128_t *)0x150870); xmm2 = intrinsic_subpd(xmm2, xmm1); var_160 = intrinsic_movapd(var_160, intrinsic_haddpd(xmm2, xmm2)); xmm2 = intrinsic_punpckldq(zero_extend_64(var_F8), xmm0); xmm2 = intrinsic_subpd(xmm2, xmm1); xmm2 = intrinsic_haddpd(xmm2, xmm2); var_170 = intrinsic_movapd(var_170, xmm2); goto loc_d196; loc_d196: var_D8 = CA::Render::ShmemBitmap::lod_width(var_100); r12 = CA::Render::ShmemBitmap::lod_height(var_100); var_F8 = CA::Render::ShmemBitmap::lod_data(var_100); rbx = CA::Render::ShmemBitmap::lod_rowbytes(var_100); if (r15 == 0x0) goto loc_d2b3; loc_d1e5: if ((r14 & 0x28) != 0x0) goto loc_d203; loc_d1eb: CMP(var_D8, r12); asm{ cmova eax, ecx }; if (r12 > 0x7) goto loc_d2b3; loc_d203: var_F0 = r14; var_118 = rbx; rax = CA::Render::ShmemBitmap::lod_width(var_100); var_124 = r12; r12 = rax; rbx = CA::Render::ShmemBitmap::lod_height(var_100); var_120 = CA::Render::ShmemBitmap::lod_data(var_100); rax = CA::Render::ShmemBitmap::lod_rowbytes(var_100); xmm2 = intrinsic_cvtsi2sd(xmm2, var_D8); xmm3 = intrinsic_cvtsi2sd(xmm3, var_124); xmm0 = intrinsic_pxor(xmm0, xmm0); xmm1 = intrinsic_xorpd(xmm1, xmm1); CA::downsample_image(var_104, var_120, rax, r12, rbx, var_F8, var_118, xmm0, xmm1, xmm2, xmm3, 0x0); goto loc_d498; loc_d498: r15 = r15 + 0x1; r14 = var_F0; if (r15 < var_110) goto loc_d196; loc_d4af: rbx = var_130; rax = rbx + 0x158; *(int32_t *)(var_100 + 0x4) = *(int32_t *)(var_100 + 0x4) + 0x1; rdi = 0x0; r13 = var_178; goto loc_d4d3; loc_d4d3: *rax = 0x0; r15 = var_138; if (rdi != 0x0) { CGSReleaseRegion(); } if (r13 != 0x0) { CGSReleaseRegion(r13); } if (0x0 != 0x0) { CGSReleaseRegion(); } CABackingStoreReleaseImages(rbx); rax = 0x0; rdi = arg_8; if (rdi != 0x0) { rax = *rdi; rax = (*(rax + 0x48))(); rax = rax + 0x1; } *(int32_t *)(var_140 + 0x20) = rax; *(var_140 + 0x28) = 0x0; *(rbx + 0x160) = 0x0; *(int8_t *)(rbx + 0x174) = 0x6; pthread_cond_broadcast(rbx + 0x50); goto loc_d554; loc_d2b3: if ((r14 & 0x20) != 0x0) goto loc_d6a1; loc_d2bd: r9 = *(var_140 + 0x8); rsi = var_D8; rdx = r12; r13 = _CAGetCachedCGBitmapContext(var_F8, rsi, rdx, var_104, rbx, r9); if (r13 != 0x0) { xmm0 = intrinsic_movsd(xmm0, *0x150850); xmm1 = intrinsic_movapd(xmm1, xmm0); if (r15 != 0x0) { xmm0 = intrinsic_cvtsi2sd(0x0, var_D8); xmm0 = intrinsic_divsd(xmm0, var_160); xmm1 = intrinsic_cvtsi2sd(0x0, r12); xmm1 = intrinsic_divsd(xmm1, var_170); } if (var_149 == 0x0) { if (r15 != 0x0) { var_70 = intrinsic_movsd(var_70, xmm0); var_D8 = intrinsic_movsd(var_D8, xmm0); var_58 = intrinsic_movsd(var_58, xmm1); var_F0 = intrinsic_movsd(var_F0, xmm1); *(0x8) = 0x0; *0x0 = 0x0; *(0x8) = 0x0; *0x0 = 0x0; xmm0 = intrinsic_movss(xmm0, *(int32_t *)0x1508a0); rdx = var_D0; CGSTransformRegion(); rsi = var_D0; CGContextReplacePathWithShapePath(r13, rsi); CGSReleaseRegion(var_D0); } else { var_F0 = intrinsic_movsd(var_F0, xmm1); var_D8 = intrinsic_movsd(var_D8, xmm0); rsi = 0x0; CGContextReplacePathWithShapePath(r13, rsi); } CGContextClip(r13); xmm0 = intrinsic_movsd(xmm0, var_D8); xmm1 = intrinsic_movsd(xmm1, var_F0); } if (r15 != 0x0) { CGContextScaleCTM(r13, rsi, rdx); } if ((r14 & 0x2) != 0x0) { rax = *_CGRectInfinite; CGContextClearRect(r13, rsi); r14 = r14 & 0xfffffffd; } var_F0 = r14; *(var_130 + 0x168) = pthread_self(); pthread_mutex_unlock(var_138); (var_148)(r13, arg_0); pthread_mutex_lock(var_138); *(var_130 + 0x168) = 0x0; _CAReleaseCachedCGContext(r13); } else { var_F0 = r14; } goto loc_d498; loc_d6a1: abort(); return; loc_d0ae: rcx = 0x0; rdi = 0x0; if (r12 == 0x0) { rcx = rdi; } rbx = var_130; rax = rbx + 0x158; *(rbx + 0x158) = rcx; goto loc_d4d3; loc_cf35: r14 = rdx; CGSNewEmptyRegion(r13); goto loc_cf52; loc_cd98: rax = 0x1; r14 = 0x1; if (rdx != var_100) { r14 = rax; } rbx = rdx; CABackingStoreDeleteBuffer(rdx); rcx = 0x1; if ((var_F0 & 0x4) != 0x0) { rax = CA::Render::format_mipmap_min_size(var_104); rsi = var_F8; rcx = 0x1; if (rsi <= rax) { rdx = var_D8; if (rdx > rax) { do { do { rcx = rcx + 0x1; rdx = rdx >> 0x1; rsi = rsi >> 0x1; } while (rsi > rax); } while (rdx > rax); } } else { rdx = var_D8; do { do { rcx = rcx + 0x1; rdx = rdx >> 0x1; rsi = rsi >> 0x1; } while (rsi > rax); } while (rdx > rax); } } rax = CA::Render::Shmem::new_bitmap(var_104, var_D8, var_F8, rcx); *r13 = rax; rdx = rbx; if (rax == 0x0) goto loc_d554; loc_ce2a: var_110 = rax; var_F0 = var_F0 & 0xfffffffd; goto loc_ce38; loc_cd6c: r15 = var_138; r12 = var_130; if (rdx == 0x0) goto loc_d554; goto loc_cd83; loc_cd04: r14 = 0x1; if (rdx != var_100) { r14 = var_110; } rbx = rdx; CABackingStoreDeleteBuffer(rdx); if ((_CAGetDebugFlags() & 0x20) != 0x0) { _x_log("CoreAnimation: triple buffered backing store %p\n", var_130, rdx, rcx, r8, r9, stack[2048]); } goto loc_cd44; loc_cd44: rdx = rbx; goto loc_cd47; loc_ccd8: r14 = 0x1; if (rbx != var_100) { r14 = var_110; } CABackingStoreDeleteBuffer(rbx); goto loc_cd44; loc_ccf8: r14 = var_110; goto loc_cd44; loc_ccae: var_F0 = r12; r13 = rax; var_118 = rax; var_100 = rcx; rdx = rcx; r12 = r15; goto loc_cccc; loc_cb16: *(r14 + 0x80) = var_D8; *(r14 + 0x88) = r13; var_F8 = r13; rbx = 0x1; goto loc_cb34; }