缓冲区溢出漏洞:
#include <stdio.h>
#include <stdlib.h>
void Printf()
{
printf("hello world");
system("pause");
}
void Magic()
{
int nNum[5] = { 0 };
nNum[7] = (int)Printf; //函数调用的c语言语法:函数名(),没有括号不是调用
} //那Printf没有括号咋调用的?
int main()
{
Magic();
return 0;
}
结果:hello world
典型的缓冲区溢出漏洞
DEP(数据保护模式):所有可写的地方都不可执行,所有可执行的地方都不可写
黑客怎么绕过dep呢?aslr(动态随机机制)
没有dep。alsr的时代:06年、07年
int nNum[15];指针数组
数组指针:
int Num[15];
int (nNum)[15];数组指针,指向15个int型的数组 nNum=Num
指针函数:int Fun(int nNum,char c)
函数指针:int (Fun)(int nNum,char c); //int (Fun)(int ,char );
int Abc(int nNum,char c);
Fun=Abc;
int nRet=Fun(111,’A’);
==================================
如果参数类型不一样,又要用函数指针指向它,就要强转
int Add(float fNum);
Fun=(int ()(int,char))Add;
==================================
怎么让强转类型变得简单一点?
typedef int (PFUN)(int ,char); 继续写可以写全一点:PFUN=Fun;
Fun=(int ()(int,char))Add; //一样
Fun=(PFUN))Add; //一样
指针的本质:指针的类型,指针指向数据的类型
二级指针:指向一级指针的指针
写程序遵循一条原则:写给人看的,附带给机器运行
命令行参数:
int main(int argc,char* argv[]) //获取命令参数用的 接受命令的个数,以空格为分隔
//一个个指向字符串的指针,分别指向所给字符串的首地址
// 一个参数传进去实际有两个,
{
printf("%d",argc);
for(i=1;i<argc;i++)
{
printf("%s,argv[i])
}
printf("\n");
system("pause");
return 0;
}
静态数据区
已初始化区
未初始化区
常量数据区
代码区
栈区
堆区 CPU寄存器组
为了加快速度常用寄存器变量(register),但是如果使用不频繁也会当初普通变量,不定义register如果使用频繁也会被当成寄存器变量
系统空间(3环的系统) 0x7000以上
0x0000~0x1000 空指针区域
系统内核
变量的生存期:
静态生存期
动态生存期
。。。
栈:给函数的局部变量 参数 栈帧 函数的返回地址 不需要自己申请和维护
堆:除了0x7000以上的地址都可以整成堆,存储数据最主要的一个手段,效率低(cpu都要参与申请操作,能少用就少用,能申请就多申请,违反了高内聚低耦合())
信息安全有建树:
1.思想适应社会,脑子跟上(多读书,哪件事傻干哪个)
2.文字能力(会写文章)
3.代码简洁 :
一个函数最多50行
注释:代码=2:1
先写注释、空函数
高内聚低耦合(函数单独拎出来可以运行)
头文件 里边只放调用其他cpp的
内存空间的动态分配“坑”
1.刚刚分配的动态内存的初始值是不确定的
2.不能对同一指针(地址)连续两次进行free操作
3.不能对指向静态内存区(全局变量)或站内内存区(局部变量)的指针应用free(但可以对空指针NULL应用free)
4.对一个指针应用free之后,它的值不会改变,但它指向了一个无效的内存区,这时称该指针为“悬空指针”
5.执行malloc、new都有一定代价,cpu都要参与申请操作,能少用就少用,能申请就多申请,违反了高内聚低耦合
6.内存分配未成功,却使用了它
7.内存分配虽然成功,但是尚未初始化就引用它(误认为初始值为0)
8.内存分配成功并且已经初始但操作越过了内存的边界
9.忘记了释放内存,造成内存泄漏
10.释放了内存却继续使用它
内存拷贝函数、内存初始化函数:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#
int main()
{
int flag = 0;
char buf[8] = { 0 };
char pass[12] = { 0 };
while (true)
{
scanf_s("%s", pass);
flag = strcmp(PASSWORD, pass);
strcpy(buf, pass);
if (!flag)
{
printf("hello");
system("pause");
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdarg>
void myArg(int nTag, ...)
{
void* argpointer; //定义变参指针
argpointer = (void*)&nTag;
int nCount = 0;
while (true)
{
argpointer = (char*)(((int)argpointer) * sizeof(int));
char argData = *(argpointer);
if (argData == 0) break;
printf("param %d is: $d\n", nCount++, argData);
}
argpointer = nullptr; //结束变参指针
}
void funArg(int nTag, ...)
{
va_list argpointer;
va_start(argpointer, nTag);
int nCount = 0;
while (true)
{
char argData = va_arg(argpointer, int);
if (argData == 0) break;
printf("param %d is: $d\n", nCount++, argData);
}
va_end(argpointer);
}
int main()
{
funArg(1, 2, 3, 4, 56, 7, 0);
return 0;
}
文件访问的基本模式————-文件指针
c语言提供的:库函数
windows提供的:api
typedef struct
{
short level 缓冲区满或空的程度
unsigned flags 文件状态标志
char fd 文件描述符
unsigned char hold 如无缓冲区不读字符
short bsize 缓冲区的大小
unsigned char buffer 数据缓冲区的位置
unsigned char curp 指针当前的指向
unsigned istemp 临时文件指示器
short token 用于有效性检查
}FILE;