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

本工具从最初版的跳转分布图只为了更直观地分析反汇编代码的分支结构,第三版开始对直观图进行逆向分支代码的输出第四版对分支输出策略的一些探索第五版结合之前的探索进行改进。第六版在现在功能的基础上进行增强,利用第六版(一)的基本功能-直译第六版(二)对条件分支增加条件判断翻译,以及改进在函数调用处附带备选参数参考

第六版(三)将(一)和(二)组合在一起进行逆向代码输出。

本篇是(四),在(三)的基础上增加对原子操作指令的逆向以及c++函数的逆向。

指令的原子操作如OSAtomic(Add|Xor|Or|And|CompareAndSwap),就是Lock锁总线后的指令操作。

下面说的是c++函数调用的逆向,主要如何套用参数。

c风格的函数和c++函数,在生成的函数符号上有区别。c风格的函数的符号不会有参数的任何信息,顶多就有参数的总大小(size),如msvc对extern "C" void test(int)可能生成 _test@4这样的符号。而c++风格的符号则会带上函数原型的全面信息,如属于哪个类哪个名字空间参数序列几何,这样才能够使c++在相同的函数名可以被重载,符号连接才不会冲突。所以在调试器反汇编出来的代码,往往可以提示出c++函数的原型,而c风格的函数只有名字(不能解析参数序列)。

既然调试器反汇编出了c++函数符号,就应该好好使用。但调试器并没有提示一个类的函数是静态成员函数还是成员函数,因为这两种函数在调用约定时,相差了一个参数位,所以在逆向分析时要进行分析区分。一般来说,构造和析构函数一定是成员函数,static和const修饰不同时使用,带const修饰就可以认为也是成员函数。剩下来的就只能够通过分析判断。

我的方法是将类方法同时分别去应用两种调用约定(不带this的静态成员函数调用和带this的成员函数调用),然后分别对两种情况下寄存器使用的匹配度进行比较,判断出其中的一种。不像hopper那样,将明明是c++的类方法,却当作c风格函数来简单处理。

下面是对CA::Render::key_path_set(void**, __CFString const*)调用的分析判断,判断结果是成员函数参数序列不相符,所以应当是静态成员函数。

