_S_empty_rep_storage 在此代码中用于什么?

逆向工程 拆卸
2021-06-20 17:28:26

在反转用 g++ 编译的 C++ 程序时,我看到使用了 _ZNSs4_Rep20_S_empty_rep_storageE。通过 c++filt 运行它表明在修改之前它是一个:

std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_empty_rep_storage

但是这个 _S_empty_rep_storage 有什么用呢?我在下面使用了一个程序集片段:

mov     rax, cs:_ZNSs4_Rep20_S_empty_rep_storageE_ptr
...
add     rax, 18h
...
mov     [rsp+328h+var_308], rax
mov     [rsp+328h+var_2F8], rax
mov     [rsp+328h+var_2E8], rax
...
lea     r14, [rsp+328h+var_308]
lea     rsi, [rsp+328h+var_2D8] ; std::string *
mov     rdi, r14        ; this
call    __ZNSs4swapERSs ; std::string::swap(std::string &)
lea     rdi, [rsp+328h+var_2D8] ; this
lea     r13, [rsp+328h+var_2F8]
lea     r12, [rsp+328h+var_2E8]
call    __ZNSsD1Ev      ; std::string::~string()

所以我的问题是:_S_empty_rep_storage 的目的是什么?还有为什么 var_308、var_2f8 和 var_2e8 被引入 r12-14?这些寄存器以后不再使用。

1个回答

检查 libstdc++ 开头的注释以basic_string.h了解 GCC 的工作std::string原理。基本上,它_S_empty_rep_storage是一个空字符串的预初始化(实际上,归零)表示,用于在默认构造函数中初始化字符串。所以var_308,var_2F8var_2E8是三个 std::string 对象,初始化为空字符串。

至于r12-r14,它们似乎被用作临时变量。我们至少可以看到,r14用于初始化rdi-this用于std::string::swap()调用指针,因此大概r12r13稍后也会使用。