程式一開始可以在IDA看到程式Call了一個__main函數,但在Ubuntu的GDB中,程式則直接開始執行其他運算,這是因為IDA這邊會進行初始化的動作,而不同的編譯器在這個階段的行為可能有所不同,這次的環境是Cygwin,如果採用動態編譯的話,就可以觀察到當程式跳入__main函數時,實際上是執行了Cygwin的DLL。
這邊會做的事情很多,會做保護等等的動作,有興趣的可以深入研究。
接著就是將我們的字串放入暫存器了,可以看到下一行是把一串Hex丟到RAX當中,而這一串Hex我們利用xxd解出來發現是ASCII code的HelloWor字串。
接著會有很多的疑問,第一個很明顯的是怎麼是反的,第二個是為什麼少了幾個字,還有什麼是MOVABS。
先從簡單的部分開始,觀察少了幾個字的狀況,稍微往下檢查程式碼,就會發現有一組21646C的十六進位值被放入了 RBP 的相對位址,這組數值很明顯是剩餘的字串部分,那麼為什麼要將它分開呢? 這與 RAX 的大小限制有關,RAX 是 64 位元的暫存器,而每個英文字母佔8個bits,也就是1 Byte,因此 RAX 最多只能容納 8 個Bytes,這也對應了HelloWor這8個英文字母。
再來解釋一下MOV和MOVABS的關係,由於Ubuntu的組合語言是由AT&T轉換過來的,在 AT&T 語法中,MOV指令會帶有後綴,用於定義記憶體大小,關於這方面的詳細資訊,可以參考AMD64 Instruction Set Overview或GNU assembler等相關資訊。
為什麼字是反的這個問題因為比較重要,我們留到下一章詳細說明。