一、openEuler和VMware
獲取openEuler鏡像
下載鏡像和其sha256文件
完整性檢驗
Windows下使用命令 certutil -hashfile 文件名 sha256
獲取文件的sha256值
我這第一次莫名其妙地下載了LTS-SP1-x86_64,所以哈希值不對,重新下一下sp2
這回對了
VMware創建並安裝openEuler
閱讀並操作了近十篇博客后,還是推薦這個教程
安裝很多次后,個人建議
-
安裝系統時,軟件選擇中,選擇最小安裝后,還應該選擇右側的“標准、開發工具、系統工具”三項,
方便進入終端之后,有一定的工具可以用 -
檢查網絡和主機名一項,看看網絡是否連接,是否有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 = 庫路徑