2024年10月28日 星期一

rappel - Assembly REPL

官方網址:
https://github.com/yrp604/rappel

rappel提供了一個 assembly的交互式介面環境,可以在執行完指令後馬上看到暫存器狀態的變化,用來嘗試一些指令非常好用。

編譯完後可從./bin/rappel執行,Ctrl + d 退出程序:

./bin/rappel
rax=0000000000000000 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400001 rsp=00007ffd6bf14b30 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf=0, zf=0, of=0, sf=0, pf=0, af=0, df=0]
cs=0033  ss=002b  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202

mov rax, 0x10
rax=0000000000000010 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000000400006 rsp=00007ffd6bf14b30 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
[cf=0, zf=0, of=0, sf=0, pf=0, af=0, df=0]
cs=0033  ss=002b  ds=0000  es=0000  fs=0000  gs=0000            efl=00000202

2024年10月11日 星期五

[Linux] GDB 使用筆記


.gdbinit

可以透過將 .gdbinit檔案放到 home目錄下對 GDB做初始化設定。


set disassemble-next-line on


GDB 指令

設置斷點

(gdb) b
(gdb) break [function name]

執行程式

(gdb) r
(gdb) run [args]

離開 gdb

(gdb) q
(gdb) quit

顯示下一個所要執行的組合語言指令

(gdb) set disassemble-next-line on

確認當前 set disassemble-next-line的設定狀態

(gdb) show disassemble-next-line

顯示暫存器的值

(gdb) i r
(gdb) info registers
(gdb) info registers [registers]

將 rax暫存器的值設為 0x1234

(gdb) set $rax = 0x1234

印出 0x402000地址的值

(gdb) p/x *(0x402000)

2024年9月24日 星期二

[Linux] grep 命令使用筆記

grep是 Linux下用來在檔案中尋找文字的工具。

語法


grep [options] [pattern] [files]

常用 Option


grep command options
Matching Control
-e PATTERNS指定搜尋的 pattern,可以宣告多次。
-i, --ignore-case忽略大小寫。
-v, --invert-match印出不符合的結果。
-wwhole word only。
General Output Control
-c, --count只印出符合結果的行數。
-l只印出符合結果的檔案名稱。
-o只印出符合的部分。
Output Line Prefix Control
-h, --no-filename只顯示符合的結果,不顯示檔案名稱。
-n, --line-number在符合的結果前面加上行號。
Context Line Control
-A NUM印出符合的結果後面 NUM行。
-B NUM印出符合的結果前面 NUM行。
-C NUM印出符合的結果前面及後面 NUM行。
File and Directory Selection
-r, --recursive尋找指定目錄下所有檔案的符合結果。

使用方法


grep "abcd" file.txt
grep -e "abcd" file.txt

在 file.txt中尋找有 abcd字串的行。


grep -e "abcd" -e "efgh" file.txt

在 file.txt中尋找有 abcd字串及有 efgh的行。


grep -e "abcd" -e "efgh" file.txt file2.txt

在 file.txt和 file2.txt中尋找有 abcd字串及有 efgh的行。


grep -r "abcd" .

在當前目錄下的所有檔案中尋找有 abcd字串的行。


grep -r -l "abcd" .

只列出當前目錄下的所有檔案中有 abcd字串的檔案名稱。


2024年8月20日 星期二

[Linux] find 命令使用筆記

find是 Linux下用來尋找檔案及目錄的命令。

語法


find [path] [options] [expression]

常用 Option


find command options
-name [pattern]搜尋符合 pattern的檔案。
-iname [pattern]搜尋符合 pattern的檔案。(case insensitive)
-type [type]搜尋特定類型的檔案。-type f為只搜尋檔案,-type d為只搜尋目錄。
-maxdepth [levels]限制最大的搜尋的目錄層數。
-mindepth [levels]限制最小的搜尋的目錄層數。
-exec [command] {} \;對於每個找到的檔案執行 [command],帶入 {}為找到的檔案。
-delete移除所找到的檔案。

使用方法


find . -name "file.txt"

在當前目錄尋找名為 file.txt的檔案。


find . -iname "file.txt"

忽略大小寫,在當前目錄尋找名為 file.txt的檔案。(case insensitive)


find . -name "*.txt"