// 64    rdi = &_30;
// 68    rsi = r12;
// 71 call
// CA::Render::key_path_set((void**)&_30, (__CFString const*)r12);
// ((CA::Render*)&_30)->key_path_set((void**)r12, (__CFString const*)rdx/*wrong*/);
CA::Render::key_path_set(void**, __CFString const*);
// 76    rdi = r15;
// 79 call
CA::Transaction::lock();
// 84    r15 = r14->_98;
// 91    rbx = r14;
// 94    _38 = r15;
// 98 testq %r15, %r15
// 101
if (!) { // 98 (0 == r15)
         // 103    r13 = &_38;
         // 107    r12d = 0;
         // 110    r14 = &_30;
_b114:     // from 174
         // 114    rsi = &r15->_10;
         // 118    edx = 0;
         // 120    rdi = r14;
         // 123 call
         // CA::Render::key_path_equal((void* const*)r14, (void* const*)&r15->_10, (bool)0);
         // ((CA::Render*)r14)->key_path_equal((void* const*)&r15->_10, (void* const*)rdx/*wrong*/, (bool)cl/*wrong*/);
    CA::Render::key_path_equal(void* const*, void* const*, bool);

再来看

if (!) { // 738 (0 == r12)
         // 751    rdi = r12;
         // 754 call
    ((CA::Render::Object*)r12)->unref();
_f759:     // from 714
} // 759
  // 759    rsi = _38;
  // 763    rdi = r13;
  // 766 call
  // CA::Layer::set_animations((CA::Layer::Animation*)r13);
  // ((CA::Layer*)r13)->set_animations((CA::Layer::Animation*)_38);
CA::Layer::set_animations(CA::Layer::Animation*);
// 771    edx = 0x1;
// 776    rdi = r13;
// 779    rsi = r14;
// 782 call
// CA::Layer::mark_animations((CA::Transaction*)r13, (bool)esi/*wrong*/);
// ((CA::Layer*)r13)->mark_animations((CA::Transaction*)r14, (bool)0x1);
CA::Layer::mark_animations(CA::Transaction*, bool);
// 787    rdi = r14;
// 790 call
CA::Transaction::unlock();

首先是CA::Render::Object::unref() const,可以确定这是一个成员函数,所以使用成员函数调用方式。

接着是CA::Layer::set_animations(CA::Layer::Animation*), 两种方式的假设都没有找出不符,优先使用成员成员函数方式。

第三是CA::Layer::mark_animations(CA::Transaction*, bool),静态成员方式调用匹配有不符,所以可以判定是成员函数。

 

下面是贴上两个函数的逆向输出:

CA::Layer::prepare_commit
{
    // 0 pushq %rbp
    // 1    rbp = rsp;
    // 4 pushq %r15
    // 6 pushq %r14
    // 8 pushq %r13
    // 10 pushq %r12
    // 12 pushq %rbx
    // 13    rsp = rsp - 0x1058;
    // 20    r15 = rsi;
    // 23    _1078 = r15;
    // 30    r14 = rdi;
    // 33    rax = (void *)0x00000001066f9070: __stack_chk_guard;
    // 40    rax = rax->_0;
    // 43    _30 = rax;
    // 47    rsi = &_1030;
    // 54    edi = 0x400;
    // 59    edx = 0x1000;
    // 64 call
    x_heap_new_with_ptr;
    // 69    rbx = rax;
    // 72    _1080 = rbx;
    // 79    rdi = r15;
    // 82 call
    CA::Transaction::lock();
    // 87    xmm0 = 0.; ;
    // 90    ((float*)&_1070)[0] = xmm0.ps[0]; ((float*)&_1070)[1] = xmm0.ps[1]; ((float*)&_1070)[2] = xmm0.ps[2]; ((float*)&_1070)[3] = xmm0.ps[3]; ;
    // 97    _1060 = 0x0;
    // 108    _1058 = r15;
    // 115    _1050 = rbx;
    // 122    _1048 = 0x2;
    // 132    _1044 = 0x4;
    // 142    _1040 = 0x0;
    // 152    rsi = &_1070;
    // 159    rdi = r14;
    // 162 call
    ((CA::Layer*)r14)->collect_layers_((CA::Layer::CollectLayersData*)&_1070);
    // 167    rbx = _1070;
    // 174    rdi = r15;
    // 177 call
    CA::Transaction::unlock();
    // 182
    goto _f188;
    _b184:     // from 403
    _b184:     // from 386
             // 184    rbx = rbx->_8;
    _f188:     // from 182
             // 188 testq %rbx, %rbx
             // 191
    if (!) { // 188 (0 == rbx)
             // 197    r12 = rbx->_0;
             // 200    r14 = r12->_10;
             // 205 testq %r14, %r14
             // 208
        if (!) { // 205 (0 == r14)
                 // 214    rdi = r15;
                 // 217 call
            CA::Transaction::lock();
            // 222    rdi = r14;
            // 225    rsi = "contents";
            // 232 call
            objc_msgSend(r14, "contents");
            // 238    r13 = rax;
            // 241 testq %r13, %r13
            // 244
            if () { // 241 (0 == r13)
                    // gen jmp 336
                goto _f336;
                // 246    rdi = r13;
                // 249 call
                CFRetain;
                // 254    rdi = r15;
                // 257 call
                CA::Transaction::unlock();
                // 262    rdi = r13;
                // 265 call
                CFGetTypeID;
                // 270    r15 = rax;
                // 273 call
                CGImageGetTypeID;
                // 278 cmpq %rax, %r15
            } // 281
            else if () { // 278 (r15 != rax)
                         // gen jmp 346
                goto _f346;
            }
            else { // 281 next
                   // 283    rdi = r14;
                   // 286    rsi = "_renderImageCopyFlags";
                   // 293 call
                objc_msgSend(r14, "_renderImageCopyFlags");
                // 299    r14d = eax;
                // 302    r15 = _1078;
                // 309    rdi = r15;
                // 312 call
                CA::Context::current_colorspace((CA::Transaction*)r15);
                // 317    xmm0 = 0.; ;
                // 320    rdi = r13;
                // 323    rsi = rax;
                // 326    edx = r14d;
                // 329 call
                CA::Render::prepare_image((CGImage*)r13, (CGColorSpace*)rax, (unsigned int)r14d, (double)xmm0);
                // 334
                goto _f369;
            _f336:     // from 244
            } // 336
              // 336    rdi = r15;
              // 339 call
            CA::Transaction::unlock();
            // 344
            goto _f377;
        _f346:     // from 281
                 // 346    rdi = r13;
                 // 349    rsi = "CA_prepareRenderValue";
                 // 356 call
            objc_msgSend(r13, "CA_prepareRenderValue");
            // 362    r15 = _1078;
        _f369:     // from 334
                 // 369    rdi = r13;
                 // 372 call
            CFRelease;
        _f377:     // from 344
        } // 377
          // 377 cmpq $0x0, 0x98(%r12)
          // 386
        if () // 377 (r12->_98 == 0x0)
            goto _b184;
        // 392    rdi = r12;
        // 395    rsi = r15;
        // 398 call
        ((CA::Layer*)r12)->prepare_animations((CA::Transaction*)r15);
        // 403
        goto _b184;
    } // 408
      // 408    rdi = _1080;
      // 415 call
    x_heap_free;
    // 420    rax = (void *)0x00000001066f9070: __stack_chk_guard;
    // 427    rax = rax->_0;
    // 430 cmpq -0x30(%rbp), %rax
    // 434
    if () // 430 (rax != _30)
    goto _f475;
    // 436    rsp = rsp + 0x1058;
    // 443 popq %rbx
    // 444 popq %r12
    // 446 popq %r13
    // 448 popq %r14
    // 450 popq %r15
    // 452 popq %rbp
    // 453 ret
    return;
    _b454:     // from 473
             // 454    r14 = rax;
             // 457    rdi = r15;
             // 460 call
    CA::Transaction::unlock();
    // 465    rdi = r14;
    // 468 call
    _Unwind_Resume;
    // 473
    goto _b454;
    _f475:     // from 434
             // 475 call
    __stack_chk_fail;


    /*****
    * global variables
    *
    */

    // 33 extern ent_off__0x7516a;    movq 0x75142(%rip), %rax;     (void *)0x00000001066f9070: __stack_chk_guard
    // 225 extern ent_off__0x6fa52;    movq 0x6f96a(%rip), %rsi;     "contents"
    // 286 extern ent_off__0x6fa12;    movq 0x6f8ed(%rip), %rsi;     "_renderImageCopyFlags"
    // 349 extern ent_off__0x6f6c2;    movq 0x6f55e(%rip), %rsi;     "CA_prepareRenderValue"
    // 420 extern ent_off__0x7516a;    movq 0x74fbf(%rip), %rax;     (void *)0x00000001066f9070: __stack_chk_guard
}
CA::Layer::prepare_commit
CA::Layer::update_removed_sublayer
{
    // 0 pushq %rbp
    // 1    rbp = rsp;
    // 4 pushq %r14
    // 6 pushq %rbx
    // 7    r14 = rsi;
    // 10    rbx = rdi;
    // 13    rbx->_8 = 0x0;
    // 21    rbx->_a4 = edx;
    // 27    edx = 0;
    // 29 call
    // CA::Layer::mark_visible((CA::Transaction*)rdi, (bool)esi);
    // ((CA::Layer*)rdi)->mark_visible((CA::Transaction*)rsi, (bool)0);
    CA::Layer::mark_visible(CA::Transaction*, bool);
    // 34    rdi = r14;
    // 37    rsi = rbx;
    // 40 call
    ((CA::Transaction*)r14)->add_root((CA::Layer*)rbx);
    // 45 lock
    // 46    OSAtomicAnd32(0xffefffff, (volatile int32_t*)&rbx->_4);
    // 53    rbx->_84 = rbx->_84 & 0xffffbfff;
    // 60    eax = rbx->_80;
    // 66    eax = eax << 0x3;
    // 69    eax = eax ^ rbx->_4;
    // 72 testl $0x400000, %eax
    // 77
    if () // 72 (0x400000 & eax)
    goto _f84;
    // 79 popq %rbx
    // 80 popq %r14
    // 82 popq %rbp
    // 83 ret
    return;
    _f84:     // from 77
             // 84    rdi = rbx;
             // 87    rsi = r14;
             // 90 popq %rbx
             // 91 popq %r14
             // 93 popq %rbp
             // 94 ret
    return;    // jmp 0x1041aa814; CA::Layer::toggle_flipped(CA::Transaction*)
            // 99 nop
}
CA::Layer::update_removed_sublayer

 

posted on 2016-05-19 17:16  bbqz007  阅读(434)  评论(0编辑  收藏  举报