滴水逆向三期笔记与作业——02C语言——06 参数_返回值_局部变量_数组反汇编

OneNote防丢失。

一、函数返回值如何传递

1.1 char类型返回

  1. 代码:
c 复制代码
char fun(){
	//代码
	return 12;
}
int main(int argc, char* argv[]){
	char i = fun();
	return 0;
}
  1. 反汇编:
  • 函数返回值,即return 12代码部分
    在fun函数中,将返回值"12"存放在eax中(教程中32位的vc6++是存放在al位置)。

  • 函数返回值赋值给main中的变量

    将一个字节长度的12赋值给rbp-0x1的位置,在教程中32位的vc6++是将1字节长度存放在ebp-4的位置,即move byte ptr ebp-4,al(ebp-4是main函数的缓冲区),同样是仅存储一个字节的长度,编译器的不同会导致程序在空间的利用程度上存在差异

1.2 short类型返回

  1. 代码:
c 复制代码
short fun(){
	//代码
	return 12;
}
int main(int argc, char* argv[]){
	short i = fun();
	return 0;
}
  1. 反汇编:
  • 函数返回值

    short为2字节长度,所以函数中将返回值12存储在eax中,但32位的vc6++中存储在ax中

  • 函数返回值赋值给main中的变量
    将2字节长度的12存储在rbp-0x2的位置,在教程中32位的vc6++是将2字节长度存放在ebp-4的位置,即move word ptr ebp-4,ax

1.3 int类型返回

  1. 代码:
c 复制代码
int fun(){
	//代码
	return 12;
}
int main(int argc, char* argv[]){
	int i = fun();
	return 0;
}

}
  1. 反汇编:
  • 函数返回值

int为4字节长度,所以函数中将返回值12存储在eax中,32位的vc6++中也存储在eax中

  • 函数返回值赋值给main中的变量

将4字节长度的12存储在rbp-0x4的位置,在教程中32位的vc6++是将4字节长度存放在ebp-4的位置,即move dword ptr ebp-4,ea

1.4 作业-long long类型(64位)返回值

  1. 代码
c 复制代码
__int64 fun(){
	//代码
	return 0x1234567890;
}
int main(int argc, char* argv[]){
	__int64 i = fun();
	return 0;
}
  1. 反汇编:
  • 函数返回值

    在64位的环境中,__int64类型的数据存放在rax寄存器中,在32位的环境中将结果放在eax和edx中
    注:在 64 位代码中,movabs可用于对mov具有 64 位位移或立即数操作数的指令进行编码。
  • 函数返回值赋值给main中的变量

    64位环境中,将rax中的函数返回值存储在rbp-0x8的位置,使用的是qword,在32位环境中将eax(低位)存入ebp-8,将edx(高位)存入ebp-4

1.5 作业-char arr3={1,2,3}与char arr4={1,2,3,4}哪个更省空间,从反汇编角度说明,用char和short分别创建10个元素的数组,观察如何分配

1.5.1 char arr3={1,2,3}与char arr4={1,2,3,4}哪个更省空间,从反汇编角度说明

  1. char arr3={1,2,3}
  • 代码
c 复制代码
void Function(){
	char arr[3] = {1,2,3};
}
int main(int argc, char* argv[]){
	Function();
	return 0;
}
  • 反汇编(64位的VScode)

    以字节大小存储,分配了0x10大小的缓冲区;
  1. char arr4={1,2,3,4}
  • 代码
c 复制代码
void Function(){
	char arr[4] = {1,2,3,4};
}
int main(int argc, char* argv[]){
	 
	Function();
	 
	return 0;
}
  • 反汇编(64位的VScode)
  1. 总结
    同样以字节大小存储,分配了0x10大小的缓冲区;
    VScode在空函数时不分配缓冲区,即nop之后直接ret返回,当arr数组长度为5时,依然分配0x10大小的缓冲区(而不是海哥视频里的0x40+4n大小的缓冲区),可见现在是优化过的,并不会浪费大量内存去提升效率。

1.5.2 用char和short分别创建10个元素的数组,观察如何分配

  • 代码
