【加密与解密】第四章④
4.整数的取模
取模运算可以通过除法指令实现。一般的优化做法是将其转换成等价的位运算或者除法运算,再由除法运算进行优化。
虚函数
C++的三大核心机制是封装,继承,多态,而虚函数就是多态的一种体现。软件逆向中,难免遇到使用面向对象思想设计的软件,而虚函数就是在实际软件逆向过程中的一种还原面向对象的重要手段。本章探讨编译器实现虚函数的原理。
1.虚表
首先在main的入口先申请了对象实例的内存空间。先调用构造函数,调用fun1,fun2.这些成员函数调用的第一个参数就是this指针,也就是rcx=this。C++语法规定在实例化对象时会自动调用构造函数,对象作用域会自动调用析构函数。
在逆向过程中,当一个对象是在某个作用域内调用的第一个函数,就可以怀疑是构造函数,如果是最后一个,就怀疑是析构函数的调用。
构造函数中首先初始化虚表指针,然后初始化数据成员,构造函数完成,返回this指针。
然而为什么析构函数还要赋值虚表,构造函数不是赋值了吗?这是因为C++语法规定,析构函数需要调用虚函数的多态性。在分辨哪一个是构造函数哪一个是析构的时候可以看调用的顺序。
虚标中的函数成员函数声明顺序依次放入的。需要注意的是函数分布顺序在某些情况,和声明顺序不一定相同。不过顺序对逆向还原也没有影响。本例中只写了一个虚析构函数吗,却生成了两个析构函数。其中一个是普通析构函数,一个是放在虚表里的。
2.单重继承虚表
为什么main函数使用new申请对象空间。因为虚表需要8字节虚表空间和8字节的内存对齐。这里可以看出派生类和基类共享一个虚表指针。
本文作者:Corax0o0
本文链接:https://www.cnblogs.com/Corax0o0/p/17054585.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步