首页 > 编程语言 >C++逆向分析——类成员的访问控制

C++逆向分析——类成员的访问控制

时间:2023-08-02 18:33:45浏览次数:27  
标签:Print1 逆向 访问控制 成员 private class int C++ public

类成员的访问控制

课外 → 好的编程习惯:定义与实现分开写,提升代码可读性。

如下代码,Student这个类的所有成员我们都可以调用,但是我们不想让被人调用Print1这个方法该怎么?

struct Student {

int age;


int sex;

 

void Print1() {


 printf("Func Print1");

 }
 

void Print() {


 printf("Func Print");

 }
};

这里我们可以使用关键词:private、public来控制我们想被人访问的和不想被人访问的成员:

struct Student {

private:


void Print1() {


 printf("Func Print1");

 }
 

public:


int age;


int sex;


void Print() {


 printf("Func Print");

 }
};

当我们调用Print1的时候就会发现无法编译:

C++逆向分析——类成员的访问控制_编译器

private(私有)、public(公有)的使用总结:

  1. 对外提供的函数或者变量,定义成public,不能随意改动
  2. 可能会改动的函数或者变量,定义成private,使用时编译器会检测
  3. 只有当前结构体内部函数才可以访问private的成员
  4. private、public可以修饰函数或者变量

那么问题来了,private修饰的函数或者变量真的不能访问吗?并不是,只是我们没有办法通过正常的方式去使用,但是我们可以使用指针的方式去调用:

C++逆向分析——类成员的访问控制_内部函数_02

那就说明private修饰的成员与普通成员没有区别,只有编译器会检测。

自己vs2022测试下:

代码如下:

#include <stdio.h>
class Person {
private:
	int age;
	int sex;

public:
	Person(int a, int b) {
		age = a;
		sex = b;
	}
};


 
void main() {
	Person tom(100, 1);	
	int* p = (int*)&tom;
	printf("%d %d\n", p[0], p[1]);
	return;
}

 

C++逆向分析——类成员的访问控制_内部函数_03

 

 

在我的vs2022里,运行下看看tom这个局部变量存放的地址:

C++逆向分析——类成员的访问控制_内部函数_04

 

是从ebp-c开始的,不是ebp-4,也不是ebp-8!

 

 

从这节课开始我们不再使用struct作为类的创建,而是直接使用class关键词,其使用没有什么区别,唯一的区别在于成员默认访问属性不一样,在struct中所有成员默认的属性是public,而在class中则相反:

C++逆向分析——类成员的访问控制_内部函数_05

除此之外还有一个就是在继承时的区别,我们可以将一个正常的struct继承修改成class:

class A {


public:


int x;


int y;

};
 

class B:A {


public:


int v;


int n;

};

当我们创建对象调用的时候却无法编译:

C++逆向分析——类成员的访问控制_父类_06

这是因为在继承的时候默认将继承过来的A的所有成员设置为private,也就是如下代码:

class A {


public:


int x;


int y;

};
 

class B:private A {


public:


int v;


int n;

};

而我们想要外部可以调用可以将private修改成public。

最后一个问题:私有成员是否会被继承?

class A {


private:


int x;

 

public:


int y;

};
 

class B:public A {


public:


int v;


int n;

};

以上代码B继承了A,这里A前面的public代表着,按照A的成员定义的属性继承过来,公有就是公有,私有就是私有。

而在这里我们想要确认B有没有继承A的私有成员,有2个方法:

1.查看数据宽度,显示为16

C++逆向分析——类成员的访问控制_父类_07

2.指针方式调用,可以成功调用获取到值

C++逆向分析——类成员的访问控制_编译器_08

所以我们得出最终结论:父类的私有成员是可以被继承的,但是也不能直接访问。(当然,使用前面指针的方式是可以访问的)

标签:Print1,逆向,访问控制,成员,private,class,int,C++,public
From: https://blog.51cto.com/u_11908275/6941579

