LMAY75
October 16, 2020, 5:35pm
1
I’m working on reversing a stripped binary and currently trying to find the location of main. I dropped into the entry point and printed the first 15 instructions from the $rip and found this:
=> 0x4006a0: xor ebp,ebp
0x4006a2: mov r9,rdx
0x4006a5: pop rsi
0x4006a6: mov rdx,rsp
0x4006a9: and rsp,0xfffffffffffffff0
0x4006ad: push rax
0x4006ae: push rsp
0x4006af: mov r8,0x400a50
0x4006b6: mov rcx,0x4009e0
0x4006bd: mov rdi,0x40085d
0x4006c4: call 0x400610 <__libc_start_main@plt>
0x4006c9: hlt
0x4006ca: nop WORD PTR [rax+rax*1+0x0]
0x4006d0: mov eax,0x60107f
0x4006d5: push rbp
Great, yay we see the call to libc_main_start. Reading this article here: Working With Stripped Binaries in GDB | by Faisal | Medium it seems so suggest the address for main is always specified in the instruction directly above the function call.
Why is that? Should it not be within the function call, and if it is then where is it? Stepping into the call shows:
→ 0x4006c4 call 0x400610 <__libc_start_main@plt>
↳ 0x400610 <__libc_start_main@plt+0> jmp QWORD PTR [rip+0x200a12] # 0x601028 <__libc_start_main@got.plt>
0x400616 <__libc_start_main@plt+6> push 0x2
0x40061b <__libc_start_main@plt+11> jmp 0x4005e0
0x400620 <srand@plt+0> jmp QWORD PTR [rip+0x200a0a] # 0x601030 <srand@got.plt>
0x400626 <srand@plt+6> push 0x3
0x40062b <srand@plt+11> jmp 0x4005e0
With no mention to the address at $rdi
As discussed, I am not sure I am the best person to answer this - hopefully bumping it will draw a bit more attention though.
So just to check, rdi
normally contains the first argument - have I remembered that correctly?
Why would the address in rdi
be in main?
LMAY75
October 16, 2020, 6:07pm
3
Type your comment> @TazWake said:
As discussed, I am not sure I am the best person to answer this - hopefully bumping it will draw a bit more attention though.
So just to check, rdi
normally contains the first argument - have I remembered that correctly?
Why would the address in rdi
be in main?
Okay so the address for main is being stored into $rdi. Setting 0x40085d as a breakpoint and continuing drops you into main.
Edit: ohh so rdi contains the first arg? I didnt know that but it would make sense and answer my question. Thanks!
@LMAY75 said:
@TazWake said:
As discussed, I am not sure I am the best person to answer this - hopefully bumping it will draw a bit more attention though.
So just to check, rdi
normally contains the first argument - have I remembered that correctly?
Why would the address in rdi
be in main?
Okay so the address for main is being stored into $rdi. Setting 0x40085d as a breakpoint and continuing drops you into main.
Edit: ohh so rdi contains the first arg? I didnt know that but it would make sense and answer my question. Thanks!
Indeed. The calling convention (aka ABI) on x64 Linux is as follows (for “integer arguments”):
function($rdi, $rsi, $rdx, $rcx, $r8, $r9)
In cases where you need more parameters, they will be pushed to the stack.
And __libc_start_main
is defined as:
int __libc_start_main(int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end));
LMAY75
October 16, 2020, 8:28pm
5
Type your comment> @HomeSen said:
@LMAY75 said:
(Quote)
Indeed. The calling convention (aka ABI) on x64 Linux is as follows (for “integer arguments”):
function($rdi, $rsi, $rdx, $rcx, $r8, $r9)
In cases where you need more parameters, they will be pushed to the stack.
And __libc_start_main is defined as:
int __libc_start_main(int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (rtld_fini) (void), void ( stack_end));
Fantastic, thanks this helped a lot!