我在 C 中創建了一個非常簡單的函式,它使用strlen()from<string.h>回傳char*變數的長度:
int length(char *str) {
return strlen(str);
}
這是相應的 x86_64 程式集objdump -M intel -d a.out:
00000000000011a8 <length>:
11a8: f3 0f 1e fa endbr64
11ac: 55 push rbp
11ad: 48 89 e5 mov rbp,rsp
11b0: 48 83 ec 10 sub rsp,0x10
11b4: 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi
11b8: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
11bc: 48 89 c7 mov rdi,rax
11bf: e8 ac fe ff ff call 1070 <strlen@plt>
11c4: c9 leave
11c5: c3 ret
這是我目前對代碼的理解(如果有任何錯誤,請糾正我):
00000000000011a8 <length>:
11a8: f3 0f 1e fa endbr64
11ac: 55 push rbp // stack setup, old rbp of previous frame pushed
11ad: 48 89 e5 mov rbp,rsp // rbp and rsp point to same place
11b0: 48 83 ec 10 sub rsp,0x10 // space is made for arguments
11b4: 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi // rdi stores argument and is moved into the space made on the line 11b0
11b8: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8] // value at memory address rbp-0x8 aka argument is stored in rax
11bc: 48 89 c7 mov rdi,rax // move the value into rdi for function call
11bf: e8 ac fe ff ff call 1070 <strlen@plt> // strlen() is called
11c4: c9 leave // stack clear up
11c5: c3 ret // return address popped and control flow resumes
如果以上任何內容不正確,請糾正我,其次如何call 1070 <strlen@plt>回傳值?因為 strlen() 函式回傳一個字串的長度,我原以為某些東西會被移到rax暫存器中(我認為它通常用于回傳值)。但是沒有移動到任何內容rax并且它沒有顯示在程式集中回傳的值。
最后這里是地址 1070 的代碼(來自呼叫 1070 strlen@plt)
0000000000001070 <strlen@plt>:
1070: f3 0f 1e fa endbr64
1074: f2 ff 25 45 2f 00 00 bnd jmp QWORD PTR [rip 0x2f45] # 3fc0 <strlen@GLIBC_2.2.5>
107b: 0f 1f 44 00 00 nop DWORD PTR [rax rax*1 0x0]
uj5u.com熱心網友回復:
call 1070 strlen@plt 如何回傳值?
在strlen把它的結果到rax暫存器,它方便也是在那里你的length()功能應該把它的回傳值。
在優化下,您length()可以編譯為一條指令:jmp strlen-- 引數已經在 中rdi,回傳值將在 中rax。
聚苯乙烯
最后這里是地址 1070 的代碼
那不是strlen. 這是一個“PLT 跳轉存根”。要了解那是什么,您可以閱讀這篇博文。
此外,從那個小地址,你可以看到這是一個 PIE 可執行檔案:那些只是影像基地址的偏移量;運行時地址將類似于0x55...
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/393266.html