相关文章

  • C++逆向分析——new和delete new[]和delete[]
    在堆中创建对象我们可以在什么地方创建对象?全局变量区,在函数外面在栈中创建对象,也就是函数内在堆中创建对象注意:之前一直提到的堆栈实际上是两个概念->堆、栈,我们之前所讲的就是栈,从本章开始要严格区分。在C语言中,我们可以通过一个函数去申请一块内存,就是malloc(N);申请的这一块内存......
  • C++逆向分析——继承
    继承structPerson{intage;intsex;};structTeacher{intage;intsex;intlevel;intclassId;};如上代码中可以看见,Teacher类与Person类都存在着相同的2个成员age和sex,那么这就相当于重复编写了,我们可以通过继承的方式避免这样重复的编写(当前类名称:要......
  • C++逆向分析——this指针
    this指针概述C++是对C的拓展,C原有的语法C++都支持,并在此基础上拓展了一些语法:封装、继承、多态、模板等等。C++拓展新的语法是为了让使用更加方便、高效,这样就需要编译器多做了很多事情,接下来我们就需要一一学习这些概念。封装之前我们学习过结构体这个概念,那么结构体可以做参数传......
  • C语言逆向——预处理之宏定义、条件编译与文件包含
    预处理之宏定义、条件编译与文件包含预处理一般是指在程序源代码被转换为二进制代码之前,由预处理器对程序源代码文本进行处理,处理后的结果再由编译器进一步编译。预处理功能主要包括宏定义、文件包含、条件编译三部分。宏定义简单的宏:#define标识符字符序列#defineFALSE0#d......
  • C语言逆向分析——Switch语句,为何大多数情况较if语句更高效?就是因为查找表
    Switch语句Switch语句也是分支语句的一种,其语法如下:switch(表达式){case常量表达式1:语句;break;case常量表达式:语句;break;case常量表达式:语句;break;......default:语句;break;}需要注意如下几点:表达式结束不能是浮点数case后的常量......
  • C语言逆向——数组和结构体,数组多维只是一个编译构造的假象,本质会转成一维数组,结构体
    数组数组是C语言中非常重要的一个概念,学习C语言主要就是两个知识点:数组、指针,学好这两个,那么你的C语言一定也会很好。什么是数组?或者说什么情况下我们需要使用数组,比如说我们需要定义一个人的年龄,我们可以定义一个变量来表示,但是如果我们需要定义三个人的年龄呢?那就需要三个变量来......
  • 逆向——字符与字符串,中文字符GB2312编码由来
    字符与字符串在之前的课程中我们了解到变量的定义决定两个事情,第一是决定存储的数据宽度,第二是决定了存储的数据格式,那么我们来看下下面的代码:inta=123;//变量x,数据宽度为4个字节,里面存储的是补码(在计算机系统中,数值一律用补码来存储)intfloatb=123.4F;//IEEE编码(浮点)......
  • 【C++数据结构】启航,打开新世界的大门!
    @TOC一、学习数据结构的原因学习数据结构对于计算机科学和软件开发非常重要,它提供了处理和组织数据的有效方法和技术。以下是几个学习数据结构的重要原因:提高问题解决能力:数据结构教会了我们如何选择和使用适当的数据结构来解决问题。了解各种数据结构的特性和性能可以帮助我们分......
  • v_jstools js逆向分析工具
    1.工具地址:https://github.com/cilame/v_jstools2.下载文件文件下载下来以后,复制到桌面,然后解压到当前文件夹,会看到一个  v_jstools-main 的文件夹。3.插件安装谷歌浏览器地址栏输入如下url,打开扩展程序页面,并打开开发者模式:chrome://extensions/打开后,点击......
  • protobuf在c++中的使用
    一、安装sudoaptinstalllibprotobuf-devprotobuf-compiler二、编辑proto文件,生成代码文件proto语法分为“proto2”和”proto3“两个版本,指定方法是在proto文件中第一行写入:syntax="proto3";,这样指定使用proto3版本的语法,如果不指定,默认是使用proto2的语法。两个语法的......