iOS逆向工程逆向工程

macOS 下 C++ 模版的反汇编

2020-01-29  本文已影响0人  码农UP2U

C++ 模版代码

先来一段简单的 C++ 模版的代码,代码如下:

#include <iostream>

using namespace std;

template<typename T>

T min(T a, T b, T c)
{
    if (a > b) a = b;
    if (a > c) a = c;
    
    return a;
}

int main()
{
    int a = 1, b = 2, c = 3;
    
    cout << min(a, b, c) << endl;
    
    long long a1 = 1000000000, b1 = 2000000000, c1 = 300000000;
    
    cout << min(a1, b1, c1) << endl;
    
    return 0;
}

代码的功能很简单的,分别传入 int 和 long long 两种类型的实参给模版函数 min,然后进行编译,编译完成后用 ht editor 进行查看。

ht editor 查看反汇编代码

用 ht editor 挺好的,打开编译后的可执行文件以后,直接可以查看 main 函数的反汇编代码,代码如下:

│_main+0                                                                                                                                                                                                                                                   │
│       100000be0 !                                                                                                                                                                                                                                        │
│       ......... ! ;********************************************************                                                                                                                                                                              │
│       ......... ! ; function _main                                                                                                                                                                                                                       │
│       ......... ! ;********************************************************                                                                                                                                                                              │
│       ......... ! _main:                                                                                                                                                                                                                                 │
│       ......... !   push        rbp                                                                                                                                                                                                                      │
│       100000be1 !   mov         rbp, rsp                                                                                                                                                                                                                 │
│       100000be4 !   sub         rsp, 40h                                                                                                                                                                                                                 │
│       100000be8 !   mov         dword ptr [rbp-4], 0                                                                                                                                                                                                     │
│       100000bef !   mov         dword ptr [rbp-8], 1                                                                                                                                                                                                     │
│       100000bf6 !   mov         dword ptr [rbp-0ch], 2                                                                                                                                                                                                   │
│       100000bfd !   mov         dword ptr [rbp-10h], 3                                                                                                                                                                                                   │
│       100000c04 !   mov         edi, [rbp-8]                                                                                                                                                                                                             │
│       100000c07 !   mov         esi, [rbp-0ch]                                                                                                                                                                                                           │
│       100000c0a !   mov         edx, [rbp-10h]                                                                                                                                                                                                           │
│       100000c0d !   call        wrapper_100002008_100000eb6                                                                                                                                                                                              │
│       100000c12 !   mov         rdi, [data_100001000]                                                                                                                                                                                                    │
│       100000c19 !   mov         esi, eax                                                                                                                                                                                                                 │
│       100000c1b !   call        wrapper_100002038_100000eda                                                                                                                                                                                              │
│       100000c20 !   mov         rdi, rax                                                                                                                                                                                                                 │
│       100000c23 !   lea         rsi, [__ZNSt3__1L4endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]                                                                                                                                            │
│       100000c2a !   call        __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRS3_S4_E                                                                                                                                                            │
│       100000c2f !   mov         qword ptr [rbp-18h], 3b9aca00h                                                                                                                                                                                           │
│       100000c37 !   mov         qword ptr [rbp-20h], 77359400h                                                                                                                                                                                           │
│       100000c3f !   mov         qword ptr [rbp-28h], 11e1a300h                                                                                                                                                                                           │
│       100000c47 !   mov         rdi, [rbp-18h]                                                                                                                                                                                                           │
│       100000c4b !   mov         rsi, [rbp-20h]                                                                                                                                                                                                           │
│       100000c4f !   mov         rdx, [rbp-28h]                                                                                                                                                                                                           │
│       100000c53 !   mov         [rbp-30h], rax                                                                                                                                                                                                           │
│       100000c57 !   call        wrapper_100002010_100000ebc                                                                                                                                                                                              │
│       100000c5c !   mov         rdi, [data_100001000]                                                                                                                                                                                                    │
│       100000c63 !   mov         rsi, rax                                                                                                                                                                                                                 │
│       100000c66 !   call        wrapper_100002040_100000ee0                                                                                                                                                                                              │
│       100000c6b !   mov         rdi, rax                                                                                                                                                                                                                 │
│       100000c6e !   lea         rsi, [__ZNSt3__1L4endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]                                                                                                                                            │
│       100000c75 !   call        __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRS3_S4_E                                                                                                                                                            │
│       100000c7a !   xor         ecx, ecx                                                                                                                                                                                                                 │
│       100000c7c !   mov         [rbp-38h], rax                                                                                                                                                                                                           │
│       100000c80 !   mov         eax, ecx                                                                                                                                                                                                                 │
│       100000c82 !   add         rsp, 40h                                                                                                                                                                                                                 │
│       100000c86 !   pop         rbp                                                                                                                                                                                                                      │
│       100000c87 !   ret                         

然后可以看到,其中地址 100000c0d 是传递 3 个 int 类型的参数给模版函数 min 时的反汇编代码,地址 100000c57 是传递 3 个 long long 类型的参数给模版函数 min 时的反汇编代码。他们都是两个 call 指令。

我们选择第一个 call 指令后命的 标示符,然后回车,然后会来到另外一处反汇编的位置,代码如下:

