内存结构

vector在内存实现中仅有三个指针,分别是_M_start指针,指向元素数组的开始,_M_finish指针指向最后一个元素的下一个元素地址,而_M_end_of_storage指针指向当前vector分配的堆空间的结束地址。

image.png

在ida中,局部变量vector的大小一般被识别为_BYTE v7[24];

可以直接将这个结构体导入ida中

struct __fixed vector
{
  unsigned int *start;
  unsigned int *finish;
  unsigned int *end_of_storage;
};

基本方法函数识别

变量创建/声明

在变量创建中会经过一条调用链,以vector<unsigned int>为例

std::_Vector_base<unsigned int>::_Vector_basestd::_Vector_base<unsigned int>::_Vector_impl::_Vector_implstd::_Vector_base<unsigned int>::_Vector_impl_data::_Vector_impl_data

也就是经过三个函数调用后,最后会进行初始化,结构长这样:

vector *__fastcall std::_Vector_base<unsigned int>::_Vector_impl_data::_Vector_impl_data(vector *a1)
{
  vector *result; // rax

  result = a1;
  a1->start = 0LL;
  a1->finish = 0LL;
  a1->end_of_storage = 0LL;
  return result;
}

push_back

调用链:

std::vector<unsigned int>::emplace_back<unsigned int>

这个函数里长这样

__int64 __fastcall std::vector<unsigned int>::emplace_back<unsigned int>(vector *a1, uint64_t a2)
{
  if ( a1->finish == a1->end_of_storage )
    std::vector<unsigned int>::_M_realloc_append<unsigned int>(a1, a2);
  else
    *a1->finish++ = *(_DWORD *)a2;
  return std::vector<unsigned int>::back(a1);
}

pop_back

没有深层的调用链

函数里长这样