I have the following disassembly of a main function in which a user input is stored using scanf function (at address 0x0000089c
). Due to the comparison that is made, I suppose that the user input is stored into the rsp register but I cannot figure out why, as rsp doesn't seem to be pushed on the stack (at least, not near the call to the scanf function).
Here is the disassembly:
0x00000850 sub rsp, 0x18
0x00000854 mov rax, qword fs:[0x28]
0x0000085d mov qword [canary], rax
0x00000862 xor eax, eax
0x00000864 call fcn.00000a3c
0x00000869 lea rsi, str.Insert_input:
0x00000870 mov edi, 1
0x00000875 xor eax, eax
0x00000877 mov dword [rsp], 0
0x0000087e mov dword [var_4h], 0
0x00000886 call sym.imp.__printf_chk
0x0000088b lea rdx, [var_4h]
0x00000890 lea rdi, str.u__u ; "%u %u" ;const char *format
0x00000897 xor eax, eax
0x00000899 mov rsi, rsp
0x0000089c call sym.imp.__isoc99_scanf ; int scanf(const char *format)
0x000008a1 mov eax, dword [rsp]
0x000008a4 cmp eax, 0x1336
0x000008a9 jg 0x867
CodePudding user response:
On x86_64, parameters are passed in registers, so your call to scanf has 3 parameters stored in 3 registers:
rdi
pointer to the string"%u %u"
, the format to parse (two unsigned integers)rsi
should be aunsigned *
, pointer to where to put the first parsed integerrdx
pointer to where to put the second parsed integer.
If you look just before the call, rsi
is set to rsp
(the stack pointer) while rdx
is set to point at the global variable var_4h
(an extern symbol not defined here).
The stack is used to hold local variables, and in this case rsp
points at a block 0x18 "free" bytes (allocated in the first instruction in your block), which is enough space for 6 integers. The one at offset 0 from rsp
is what rsi
points to, and it is the value read by the mov instruction immediately after the call.