│       ......... ! ;----------------------------------------------                                                                                                                                                                                        │
│       ......... ! ;  W R A P P E R for address 100002008                                                                                                                                                                                                 │
│       ......... ! ;----------------------------------------------                                                                                                                                                                                        │
│       ......... ! wrapper_100002008_100000eb6:    ;xref c100000c0d                                                                                                                                                                                       │
│       ......... !   jmp         qword ptr [data_100002008]     

可以看到,这里 ht editor 还给出了提示,它是一个 wrapper,其实观察这个代码下面的代码,都是类似的形式,这里应该是一个由 jmp 构成的跳表。光标移动到 [data_100002008] 位置处按下回车,然后就反汇编代码会跳转到 100002008 的位置处,然后起反汇编代码如下:

       100002008   data_100002008:                 ;xref J100000eb6                                                                                                                                                                                       │
│       .........     db          90h ; '?'                                                                                                                                                                                                                │
│       100002009     db          0ch ; ' '                                                                                                                                                                                                                │
│       10000200a     db          00h ; ' '                                                                                                                                                                                                                │
│       10000200b     db          00h ; ' '                                                                                                                                                                                                                │
│       10000200c     db          01h ; ' '                                                                                                                                                                                                                │
│       10000200d     db          00h ; ' '                                                                                                                                                                                                                │
│       10000200e     db          00h ; ' '                                                                                                                                                                                                                │
│       10000200f     db          00h ; ' '                                                                                                                                                                                                                │
│       100002010   data_100002010:                 ;xref J100000ebc                                                                                                                                                                                       │
│       .........     db          50h ; 'P'                                                                                                                                                                                                                │
│       100002011     db          0dh ; ' '                                                                                                                                                                                                                │
│       100002012     db          00h ; ' '                                                                                                                                                                                                                │
│       100002013     db          00h ; ' '                                                                                                                                                                                                                │
│       100002014     db          01h ; ' '                                                                                                                                                                                                                │
│       100002015     db          00h ; ' '                                                                                                                                                                                                                │
│       100002016     db          00h ; ' '                                                                                                                                                                                                                │
│       100002017     db          00h ; ' '                                     

在 100002008 的位置处,都是字节定义的数据,但是这部分数据应该是真实的地址,看看 wrapper 的代码,它是一个间接寻址,那么这部分数据就是一个地址,实际的地址是 100000c90。然后去这个地址看其具体的反汇编代码,代码如下:

│       100000c90 !                                                                                                                                                                                                                                        │
│       ......... ! ;********************************************************                                                                                                                                                                              │
│       ......... ! ; function int min<int>(int, int, int)                                                                                                                                                                                                 │
│       ......... ! ;********************************************************                                                                                                                                                                              │
│       ......... ! __Z3minIiET_S0_S0_S0_:                                                                                                                                                                                                                 │
│       ......... !   push        rbp                                                                                                                                                                                                                      │
│       100000c91 !   mov         rbp, rsp                                                                                                                                                                                                                 │
│       100000c94 !   mov         [rbp-4], edi                                                                                                                                                                                                             │
│       100000c97 !   mov         [rbp-8], esi                                                                                                                                                                                                             │
│       100000c9a !   mov         [rbp-0ch], edx                                                                                                                                                                                                           │
│       100000c9d !   mov         edx, [rbp-4]                                                                                                                                                                                                             │
│       100000ca0 !   cmp         edx, [rbp-8]                                                                                                                                                                                                             │
│       100000ca3 !   jng         loc_100000caf                                                                                                                                                                                                            │
│       100000ca9 !   mov         eax, [rbp-8]                                                                                                                                                                                                             │
│       100000cac !   mov         [rbp-4], eax                                                                                                                                                                                                             │
│       100000caf !                                                                                                                                                                                                                                        │
│       ......... ! loc_100000caf:                  ;xref j100000ca3                                                                                                                                                                                       │
│       ......... !   mov         eax, [rbp-4]                                                                                                                                                                                                             │
│       100000cb2 !   cmp         eax, [rbp-0ch]                                                                                                                                                                                                           │
│       100000cb5 !   jng         loc_100000cc1                                                                                                                                                                                                            │
│       100000cbb !   mov         eax, [rbp-0ch]                                                                                                                                                                                                           │
│       100000cbe !   mov         [rbp-4], eax                                                                                                                                                                                                             │
│       100000cc1 !                                                                                                                                                                                                                                        │
│       ......... ! loc_100000cc1:                  ;xref j100000cb5                                                                                                                                                                                       │
│       ......... !   mov         eax, [rbp-4]                                                                                                                                                                                                             │
│       100000cc4 !   pop         rbp                                                                                                                                                                                                                      │
│       100000cc5 !   ret                            

可以看到,这段代码的位置就在 main 函数的位置下方,ht editor 也给出了注释,它就是 min 函数,且形参类型是 3 个 int 类型。在代码中,除了开辟栈帧以外,其余的部分使用的都是 32 位的寄存器。

按照类似的方法找到传递 3 个 long long 类型的 min 函数,可以看到它使用的都是 64 位的寄存器。

C++ 模版反汇编总结

可以看到,C++ 的模版在编译后实际是有两份,一份是 3 个 int 形参的 min,另一份是 3 个 long long 形参的 min,C++ 在语法上为我们程序员提供了便利,但是编译器却为我们做了很多的事情。



我的微信公众号:“码农UP2U”
上一篇下一篇

猜你喜欢

热点阅读