首页 技术 正文
技术 2022年11月21日
0 收藏 623 点赞 4,936 浏览 3506 个字

2017-2018-1 20155239 《信息安全系统设计基础》第五周学习总结+mybash的实现

mybash的实现

  • 使用fork,exec,wait实现mybash
  • 写出伪代码,产品代码和测试代码
  • 发表知识理解,实现过程和问题解决的博客(包含代码托管链接)

首先通过man命令了解fork、exec和wait

命令行输入:man fork

命令行输入:man exec

命令行输入:man wait

  • 伪代码

      while(1)
    {
    fgets(命令行输入);
    if(内置的shell命令)
    {
    解释命令;
    }
    else if(可执行文件)
    {
    新的子进程加载并运行文件;
    }
    }

产品代码

    #include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#define MAX 128 void eval(char *cmdline);
int parseline(char *buf, char **argv);
int builtin_command(char **argv); int main()
{
char cmdline[MAX]; printf("This is 20155212's bash!\n");
while(1)
{
printf("> ");
fgets(cmdline, MAX, stdin);
if(feof(stdin))
exit(0);
eval(cmdline);
}
} void eval(char *cmdline)
{
char *argv[MAX];
char buf[MAX];
int bg;
pid_t pid;
strcpy(buf,cmdline);
bg = parseline(buf,argv);
if(argv[0]==NULL)
return;
if(!builtin_command(argv))
{
if((pid=fork()) == 0)
{
if(execvp(argv[0],argv) < 0)
{
printf("%s : Command not found.\n",argv[0]);
exit(0);
}
}
}
if(!bg)
{
int status;
if(waitpid(-1,&status,0) < 0)
printf("waitfg: waitpid error!");
}
else
{
printf("%d %s",pid, cmdline);
return;
}
} int builtin_command(char **argv)
{
if(!strcmp(argv[0], "quit"))
exit(0);
if(!strcmp(argv[0],"&"))
return 1;
return 0;
} int parseline(char *buf,char **argv)
{
char *delim;
int argc;
int bg; buf[strlen(buf)-1]=' ';
while(*buf && (*buf == ' '))
buf++; argc=0;
while( (delim = strchr(buf,' ')))
{
argv[argc++] = buf;
*delim= '\0';
buf = delim + 1;
while(*buf && (*buf == ' '))
buf++;
}
argv[argc] = NULL;
if(argc == 0)
return 1;
if((bg=(*argv[argc-1] == '&')) != 0)
argv[--argc] = NULL; return bg;
}

测试代码

ls
ls -a
git --version

运行结果如下:

代码链接: https://gitee.com/bestiisjava2017/lvyuxuan20155239/blob/master/mybash.c

学习目标

  • 理解逆向的概念

  • 掌握X86汇编基础,能够阅读(反)汇编代码

  • 了解ISA(指令集体系结构)

  • 理解函数调用栈帧的概念,并能用GDB进行调试

教材学习内容总结

一、简单的汇编程序

  • 汇编代码的特点:用可读性更好的文本格式来表示。

  • 程序计数器(CS:IP)

  • 整数寄存器(AX,BX,CX,DX)

  • 条件码寄存器(OF,SF,ZF,AF,PF,CF)

学习了书上的代码例子

 long mult2(long,long); void multstore(long x,long y,long *dest){ long t= mult2(x,y);
*dest = t;
}

  • 在命令行上使用“-S”选项,编译器产生的汇编代码:gcc -Og -S mstore.c
  • “-c”命令行选项,则会编译并汇编该代码:gcc -Og -c mstore.c

如图所示:

以下面这段简单的汇编代码为例

.section .data
.section .text
.globl _start
_start:
movl $1, %eax
movl $4, %ebx
int $0x80

将这段程序保存为demo.s,然后用汇编器as把汇编程序中的助记符翻译成机器指令(汇编指令与机器指令是对应的)生成目标文件demo.o。然后用链接器ld把目标文件demo.o链接成可执行文件demo(虽然只有一个目标文件但是也需要经过链接才能成为可执行文件因为链接器要修改目标文件中的一些信息)。这个程序只做了一件事就是退出,退出状态为4。shell中可以echo$?得到上一条命令的退出状态。

运行如下:

二、寻址方式

访问内存时在指令中可以用多种方式表示内存地址。内存寻址在指令中可以表示成如下的通用格式:

ADDRESS_OR_OFFSET(%BASE_OR_OFFSET,%INDEX,MULTIPLIER)

它所表示的地址可以这样计算出来:

FINAL ADDRESS = ADDRESS_OR_OFFSET + BASE_OR_OFFSET + MULTIPLIER * INDEX

其中ADDRESS_OR_OFFSET和MULTIPLIER必须是常数,BASE_OR_OFFSET和INDEX必须是寄存器。在有些寻址方式中会省略这4项中的某些项,相当于这些项是0。

直接寻址:只使用ADDRESS_OR_OFFSET寻址,例如movl ADDRESS, %eax把ADDRESS地址处的32位数传送到eax寄存器。

变址寻址:movl data_items(,%edi,4), %eax就属于这种方式,用于访问数组很方便

间接寻址:只使用BASE_OR_OFFSET寻址,例如movl (%eax), %ebx,把eax寄存器的值看作地址,把这个地址处的32位数传送到ebx寄存器。

基址寻址:只使用ADDRESS_OR_OFFSET和BASE_OR_OFFSET寻址,例如movl 4(%eax), %ebx,用于访问结构体成员比较方便,例如一个结构体的基地址保存在eax寄存器中,其中一个成员在结构体内偏移量是4字节,要把这个成员读上来就可以用这条指令。

立即数寻址:就是指令中有一个操作数是立即数,例:movl $3, %eax。

寄存器寻址:就是指令中有一个操作数是寄存器。在汇编程序中寄存器用助记符来表示,在机器指令中则要用几个Bit表示寄存器的编号,这几个Bit与可以看做寄存器的地址,但是和内存地址不在一个地址空间。

教材学习中的问题和解决过程

老师提过反汇编的使用,我一直没有理解,上网学习了一些资料,首先要知道什么是反汇编?

这里我必须要学习下总结一下汇编和反汇编的区别了:

汇编:

  • 动词,指的是把汇编语言翻译成机器语言的过程。

    就是图中hello.s文件经过汇编器变成二进制hello.o文件的过程。

  • 名词,指的便是汇编语言

    就是hello.c经过预处理器,再经过编译器生成的hello.s文件。这个文件里的东西就叫汇编程序(汇编语言)。

  • 在linux查看.s文件(Ps:源程序为test.c)

    我们可以输入gcc-O -S test.c直接生成test.s文件,然后用vim编辑器打开它:gcc -O -S test.c

反汇编

  • 动词,指的是由已生成的机器语言(二进制语言)转化为汇编语言的过程,也可以说是汇编的逆向过程。
  • 名词,指的是有机器语言经过反汇编过程生成的汇编语言。
  • 在linux下对利用反汇编器对.o文件进行反汇编。

    objdump -d test.o

可以发现,反汇编生成的汇编代码,每一行前面都有一串16进制的数字。这些数字就是每一行汇编代码对应的机器代码。

代码调试中的问题和解决过程

  • 问题1:P107

利用vim编写一个xxx.c文件

gcc -S xxx.c得到汇编文件xxx.s

代码:

int accm = 0;
int sum(int x,int y)
{
int t = x + y;
accm += t;
return t;
}

运行如下:

问题:生成的汇编文件打开的是空的,发现-s应该是大写-S

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,474
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,889
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,724
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,479
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,118
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,278