I have made a function in C which is pretty straightforward, it uses strlen()
from <string.h>
to return the length of a char*
variable:
int length(char *str) {
return strlen(str);
}
Here is the corresponding x86_64 assembly from 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
Here is my current understanding of the code (please correct me if anything seems wrong):
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
If anything above is incorrect please correct me, secondly how does call 1070 <strlen@plt>
return a value? because the strlen() function returns the length of a string and i would have thought that something would have been moved into the rax
register (which i believe is commonly used for return values). But nothing is moved into rax
and it does not show a value returned in the assembly.
Lastly here is the code at address 1070 (from call 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]
CodePudding user response:
how does call 1070 strlen@plt return a value?
The strlen
puts its result into rax
register, which conveniently is also where your length()
function should put its return value.
Under optimization your length()
could be compiled into a single instruction: jmp strlen
-- the parameter is already in rdi
, and the return value will be in rax
.
P.S.
Lastly here is the code at address 1070
That isn't the actual code of strlen
. This is a "PLT jump stub". To understand what that is, you could read this blog post.
Also, from that small address, you can see this is a PIE executable: those are just offsets from the image base address; the runtime address will be something like 0x55...