7.49 滴水逆向(一)

中间笔记

变量

全局变量,其地址固定(我的想法:即在程序加载到内存时就存在,不像局部变量需要在使用的时候才分配内存),变量名即是内存地址的标号;

变量与参数的内存布局

1.参数在内存中的位置 参数从 ebp + 8 开始; 返回地址在 ebp + 4; ebp指向原 ebp 的值;

2.局部变量在内存中的位置 分配的CCCC缓冲区存储局部变量;

3.返回值是如何返回的,如何使用的 eax通常存储结果(返回值);

数组

在声明的时候,括号内只能是常量,但是使用时,括号内可以是变量;

字节对齐

一个变量占用 N 个字节,那么该变量的起始地址必须是 N 的整数倍,即:存放起始地址 % N = 0;如果是结构体,那么结构体的起始地址是其最宽数据类型成员的整数倍。

sizeof的使用 可以用来获取数据类型的宽度;

#pragma pack(n) 用来改变对齐参数;

指针

指针类型的变量宽度永远是4字节,无论类型是什么。

# 指针类型自加和自减
1.不带*类型的变量,++或者--都是加1或者减1。
2.带*类型的变量,++或者--新增(减少)的数量是去掉一个*后变量的宽度。

# 指针类型变量与其它整数相加或者相减时:
指针类型变量 + N = 指针类型变量 + N * (去掉一个*后类型的宽度)
指针类型变量 - N = 指针类型变量 - N * (去掉一个*后类型的宽度)

c语言数据类型

# 基本类型
1.整数类型 char short int 
2.浮点类型 float double

# 构造类型
1.数组类型
2.结构体类型
3.共用体(联合)类型

# 指针类型
# 空类型(void)

&的使用

"&变量"的类型:即变量类型后面再加一个*;

取值运算符

"*"的几种用途

1.乘法运算符
2.定义指针类型,如 char* y;
3.取值运算符,即 * + 指针 => 此时的类型即指针类型减去一个*;

数组传递参数

1.数组作为参数时,传递的是地址; 2.数组作为参数时,应该传递数组的长度;

字符串处理函数

1.字符串的几种表示方式?

(1) char str[6] = {'A', 'B', 'C', 'D', 'E', 'F', '\0'};  # 结尾'\0'或0
(2) char str[] = "ABCDE";   # 编译器在末尾自动添加0
(3) const char* str = "ABCDE";    # 常量区,目前改不了;

2.常用的字符串函数

int strlen(char* s); # 返回值是字符串 s 的长度,不包括结束符 '\0'
char* strcpy(char* dest, char* src); # 复制字符串 src 到 dest 中,返回指针为dest的值
char* strcat(char* dest, char* src); # 将字符串 src 添加到 dest 尾部
int strcmp(char* s1, char* s2); # 一样返回0,不一样返回非0

3.指针函数 本质就是函数,只不过函数的返回类型是某一类型的指针。 如 char* strcpy(char* dest, char* src);

指针取值的两种方式

*() 和 [] 可以互换 即 p[1][2] 和 ((p+1)+2)

结构体指针

结构体指针读取和修改结构体属性,用箭头,如 px->x

总结

“被指针是地址”这句话误导了,学了汇编才知道~。

指针什么类型跟其指向的数据类型一点关系都没有;

Last Updated:
Contributors: Hunter-0x07