2017-2018-1 20155216 《信息安全系统设计基础》第五周学习总结
2017-2018-1 20155216 《信息安全系统设计基础》第五周学习总结
教材学习内容总结
理解逆向的概念
由百度百科上查询到的逆向工程官方的定义:
逆向工程(又称逆向技术),是一种产品设计技术再现过程,即对一项目标产品进行逆向分析及研究,从而演绎并得出该产品的处理流程、组织结构、功能特性及技术规格等设计要素,以制作出功能相近,但又不完全一样的产品。逆向工程源于商业及军事领域中的硬件分析。其主要目的是在不能轻易获得必要的生产信息的情况下,直接从成品分析,推导出产品的设计原理。
逆向工程被广泛地应用到新产品开发和产品改型设计、产品仿制、质量分析检测等领域,它的作用是:
1、缩短产品的设计、开发周期,加快产品的更新换代速度;
2、降低企业开发新产品的成本与风险;
3、加快产品的造型和系列化的设计;
4、适合单件、小批量的零件制造,特别是模具的制造,可分为直接制模与间接制模法。
掌握X86汇编基础,能够阅读(反)汇编代码
通过理解和阅读汇编代码,使我们更容易理解编译器的优化能力,并能分析代码中隐含的低效率,从而使得自己所编写的代码效率有所提升。
了解ISA(指令集体系结构)
指令集体系结构指的是计算机体系结构中与程序设计有关的部分,包含了基本数据类型,指令集,寄存器,寻址模式,存储体系,中断,异常处理以及外部I/O。
ISA在编译器编写者和处理器设计人员之间提供了一个抽象层:
处理器设计者:依据ISA来设计处理器
处理器使用者:依据ISA就知道CPU选用的指令集,就知道自己可以使用哪些指令以及遵循哪些规范
定义处理器上的软件如何构建,这是ISA的最重要内涵,现代处理器都是支持高级语言编程、操作系统等等特性,ISA要定义出指令集内的指令是如何支撑起C语言里堆栈、过程调用,操作系统里异常、中断等。
理解函数调用栈帧的概念,并能用GDB进行测试
在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。函数中的参数总是被调用的函数中的参数先入栈,而后才是调用的函数中的参数。
其中低地址是栈顶地址,高地址是栈底地址。
过程
过程提供了一种封装代码的方式,用一组指定的参数和一个可选返回值实现了某种功能,然后,可以在程序中不同的地方调用这个函数。
当调用一个过程时,除了要把控制传递给它并在过程返回时再传递回来之处,过程调用还可能包括把数据作为参数传递,而从过程返回还有可能包括返回一个值。大部分过程间的数据传达室通过寄存器实现的。
寄存器是唯一被所有过程共享的资源。
每个过程调用在栈中都有它自己的私有空间,因此多个未完成调用的局部变量不会相互影响。
浮点代码
当函数包括指针,整数和浮点数混合的参数时,指针和整数通过通用寄存器传递,二浮点值通过XMM寄存器传递。
AVX浮点操作不能以立即数据作为操作数,相反,编译器必须为所有的常量值分配和初始化存储空间。
教材学习中的问题和解决过程
-
问题1:常用指令集的简单包含哪些。
-
问题1解决方案:
AMD指令集:
AMD 3DNow!
AMD 3DNow! Professional
AMD 3DNowPrefetch
AMD Enhanced 3DNow!
AMD Extended MMX
AMD MisAligned SSE
AMD SSE4A
AMD SSE5
Cyrix Extended MMX
Intel指令集:
IA-64
IA MMX
IA SSE
IA SSE 2
IA SSE 3
IA Supplemental SSE 3
IA SSE 4.1
IA SSE 4.2
IA AVX
IA FMA
IA AES Extensions
-
问题2:对于函数调用时,数据在栈中的存放不清楚。
-
问题2解决方案:
当发生函数调用的时候,栈空间中存放的数据:
1、调用者函数把被调函数所需要的参数按照与被调函数的形参顺序相反的顺序压入栈中,即:从右向左依次把被调函数所需要的参数压入栈;
2、调用者函数使用call指令调用被调函数,并把call指令的下一条指令的地址当成返回地址压入栈中(这个压栈操作隐含在call指令中);
3、在被调函数中,被调函数会先保存调用者函数的栈底地址(push ebp),然后再保存调用者函数的栈顶地址,即:当前被调函数的栈底地址(mov ebp,esp);
4、在被调函数中,从ebp的位置处开始存放被调函数中的局部变量和临时变量,并且这些变量的地址按照定义时的顺序依次减小,即:这些变量的地址是按照栈的延伸方向排列的,先定义的变量先入栈,后定义的变量后入栈。
图示:
代码调试中的问题和解决过程
- 问题1:
#include <stdio.h>
#include <string.h>
int main()
{
int x = 1;
int y = 2;
int z = 3;
printf("addr x = %u\n",(unsigned int)(&x));
printf("addr y = %u\n",(unsigned int)(&y));
printf("addr z = %u\n",(unsigned int)(&z));
printf("x = %d; y = %d; z = %d;\n", x,y,z);
return 0;
}
运行结果:
可见后定义的参数先入栈,参数入展是从右向左或从后先前的。
#include <stdio.h>
#include <string.h>
struct C
{
int a;
int b;
int c;
};
int test(int x, int y, int z)
{
int a = 1;
int b = 2;
int c = 3;
struct C st;
printf("addr x = %u\n",(unsigned int)(&x));
printf("addr y = %u\n",(unsigned int)(&y));
printf("addr z = %u\n",(unsigned int)(&z));
printf("addr a = %u\n",(unsigned int)(&a));
printf("addr b = %u\n",(unsigned int)(&b));
printf("addr c = %u\n",(unsigned int)(&c));
printf("addr st = %u\n",(unsigned int)(&st));
printf("addr st.a = %u\n",(unsigned int)(&st.a));
printf("addr st.b = %u\n",(unsigned int)(&st.b));
printf("addr st.c = %u\n",(unsigned int)(&st.c));
return 0;
} int main(int argc, char** argv)
{
int x = 1;
int y = 2;
int z = 3;
test(x,y,z);
printf("x = %d; y = %d; z = %d;\n", x,y,z);
return 0;
}
运行结果:
被调用的结构体或函数里的参数先入栈,但是主函数中的参数入栈顺序却相反,不是从右向左。
- 问题1解决方案:
尚未明白函数入栈规律。
代码托管
结对及互评
本周结对学习情况
- [结对同学学号1](博客链接)
- 结对照片
- 结对学习内容
- XXXX
- XXXX
- ...
其他(感悟、思考等,可选)
1、Linux系统下的C源文件的处理方式比windows下的要更加丰富。
2、关于计算机语言中的各种运算仍需要加深理解。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第三周 | 114/114 | 3/3 | 20/20 | |
第四周 | 136/250 | 2/5 | 18/38 | |
第五周 | 87/337 | 2/7 | 22/60 | |
第六周 | 300/1300 | 2/9 | 30/90 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
-
计划学习时间:25小时
-
实际学习时间:20小时
-
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)