Untitled
1.输入4个正整数,按从小到大的顺序输出123456789101112131415161718#include<iostream>using namespace std;int main(){ int a,b,c,d,m; cout<<"请输入4个整数"<<endl; cin>>a>>b>>c>>d; m = a; if(a>b){t=a;a=b;b=t;} if(a>c){t=a;a=c;c=t;} if(a>d){t=a;a=d;d=t;} if(b>c){t=b;b=c;c=t;} if(b>d){t=b;b=d;d=t;} if(c>d){t=c;c=d;d=t;} cout<<"从小到大的排序为"&...
C筑基——引用
引用 为一个变量起一个别名,是C++的重要扩充; C++之所以增加引用机制,主要是把它作为函数参数,以扩充函数传递数据的功能。 变量的引用 声明一个引用时,必须同时使之初始化,即声明它代表哪一个变量(当引用作为函数形参时不必在声明中初始化) 12345int a;//声明b是a的“引用”,&是引用声明符,将a的地址赋给b【只有这个形式才是引用声明符,其余的都是取地址符】int &b = a; /*经过声明后,a与b的作用相同,都代表同一内存数据*/ 在声明一个引用后,不能再使之作为另一变量的引用 -不能建立对数组的引用,即int &b[5] = a;这样是错误的,不过可以建立对数组元素的引用int &b = a[0];.-不得建立对引用的引用,引用的指针(因为引用他没有自己独立的内存地址)-但是在建立引用后,可以有int *p;p = &b;-在声明了引用后,在使用它时不带&-cout<<”引用b的值为”<<b<<“引用b的地址为”<<&b; 引用作为函数参数三种方式实现函...
C筑基——结构体
结构体 UDT(用户自定义类型):分为结构体、共用体和枚举类型等; 结构体类型声明一个结构体类型的一般形式如下,使用时必须对各成员都进行类型声明即类型名 成员名; 123struct 结构体类型名{ //类型名用于作结构体类型的标志 成员表 //又称为域表,每一个成员称为结构体中的一个域}; 在C++中,结构体的成员既可以包括数据也可以包括函数; 当我们对结构体类型作出定义时,相当于定义了一个模型,系统并不对之分配实际内存单元; 在使用时要定义结构体类型的变量,并在其中存放具体的数据; [!NOTE] 结构体变量必须先定义、赋值,然后使用。 定义方法: 先声明类型再定义(推荐) 便于修改和使用 1234567891011121314151617181920//#include<string>,如果换为string类型,要引入这个头文件#include<cstring> //引用strcpy等函数using namespace std;//C++会...
C筑基——输入输出流
输入输出流文件存储在外部介质上的数据集合;操作系统以“文件”为单位对数据进行管理 根据文件内容分类:程序文件(.cpp/.obj/.exe)+数据文件 根据文件存储和访问方式:顺序存取文件+随机存取文件 根据文件中数据的组织形式:ASCII码文件(文本文件)+二进制文件(字节文件,节省内存和转换时间) 文件流 针对文件的操作在执行时需要手动关联磁盘文件 在C++的I/O库种定义标准输入输出流类:istream,ostream,iostream; 专用于对磁盘文件的输入输出类:ifstream(读文件),ofstream(写文件),fetream(输入输出) 文件输入/输出参数设置 方式 作用 ios::in 以输入方式打开文件,【对fstream:ios::in是 “读文件的开关”,必须写】 ios::out 以输出方式打开文件,文件已存在则原有内容会被清除(只有ofstream默认) ios::app 一、先给核心结论(以输出方式打开文件,数据追加在文件末尾【不然直接打开会被清空原有的】 ios::at...
C筑基——指针
指针 我们在声明变量时,有两个要素即“对应地址+对应值”,变量的指针就是变量的地址 优点:提高效率,使用灵活,可实现动态存储分配 缺点:过于灵活,易出现危险的野指针 指针变量访问变量的方式12int arr[3] = {10, 20, 30};int *p = arr; // 数组名arr等价于&arr[0],直接指向第一个元素 直接访问(通过变量名找到其所在的存储空间) 1cout<<arr[1]<<endl; 间接访问(将a的地址放入p,通过p去访问变量a) 1cout<<*(p + 1)<< endl; //&:取地址符 *:指针运算符,所声明的即指针变量 [!TIP] 直接访问(变量名 / 数组下标)是最基础、最直观的内存操作方式,胜在可读性高、出错风险低,适合简单变量操作、非性能敏感的普通场景;而间接访问(指针)的核心价值在于突破直接访问的局限 —— 能直接操作底层固定内存地址适配硬件开发、支持运行时动态创建可变长度数据、传递大对象时无需拷贝提升效率,是实现...
C筑基——数组
数组 一组有相同数据类型的结构,数据的有序集合,通过下标区分不同变量 减少变量数量 统一的数组名易于理解和使用 可利用循环语句对数组元素进行操作 一维数组 类型名 数组名[常量表达式(数组长度)] ,如int a[10],下标是从0开始的,比如这个例子的下标就是0-9 C++不允许用变量作为数组长度 1234567891011/*利用循环语句实现*/#include <iostream>using namespace std;int main(){ int i,a[10]; for(i=0;i<=9;i++)a[i] = i+1; //使a[0]的值为1,后面的类似 for(i=9;i>=0;i--)cout<<a[i]<<" "; //逆序输出 cout<<endl; return 0;} 需要注意的是,若只定义而不赋值,那么数组内的每个元素值都是不确定的 定义初始化示例:int a[10]= {0,1,2,3,4,5...
软件安全逆向——软件漏洞
Shellcode可了解 漏洞利用(exploit):指利用已有漏洞(故有exploit就一定有漏洞,反之不一定),根据漏洞类型和特点采取相应的技术方案,进行尝试性或实质性攻击;(发起动作的代名词) Shellcode:植入进程代码(实现具体功能) payload:exploit的有效部分,负责触发漏洞,将控制权转移给shellcode(实际的完整结构) 需掌握(大题大题)shellcode代码植入⭐⭐⭐ 主要是利用溢出覆盖邻接变量以实现控制流劫持从而完成破解 对于一个Verify函数栈帧【buffer[44]+flag(4B)+前EBP(4B)】若想淹没此函数栈的返回地址,即要构建的代码块的第53~56字节(反写buffer的地址,其他的部分用90(NOP)填充)用于去覆盖掉返回地址 我们对获取函数入口地址的代码进行反汇编(比如获取一个MessageBoxA的地址为0x76670380),按照汇编指令转成对应的机器代码【33 DB 53 68 77 65 73 74 68 66 61 69 6C C4 53 50 53 B8 80 03 67 76 FF D0】(因为...
软件安全逆向——漏洞利用
漏洞利用可了解堆喷洒技术(Heap Soray)【对没用ASLR的管用】在shellcode前面加上大量的滑板指令(slide code),组成非常长的注入代码段,向系统申请大量内存,并反复用这个注入代码段去填充; ASLR空间地址分布随机化,将系统关键地址随机化,使攻击者无法获得需要跳转的精确地址 微软从操作系统加载时的地址变化和可执行程序编译时的编译器选项两方面进行实现和完善 系统加载地址变化:当程序将执行文件加载到内存时,操作系统通过将内核模块提供的ASLR功能在原映像基址基础上加一个随机数作为新的映像基址; 编译器选项(DYNAMICBASE):使用该选项后编译后的程序每次运行时其内部的栈等结构地址都被随机化。 G S 对栈的缓冲区溢出防范效果好 VC++编译器中提供/GS编译选项,使用时编译器针对函数调用和返回时添加保护和检查功能代码,在函数被调用时,在缓冲区和函数返回地址之间加上一个32位随机数security_cookie,在函数返回时调用检查函数检查security_cookie是否发生变化 security_cookie的值在进程启动时随机产生...