在當前目錄尋找名稱結尾為 .txt的檔案


find . -name "*file*" -type -d

在當前目錄尋找名稱帶有 file的目錄


find . -name "*file*" -type -f

在當前目錄尋找名稱帶有 file的檔案


find . -iname "*file*" -exec rm -i {} \;

移除所有帶有 file名稱的檔案


應用


find . -iname "*file*" | grep -c ".*"

計算用 find所找到檔案的數量


find . -iname "*file*" | sort

排序用 find所找到的檔案


find . -iname "*file*" | xargs md5sum

取得找到檔案的 md5值


2024年7月1日 星期一

[Linux] tmux 使用筆記

tmux是個 Linux下的終端機管理程式,可以在同一個終端 (terminal)下同時操作多個程式, 對於透過 SSH連線來使用機器來說非常方便。


tmux指令

開啟新的 tmux session

tmux

開啟名為 <session_name>新的 session

tmux new -s <session_name>

列出當前的所有的 tmux session

tmux ls

attach到 <session_name>的 tmux session

tmux a -t <session_name>

detach當前的 tmux session

tmux detach

關閉session

tmux kill-session -t <session_name>

tmux快捷鍵


tmux快捷鍵
[Ctrl]+b ddetach當前的 tmux session
[Ctrl]+b "垂直分割兩個 pane
[Ctrl]+b %水平分割兩個 pane
[Ctrl]+b [←/↓/↑/→]切換 pane
[Ctrl]+b x關閉當前的 pane
[Ctrl]+b c建立新的 window
[Ctrl]+b n移動到下個 window
[Ctrl]+b p移動到上個 window
[Ctrl]+b <index>移動到第<index>個 window
[Ctrl]+b &關閉當前的 window
[Ctrl]+b w打開操作面板,可以瀏覽所有 tmux session

參考連結:
A beginner's guide to tmux

2024年6月28日 星期五

[Linux] vim 使用筆記

模式 (mode)

一開始認識 vim就要先了解其不同的模式:

  • 普通模式 (Normal Mode)
  • 插入模式 (Insert Mode)
  • 命令列模式 (Command Line Mode)
  • 可視模式 (Visual Mode)

其中最常用是一般模式 (Normal Mode)、插入模式 (Insert Mode)及命令列模式 (Command Line Mode)。一開始進入 vim時的模式為普通模式, 其他模式都要經過普通模式進入,透過 Esc鍵返回。

普通模式 (Normal Mode)


游標移動
h or [←]游標向左移動一個字元
j or [↓]游標向下移動一個字元
k or [↑]游標向上移動一個字元
l or [→]游標向右移動一個字元
可以在指令前加上要執行指令的次數,例如 20l or 20[→],就可以往右移動 20個字元。
[Ctrl] + b or [PgUp]向上移動一頁 (backward)
[Ctrl] + f or [PgDn]向下移動一頁 (forward)
[Ctrl] + u 向上移動半頁 (upward)
[Ctrl] + d 向下移動半頁 (downward)
0 or [Home] 移動到此列的起始位置
$ or [End] 移動到此列最後面非空字元
^ 移動到此列最前面非空字元
+ 移動到下一列最前面的非空字元
- 移動到上一列最前面的非空字元
gg 移動到檔案的第一行
G 移動到檔案的最後一行
{number}G 可以移動到第 {number}行,例如 20G,可以移動到檔案第 20行
H 移動到目前顯示的第一行首字元
M 移動到目前顯示的中間一行首字元
L 移動到目前顯示的最後一行首字元
[Space] 向右移動一個字元
[Enter] 移動到下一行
{number}[Space]可以向右移動 {number}個字元,與[→]不同的是,[Space]會移動到下一行。 {number}[Enter]可以向下移動 {number}行。

搜尋與取代
/{string}向後搜尋 {string}字串
?{string}向前搜尋 {string}字串
n執行上一個搜尋操作
N反向執行上一個搜尋操作
s/{string1}/{string2}/g將此行的 {string1}取代成 {string2}
%s/{string1}/{string2}/g將檔案裡的 {string1}取代成 {string2}
%s/{string1}/{string2}/gc將檔案裡的 {string1}取代成 {string2},取代前需要確認

