20155337 2017-2018-1 《信息安全系统设计基础》第五周课堂实践
20155337 2017-2018-1 《信息安全系统设计基础》第二周课堂实践
实践一
实践要求
- 1.参考附图代码,编写一个程序 “week0601学号.c",判断一下你的电脑是大端还是小端。
-
- 提交运行结果”学号XXXX的笔记本电脑是X端“的运行截图,要全屏,包含自己的学号信息
实践知识点
- 小端模式:按照从低地址到高地址的顺序,依次存放数据的低字节到高字节。
高八位 | 低八位 | |
---|---|---|
小端模式 | 0000 0110 | 0000 0011 |
- 大端模式:按照从低地址到高地址的顺序,依次存放数据的高字节到低字节。
| | 高八位|低八位
---|---|---|
大端模式| 0000 0011 | 0000 0110
一般来说,x86 系列 CPU 都是小端模式的字节序,PowerPC 通常是大端模式字节序,还有的CPU能通过跳线来设置CPU工作于小端模式还是大端模式模式。
实践代码
这里的代码便是如何判断自己虚拟机是大端还是小端
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start,size_t len)
{
size_t i;
for (i=0;i<len;i++)
printf("%.2x",start[i]);
printf("\n");
}
void show_int (int x)
{
show_bytes((byte_pointer) &x,sizeof(int));
}
void show_float(float x)
{
show_bytes((byte_pointer) &x,sizeof(float));
}
void show_pointer(void *x)
{
show_bytes((byte_pointer) &x,sizeof(void *));
}
void test_show_bytes(int val)
{
int ival=val;
float fval=(float)val;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(pval);
}
main()
{
char c=0x12345678;
show_int(c);
if(c==0x12)
printf("20155337是大端\n");
else
printf("20155337是小端\n");
实践截图
实践二
实践要求
-
- 调用附图代码,编写一个程序 “week0602学号.c",用show_int(), show_float()打印一下你的4位学号,参考教材P33打印出匹配的位序列。
-
- 提交运行结果截图,要全屏,要包含自己的学号信息
实践知识点
使用type得分来命名数据类型
C语言中的typedef声明提供了一种给数据类型命名的方式。者能够极大地改善代码的可读性,因为深度嵌套的类型声明很难读懂。
typedef的语法与声明变量的语法十分相像,除了它使用的是类型名,而不是变量名。
使用printf格式化输出
printf函数提供了一种打印信息的方式,这种方式对格式化细节有相当大的控制能力。第一个参数是格式串,而其余的参数都是要打印的值。在格式串里,每个以“%”开始的字符序列都表示如何格式化下一个参数。
实践代码
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start,size_t len)
{
size_t i;
for (i=0;i<len;i++)
printf("%.2x",start[i]);
printf("\n");
}
void show_int (int x)
{
show_bytes((byte_pointer) &x,sizeof(int));
}
void show_float(float x)
{
show_bytes((byte_pointer) &x,sizeof(float));
}
void show_pointer(void *x)
{
show_bytes((byte_pointer) &x,sizeof(void *));
}
void test_show_bytes(int val)
{
int ival=val;
float fval=(float)val;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(pval);
}
int main()
{
int x=5337;
test_show_bytes(x);
}
实践截图
实践三
实验要求
-
- 编写一个程序 “week0603学号.c",运行下面代码:
1 short int v = -学号后四位
2 unsigned short uv = (unsigned short) v
3 printf("v = %d, uv = %u\n ", v, uv);
-
- 在第三行设置断点用gdb调试,用p /x v; p /x uv 查看变量的值,提交调试结果截图,要全屏,要包含自己的学号信息
实践代码
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start,size_t len)
{
size_t i;
for (i=0;i<len;i++)
printf("%.2x",start[i]);
printf("\n");
}
void show_int (int x)
{
show_bytes((byte_pointer) &x,sizeof(int));
}
void show_float(float x)
{
show_bytes((byte_pointer) &x,sizeof(float));
}
void show_pointer(void *x)
{
show_bytes((byte_pointer) &x,sizeof(void *));
}
void main()
{
short int v = -学号后四位
unsigned short uv = (unsigned short) v
printf("v = %d, uv = %u\n ", v, uv);
}
实验知识点
上述的代码,它使用强制类型转换来访问和打印不同程序对象的字节表示。用typedef将数据类型byte_pointer定义为一个指向型类型为“unsign char”的对象指针。这样一个字节指针引用一个字节序列,其中每个字节都被认为是一个非负整数。show_bytes的输入是一个字节序列的地址,他用一个字节指针以及一个字节数来指示。该字节数指定为数据类型size_t,表示数据结构大小的首选数据类型。show_bytes打印出的每个以十六进制表示的字节。C格式化指令“%。2x”表明数必须用至少两个数字的十六进制格式输出。
实践截图
实践四
实验要求
1 通过输入gcc -S -o main.s main.c 将下面c程序”week0603学号.c“编译成汇编代码
int g(int x){
return x+3;
}
int f(int x){
int i = 学号后两位;
return g(x)+i;
}
int main(void){
return f(8)+1;
}
- 删除汇编代码中 . 开关的代码,提交f 函数的汇编代码截图,图中用矩形标出函数栈帧的形成和销毁的代码
实验知识点
这里我从下面的博客中学习到了栈的创建和销毁的过程,自己一开始不是很理解这个过程但是博主的图文解释让我理解这个过程。
实践代码
include <stdio.h>
int g(int x){
return x+3;
}
int f(int x){
int i = 学号后两位;
return g(x)+i;
}
int main(void){
return f(8)+1;
}
实践截图
实践五
实验要求
1 通过输入gcc -S -o main.s main.c 将下面c程序”week0603学号.c“编译成汇编代码
int g(int x){
return x+3;
}
int f(int x){
int i = 学号后两位;
return g(x)+i;
}
int main(void){
return f(8)+1;
}
- 参考http://www.cnblogs.com/lxm20145215----/p/5982554.html,使用gdb跟踪汇编代码,在纸上画出f中每一条语句引起的eip(rip),ebp(rbp),esp(rsb),eax(rax)的值和栈的变化情况。提交照片,要有学号信息。
实验知识点
实验知识点[http://www.cnblogs.com/lxm20145215----/p/5982554.html]
实践截图
首先我们因为要编译64位Linux版本32位的二进制文件,需要安装一个库,使用指令sudo apt-get install libc6-dev-i386
使用gcc - g xxx.c -o xxx -m32
指令在64位的机器上产生32位汇编,然后使用gdb xxx指令进入gdb调试器
进入之后先在main函数处设置一个断点,再run一下,使用disassemble指令获取汇编代码,用i(info) r(registers)指令查看各寄存器的值
此时主函数的栈基址为0xffffd454,用x(examine)指令查看内存地址中的值,但目前%esp所指堆栈内容为0,%ebp所指内容也为0
call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:
执行sub语句:
赋值语句i=37
实参入栈
执行到断点处