c 复制代码
int main(int argc, char* argv[]){
 
	char arr0[10] = {1,2,3,4,5,6,7,8,9,10};
	short arr1[10] = {1,2,3,4,5,6,7,8,9,10};
	 
	return 0;
}
  • 反汇编

    char使用字节大小存储,short使用字大小存储(可见新版本还是优化了的,该是多大就是多大)。

1.6 作业-找出下面赋值过程的反汇编代码

1.6.1 作业部分

  • 代码:
c 复制代码
void Function(){
	int x = 1;
	int y = 2;
	int r;
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	r = arr[1];
	r = arr[x];
	r = arr[x+y];
	r = arr[x*2+y];
}
  • 反汇编


    数组寻址:值=取值(rbp/ebp + rax/eax * 数值宽度 - 数组首地址),其中rax/eax中存的是arrn中的n。

1.7 作业-选做桶排序

之前还在卷开发的时候都直接跳过的玩意,略过略过。

二、参数传递的本质

2.1 8位参数传递

  • 代码:
  • 汇编:

使用堆栈传递参数,并且使用4字节大小内存存储参数,从右往左入栈,并且外平栈,可见使用的调用约定是__cdecl。

2.2 16位参数传递

  • 代码:
  • 汇编:

2.3 32位参数传递

  • 代码:

  • 汇编:

2.4 总结:

  1. 在32位的系统中,参数传递始终按照4字节的大小入栈,所以定义char或者short类型的参数并不会节约空间,反而在char a = 1;Fun(1);传递参数时会产生额外的操作去进行al或者ax的转换。

  2. 如果本机是32位的,那么及其对于32位的数据支持度最好,反之32位时,对于32位的支持度最好。所以整数类型的参数,全部使用int传递参数。

  3. 参数传递的本质是将上层函数的变量或者表达式的值复制一份再传递给下层函数。

三、局部变量的内存分配

  1. (32位环境中)小于32位的局部变量,空间在分配时,按32位分配;

  2. 使用时按实际的宽度使用;

  3. 不要定义char/short类型的局部变量;

  4. 参数与局部变量没有本质区别,都是局部变量,都在栈中分配(参数是函数调用前分配的值,局部变量是函数执行时分配的值);

  5. 完全可以把参数当初局部变量使用。

四、赋值语句的本质

将某个值存储到变量中的过程就是赋值。

思考题:

int r = x + y;是赋值语句吗?那么 int r = Add(x,y)是赋值语句吗?

是,无本质区别(此处的区别是在于逆向人的眼中)。

五、数组的本质

1、总结:

1.1 一组相同类型的变量,为了方便读写,采用另外一种表示形式.

1.2 数组在声明的时候,必须用常量来指明长度,不能使用变量.

示例:定义10个变量,观察反汇编:

  • 分别赋值

在缓冲区将数组中的数据一一填入

  • 数组赋值


    可见在底层是一样的。

六、数组的使用

偏向开发的知识点

结尾依然是,海哥牛逼。

相关推荐
RainCity2 小时前
Java Swing 自定义组件库分享(十二)
java·笔记·后端
LinXunFeng8 天前
Obsidian - 使用 Share Note 分享笔记并自部署
前端·笔记·github
闪闪发亮的小星星12 天前
高斯光以及高斯光公式解释
笔记
cqbzcsq12 天前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
阿米亚波12 天前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm
自传.12 天前
尚硅谷 Vibe Coding|第三章(1) Claude Code深度使用与进阶技巧 学习笔记
笔记·学习·尚硅谷·vibecoding
.千余12 天前
【C++】模板进阶全解:非类型参数|全特化|偏特化|分离编译完全指南
开发语言·c++·笔记·学习·其他
自传.12 天前
尚硅谷 Vibe Coding|第二章 AI编程工具生态 学习笔记
笔记·学习·ai编程·尚硅谷·vibe coding
秋波。未央12 天前
Java Agent 开发 · Day 1 学习笔记(含作业完整标准答案)
java·笔记·学习
中屹指纹浏览器12 天前
2026指纹浏览器字体指纹、字体渲染偏差检测与全维度虚拟字体池搭建方案
经验分享·笔记