編輯
x刪除游標後面的字元
X刪除游標前面的字元
dd刪除游標所在的這一行
{number}X及 {number}x可以刪除游標前、後 {number}個字元。 {number}dd可以刪除游標往下 {number}行。
d1G刪除游標到第一行中的內容
dG刪除游標到最後一行的內容
d0刪除游標前的這一行的內容
d$刪除游標後的這一行的內容
yy複製游標所在的這一行 (yank)
{number}yy可以複製游標往下 {number}行。
y1G複製游標到第一行中的內容
yG複製游標到最後一行的內容
y0複製游標前的這一行的內容
y$複製游標後的這一行的內容
p在游標的後一行貼上
P在游標的前一行貼上
J將此行與下一行合成同一行
u回到上一個操作的狀態 (undo)
[Ctrl] + r回到下一個操作的狀態 (redo)
.重複上一個操作

插入模式 (Insert Mode)


進入插入模式
i在游標字元處前插入 (insert)
I從此行第一個非空字元前插入
a在游標字元處後插入 (append)
A從此行最後字元後插入
o插入新的下面一行 (open)
O插入新的上面一行
r進入取代模式,只取代一個字元 (replace)
R進入取代模式,直到離開

命令列模式 (Command Line Mode)


Command Line Mode指令
:w儲存目前檔案變更 (write)
:q離開 vim (quit)
:w!可以強制寫入唯讀檔案。:q!可以強制不儲存離開。
:wq儲存並離開
ZZ若檔案沒有修改,直接離開。若檔案有修改,儲存並離開
:w {filename}將檔案另存到 {filename}
:r {filename}將另外一個檔案的內容加到游標位置的下一行
:! {command}暫時離開 vim並執行 {command}
vim 可以同時打開多個檔案進行編輯。ex: vim a.txt b.txt。
:files列出目前 vim所開啟的檔案
:n編輯下一個檔案
:N編輯上一個檔案

可視模式 (Visual Mode)


Visual Mode指令
v將游標經過的字元反白選擇
V將游標經過的行反白選擇
[Ctrl + v]以blcok的方式進行反白選擇
y複製選擇的內容
d刪除選擇的內容
p貼上選擇的內容

參考連結:
鳥哥私房菜 第九章、vim程式編輯器

2024年6月2日 星期日

[Python] threading

在閱讀關於 python multi-thread(多執行緒)、multi-process(多行程)及GIL的相關文章時,突然想到在公司寫的一個 script。 這 script需要使用同個 api發送不同參數的HTTP request,一開始的寫法是使用 for loop來執行,等到 request結束,再執行下一個。

由於每個 request需要幾十秒才會完成,所以整個 sciprt跑完就要花費好幾分鐘。如果能改寫成 使用 multi-thread的方式來發送 request,就能省下大量的時間。因為 GIL的關係,同時間只會 有一個 thread在執行,但以這 case來說已經很夠用了。

以下是要修改的 sample code,使用 for loop來執行 20次的 request:

import requests

def do_request(url):
    response = requests.get(url)
    print(response.status_code)
    return response

if __name__ == '__main__':
    for i in range(0, 20):
        ret = do_request("https://api.github.com")
        print (ret.json())

使用 python threading來改寫:

import requests
import threading

def do_request(url):
    response = requests.get(url)
    print(response.status_code)
    return response

if __name__ == '__main__':
    thread_list = []
    for i in range(0, 20):
        t = threading.Thread(target=do_request, args=("https://api.github.com",))
        thread_list.append(t)
        t.start()

    for t in thread_list:
        t.join()


宣告 Thread


t = threading.Thread(target=do_request, args=("https://api.github.com",))

建立一個 Thread物件,將要使用 threads來執行的 function傳入 target,並把 target所需要的引數以 tuple的形式傳入 args。


啟動 Thread


t.start()

透過呼叫 start來啟動此 thread。


等待 Thread執行完成


t.join()

使用 join來等待此 thread結束。這裡使用 for loop來等待所有的 thread結束。 若沒有使用 join,thread可能會在主程式後才執行完成。


獲得 Thread的返回值

上面的程式碼雖然可以讓函式使用 thread的方式執行,卻沒辦法得到函式的返回值。其中一個解法是將函式改寫,使其將返回值存到 list中。

