Linux学习笔记1&openEuler vmware安装
一、openEuler和VMware
获取openEuler镜像
下载镜像和其sha256文件
完整性检验
Windows下使用命令 certutil -hashfile 文件名 sha256
获取文件的sha256值
我这第一次莫名其妙地下载了LTS-SP1-x86_64,所以哈希值不对,重新下一下sp2
这回对了
VMware创建并安装openEuler
阅读并操作了近十篇博客后,还是推荐这个教程
ukui桌面环境
yum install ukui -y
systemctl set-default graphical.target
==========================================
vmtools
复制压缩包到桌面解压
sudo ./pl
一路回车
安装很多次后,个人建议
-
安装系统时,软件选择中,选择最小安装后,还应该选择右侧的“标准、开发工具、系统工具”三项,
方便进入终端之后,有一定的工具可以用 -
检查网络和主机名一项,看看网络是否连接,是否有IP地址,默认路由,和DNS,顺便改一下主机名;
这个截图一定要保留一下,如果后面网络出了问题,要用截图里的信息配置网络 -
不要锁定root用户,方便之后做一些需要root权限的操作
-
可以使用ukui的桌面环境,也可以考虑deepin、gnome等
安装并重启openEuler之后,可能遇到的问题
-
SMBus Host Controller not enabled
-
Name or Service not known
-
表现:ping www.baidu.com 报错
-
首先检查ip地址,看看目前的IP地址能不能上网
-
方法一:静态IP,但是我发现隔壁的ubuntu和kali也上不了网了。。。这里对VMware的操作好像对所有虚拟机都生效
-
方法二:思前想后,回忆一下看过的二十几篇博客,研究了一下隔壁ubuntu的网络配置,a sudden enlightenment
- ifconfig 查看下网卡,应该有一个ens33
ifconfig 命令 之前在安装系统时应该已经安装了(软件选择一项),如果没有的话,现在又没有网,个人觉得只能重装一下系统。
使用ifconfig ens33 {某个IP}
配置ens33的IP地址
{某个IP} = 之前安装系统时,有个网络和主机名的选项界面,右侧有一个IP地址,顺便把默认路由也记下来
- route add default gw {某个网关IP}
{某个网关IP} = 之前安装系统时,有个网络和主机名的选项界面,右侧有一个默认路由
- 用 ifconfig -a 和 route 命令检查配置是否成功
- ping www.baidu.com 应该可以成功,然后重启后配置失效
- 永久生效,修改网卡配置文件
vi /etc/sysconfig/network-scripts/ifcfg-ens33.conf
reboot 重启,大概率就好了,之后就可以愉快地yum 和 wget 了
- ifconfig 查看下网卡,应该有一个ens33
-
VMwareTools和终端中文输入
-
VMware Tools
安装VMware Tools时,相当于VMware给openEuler挂了个U盘。把里面的安装文件夹复制到桌面,
解压缩里面的压缩包,打开终端,sudo运行.pl文件,一路回车(默认配置)即可 -
openEuler终端中文输入
sudo yum install ibus-libpinyin
ibus-setup
全部默认配置即可- 安装好以后,在任务栏会有图标,可以点击图标切换中英文输入,也可以使用快捷键
二、学习笔记(1、2章)
知识点归纳
最有收获的内容
最有收获的内容还是 堆栈和栈帧 的部分,以前也做过缓冲区溢出的攻击试验,当时就因为对底层的情况了解的不是很清楚,而导致shellcode没法运行。
虽然当时也查找了不少资料,但本书中的讲解,提到了之前没有注意到的知识,也加深了我对 程序执行时堆栈实际情况 的理解。
为了方便描述堆栈的情况,这里将函数调用过程,分为两个部分,函数调用和函数返回
-
函数调用
- 函数接收的参数入栈(如果不这么做,进入函数之后,就看不到参数了)
- 将函数完成之后下一条待执行指令的地址,压入堆栈
- 进入函数
- 上一个函数的栈帧地址(FP)入栈(栈帧地址,就是上学期mips汇编时,在函数中用到的基地址,如果不保存基地址,之后用偏移量访问变量时,地址就错误了)
- 将当前位置,作为当前函数的栈帧地址(FP)
- 向低地址端移动SP,扩展堆栈空间
- 为当前函数中的局部变量分配空间
- 至此,从第一步的参数,到sp 之间的空间,就是栈帧(粗略地讲),代表了当前函数可见的内存空间区域。
-
函数返回
- 将返回值存入AX寄存器
- 将sp移动到当前函数的栈帧地址,释放该地址之前的堆栈空间(低地址部分,也就是局部变量那一部分的空间)
- 弹出堆栈中存储的上一个函数的栈帧地址,让FP指向上一个函数的栈帧地址
- 弹出堆栈中存储的下一条待执行指令的地址,让PC指向此地址,继续执行函数结束后 后面的指令
-
关于缓冲区溢出
- 在栈帧的局部变量部分,写入数据时,是从低地址向高地址写入数据
- 也就是说,如果数据足够长,就可以覆盖掉 堆栈中保存的上一个函数的栈帧地址 和 函数结束后下一条待执行指令的地址
- 设计数据之后,就可以在pop pc 时,让pc变成我们设计好的shellcode的执行首地址
- 当然,实际操作不会这么简单
问题与解决思路
硬链接怎么实现的
读写时怎么做的?
inode(index node)索引节点,inode本质是一个结构体,存储着文件详细信息,
删除时怎么做的?
只是删除硬链接计数,当删到0时,再真正去删除inode
warning:隐式声明
函数调用之前,如果没有函数声明和函数定义,那么编译器会帮忙做隐式声明
int add(int ,int ) 变量都自动定义成int类型
这是一件危险的事情,这次是正好碰上了,所以能运行成功
解决方法就是为静态库 配套编写一个头文件
gcc src/ch1/staticlib.c -o bin/staticlib -L lib -l mymath -I include
创建用户以后,进不去home/下面的用户文件夹
三、实践内容与截图
openEuler的Git安装与使用
虽然没有现成的openEuler教程,但下面两个博客基本能解决问题
初始化好了之后,常用的git命令也就差不多,add、commit和push
创建好本地仓库的目录结构后,先编写个hello.c测试一下,makefile之后再写
本地gcc正常,hello.c正常执行,git正常工作,远程库正常更新
history命令
用 !数字
重新执行某条命令
ll命令
ll命令 等价于 ls -l命令,
结果解析
-
第一部分,10个字母
-
第一个字母,代表文件类型,Linux下有七个文件类型,对应七个字母,列举三个常见的:普通文件 (-)目录文件(d) 符号链接(|)
-
剩下9个字母,被分成3组,每组3个字符,依次为rwx,代表三种权限,r(可读)w(可写)x(可执行),如果没有该项权限,则用 - 标志
-
第一组表示所有者(Owner)的权限,第二组表示同一组用户的权限(Group),第三组表示其他用户的权限(Others)
-
-
第二部分,一个数字,代表硬链接数,inode值,关于硬链接与inode
-
第三部分,所属用户
-
第四部分,所属组
-
第五部分,文件大小,如果没有单位,默认以字节为单位
-
第六部分,最后一次修改时间,可能是“月、日、时:分” ;或者“月、日、年”(最后一次修改时间不是今年)
-
第七部分,文件名
cat命令
cat -n 文件名
显示行号
cat -b 文件名
显示行号,不算空行
cp命令
cp -a 源文件 目标文件
保留链接、文件属性,并复制目录下的所有内容
cp -r 源文件 目标文件
通过ls -l查看,可以发现文件的最后一次修改时间发生了变化
cp -d 源文件 目标文件
复制软连接。正常不加-d,就会复制目标文件
软连接
rm命令
正常rm命令是不询问的,直接做删除操作
如果希望它询问,加 -i
如果正常rm命令删除一些受保护的文件,不会直接删除,会先询问
如果不希望它询问,加-f
删除文件夹 加-r
ln命令
- 创建软连接
ln -s 相对路径 文件名
将软连接换一个位置就会出错
ln -s 绝对路径 文件名
将软连接搬移到任意位置,都能找到对应的文件
虽然不论是cat还是vi,都会查看目标文件,而不是连接文件本身,
但我们可以从文件大小,以及一些资料推测:软连接文件中存储的就是路径
- 1.txt.link 大小是5字节,就是存的 1.txt
- 1.txt.s 大小是 7 字节,存的是 ./1.txt
- 1.txt.s2 大小是 27 字节,存的是 /home/doxide/桌面/1/1.txt (中文编码,一个汉字3字节)
软连接记录相对位置,搬移后出错,记录绝对位置则没问题
- 创建硬链接
ln 文件名 链接名
find命令
-type -maxdepth(find默认搜索所有子目录,如果不想这么做,需将-maxdepth作为第一个参数,指定搜索深度)
-name 结合正则表达式
-size -size (同时上下限,需要两个size)
单位:注意大小写
- b(默认) 块 等于512字节
- k(KB) 小写
- M(MB) 大写
- G(GB)
-atime -ctime -mtime(按照最近访问、更改、改动时间,查找)
-exec 命令 {} ; 不询问
-ok 命令 {} ; 询问
{}代表搜索结果集合
; 转义,语句结束标记
grep命令与ps命令
-r 进入子目录 -n 显示行号
ps aux (类似任务管理器)
ps aux | grep kernel(搜索进程,至少有一个,那是这条命令的进程)
kill + 进程id (杀死进程)
tar命令
-zcvf 压缩
-zxvf 解压缩
man命令
/string 查找
n 查找下一个 N 查找上一个
Vim
末行模式,替换
:2,3s /thinked/thinks/g
:%s /thinks/thought/g
命令模式,man手册
3K
创建2.txt,并将1.txt的内容复制到2.txt
vi 1.txt
:vsp 2.txt
Ctrlww
ggyG
Ctrlww
P
:Wqall
gcc
hello.c
#include <stdio.h>
#include "hello.h"
void say_hello(){
printf("191206say hello\n");
}
int main(){
say_hello();
return 0;
}
hello.h
#ifndef _HELLO_H_
#define _HELLO_H_
/*comments*/
void say_hello();
#endif
gcc src/ch1/hello.c -I include -o bin/hello
gdb
gcc src/ch1/gdb.c -o bin/gdbtest -g
l(list)显示源代码
b(break)设置断点 r(run)运行,遇到断点自然停下
n(nextline)下一行代码 s(step)下一步,会进入函数
p(print)查看变量 display(持续展示变量值)
使用until,运行到指定行,用来跳出循环
使用finish,结束函数
条件断点 b 行号 if 条件
查看、切换栈帧 bt 和 frame (查看不在当前函数栈帧中的变量)
用set args设置命令行的输入的参数
makefile
src = $(wildcard src/ch1/*.c)
obj = $(patsubst %.c,%.o,$(src))
myArgs= -Wall -g
ALL:a.out
a.out:$(obj)
gcc $^ -o $@ $(myArgs)
$(obj):%.o:%.c
gcc -c $< -o $@ -Iinclude $(myArgs)
clean:
-rm -rf $(obj) a.out
.PHONY: clean ALL
因为现在项目里面有两个main函数,所以报错了,但头文件正常包含,目标文件正常生成了
改进
还要注意一下,.o 文件不能 -g生成调试信息
1 src = $(wildcard src/*/*.c)
2 obj = $(patsubst %.c,%.o,$(src))
3
4 #obj = $(patsubst %.c,%.o,$(notdir $(src)))
5 #obj0 = $(addprefix lib/,$(notdir $(src)))
6 #obj1 = $(patsubst %.c,%.o,$(obj0))
7 #exe = $(addprefix bin/,$(notdir $(src)))
8 #finalexe = $(patsubst %.c,%,$(exe))
9
10
11 myArgs= -Iinclude -Llib -Wall
12
13 ALL:a.out
14
15 a.out:$(obj)
16 gcc lib/*.o -o $@ $(myArgs)
17
18 $(obj):%.o:%.c
19 gcc -c $< -o lib/$(notdir $@) $(myArgs)
20 -gcc lib/$(notdir $@) -o bin/$(patsubst %.o,%,$(notdir $@)) $(myArgs)
21 -gcc -g $< -o test/$(patsubst %.o,%,$(notdir $@)) $(myArgs)
22
23 clean:
24 -rm -rf lib/*.o a.out
25
26 .PHONY: clean ALL test
27
28 test:
29 @echo $(src)
30 @echo $(obj)
31 # @echo $(exe)
32 # @echo $(finalexe)
新增:makefile的VPATH
VPATH是对于makefile来说搜索目标和依赖文件的路径,
对于命令行来说是无效的,执行gcc命令时不会自动从vpath中自动搜索文件
也就是说,make能找到,但是gcc找不到
所以应该在命令中使用隐式规则中的自动变量 $<
还有个vpath(小写),比较灵活,百度一下就知道了
VPATH=src:include
testmymath:add.o sub.o mul.o div.o main.o
gcc -Iinclude add.o sub.o mul.o div.o main.o -o testmymath
add.o:add.c head.h
gcc -c -Iinclude $< -o add.o
sub.o:sub.c head.h
gcc -c -Iinclude $< -o sub.o
mul.o:mul.c head.h
gcc -c -Iinclude $< -o mul.o
div.o:div.c head.h
gcc -c -Iinclude $< -o div.o
main.o:main.c head.h
gcc -c -Iinclude $< -o main.o
clean:
rm testmymath *.o
静态库制作
ar rcs ../../lib/libmymath.a add.o sub.o div1.o
gcc src/ch1/staticlib.c -o bin/staticlib -L lib -l mymath
gcc src/ch1/staticlib.c -o bin/staticlib -L lib -l mymath -I include
动态库制作
gcc -c %.c -o %.o -fPIC (生成与位置无关的代码)
gcc -shared -o lib库名.so %.o
gcc -shared -o ../../lib/libmymath.so addd.o subd.o div1d.o
gcc src/ch1/staticlib.c -o bin/dynamiclib -L lib -l mymath -I include
bin/dynamiclib 运行报错,找不到文件???
原因:动态链接器,会到默认的地方寻找动态库,然而默认的地方,没有libmymath.so
解决:设置环境变量,export LD_LIBRARY_PATH = 库路径