最近弄Android c/c++方面的逆向,发现c++的类,stl模板,在逆向的时候相比c语言都带来了不小的困难。
今天自己写了个小程序,然后逆向分析了一下
vector<int> array_int; array_int.push_back(1); array_int.push_back(2); array_int.push_back(5);
定义一个vector,然后添加数据。
ida反汇编如下:(已添加注释)
. int_tmp = -0x18 . vector_ptr = -0x14 . var_8 = - . . PUSH {R4-R7,LR} . LDR R5, =(__stack_chk_guard_ptr - 0x1170) . SUB SP, SP, #0x1C . .text:0000116C ADD R5, PC ; __stack_chk_guard_ptr .text:0000116E LDR R5, [R5] ; __stack_chk_guard . ADD R6, SP, #0x1C+vector_ptr . ; [SP,#0x1C+int_tmp] . LDR R3, [R5] . MOVS R0, R6 . STR R3, [SP,#0x1C+var_8] . .text:0000117C MOVS R1, R7 .text:0000117E STR R3, [SP,#0x1C+int_tmp] . STR R4, [SP,#0x1C+vector_ptr] . ] . ] . BL _ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::push_back(int const&) . .text:0000118C MOVS R0, R6 .text:0000118E MOVS R1, R7 . STR R3, [SP,#0x1C+int_tmp] . BL _ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::push_back(int const&) . MOVS R3, # . MOVS R0, R6 .text:0000119A MOVS R1, R7 .text:0000119C STR R3, [SP,#0x1C+int_tmp] .text:0000119E BL _ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::push_back(int const&)
分析如下:
. ADD R6, SP, #0x1C+vector_ptr
将栈的vector_ptr处的地址复制给R6
. ; [SP,#0x1C+int_tmp]
将sp+4的地址赋值给R7 ,这个地址相当于栈的int_tmp处
. MOVS R0, R6
将vector_ptr的地址赋值给R0,作为push_back的第一个参数
.(顺序已调整,看地址号) . .text:0000117C MOVS R1, R7 .text:0000117E STR R3, [SP,#0x1C+int_tmp] . STR R4, [SP,#0x1C+vector_ptr]
将要push_back的int值1储存到栈的int_tmp处。将R7赋值给R1,作为push_back的第二个参数,第一个参数为vector对象指针,也就是this指针。
将vector_ptr处赋值为0。
. ] . ]
将vector_ptr处的后两个栈中的项赋值为0,其中[R6,#4]处保存的是vector中的最后一项元素的下一项的指针,相当于end()。
而[R6,#8]处的值也会随着一次次push_back发生改变,暂时没有发现其作用
. BL _ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::push_back(int const&)
执行push_back(R0,R1)
这是R0里边为vector_ptr的地址(地址处的值为0),R1为int_tmp的地址(地址处的值为要添加的数据1)
执行完这一句时,vector_ptr地址的处的值将被修改为对象array_int的地址。
在以后的每次push_back()操作,vector_ptr处,vector_ptr+4处,vector_ptr+8处的值都会变化。
对应的函数原型为push_back(vector<int>*,int*)
调试结果:
第一次push_back
第二次push_back
第三次push_back
最后附上循环打印的代码
for (vector<int>::size_type i = 0; i < array_int.size(); ++i) { cout<<array_int.at(i); }
整个循环过程就比较容易理解了.