import requests
import threading

def do_request(url, index, response_list):
    response = requests.get(url)
    print(response.status_code)
    response_list[index] = response

if __name__ == '__main__':
    thread_list = []
    response_list = [None] * len(range(0, 20))
    for i in range(0, 20):
        t = threading.Thread(target=do_request, args=("https://api.github.com", i, response_list))
        thread_list.append(t)
        t.start()

    for t in thread_list:
        t.join()

    print(response_list)

參考資料:
https://docs.python.org/zh-tw/3/library/threading.html
https://realpython.com/intro-to-python-threading/


2024年3月24日 星期日

ipmitool 命令列表

官方網址:

https://github.com/ipmitool/ipmitool


bmc

顯示 bmc相關資訊

ipmitool bmc info

顯示當前 bmc已啟用選項

ipmitool bmc getenables

啟用/停用 bmc選項

ipmitool bmc setenables <OPTION>=[on|off]

option desctiption
recv_msg_intr Receive Message Queue Interrupt
event_msg_intr Event Message Buffer Full Interrupt
event_msg Event Message Buffer
system_event_log System Event Logging
oem0 OEM-Defined option #0
oem1 OEM-Defined option #1
oem2 OEM-Defined option #2

啟用 Event Message Buffer
ipmitool bmc setenables event_msg=on

停用 Event Message Buffer
ipmitool bmc setenables event_msg=off



sensor

顯示當前 sensor的資訊

ipmitool sensor list

透過 Sensor ID讀取特定 sensor的資訊

ipmitool sensor get "<SERDOR_ID>"


chassis

顯示當前 chassis狀態

ipmitool chassis status


user

顯示 user在 channel的相關資訊

ipmitool user list <CHANNEL_ID>

顯示 channel 1的 user資訊
ipmitool user list 1


設定 user的名稱

ipmitool user set name <USER_ID> <USER_NAME>

設定 user id 2的名稱為 testuser
ipmitool user set name 2 testuser


設定 user的密碼

ipmitool user set password <USER_ID> <USER_NAME>

設定 user id 2的密碼為 test
ipmitool user set password 2 test


啟用 BMC存取

ipmitool user enable <USER_ID>

啟用 user id 2的 BMC存取
ipmitool user enable 2


停用 BMC存取

ipmitool user disable <USER_ID>


channel

顯示 channel的資訊

ipmitool channel info <CHANNEL_ID>

顯示 channel 1的資訊
ipmitool channel info 1


設定 user存取 channel

ipmitool channel setaccess <CHANNEL_ID> <USER_ID> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=<level>]

設定 user id 2在 channel 1的 ipmi on及privilege level為 4
ipmitool channel setaccess 1 2 ipmi=on privilege=4



2024年3月9日 星期六

機械式硬碟相關名詞

最近在讀早期 linux kernel的相關書籍,其在塊設備章節提到 hard disk controller(硬碟控制器)有很多機械硬碟物理層面的相關名詞。 因為這時的 hd controller的操作使用底層的細節,用於操作硬碟控制器的命令參數。



示意圖中是以 3個磁盤(Platters)及 6個磁頭 (Heads)所組成的硬碟,磁盤的兩面都能讀寫。硬碟主要以兩組馬達控制,一組控制磁盤的旋轉,另一組控制磁頭的移動。

Sector (磁區,扇區)
磁區是磁盤上以相同的角度劃出的等分區域,也是硬碟最小的讀寫單位,最開始統一的單位為 512 Bytes。

Track (磁軌,磁道)
磁軌是磁頭在磁盤上以相同半徑所畫出的軌跡。

Cylinder (磁柱,柱面)
磁柱是所有磁盤上相同半徑的磁道所形成的圓柱體。

CHS 定址

早期的硬碟定址使用 Cylinder-Head-Sector方法,從上方的硬碟物理構造可以看出,以這三個參數就能定位到某個確定的磁區。這方法在之後被 LBA(Logic Block Address)所取代。

2024年1月15日 星期一

com0com - Null modem emulator

官方網址:
https://com0com.sourceforge.net/

com0com可以在 Windows下虛擬出一組對接com port。

安裝完後,可用putty打開兩個com port進行測試是否可互傳訊息。