《C++反编译与逆向分析技术揭秘》之学习笔记02--结构体和类之内存分布

※结构体和类之内存分布

1、空类的大小
空类:其实空类至少会占用1个字节的长度。

2、字节对齐
在为结构体和类中的数据成员分配内存时,结构体中的当前数据成员类型长度为M,指定对齐值为N,那么实际对齐值位q=min(M,N),其成员的地址安排在q的倍数上。
 

vc6.0缺省对齐8个字节
sShort占用2个字节,所以安排的地址0x0012FF70为2的倍数。
nInt占用4个字节,所以安排的地址0x0012FF74为4的倍数。
因为结构体中最大的字段长度为4,所以对齐值调整为4个字节。因为test对象为8个字节,恰好为4的倍数,所以整个对象不用补字节对齐了。

以下tagTwo的size是多少?

在tagTwo中将tagOne解开看,最大的字段长度是8个字节,所以对齐按照8字节来,那么nInt之后需要补4个空字节,而tagOne正好是16个字节,所以是24个字节。那么能否将nInt之后的补齐的4个字节放到tagOne之后呢?就像书上说的各个编译器厂商实现也有所不同。

时间: 2024-10-12 13:24:07

《C++反编译与逆向分析技术揭秘》之学习笔记02--结构体和类之内存分布的相关文章

《C++反编译与逆向分析技术揭秘》之学习笔记01--浮点数转IEEE编码

※浮点数转IEEE编码 1.float类型的IEEE编码(31,30~23,22~0=>符号位,指数位,尾数位)eg1:12.25 经过IEEE编码后的各位情况:符号位:0指数位:3+127, 10000010尾数位:100010000000000000000004字节二进制:0x41440000vc6.0截图: eg2:-0.125 经过IEEE编码后的各位情况:符号位:1指数位:-3+127, 01111100尾数位:000000000000000000000004字节二进制:0xBE000

《C++反编译与逆向分析技术揭秘》之学习笔记03--函数的调用方式

※函数的调用方式 EBP:扩展基址指针寄存器(extended base pointer) 其内存放一个指针,该指针指向系统栈最上面一个栈帧的底部. ESP:(Extended stack pointer)是指针寄存器的一种,用于指向栈的栈顶. _cdecl:C/C++默认的调用方式,调用方平衡栈,不定参数的函数可以试用. 调用方:1.参数压栈.esp-=42.调用函数.3.实现栈平衡.esp+=4 此处的printf也是同样道理0x004010CB.0x004010CC两处压入参数,共8个字节

《C++反汇编与逆向分析技术揭秘》--认识启动函数,找到用户入口

<C++反汇编与逆向分析>和<程序员的自我修养>都是以VC6的代码作为例子讲解的.这里是在vs2017下,CRT代码有些区别,但整体流程上都是初始化环境,设置参数,最后转到用户main函数. class COne { public: COne() { printf("COne \r\n"); } ~COne() { printf("~COne \r\n"); } }; COne g_One; int main() { printf("

《C++反汇编与逆向分析技术揭秘》--数据类型

  浮点数类型 IEEE标准从逻辑上采用一个三元组{S, E, M}来表示一个数N,它规定基数为2,符号位S用0和1分别表示正和负,尾数M用原码表示,阶码E用移码表示.根据浮点数的规格化方法,尾数域的最高有效位总是1,由此,该标准约定这一位不予存储,而是认为隐藏在小数点的左边,因此,尾数域所表示的值是1.M(实际存储的是M),这样可使尾数的表示范围比实际存储多一位.为了表示指数的正负,阶码E通常采用移码方式来表示,将数据的指数e 加上一个固定的偏移量后作为该数的阶码,这样做既可避免出现正负指数,

《C++反汇编与逆向分析技术揭秘》之十——析构函数

局部对象 当对象所在作用域结束之后,销毁栈空间,此时析构函数被调用. 举例: 函数返回时自动调用析构函数: 堆对象 调用析构代理函数来处理析构函数: 为什么使用析构代理函数来调用析构函数?考虑到如果delete的对象是一个对象数组,可以使用析构代理函数依次析构所有的对象.举例: 调用了构造代理函数: vector deleting destructor函数中先对标志位进行判断: 如果没有跳转,表明delete的是一个数组,则会调用调用析构代理函数对对象进行逐一的析构.如果进行了跳转,则只进行一次

《C++反汇编与逆向分析技术揭秘》之十一——虚函数

虚函数的机制 当类中定义有虚函数时,编译器会将该类中所有虚函数的首地址保存在一张地址表中,这张表被称为虚函数地址表.编译器还会在类中添加一个虚表指针. 举例: CVirtual类的构造函数中没有进行任何操作,但是我们来看构造函数内部,还是有一个赋初值的操作: 这个地址指向的是一个数组: 这些数组中的内容就是虚函数的指针: 值得注意的是,如果没有虚指针的存在,那么CVirtual大小就是4字节.有了这个指针存在就是8字节. 本例子中,使用了一个空的构造函数,但是编译器自己擅自插入了代码,实现了对虚

一行一行分析JQ源码学习笔记-02

1.防止冲突    设置新变量保存??   $ = jquery 2. jquery = function() { return new jqery.fn.init () } 3. 为什么构造函数有引用关系 例如: jquery().css() 构造函数 jquery.prototype.init.prototype = jquery.prototype; //对象引用对象

APK反编译jd-gui代码分析(草稿记录)

1. 连续for循环 反编译代码: 1 private void removeHideLines() 2 { 3 int i = 0; 4 if (i >= this.lines.size()) {} 5 for (int j = 0;; j++) 6 { 7 if (j >= this.recordLines.size()) 8 { 9 return; 10 if (((MusicTrackLine)this.lines.get(i)).getX() + ((MusicTrackLine)t

反编译 APKTool 逆向助手

最佳实践:Android逆向助手 1.点击"反编译apk,完成后res下的所有资源就都可以正常使用了,相当于apktool的功能------目前已失效,但是直接用rar解压是可以的!2.点击"提取dex",可以提取出apk文件中的.dex文件,相当于把.apk更改后缀后解压3.点击"dex转jar",相当于dex2jar的功能4.点击"jd打开jar",可以自动使用jd-gui打开jar文件,现在已经可以查看源码了5.在jd-gui中不