C++面向对象基础——数据语义学
C++面向对象基础——数据语义学
PS:这节课感觉没有太多东西
歧义的纠正在 C 里面,局部变量和全局变量是可以同名的,但是局部变量会屏蔽全局变量。同样的,在类内也是这样,它会尽量在作用域范围较小的地方找到定义。即使我函数只在类内申明,类外定义,依然是会优先找到类内的定义的,因为成员函数不管在哪里定义,它的作用域都是在类内。
但是呢,跟之前的类一样,重写的方法具有覆盖继承方法的特性,只是因为它优先在本作用域找而已,并不是说就没了,我们想调用依然可以调用,我们在调用成员方法之前使用 FatherClass:: 限定作用域可以去调用父类的成员方法和成员变量。同样,我们如果类内和类外都定义了同名的变量,我们可以加上 :: 标定我们方法全局作用域的变量,这样就可以解决变量屏蔽的问题了。
预处理设置数据对对齐#pragma pack 的主要作用就是改变编译器的内存对齐方式,这个指令在网络报文的处理中有着重要的作用,#pragma pack(n)是他最基本的用法,其作用是改变编译器的对齐方式, 不使用这条指令的情况下,编译器默认采取#pragma pack(8)也就是8字节的默认对齐方式,n值 ...
C++基础——调用约定分析
C++基础——调用约定分析
调用约定其实自己 Pwn 打了两年半了也是比较了解的,但是还是开个具体的笔记去记录吧。
CPU架构常见的 CPU 架构有 x86 架构,ARM 架构和 MIPS 架构。不同的架构能执行的机器指令集是不一样的,比如 ARM 下面编译的程序指定是不能在 x86 架构下面去跑的。
x64 为一个简称,全称是 x86-64 架构,也就是 x86 架构下的 64 位版本,多见于我们的 PC,服务器,笔记本等等。
ARM 架构多见于一系列的水果产品和移动端设备。
MIPS 架构多见于路由器、智能设备等等。
处理器发展史
1971年,Intel推出了世界上第一款微处理器4004,它是一个包含了2300个晶体管的4位cPU。
1978年,Intel公司首次生产出16位的微处理器命名为i8086,同时还生产出与之相配合的数学协处理器i8087。
1978年,Intel还推出了具有16位数据通道、内存寻址能力为1MB、最大运行速度8MHz的8086,并根据外设的需求推出了外部总线为8位的8088,从而有了IBM的XT机。
1979年,Intel公司推出了8088芯片,它是第 ...
C++面向对象基础——虚函数分析
C++面向对象基础——虚函数分析
虚函数调用调用方式指针创建式调用函数(ClassName obj=new ClassName())调用的是虚表当中的函数地址,每个对象是不一样的,而如果是直接创建对象(ClassName obj)调用的函数地址就是同一个,都是类里面的函数。
写一个代码
1234567891011121314151617181920212223242526272829303132333435#include"main.h"class A{public: A() {}; ~A() {}; virtual void testA() { cout << "A::TestA" << endl; } virtual void testB() { cout << "A::TestB" << endl; } ...
C++面向对象基础——构造与拷贝构造函数
C++面向对象基础——对象&构造函数&拷贝构造函数
对象模型的探索占用内存对象所占用的空间至少1个字节,空类也会占用一个字节,这里根结构体是几乎一样的。类也和结构体一样,异构的数据类型就是会存在数据对齐,即当前位置所在的地址不在该类大小的整数倍则需要向后寻找合适的地址。
如果对象有静态变量,则静态变量不计入对象的空间,因为静态变量不属于对象,属于全体类共有,成员方法同理,也属于类,不会占用对象的空间。
如果有虚函数存在,那么对象会额外存一个虚表指针,又多 4 个字节或者是 8 个字节。
内存分布我们先来看一个例子。
123456789101112131415161718192021222324252627282930313233343536373839#pragma once#include<iostream>class A{public: A() {}; ~A() {}; int a; void TestA() { printf("A:%p\r\n" ...
一些关于Ubuntu的东西
写这个完全是因为最近在 Ubuntu 上面踩的坑有点多了。
Ubuntu
Ubuntu 是基于Debian,以桌面应用为主的Linux发行版。Ubuntu有三个正式版本,包括桌面版、服务器版及用于物联网设备和机器人的Core版。前述三个版本既能安装于实体电脑,也能安装于虚拟电脑。从17.10版本开始,Ubuntu以GNOME为默认桌面环境。Ubuntu是著名的Linux发行版之一,也是目前最多用户的Linux版本。Ubuntu每六个月(即每年的四月与十月)发布一个新版本,长期支持(LTS)版本每两年发布一次。普通版本一般只支持9个月,但LTS版本一般能提供5年的支持。
这个一直存在于 wiki 的介绍我现在才仔细地去看了看。
Ubuntu 应该算是我最喜欢用的系统了,连 Windows 都无法撼动它的地位。这里 wiki 也讲了,它主要分三个发行版:桌面版(desktop),服务器版(server),和 Core 版。我们用的最多的应该是前两个,然后就是它版本号的一些说明了,它每半年发布一个小版本(只提供9个月的支持),两年发布一个长期版本(LTS),提供五年支持。
然后每个版本 ...
HITCTF2022题解
打到第三,最后把RSA想到解法了,还行,已知高位攻击分解 p 的方法还可以学学。
附件下载
CryptoCrypto1拿出来是一个16进制,看着像 tar 的文件头,拿到解压,得到 1 文件,文件结构比较乱。看着像base家族,然后拿到 base85转hex之后发现又是熟悉的文件头。
所以可能应该是严重套娃,写个脚本统计字符数,如果发现是 tar 文件头那就直接解压拿文件内容,如果类似 base 家族的信息就 base 解码。
12345678910111213141516171819202122232425262728293031323334import gzipimport base64import base91import base58import base62from collections import Counterwith open('1','rb')as f: text=f.read()def get_count(str1): c=dict(Counter(str1)) return len(c)baseX= ...
C++面向对象基础——继承
C++面向对象基础——继承
继承面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。
当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。
继承的权限和作用域C++中的类也是可以继承的,用冒号标识继承的类,并且还可以表时是以什么权限(public,private,protected)去继承的。
公有继承:继承父类的 public 和 protected 的所有方法和成员,保持权限不变。
保护继承:继承父类的 public 和 protected 的所有方法和成员,权限全部改为 protected
私有继承:继承父类的 public 和 protected 的所有方法和成员,权限全部改为 private
继承之后,子类可以使用父类的所有方法和成员。在不指定命名空间的时候,优先访问本类命名空间的方法和成员,否则逐级向父类寻找,第一个找到的会被调用。
我们也可以在成员名或者方法 ...
KCTF2022秋季赛第二题——盗贼作乱题解
KCTF2022秋季赛第二题——盗贼作乱题解
外层分析序列号形式,先拿 ida 上手
输入部分应该就是,会先找到一个 -,所以序列号的形式是
1xxxxxxx-xxxxxx
然后下面进行一大波判断,逐一下断点动调分析。
遇到的第一个函数,经过反复动调,确定是找表得到下标值,有点像 base62 感觉,并且传的第三个参数也很像 base62 的表
最后确定应该是 62 进制的一个转换,结果保存在第一个参数,并且保存的地址类似一个结构体,第一个 int 为长度,往后都是 int 型存储,这边把结构体定义一下,改改。
12345struct number{ int len; int num[8];};
里面有一个常数,是由 IRtzloZ6iuB 字符串转换而来,把它转 10 进制发现它的值刚好是:
110000000000000000000
下面那个函数经过动调之后,发现只是把结构体设置了一下,所以我叫它 set_number。
最下面还有一个函数,它对我们之前转换的三个数字做了比较,并且需要返回结果都小于 0。
其实不难想到,先判断长度,大 ...
C++面向对象基础——运算符重载
C++面向对象基础——C++基本用法&运算符重载
C++基础知识命名空间namespace,C++ 为我们提供了一个允许我们定义在不同作用域的同名函数。我们可以用如下定义:
12345namespace name{ void f1(); void f2(); ...}
通过以上的申明我们可以在 namespace 外调用函数,通过如下方式调用
12name::f1();name::f2();
C++还有 using 关键字,使用 using 之后,我们不必通过以上方式调用,而是可以直接使用它的函数名调用。比如我如果在调用 f1() 之前用了 using namespace name;
那么我就不需要再用 name::f1() 了,而是可以直接使用 f1() 调用指定函数。
namespace 可以嵌套定义。
函数重载C++开始已经支持了同名函数的存在,在相同 namespace 下也可以定义同名的函数,只要参数类型不一样即可,它会根据你调用的方式选择合适的重载函数,主要是因为 C++ 有一个名称粉碎机制,它会根据你的参数名和参数个数 ...
护网红队面经
就随便上传一篇护网面经
红队反弹shellhttps://zhuanlan.zhihu.com/p/138393396
https://www.anquanke.com/post/id/87017
OWASP TOP 10https://blog.csdn.net/fly910905/article/details/120541498
https://www.cnblogs.com/zhijiya/p/15142003.html
shiro反序列化https://www.cnblogs.com/xiaozi/p/13239046.html
shiro在路径控制的时候,未能对传入的url编码进行decode解码,导致攻击者可以绕过过滤器,访问被过滤的路径
反序列化
aes key泄露 版本<1.2.4 key都为默认key rememberMe字段,使用密钥构造一个payload最后在不断地解密后到达readobject()
访问http://127.0.0.1/admin 的时候,页面返回403。因此可以确定admin路径是属于被过滤路径。此时使用burp截断,然后在访问路径 ...